July - GTK4 migration

Hello! I've joined working with Tav on migrating Inkscape from GTK/mm version 3 to version 4. See his blog about this work here: https://inkscape.org/*membership/blog/june-gtk4-migration/

 

With good experience of developing with and contributing to GTK and gtkmm, I'm here mostly to do work and advise on topics relating more closely to those, whereas of course Tav is a long-standing expert in Inkscape itself and its codebase. Between us, I hope, we'll knock this task out of the park!

 

I started by wrangling the codebase: cloning, building, and making it work on my Mildly Venerable laptop from 2012. It was pleasantly easy, thanks to our wiki and scripts! I immediately saw some warnings re old properties from GTK2 in our startup UI and submitted a MR - first impressions are important! :-) Then I resumed Tav's work of trying to build on GTK4: piling up small migration fixes in another branch to later become our GTK4, and backporting anything I can to the master branch.

 

A main task was porting existing widgets (aside from those covered by PBS in his canvas work) from GdkEvents to EventControllers/Gestures. This involved creating clever helpers to make creating/adding and connecting a Controller to a Widget look more succinct and pleasant than GTK allows natively, saving us going from tidy 1-liners to piles of spaghetti. I also added a manage() helper, which ties the life of a RefPtr-held Object to a 'manager' object, so we can add Controllers to Widgets (or Bindings to Objects) without having to hold a RefPtr to keep them alive. That is how GTK4 manages such objects, so we'll be ready: we will just remove the then-unnecessary helper!

 

Converting from events to controllers varies wildly from 'nice and easy' to 'oh no, why, why are you like this, how do I make these disparate combinations of inputs coexist??' ...but in any case, it leads to more modern code, and our helpers make it all easier to understand. Also it often pointed me in the direction of many other things we could do to cleanup or optimise code alongside porting.

 

Another main task this month was reducing reliance on GtkMenu et al., which GTK4 removes in favour of GtkPopover, GMenuModel, etc. To this end, I have our column menu builder, as used in the notebook, filter-effects, and LPE – migrated to a snazzy new Inkscape PopoverMenu that emulates the old GtkMenu. So is the toolbar context menu, which also got cleanups and speedups.

 

One thing I noted when trying to build on GTK4, and have backported to GTK3/master, is how we detect whether you are running a dark theme. We have been using GtkStyleContext, asking for the BG colour, and checking its luminance. Great, but… StyleContext is now deprecated in GTK4, so if we can reduce its use in GTK3, that's a win. Hence, I rewrote that to use the foreground colour instead, which GTK4 makes available via Widget.get_color(), which will make migrating that trivial.

 

I built on this by removing reliance on StyleContext API that GTK4 outright removes, specifically that we used to get BG and border colours from themes. You can't do this anymore in GTK4, only get the foreground colour - so with a bit of magicianship in our CSS to 'pass' the needed colours as-if they're FG colours, we now have GTK4-proof code for getting those colours into our code. This was also a great occasion to tidy up the code getting colors & checking for dark themes.

 

I also worked to upstream some features from Inkscape. This included successfully submitting a "scoped connection" to libsigc++, to auto-disconnect when destroyed. We currently ‘reinvent’ this as `auto_connection`. By upstreaming, we can use that and remove our copy later. My upstream MR added plenty tests to ensure the new scoped connection works right, which let me fix some bugs in ours too. I also earlier enabled our auto_connection to be movable and work in containers.

 

Overall a very productive month, lots of essential work to make us GTK4-ready and various fixes and improvements along the way. August is shaping up to be just as good, so see you later at the next report!