How to use the arrows keys as accelerators

EDIT: It was a typo in the action name, you can use set_accels_for_action with modifiers and everything.

The method GtkApplication.set_accels_for_action doesn’t work with arrows (or at least I don’t know how to get it to work), this post will hopefully explain how I solved it using GtkEventControllerKey. If you know any other way to solve this, please leave a comment to let others know about it.

I’m going to use rust for the code snippets, this should be mostly the same for the rest of the bindings.

So at first glance, I tried using GtkApplication.set_accels_for_action:

impl ApplicationImpl for MyApp {
    fn startup(&self) {
        self.parent_startup();

        self.set_accels_for_action("win.foo-action", &["<Alt>Left"]);
        self.set_accels_for_action("win.bar-action", &["<Alt>Right"]);
    }
}

If you test this, you’ll see that the action is not being called and that the accelerator is being ignored.

What I did was to add a GtkEventControllerKey to the window of the app in the constructed method, that listens to those keys specifically and activates the specified action.

impl ObjectImpl for MyWindow {
    fn constructed(&self) {
        self.parent_constructed();

        let key_controller = gtk::EventControllerKey::new();
        key_controller.connect_key_pressed(|_, key, _, modifiers| {
            if modifiers == gdk::ModifierType::ALT_MASK {
                match key {
                    gdk::Key::Left => (/* Activate action for <Alt>Left */),
                    gdk::Key::Right => (/* Activate action for <Alt>Right */),
                    // More accelerators...

                    // When none matches, we return proceed because we are not handling it
                    // Note that the return expression applies to the function, not the match.
                    _ => return glib::Propagation::Proceed,
                }
                // At least one accelerator matched, we return stop because we handle it
                return glib::Propagation::Stop;
            }
            // No key nor modifier matched, we return proceed
            return glib::Propagation::Proceed;
        });
    }
}

The only downside I found for this method was that I couldn’t use the action-name property in a GtkShortcutsShorcut to automatically search for the accelerator, so you have to set that manually.

Left and Right should work fine in set_accels_for_action(), at least they do in Showtime.

It’s true, but using modifiers <Alt>, <Control>, etc. Is not working for me, maybe I should update this post specifying this.

I also tried it with a modifier, specifically <Alt>, and it was still working :thinking:

Mmm, you are right, I may have a typo in the action name :laughing:

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.