August - GTK4 migration - dboles
25 de Agosto de 2023 às 14:42
A new month brings a new pile of great progress to make Inkscape ready for GTK4! And also a very useful selection of fixes, refactors or 'nice-to-haves' found along the way. In all, I’m just shy of 100 committed merge requests now, and I think that’s a great excuse to have a long weekend and not think about Git, widgets, etc…
I started by removing all use of GtkContainer:border-width, since Container is gone in GTK4. The border-width property can be replaced with Widget:margin in most cases, except when it was set on a top-level widget like a Window or Popover, where it must be moved to the child. In this, I noticed various places redundantly setting margin/ spacing to 0 (default) or other properties to default values, so I removed those for tidiness and speed.
Continuing to be a primary task was migrating away from GdkEvent to GtkEventControllers, and many more widgets/dialogs have had this completed this month. I also updated PBS's work on the canvas to use our Controller helpers to get more concise code. Things ported away from events include the XML/Attributes dialog, Style dialog, FontSelectorToolbar, Preferences, TextEditor, and various uses of Widget::focus-*-event.
I took breaks to help fix bugs! Moving between tools in the left-hand toolbar required 2 presses of Tab, when it should've been 1: fixed! An oversight in our extension ParameterColor which sometimes crashed the app: fixed
I spent time fixing a regression whereby the color-palette only shows 1 row initially, despite having space for 2, but in the end it was somewhat-inadvertently fixed by Mike’s rework of the Swatches dialog. Ah well, still fixed!
I also noticed missing escaping of HTML entities in Preferences shortuts: fixed!
And on the XML/AttrDialog I noticed the code to react to the +/Ins/Del keys was not working, so… now it is!
A big task was developing helper functions to remove most pain of porting code from Box.pack_start|end(), removed in GTK4. My new functions replicate 99% of those child/packing properties in a GTK4-proof way, by moving properties to the child widgets. Then a few manual tweaks to fix an expected small level of slight changes, as the GTK3→4 migration guide warns to anticipate. We will then be able to lift-and-shift existing code to call our versions of pack_*() instead of Box.pack_*() and should thus be able to keep the code diff to a minimum and preserve layouts. PBS has kindly started testing this and helping find small issues that I can fix!
Porting our Glade/ui files will be more work… but we've made a start: gtk-builder-tool can simplify files, so Tav has run that on our UI files while still on GTK3, so we’ll have less stuff to migrate, as well as no unnecessary property lines reapplying default values, which saves CPU time parsing the XML and setting those. Very nice!
Along the way, I found some issues with missing or suboptimal spacing in the main window and within some prominent dialogs, so I've been submitting patches to help make such areas look nicer. The Filter Editor dialog has some fixes to popover style. I also spent some time reorganising the UI file of our startup dialog, including fixing glitching bottom corners on our images when switching tabs/pages, and simplifying the widget layout.
Also receiving a good deal of attention was our SpinButtonToolItem, which I noticed retained a visual text selection on focus-out, which of course does not look great. I fixed that by clearing the selection on focus-out, migrated the widget from GdkEvents to Controllers, migrated from GtkMenu to our PopoverMenu… and removed support of the GtkToolbar proxy menu item, seeing as GTK4 removes the GtkToolbar and another dev has an MR to migrate away from ToolBars, which includes removing the fairly un-useful proxy item ability.
Another significant continuing task is moving from GtkMenu to Gio::Menu or our snazzy PopoverMenu. First getting the treatment this month was our filter editor, & here I also fixed a regression where the 'tails' of our popovers were drawn wrong, and an older gremlin that the text in the info popup had an odd darker background.
Ditto our SelectedStyle widgets: I tidied up the code for making GtkMenus, moved to PopoverMenus, & added headings to let the opacity menu explain itself! Our Document Properties dialog moved to PopoverMenus too.
On to porting away from GdkEvents in our Command Palette, I found that it first needed some fixes: the Escape key didn't close via history, editing was not fully disabled there, some strings were not translateable, we had widgets that did nothing, and we didn't properly scroll to end of history 1st try. Phew!
Then removing events was very challenging, I suspect due to bodges for GTK3 that will go away on GTK4. Thankfully, many key events could be moved higher in abstraction: Enter/Return were replaced with Entry::activate, and arrows with Widget::focus, meaning fewer key events to convert and we neednʼt test all such keys (Enter/Return, main/KP…). Left over was closing when pressing Esc, which ideally could be done by using a GtkPopover… but for now, after trying many, *many* permutations, I found putting the handler on the top Window worked for events – and then controllers, finally!
I've also spent some time trying to optimise code in the Command Palette, in the hope of reducing down the time it takes to open the 1st time. Another place that has seen significant optimisation attempts is the Style dialog's string parsing.
And later, our ColorWheels: I found that we were reallocating & repopulating the HSL wheel's gradient buffers & surfaces on every draw signal…! So that explained why it was sometimes very slow to redraw & thrashed my CPU while moving by keys!
That is now fixed, & into the bargain I fixed Up/Down keys not working in HSLuv.
Another item I worked on was avoiding use in our InkRuler of GtkStyleContext API that is removed in GTK4. Thankfully, there were quite easy ways around this, and the result is not only GTK4-ready but also cleaner and easier-to-grasp code! \o/
The same is true for our color wheels, which used style props and render_focus() – neither of which are in GTK4; however, we can easily avoid them now. I also took the opportunity to improve the focus shape in 'ring edit' & dash on markers too.
I continued and stripped StyleContext API that has been removed or deprecated in GTK4 from other widgets. This was also a great way to spot various gnarly old code that could be improved.
Lastly, in spare moments between frantically spinning plates around the Inkscape codebase, I found some time to contribute upstream to GTK and gtkmm too.
I have submitted MRs to make the GtkPopoverMenu 'nested submenus' functionality usable from UI files and to add some, if brief, documentation of how its CSS nodes are.
I also submitted an MR to `gtkmm` to make its SignalListItemFactory usable with the new section ListHeaders from GTK 4.12, by adding suitable signal overloads. Both of these MRs have now been merged! \o/