TL; DR
Aquí hay una clase:
KeyManager: new Lang.Class({
Name: 'MyKeyManager',
_init: function() {
this.grabbers = new Map()
global.display.connect(
'accelerator-activated',
Lang.bind(this, function(display, action, deviceId, timestamp){
log('Accelerator Activated: [display={}, action={}, deviceId={}, timestamp={}]',
display, action, deviceId, timestamp)
this._onAccelerator(action)
}))
},
listenFor: function(accelerator, callback){
log('Trying to listen for hot key [accelerator={}]', accelerator)
let action = global.display.grab_accelerator(accelerator)
if(action == Meta.KeyBindingAction.NONE) {
log('Unable to grab accelerator [binding={}]', accelerator)
} else {
log('Grabbed accelerator [action={}]', action)
let name = Meta.external_binding_name_for_action(action)
log('Received binding name for action [name={}, action={}]',
name, action)
log('Requesting WM to allow binding [name={}]', name)
Main.wm.allowKeybinding(name, Shell.ActionMode.ALL)
this.grabbers.set(action, {
name: name,
accelerator: accelerator,
callback: callback,
action: action
})
}
},
_onAccelerator: function(action) {
let grabber = this.grabbers.get(action)
if(grabber) {
this.grabbers.get(action).callback()
} else {
log('No listeners [action={}]', action)
}
}
})
Y así es como lo usas:
let keyManager = new KeyManager()
keyManager.listenFor("<ctrl><shift>a", function(){
log("Hot keys are working!!!")
})
Necesitarás importaciones:
const Lang = imports.lang
const Meta = imports.gi.Meta
const Shell = imports.gi.Shell
const Main = imports.ui.main
Para dejar de escuchar:
for (let it of keyManager.grabbers) {
global.display.ungrab_accelerator(it[1].action)
Main.wm.allowKeybinding(it[1].name, Shell.ActionMode.NONE)
}
Explicación
Podría estar terriblemente equivocado, pero eso es lo que he descubierto en los últimos días.
En primer lugar, Mutter es el responsable de escuchar las teclas de acceso rápido. Mutter es un marco para crear administradores de ventanas, no es un administrador de ventanas en sí mismo. Gnome Shell tiene una clase escrita en JS y llamada "Administrador de ventanas": este es el Administrador de ventanas real que usa Mutter internamente para hacer todas las cosas de bajo nivel. Mutter tiene un objeto MetaDisplay. Este es un objeto que utiliza para solicitar escuchar una tecla de acceso rápido. ¡Pero! Pero Mutter requerirá que Window Manager apruebe el uso de esta tecla de acceso rápido. Entonces, ¿qué sucede cuando se presiona la tecla de acceso rápido? - MetaDisplay genera el evento 'filter-keybinding'. - El Administrador de ventanas en Gnome Shell verifica si esta tecla de acceso rápido permitió ser procesada. - Window Manager devuelve el valor apropiado a MetaDisplay - Si se le permite procesar esta tecla de acceso rápido, MetaDisplay genera el evento 'acelerador-activado'