Here's a summary of my work at the Boston Hackfest.
Before I continue, I'd like to thank everyone who donated their money or
time to support this Hackfest. This has been a really useful event - it's
so much easier to deal with tricky design challenges and project management
stuff when we can meet face to face. It has also brought together people
with very diverse expertise across the project (UI, web, build, extensions,
project management etc). This week, we've figured out a path to deliver
long desired features (multipage support etc), roadmapped our final route
to deliver Inkscape 1.0, done some great website design work, and handled
some tricky code structure issues that I'll discuss in this message.
If you're able to donate some money to support Inkscape, and future
Hackfests, we really appreciate this. You can find the donation link on
our website: https://inkscape.org/en/support-us/hackfests/
It would also be great to get some more of the regular contributors from
our wider community to join us at future events (i.e., designers, bug-team,
experienced users... not just C++ developers!). The developers can learn
so much more about the project by discussing it with you.
So... what have I been doing this week?
== What are Actions? ==
Basically, an "action" is a thing that Inkscape can do (e.g., flip an
object horizontally), which we can identify using an ID code (e.g.,
"SP_VERB_OBJECT_FLIP_HORIZONTAL"). We can then hook up buttons, menu items
etc to activate these actions. In this example, we would set up our Flip
Horizontal button in the select-tool toolbar so that when the user clicks
it, it activates the required action.
My work this week has focused on improving the way we implement actions in
our code, which will
1. Allow Inkscape to run on machines with future versions of the Gtk+
library (Gtk 4+)
2. Provide much better separation between the behaviour and user
interface (i.e.,, separate pieces of the code will describe what Inkscape
"does", and what it "looks like")
3. Make it much easier to create new "flavours" of the Inkscape user
interface - for example, an "Inkscape for Kids" or "Inkscape CAD"
4. Make it easier for "non-programmers" to create and reorganise custom
toolbars and dialogs
5. Allow us to remove a lot of older "C" code that is very difficult for
current "C++" developers to maintain
== Where we are now? ==
In the Inkscape code, we have a mechanism called "verbs" that acts as a
kind of action mechanism... it provides a way of using an ID code to look
up the required commands to perform an action.
On top of this, we have another structure called SPAction that essentially
hooks up a couple of signals to the verb.
Finally(ish), we use objects called GtkActions from the Gtk+ library, which
let us create GUI elements (buttons etc) that we can add to our menus or
toolbars that activate the required action.
We have also got a few custom sub-classes of GtkAction that let us create
special kinds of tool-item that can activate actions... for example, one of
these creates a spin-button (a box with a number in it, and "up/down"
arrows) that can also handle units, basic arithmetic, and provides a label.
== What's the problem? ==
First, the GtkAction widget (and hence all our custom sub-classes) is
deprecated and has been removed from Gtk+ 4, so we need to change. Since
Inkscape 1.0 is intended as a "stable" release, we want to make it as
future-proof as possible.
The main reason for this deprecation is that the GtkAction widget is a
slightly weird mix of paradigms: it mixes information about how to display
a tool/menu item with information about behaviour. This causes some
problems... what if we wanted to run a "headless" Inkscape on a system that
has no display? What if we wanted to provide several different GUI options
for different kinds of user to trigger the same behaviour?
This is one of the reasons why we have the "verbs" system is in place, as
it separates behaviour from the GUI. However, there is still quite a lot
of code "overhead" needed if we want to hook up Inkscape's Verb behaviour
to a GUI element. Essentially, it's "programmers only" territory. What if
a designer wanted to add a new toolbar button to their Inkscape to handle a
useful feature that is currently buried deep in a menu? What if a teacher
wanted to strip out a lot of "advanced" behaviour from the interface to
make it easier to introduce Inkscape to their class? At the moment, they
have to edit the C++ code, and recompile it... a slow and complicated
== Where are we going? ==
We need to move to using GActions (a feature in the Glib/GIO library).
This *only* describes the action's behaviour and provides an "activated"
signal that we can trigger by simply knowing the action's name. This is
completely separated from the GUI. These actions can be activated very
easily from a whole range of places, for example:
1. By attaching the action's name to a GUI element in the C++ code
(replacing our SPAction/GtkAction code)
2. By activating the action (using its name) from a command-line
interface (replacing some of our verbs code)
3. By attaching the action's name to elements in a customised GUI file
4. From external applications, using the DBus system
Number 3 in the list provides some very exciting opportunities for future
releases, as non-programmers will be able to make a customised user
interface by drawing one in the Glade application. You then just attach
the name of the required Inkscape action to each GUI element. Want a new
button? Just edit Inkscape's user-interface file in Glade and see the
changes immediately next time you start... no C++ knowledge needed!
== What have I done so far? ==
I've started working through Inkscape's toolbars, and have replaced the
deprecated GtkAction-based widgets with standard widgets (buttons etc).
Some of these now hook up to GAction descriptions of behaviour, while
others are just based on handling GUI signals (e.g., Button::clicked).
So far, I have migrated the toolbars for the Select, Dropper and Connector
toolbar, and have killed off a couple of the custom GtkAction-based widgets
that were only used in these.
In the process, I have also migrated the toolbar code to C++, which should
make it a little easier for the current core developers to maintain. Since
all the data is now stored as C++ member variables, rather than as GObject
data, we now benefit from better compile-time and run-time type-checking
that will help to safeguard against errors being introduced in the code in
I have placed the updated toolbars in the Inkscape::UI::Toolbar namespace
and made them into proper sub-classes of the Gtk::Toolbar class.
== How can you help? ==
This important refactoring project must be done before Gtk+ 4 is widely
used, and represents a major change to the way that our toolbars are
implemented. It represents a couple of thousand lines of code changes and
will inevitably cause some regression bugs. I will need your help in
thoroughly testing that all the toolbars work correcly!
All of these changes are currently in a git branch
("gtk-actions-migration") and will not be merged into the master branch
until preliminary testing has been completed. In other words, this will
not "mess up" your stable version of Inkscape and will never be part of the
current 0.92.x release series! I intend to merge this work well in advance
of the Inkscape 1.0 release, so that we have plenty of time for very
thorough developer and user testing, and several preliminary bug-fix
"alpha" pre-releases before the final stable release.
For the very brave: please checkout the "gtk-actions-migration" branch in
git, rebuild and test. Please note that this is work-in progress. Do not
use this experimental branch for your regular Inkscape drawing work!!! The
Node toolbar will not work... the Select, Dropper and Connector toolbars
are highly experimental; all the other toolbars are "at risk"! If you
don't know how to do this, check out our developer guide.
For the quite brave: I'll merge this experimental branch into our master
development branch in a few weeks once (a) I've completed the basic work,
(b) I've had a good amount of feedback on the branch and know that it
"works" to some extent. I'll message you again at this stage and ask
everyone to help look for bugs. Again, this will only be visible to
developers and users of our experimental "trunk" PPA in Ubuntu.
For the intrepid: If you're interested in helping with the code migration -
message me and I'll help to divide up the tasks.
== The end ==
I hope this gives an insight into the work I've started doing this week,
and will continue over the coming weeks. Thanks once again to everyone who
has contributed time, money or even just attention and enthusiasm for the
Alex Valavanis (valavanisalex)