Gnome Shell Extension Key Binding


11

Quel est le moyen le plus simple de lier (globalement) une combinaison de touches (par exemple <Super>+A) à une fonction dans une extension de shell gnome?

En inspectant quelques extensions, j'ai rencontré le code suivant:

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

Je comprends que la combinaison de touches est spécifiée par le paramètre de schéma et qu'il est possible de créer un fichier XML décrivant la combinaison. Existe-t-il un moyen plus simple de procéder?


Si vous créez une extension de shell GNOME, vous obtiendrez probablement de meilleures réponses sur http://stackoverflow.com/ . Marquez l'attention du modérateur et ils devraient migrer votre question.
NobleUplift

Réponses:


5

TL; DR

Voici une classe:

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

Et c'est comme ça que vous l'utilisez:

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

Vous allez avoir besoin d'importations:

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

Pour arrêter d'écouter:

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

Explication

Je me trompe peut-être terriblement, mais c'est ce que j'ai compris ces derniers jours.

Tout d'abord, c'est Mutter qui est responsable de l'écoute des raccourcis clavier. Mutter est un cadre pour créer des gestionnaires de fenêtres, ce n'est pas un gestionnaire de fenêtres lui-même. Gnome Shell a une classe écrite en JS et appelée "Window Manager" - c'est le vrai Window Manager qui utilise Mutter en interne pour faire toutes les choses de bas niveau. Mutter a un objet MetaDisplay. Il s'agit de l'objet que vous utilisez pour demander l'écoute d'un raccourci clavier. Mais! Mais Mutter demandera au gestionnaire de fenêtres d'approuver l'utilisation de ce raccourci clavier. Que se passe-t-il donc lorsque la touche de raccourci est enfoncée? - MetaDisplay génère un événement 'filtre-raccourci clavier'. - Le gestionnaire de fenêtres dans Gnome Shell vérifie si cette touche de raccourci a pu être traitée. - Le gestionnaire de fenêtres renvoie la valeur appropriée à MetaDisplay - S'il est autorisé à traiter ce raccourci clavier, MetaDisplay génère l'événement «activé par l'accélérateur»


J'ai testé ce code uniquement dans Gnome 3.22
p2t2p

Ceci est une réponse fantastique, merci beaucoup de partager cela.
andy.holmes

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.