Gnome Shell Extension Key Binding

11

Was ist der einfachste Weg, eine Tastenkombination (z. B. <Super>+A) (global) an eine Funktion in einer Gnome-Shell-Erweiterung zu binden ?

Bei der Überprüfung einiger Erweiterungen stieß ich auf den folgenden Code:

global.display.add_keybinding('random-name',
                              new Gio.Settings({schema: 'org.gnome.shell.keybindings'}),
                              Meta.KeyBindingFlags.NONE,
                              function() { /* ... some code */ });

Ich verstehe, dass die Schlüsselkombination durch den Schemaparameter angegeben wird und dass es möglich ist, eine XML-Datei zu erstellen, die die Kombination beschreibt. Gibt es einen einfacheren Weg, dies zu tun?

Mark Jones
quelle
Wenn Sie eine GNOME-Shell-Erweiterung erstellen, erhalten Sie wahrscheinlich bessere Antworten auf http://stackoverflow.com/ . Markieren Sie die Aufmerksamkeit des Moderators und er sollte Ihre Frage migrieren.
NobleUplift

Antworten:

5

TL; DR

Hier ist eine Klasse:

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)
        }
    }
})

Und so benutzt du es:

let keyManager = new KeyManager()
keyManager.listenFor("<ctrl><shift>a", function(){
    log("Hot keys are working!!!")
})

Sie benötigen Importe:

const Lang = imports.lang
const Meta = imports.gi.Meta
const Shell = imports.gi.Shell
const Main = imports.ui.main

So hören Sie auf zu hören:

for (let it of keyManager.grabbers) {
    global.display.ungrab_accelerator(it[1].action)
    Main.wm.allowKeybinding(it[1].name, Shell.ActionMode.NONE)
}

Erläuterung

Ich könnte furchtbar falsch liegen, aber das habe ich in den letzten Tagen herausgefunden.

Zuallererst ist es Mutter, die für das Abhören von Hotkeys verantwortlich ist. Mutter ist ein Framework zum Erstellen von Fenstermanagern, es ist selbst kein Fenstermanager. Gnome Shell hat eine in JS geschriebene Klasse namens "Window Manager" - dies ist der echte Window Manager, der Mutter intern verwendet, um alle Low-Level-Aufgaben zu erledigen. Mutter hat ein Objekt MetaDisplay. Mit diesem Objekt fordern Sie das Abhören eines Hotkeys an. Aber! Mutter verlangt jedoch von Window Manager, dass die Verwendung dieses Hotkeys genehmigt wird. Was passiert also, wenn der Hotkey gedrückt wird? - MetaDisplay generiert das Ereignis 'Filter-Keybinding'. - Window Manager in Gnome Shell prüft, ob dieser Hotkey verarbeitet werden darf. - Window Manager gibt den entsprechenden Wert an MetaDisplay zurück. - Wenn dieser Hotkey verarbeitet werden darf, generiert MetaDisplay das Ereignis "Beschleuniger aktiviert".

p2t2p
quelle
Ich habe diesen Code nur in Gnome 3.22
p2t2p
Dies ist eine fantastische Antwort, vielen Dank, dass Sie dies geteilt haben.
andy.holmes
1

gconf-editorkönnte tun, was Sie wollen: Link

Andrea Gottardi
quelle