Wiązanie klucza powłoki Gnome

11

Jaki jest najprostszy sposób (globalnego) powiązania kombinacji klawiszy (np. <Super>+A) Z funkcją w rozszerzeniu powłoki gnome?

Sprawdzając kilka rozszerzeń, natrafiłem na następujący kod:

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

Rozumiem, że kombinacja klawiszy jest określona przez parametr schematu i że można utworzyć plik XML opisujący kombinację. Czy istnieje prostszy sposób na zrobienie tego?

Mark Jones
źródło
Jeśli tworzysz rozszerzenie powłoki GNOME, prawdopodobnie uzyskasz lepsze odpowiedzi na http://stackoverflow.com/ . Zgłoś uwagę moderatora, która powinna przenieść Twoje pytanie.
NobleUplift,

Odpowiedzi:

5

TL; DR

Oto klasa:

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

I tak to wykorzystujesz:

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

Będziesz potrzebował importu:

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

Aby przestać słuchać:

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

Wyjaśnienie

Mógłbym się bardzo mylić, ale o tym dowiedziałem się w ciągu ostatnich kilku dni.

Przede wszystkim to Mutter jest odpowiedzialny za słuchanie skrótów klawiszowych. Mutter jest strukturą do tworzenia menedżerów okien, nie jest nim sam. Gnome Shell ma klasę napisaną w JS o nazwie „Window Manager” - jest to prawdziwy Window Manager, który używa Mutter wewnętrznie do robienia wszystkich rzeczy na niskim poziomie. Mutter ma obiekt MetaDisplay. Jest to obiekt, którego używasz do żądania nasłuchiwania skrótu. Ale! Ale Mutter będzie wymagał Menedżera okien, aby zatwierdził użycie tego skrótu. Co dzieje się po naciśnięciu klawisza skrótu? - MetaDisplay generuje zdarzenie „kluczowanie filtrów”. - Menedżer okien w Gnome Shell sprawdza, czy ten skrót klawiszowy może zostać przetworzony. - Menedżer okien zwraca odpowiednią wartość do MetaDisplay - Jeśli przetwarzanie tego skrótu jest dozwolone, MetaDisplay generuje zdarzenie „aktywowane akceleratorem”

p2t2p
źródło
Testowałem ten kod tylko w Gnome 3.22
p2t2p
To fantastyczna odpowiedź, bardzo dziękuję za podzielenie się tym.
andy.holmes
Skąd pochodzi świat? Która biblioteka jest częścią?
borizzzzz
1

gconf-editormoże zrobić, co chcesz: link

Andrea Gottardi
źródło