Skip to content

GTK4 Migration and Wayland Integration for Sugar Shell - #1106

Open
Dev10-sys wants to merge 26 commits into
sugarlabs:gtk4-portfrom
Dev10-sys:gtk4-migration-structured
Open

GTK4 Migration and Wayland Integration for Sugar Shell#1106
Dev10-sys wants to merge 26 commits into
sugarlabs:gtk4-portfrom
Dev10-sys:gtk4-migration-structured

Conversation

@Dev10-sys

@Dev10-sys Dev10-sys commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

This pull request ports the core UI components, background handlers, and window management of the Sugar desktop environment to GTK4 and Wayland. Sugar previously ran in an X11 session, and this PR transitions the shell to run natively on Wayland using Casilda as the embedded compositor. With this PR, the core shell systems, frame, journal, control panel, and popup/palette systems are fully migrated to GTK4, enabling native Wayland activity launching directly within the shell.

What I Ported

I focused on migrating the critical components of the Sugar Shell:

  • The Frame: Updated edge trays, floating toolbars, and animations using Gtk.Revealer.
  • The Journal: Ported core list views, object choosers, and search toolbars to modern grid layouts like Gtk.FlowBox.
  • The Neighborhood View: Updated spatial layouts and home screen ring rendering to GTK4 coordinate calculations and Gtk.Snapshot.
  • Clipboard and Palette Systems: Replaced legacy Gtk.Menu implementations with Gtk.PopoverMenu / Gtk.Popover and updated clipboard interactions to Gdk.Clipboard.
  • Control Panel: Updated GUI layouts, network configurations, and dynamic monitor scaling with Gdk.Display.

Technical Details (X11 to Wayland Migration)

  • Moving from X11 window embedding to Casilda (Wayland compositor) fundamentally changed window management. I completely stripped deprecated X11 window attributes (like Gdk.WindowTypeHint.DIALOG and SPLASHSCREEN).
  • I resolved Wayland's strict window mapping constraints by explicitly enforcing set_transient_for() on all modal alert dialogs, attaching them directly to the primary shell window.
  • I added file descriptor (fd >= 0) validity checks for the Wayland compositor socket to prevent silent launch failures.
  • I completely removed legacy container packing (Gtk.VBox, Gtk.HBox, add) and replaced them with Gtk.Box and append.
  • I transitioned from deprecated event boxes and X11 specific signal handlers to modern GTK4 input mechanisms like Gtk.EventControllerKey and Gtk.GestureClick.
  • GTK4 introduces major changes to the CSS node engine by abandoning element tags for CSS nodes. The legacy styling previously handled by sugar-artwork has been ported to a dedicated GTK4 theme in the sugar-artwork repository (gtk4 branch).

Proper Testing Methodology

The migration has been comprehensively tested within a Debian live-build VirtualBox environment to ensure stability across shell views and activity interactions:

  • Toolkit & Extension Integration: Built and installed sugar-ext via Meson, and linked sugar-toolkit-gtk4 alongside sugar by dynamically configuring PYTHONPATH, GI_TYPELIB_PATH, and LD_LIBRARY_PATH.
  • Theme Validation: Applied the GTK4 stylesheet from sugar-artwork (gtk4 branch) to verify CSS node parsing, dropdown styling, control panel section contrast, and treeview selection states under GTK_DEBUG=css.
  • Activity Lifecycle Testing: Verified end-to-end launching, window embedding over the Casilda Wayland socket, focus propagation, and frame animations using GTK4-migrated activities (Calculate, ImageViewer, Log, Chat, Browse).

Testing Notes for Reviewers:
Reviewers can test this PR in any GTK4/Wayland-capable Debian or Fedora environment by building sugar-ext, pointing PYTHONPATH to sugar/src and sugar-toolkit-gtk4/src, installing the sugar-artwork GTK4 theme under /usr/share/themes/sugar-72/gtk-4.0/, and launching python3 src/jarabe/main.py.

(Note for reviewers: To provide a fully functional GTK4 environment that can be accurately tested end-to-end, this port is submitted as a unified PR. The work is strictly structured into multiple commits, allowing you to review each component incrementally.)

@quozl

quozl commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Yay. 💯

@walterbender

Copy link
Copy Markdown
Member

Nice that this is finally progressing.

@Dev10-sys
Dev10-sys force-pushed the gtk4-migration-structured branch 2 times, most recently from 6916089 to bbbd88c Compare June 28, 2026 04:53

@chimosky chimosky left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something to look at is your empty line deletions, I'm assuming it's something in your workflow that's doing that.

Comment thread bin/sugar.in Outdated
Comment thread src/jarabe/apisocket.py
Comment thread src/jarabe/main.py Outdated
Comment thread src/jarabe/model/screenshot.py
Comment thread src/jarabe/model/session.py Outdated
Comment thread src/jarabe/model/shell.py
Comment thread src/jarabe/model/shell.py Outdated
Comment thread src/jarabe/model/shell.py
Comment thread src/jarabe/model/shell.py Outdated
Comment thread src/jarabe/model/speech.py
Comment thread src/jarabe/model/speech.py
Comment thread data/sugar.css Outdated
Comment thread src/jarabe/desktop/activitieslist.py Outdated
Comment thread src/jarabe/desktop/favoritesview.py Outdated
@chimosky

Copy link
Copy Markdown
Member

Reviewed 8e4d4e1, not tested.

@Dev10-sys

Copy link
Copy Markdown
Contributor Author

Hi @chimosky , i have addressed all your review comments. Please review !

@chimosky

chimosky commented Jul 3, 2026

Copy link
Copy Markdown
Member

You're yet to respond to some of my comments above.

Comment thread src/jarabe/desktop/homebox.py
Comment thread src/jarabe/desktop/homewindow.py
Comment thread src/jarabe/desktop/grid.py
Comment thread src/jarabe/desktop/grid.py

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make the top-level class definitions pep8 compliant.

Comment thread src/jarabe/desktop/transitionbox.py
Comment thread src/jarabe/desktop/viewcontainer.py
Comment thread src/jarabe/desktop/viewtoolbar.py Outdated
Comment thread src/jarabe/desktop/viewtoolbar.py

@chimosky chimosky left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a tool in your workflow that keeps deleting the two lines before top-level class definitions? You should change this particular thing it does.

AFAIK, Python style guide hasn't changed, but this keeps ignoring that.

Comment thread src/jarabe/frame/activitiestray.py
Comment thread src/jarabe/frame/activitiestray.py
Comment thread src/jarabe/frame/activitiestray.py
Comment thread src/jarabe/frame/activitiestray.py
Comment thread src/jarabe/frame/__init__.py
Comment thread src/jarabe/frame/clipboard.py
@Dev10-sys
Dev10-sys force-pushed the gtk4-migration-structured branch from d933ec0 to 3179f5f Compare July 5, 2026 08:39

@MostlyKIGuess MostlyKIGuess left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have been running this locally on GTK4 with the Casilda compositor (via nix), and it boots to the home view!! Journal is now registered on the shell stack, and the CSS no longer uses !important. Nice.

Most of the review so far has been by reading. The inline notes are the runtime crashes I actually hit while navigating: the palettes, the object chooser, and an fd leak on activity launch. All are small. The bigger items, the activity chooser and the activities list (still on the deprecated Gtk.TreeView / CellRenderer, which probably wants a Gtk.ColumnView rewrite), I will write up separately. Happy to pair on any of these.

Comment thread src/jarabe/view/palettes.py
Comment thread src/jarabe/view/palettes.py
Comment thread src/jarabe/journal/objectchooser.py Outdated
vbox.set_visible(True)

title_box = TitleBox(what_filter, filter_type)
title_box.connect('volume-changed', self.__volume_changed_cb)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TitleBox is now a plain Gtk.Box (defined at line 196) with no __gsignals__, so this raises unknown signal name: volume-changed and the chooser fails to construct. TitleBox no longer carries the volume buttons, so this connect and the now-dead __volume_changed_cb at line 170 can both go.

Comment thread src/jarabe/journal/journalactivity.py Outdated
Comment thread src/jarabe/util/activityfactory.py Outdated
if os.name != 'nt' and pass_fds:
kwargs['pass_fds'] = pass_fds

child = subprocess.Popen([str(s) for s in command], **kwargs)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The compositor fd from get_client_socket_fd() (line 233) is handed to the child via pass_fds (line 238) but never closed in the parent after this Popen, so each activity launch leaks one Wayland socket fd. An os.close(fd) after the spawn fixes it. (dev_null on line 227 is a Python file object so GC closes it, but a with block would be cleaner.)

@Dev10-sys

Copy link
Copy Markdown
Contributor Author

Hey @MostlyKIGuess , I've addressed the issues you pointed out. Replaced set_icon_widget with set_image on both PaletteMenuItems, removed the dead volume-changed connect and its callback from objectchooser along with the unused import, fixed the ObjectChooser call in __choose_project_cb to pass None instead of self since JournalActivity is a Gtk.Box, and added os.close(fd) after the Popen call to stop the socket leak. Also moved dev_null into a with block while I was at it.

@Dev10-sys
Dev10-sys force-pushed the gtk4-migration-structured branch 2 times, most recently from 3fbe6e1 to 5638b4a Compare August 3, 2026 17:45
Updated the underlying build scripts and executable binaries to link against GTK4. Removed legacy GTK3 dependencies and updated the environment variables required for the new toolkit.
Migrated the foundational base classes and application models to GTK4. Replaced deprecated lifecycle methods and updated the core application initialization to use Gtk.Application.
Added a comprehensive GTK4 CSS stylesheet (data/sugar.css) that ports the core visual identity, colors, and layout metrics previously provided by the GTK3 sugar-artwork repository. Since GTK4 introduces major changes to the CSS node engine, bundling these baseline styles directly in the sugar repo ensures UI consistency during the migration.
Updated the activities list and favorites ring to GTK4. Migrated the UI components to use modern list models and replaced deprecated event boxes with Gtk.GestureClick.
Migrated the spatial desktop layouts and home screen ring rendering to GTK4. Updated the coordinate calculation logic and replaced legacy drawing areas with Gtk.Snapshot where appropriate.
Updated the main desktop rendering views and toolbars to GTK4. Replaced legacy container packing with append() and updated the layout logic for dynamic resizing.
Migrated the edge trays and floating toolbars used by the Sugar Frame. Replaced deprecated window types and used Gtk.Revealer for smooth slide-in animations.
Updated the clipboard manager and notification trays to GTK4. Migrated clipboard operations to use Gdk.Clipboard and updated the notification popups to use modern overlay positioning.
Migrated the core Journal list views and icon layouts to GTK4. Replaced the deprecated Gtk.IconView with Gtk.FlowBox for a more modern and responsive grid layout.
Updated the Journal data models and floating palettes to GTK4. Replaced legacy menu items with popover menus and updated the palette positioning logic to work with Wayland constraints.
Ported the main Journal toolbars and search input entries to GTK4. Replaced legacy Gtk.Toolbar widgets with styled Gtk.Box containers and updated the search entry event handling.
Migrated the network configuration language selector and keyboard settings panels to GTK4. Updated the list boxes and selection models to use modern GTK4 widget properties.
Updated the backup management and about dialog sections in the control panel to GTK4. Replaced deprecated layout containers and updated the scrolling views to use Gtk.ScrolledWindow correctly.
Migrated the updater and power management modules to GTK4. Updated their respective UI layouts to use Gtk.Box and replaced legacy event connections with modern signal handling.
Ported the device tray icons and battery indicators to GTK4. Replaced deprecated drawing methods and updated icon scaling to work seamlessly with the new rendering engine.
Updated the global key handling logic to use Gtk.EventControllerKey instead of the legacy SugarExt key grabber. This ensures keyboard shortcuts are captured correctly in the GTK4 environment.
Migrated right-click context menus to use Gtk.PopoverMenu instead of the deprecated Gtk.Menu. Upgraded the source viewing components to be compatible with GtkSourceView 5.
Updated the view toolbars and standalone modal dialogs to use Gtk.Box layouts instead of deprecated Gtk.Toolbar. Migrated the associated event handling to use modern event controllers.
Migrated the introductory wizard along with the age and gender pickers. Updated the drawing areas and event handlers to use modern GTK4 rendering and input controllers.
Ported the core Control Panel GUI including alerts and section views to GTK4. Replaced deprecated container additions with append() and updated toolbar packing to match the new GTK4 layout paradigms.
Updated the web account services to use modern GTK4 widget packing methods. Modified the unit test suite to initialize GTK4 environments properly and replaced deprecated Gtk.main() calls with GLib.MainLoop.
Updated the downloader to use the latest Soup.Session initialization parameters required by libsoup3. Migrated telepathy connection watchers and other background utilities to use GLib.MainLoop instead of the deprecated GObject main loop.
…yling

Fix GtkWindow closing across Shell, ActivityChooser, and ViewHelp to use
close() instead of GTK3 destroy() call.

Fix popover dismissal and unparenting in favoritesview and frame trays to avoid
GTK4 widget lifecycle leaks.

Update PaletteMenuItem icon rendering, battery D-Bus client, and Control Panel
styles for GTK4.

Migrate keyboard extensions to Wayland and harden GDK display handling.
@Dev10-sys
Dev10-sys force-pushed the gtk4-migration-structured branch from 5638b4a to 88d70d9 Compare August 3, 2026 17:50
Comment thread src/jarabe/journal/expandedentry.py Outdated
Use set_css_classes() for widget background styling across journal views
and control panel per review feedback. Clean up activitiestray and shell
window handling to use native GTK4 methods. Remove legacy subprocess
casilda launcher from main.py and fix viewcontainer measurement.
Remove hardcoded cell text foreground properties in ActivitiesTreeView to allow
theme CSS styling, and configure favorite icon cell renderer fill and stroke colors.
Ensure activity window registration before sending DBus active state, and
restore 500ms frame revealer transition duration. Migrate viewsource modal
event to map signal and clean up transition delay timers.
@Dev10-sys Dev10-sys changed the title Core GTK4 Migration and Wayland Integration for Sugar Shell GTK4 Migration and Wayland Integration for Sugar Shell Aug 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants