I'm trying to implement key bindings inside a Cinnamon Applet. Basically, a click on a St.Button
and a ENTER keypress on the same should call a specific method, and the signal should be consumed:
let button = new St.Button({ can_focus: true });
button.connect('button-release-event', Lang.bind(this, function(_, event) {
const button = event.get_button();
if (button !== 3) {
this._onDayActivated();
return Clutter.EVENT_STOP;
}
return Clutter.EVENT_PROPAGATE;
}));
button.connect('key-press-event', Lang.bind(this, function(_, event) {
const symbol = event.get_key_symbol();
const relevantKeys = [Clutter.KEY_space, Clutter.KEY_KP_Enter, Clutter.KEY_Return];
if (relevantKeys.includes(symbol)) {
this._onDayActivated();
return Clutter.EVENT_STOP;
}
return Clutter.EVENT_PROPAGATE;
}));
This works so far, the method is executed as it should. But the applet is implemented as a Cinnamon TextApplet
with a PopupMenu
. These menus, as a default, close on clicks and ENTER keypresses. In class PopupBaseMenuItem
, the wrapper container has these signal handlers:
_onButtonReleaseEvent(actor, event) {
this.activate(event, false);
return true;
}
_onKeyPressEvent(actor, event) {
let symbol = event.get_key_symbol();
if (symbol === Clutter.KEY_space ||
symbol === Clutter.KEY_Return ||
symbol === Clutter.KEY_KP_Enter) {
this.activate(event);
return true;
}
return false;
}
activate(event, keepMenu) {
this.emit('activate', event, keepMenu); // basically closes the menu for keepMenu == false
}
If I click the button, the menu remains open. If I set the focus on the button and press ENTER (or SPACE), the menu closes.
What am I missing? Is it relevant that the button is destroyed before the signal handler returns with Clutter.EVENT_STOP
?