TL; DR
Ini kelasnya:
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)
}
}
})
Dan itulah cara Anda menggunakannya:
let keyManager = new KeyManager()
keyManager.listenFor("<ctrl><shift>a", function(){
log("Hot keys are working!!!")
})
Anda akan membutuhkan impor:
const Lang = imports.lang
const Meta = imports.gi.Meta
const Shell = imports.gi.Shell
const Main = imports.ui.main
Untuk berhenti mendengarkan:
for (let it of keyManager.grabbers) {
global.display.ungrab_accelerator(it[1].action)
Main.wm.allowKeybinding(it[1].name, Shell.ActionMode.NONE)
}
Penjelasan
Saya mungkin sangat salah, tetapi itulah yang saya temukan dalam beberapa hari terakhir.
Pertama-tama adalah Mutter yang bertanggung jawab untuk mendengarkan hotkey. Mutter adalah kerangka kerja untuk membuat Window Managers, itu bukan window manager itu sendiri.
Gnome Shell memiliki kelas yang ditulis dalam JS dan disebut "Window Manager" - ini adalah Window Manager nyata yang menggunakan Mutter secara internal untuk melakukan semua hal tingkat rendah.
Mutter memiliki objek MetaDisplay. Ini adalah objek yang Anda gunakan untuk meminta mendengarkan hotkey.
Tapi!
Tetapi Mutter akan meminta Window Manager untuk menyetujui penggunaan hotkey ini. Jadi apa yang terjadi ketika hotkey ditekan?
- MetaDisplay menghasilkan 'filter-keybinding' acara.
- Window Manager di Gnome Shell memeriksa apakah hotkey ini diizinkan untuk diproses.
- Window Manager mengembalikan nilai yang sesuai ke MetaDisplay
- Jika diizinkan untuk memproses hotkey ini, MetaDisplay menghasilkan acara 'akselerator-diaktifkan'
- Ekstensi Anda harus mendengarkan acara itu dan mencari tahu dengan action id hotkey mana yang diaktifkan.