How to make focused widget handle key events before activating accelerators?

Using gtk_application_set_accels_for_action, the window handles the event before anything else, so even when a GtkEntry is focused, typing or using shortcuts like Ctrl+A activates actions rather than interacting with the entry.

I looked at Evince’s code, and it seems that it’s possible to use gtk_window_propagate_key_event and gtk_window_activate_key:

/*
 * GtkWindow catches keybindings for the menu items _before_ passing them to
 * the focused widget. This is unfortunate and means that pressing Ctrl+a,
 * Ctrl+left or Ctrl+right in the search bar ends up selecting text in the EvView
 * or rotating it.
 * Here we override GtkWindow's handler to do the same things that it
 * does, but in the opposite order and then we chain up to the grand
 * parent handler, skipping gtk_window_key_press_event.
 */
static gboolean
ev_window_key_press_event (GtkWidget   *widget,
			   GdkEventKey *event)
{
	static gpointer grand_parent_class = NULL;
	GtkWindow *window = GTK_WINDOW (widget);

	if (grand_parent_class == NULL)
                grand_parent_class = g_type_class_peek_parent (ev_window_parent_class);

        /* Handle focus widget key events */
        if (gtk_window_propagate_key_event (window, event))
		return TRUE;

	/* Handle mnemonics and accelerators */
	if (gtk_window_activate_key (window, event))
		return TRUE;

        /* Chain up, invokes binding set on window */
	return GTK_WIDGET_CLASS (grand_parent_class)->key_press_event (widget, event);
}

But when I do something like this in GJS:

win.connect('key-press-event', (widget, event) => {
    win.propagate_key_event(event)
})

It gives “TypeError: Object […] is not a subclass of GObject_Boxed, it’s a GObject_Union”.

This is probably a bug in GJS, would you mind creating a bug report for it with a minimal example? Thanks.

I’ve opened an issue: https://gitlab.gnome.org/GNOME/gjs/issues/323

1 Like

It may also be an annotation issue; gtk_window_propagate_key_event() might need to use (type GdkEvent) on its argument.

1 Like