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.