[SOLVED] [GTK4] keyboard accelerators doesn't work with an added "action group"


I made an application in c using Gtk4 with a GtkText to which I assigned and added an ‘action group’.

Using the GtkInspector it appears and I can activate it.

The problem is when I want to activate it using a key combination: it just doesn’t work.

Use as a guide #actions from the gtk-rs book

If as ‘detailed action name’ I use any of the predefined actions like window.* or app.* the keystroke works.

/* main function */
  app = gtk_application_new("org.example.Term", G_APPLICATION_DEFAULT_FLAGS);

  g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);

  /* Set keyboard accelator to trigger "mytext.clear" */
  gtk_application_set_accels_for_action(app, "mytext.clear", (const char *[])  {"<Control>l", NULL});
/* activate function */
  /* Create a text widget */
  GtkWidget * my_text  = gtk_text_new();

  /* Add action "clear" to `my_text` */
  GSimpleAction *clear_text_action = g_simple_action_new("clear", NULL);
  g_signal_connect_swapped(clear_text_action, "activate", G_CALLBACK(on_clear_text_action), NULL);

  /* Create a new action group */
  GSimpleActionGroup *actions = g_simple_action_group_new();
  g_action_map_add_action(G_ACTION_MAP(actions), G_ACTION(clear_text_action));
  gtk_widget_insert_action_group(my_text, "mytext", G_ACTION_GROUP(actions));

Complete code: https://privatebin.net/?6edf986e74d7fd7b=#GchqYrKCnXF7XRFR3qyMsCURipevWCFNutDaz92dbvxj

I would appreciate any help or reference. Thank you.

gtk_application_set_accels_for_action() sets global shortcuts and only seems to work with app and win actions, which makes sense. You could add the action to the window instead and reference it as win.clear (GtkApplicationWindow implements GActionMap). Action lookup traverses a widget’s ancestors but not its children, so you can activate a parent’s action in a child but not vice versa.

For a widget-scoped shortcut, you can use GtkShortcut:

  GtkEventController *controller = gtk_shortcut_controller_new ();
  gtk_widget_add_controller (my_text, controller);
  GtkShortcut *shortcut = gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_L, GDK_CONTROL_MASK),
                                            gtk_named_action_new ("mytext.clear"));
  gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller), shortcut);

It’s also possible to make global shortcuts this way, see gtk_shortcut_controller_set_scope().

There are convenience APIs like gtk_widget_class_add_binding_action(), but they can only be used in widget class implementations.

P.S. Thanks for including your complete code. It makes this much easier.

1 Like

I just realized that it is explained in the migration guide: use-the-new-apis-for-keyboard-shortcuts :face_exhaling:

Thank you very much for responding, I already tried it and it works for what I need.

I hope you don’t mind if you can answer some question:

Is there a ‘trigger’ to call actions based on mouse scroll? That is, if you scroll up or down. Or if the only way is with EventControllerScroll and check the address.