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
!266 (closed)
Associated merge request: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 COPY
or 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 ASK
)
gtk#1260 (closed) (I wanted to use this to play compositor in Nautilus and retain compatibility wrt drop actions, since now ASK
> COPY
> MOVE
)
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 AtkTextIface
instead of writing a custom one).
Nautilus (up to 2 weeks)
-
Replacing uses of deprecated GtkStyleContext
API. -
Dropping deprecated event handlers by either using gestures or overriding the event
vfunc/connecting to::event
.
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.
-
Done
Changes include, but are not limited to (as GTK+ 4 evolves):
- Updating the GTK+ code getter for
GtkPlacesView
- Adding
GtkPlacesSidebar
to the getter
- Getting rid of
GdkPixbuf
and using paintables more liberally - Image and video file thumbnails framing needs to be redone
- Adapting custom widget size allocation code to API changes
- Replacing
forall()
override in containers -
include_internals
isn’t passed anymore - Ceasing to create new
GdkSurface
s - Happens in a few places for event handling, the canvas being the sorest point
- Adapting to changes in
GtkImage
API - No longer takes icon size, and
GtkIconSize
lost many a value, meaning that, in some cases, the size will have to be hardcoded/taken from the theme - Adapting to changes in
GtkButton
API - Should be used as a container from now on, doesn’t have any special
GtkImage
API to set the image - Removing style properties
- Adapting to changes in
GtkStyleContext
API - Getters don’t take state arguments
- Removing custom instances of
GdkEvent
- 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))
- Using
GtkCenterBox
whenever the center widget is set for aGtkBox
- Adapting to
GtkBox
API changes - Padding and expansion/alignment should be controlled manually
- More event controllers
- Chaining up to parent event handlers is no longer possible (although
GtkEventControllerKey
allows forwarding events, which would only be useful ifNautilusLocationEntry
used composition)
After the switch (up to 4 weeks)
libgd
-
Upstream GdTaggedEntry
-
Port to GTK+ 4
Total time estimate: up to 14 weeks
Contingency plan
- 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.
Non-goals
-
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.
The switch
-
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) -
Address regressions listed in !717 (merged): gtk#3462 (closed) #2087 (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.