Gtk applications are more and more using GAction
and GActionGroup
and it’s easy to see why. They are stateful, allow parameters when activating, and can be inserted into the widget hierarchy using gtk_widget_insert_action_group()
. The latter is useful so that you only activate actions (or toggle button sensitivity) in the portion of the user interface that makes sense.
One thing to consider is what your strategy will be for using GActionGroup
. One way is to encapsulate the GActionGroup
by using GSimpleActionGroup
. Another, which I prefer, is to implement the GActionGroupInterface
. Although, this requires much more boilerplate code.
Until now…
In libdazzle, I added a header-only helper to ease creating action groups with much less effort on your part.
It goes something like this.
#include <dazzle.h> #include "foo-bar.h" static void foo_bar_action_frobnicate (FooBar *self, GVariant *param); DZL_DEFINE_ACTION_GROUP (FooBar, foo_bar, { { "frobnicate", foo_bar_action_frobnicate }, }) G_DEFINE_TYPE_WITH_CODE (FooBar, foo_bar, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP, foo_bar_init_action_group))
There are a few niceties when defining action groups this way.
- Your function signatures get your proper class type as parameter 1.
- You no longer need to instantiate a
GSimpleAction
for every action. - No unnecessary parameters (like user_data) need to be provided anymore.
- It uses GActionGroupInterface.query_action to optimize for certain queries.
- You can change action state with
${prefix}_set_action_state()
. - You can change if an action is enabled with
${prefix}_set_action_enabled()
. - You can take your new
GActionGroup
andgtk_widget_insert_action_group()
directly.
That’s it for now, happy hacking!