Port to GTK4
Early GTK 3.9x port
In 2018, Ernestas's GSoC project produced port of Files to an early development version of what would become GTK4. It included a port of the custom EelCanvas widget (used to implement the Files icon view). It was very useful, both for the development of GTK 4 itself, as well as the preparation of the Files app for the future. Many compatible changes were applied to the master branch to make a later port to GTK4 useful. The present issue preserves the history of that effort.
Show 2018 content
End-of-GSoC status report
Nautilus is operational at this point, but not exactly ready to face the public. Drag-and-drop is not so much a straightforward port of the original code, so I’m about ready to give up on making it work exactly the same as in the GTK+ 3 versions. The
LINK action is no longer accessible via the ctrl-shift modifier, likely due to it not being supported in Wayland; it’s not quite possible to have Nautilus default to
MOVE when the action bitmask contains
ASK, and both of those will take precedence, making things very awkward, as one can’t even pop up a menu at pointer at the moment due to a bug in GTK+. I’ve wasted two weeks trying to investigate what’s happening in GTK+ and filed several issues, but the problem is that some of them are “things working as expected, even though there exists a shortcoming in this particular backend”, others are unsolved problems due to developers being focused on other things, such as reworking how keyboard shortcuts work, which leads me to…
Another pain point pending being addressed - action accelerators. In a post-event-controller world, our hackaround of “checking whether the current focus widget is a
GtkEditable, and, if so, forwarding the key event to it and stopping propagation” does not work anymore, meaning that you’re screwed if you want to undo or select all while renaming a file, the former will undo the last file operation and the latter will select all files in the view, instead. These issues could probably be fixed by using key bindings, which work only on the currently-focused widget, since they’re not willy-nilly added to the toplevel.
The operations button reveal animation is broken as well, given that
GtkWidget::draw has been removed. I removed things that weren’t used in our copy of libegg, but this one remains a head-scratcher. Maybe
IdeBoxTheatric could be turned into a widget and do its thing in
snapshot()? Who knows. Simply adding a CSS class to set the background doesn’t work, given that the position and size are also part of the animation.
Related GTK+ issues and MRs
gtk!281 (closed) (Actually contains a fix for the sidebar rejecting drops)
gtk#1257 (closed) (Broken
gtk#1260 (closed) (I wanted to use this to play compositor in Nautilus and retain compatibility wrt drop actions, since now
It’s high time Nautilus once again got ahead of the game by using cutting-edge technology. The plan is as follows:
Before the switch (up to 4 weeks)
gnome-desktop (up to 1 week)
gnome-desktop links against GTK+ 3, which is a major roadblock, but this can be worked around until things happen.
The plan so far is to
copy the thumbnailing code to Nautilus.
However, this will require adding a dependency to seccomp (build time) and bubblewrap (runtime). An alternative could be having a separate D-Bus-activatable service that links to gnome-desktop.
eel (up to 1 week)
Our pet eel pulls in GTK+ 3 via GAIL. Taking caring of this will require
making use of ATK (implementing
AtkTextIfaceinstead of writing a custom one).
Nautilus (up to 2 weeks)
Replacing uses of deprecated
Dropping deprecated event handlers by either using gestures or overriding the
At the time of switch (up to 6 weeks)
libgd (up to 2 weeks)
Since Nautilus does not use much from libgd, utilities that are needed can be copied. The tagged entry requires more work and will at first be reimplemented similar to Matthias’ experiment.
Copy code from libgd
Write a GTK+ 4-ready tagged entry widget.
An implementation exists at https://gitlab.gnome.org/ernestask/tagged-entry.
Nautilus (up to 4 weeks)
This will be a singular big push, so makes no sense to split work into subtasks.
Changes include, but are not limited to (as GTK+ 4 evolves):
- Updating the GTK+ code getter for
GtkPlacesSidebarto the getter
- Getting rid of
GdkPixbufand using paintables more liberally
- Image and video file thumbnails framing needs to be redone
- Adapting custom widget size allocation code to API changes
forall()override in containers
include_internalsisn’t passed anymore
- Ceasing to create new
- Happens in a few places for event handling, the canvas being the sorest point
- Adapting to changes in
- No longer takes icon size, and
GtkIconSizelost many a value, meaning that, in some cases, the size will have to be hardcoded/taken from the theme
- Adapting to changes in
- Should be used as a container from now on, doesn’t have any special
GtkImageAPI to set the image
- Removing style properties
- Adapting to changes in
- Getters don’t take state arguments
- Removing custom instances of
- Canvas view is guilty of this; not using widgets means that synthesis is hand-rolled
- Adapting to changes in clipboard APIs (GtkClipboard is gone, should be replaced with GdkClipboard)
- Not just a simple rename
- Adapting to changes in DnD API (lots of changes; GdkDragContext split into GdkDrag and GdkDrop, changes in signal handler signatures, etc.)
- Drag gestures should be used instead of listening to widget signals (gtk#1095 (closed))
GtkCenterBoxwhenever the center widget is set for a
- Adapting to
- Padding and expansion/alignment should be controlled manually
- More event controllers
- Chaining up to parent event handlers is no longer possible (although
GtkEventControllerKeyallows forwarding events, which would only be useful if
After the switch (up to 4 weeks)
Port to GTK+ 4
Total time estimate: up to 14 weeks
- If canvas view is a pain (editor’s note: it always is), we will disable canvas view with a compile time switch while we slowly implement everything we need to switch to the new views by default over time.
Remove instances of enabling widget visibility, as that is default behavior in GTK+ 4.
GNOME 42 porting effort
During the 42 development cycle, the porting is happening on the master branch. GTK4 has changed a lot since 2018, so a rebase of the early port branch was not an option, and a new roadmap has been created. However, as much as possible of that early branch is getting cherry-picked.
Target is for the switch to happen before the GNOME 42.alpha release.
Contingency plan if we fail the target is to skip the 42 release (backport bugfixes to gnome-41 branch).
Update: The port wasn't ready in time for 42 but neither was the release skipped. Instead, a
gnome-42 branch has been forked from
master with the port reverted, but benefitting from some side effects of the porting effort, such as the new pathbar.
Before the switch
The steps before the switch to GTK 4 can be worked on independently and merged in any order.
Complete the "preparation in GTK 3.x" steps (steps board)
Reimplement pathbar without custom widgetry. !730 (merged)
Prepare the new grid view. !717 (merged)
Stop using libgd/ !721 (merged)
- Temporary regression: tagged entry for search filters.
- Temporary regression: list view lost thumbnail frames, yet has no shadows.
Introduce a copy of GtkPlacesSidebar and use it instead. !741 (merged)
Stop using and remove src/animation/ (temporary regression in operations button). !743 (merged)
Disable code that needs reimplementation (temporary regressions) !743 (merged)
- Disable clipboard and drag’n’drop code.
- Drop GEmblemedIcon and cairo-based support for HDPI icons.
- Disable A11y code (temporary regression).
- Disable interactive tests, dependant on gtk_main().
- Disable audio-video-properties extension
Review the extension API which adds widgets.
GTK 3->4 !757 (merged)
- libgnome-desktop->libgnome-desktop-4, libportal-gtk3->libportal-gtk4.
- libhandy->libadwaita and Hdy->Adw mass renaming
- Update GtkPlacesSidebar and GtkPlacesView code (copy from GTK?)
- Fix things until it builds (following advice from the porting guide).
After the switch
Swap GtkFlowBox for GtkGridView. #319 (closed)
Replace GtkTreeView with GtkColumnView !817 (merged)
Reintroduce drag'n'drop support. #2267 (closed)
Reitroduce clipboard support. !759 (merged)
Reintroduce tagged entry. !824 (merged)
Reintroduce HDPI icons !931 (merged)
Reintroduce emblems #2017 (closed) !870 (merged)
Reintroduce operations button's animation (libadwaita animations?)abandoned
Use new a11y API. !906 (merged)
Reimplement interactive tests without gtk_main() #1993 (closed)
Port the audio-video-properties extension (if totem is not yet ported) !829 (merged)
Fix compress formats popover #2084 (closed), !766 (merged)
Bring back "Format..." option to sidebar context menu.
Update screenshots referenced in appdata file !946 (merged)
GNOME 43: finishing the port
The work wasn't ready for production in time for 42.beta, so it's been postponed to version 43.
The development continues in the
master branch. The final milestone (ticking all checkboxes above) should be achievable before the alpha release, allowing for extensive testing and even new features.