Ключ розширення оболонки гнома


11

Який найпростіший спосіб (глобально) прив’язати комбінацію клавіш (наприклад <Super>+A) до функції в розширенні оболонки гнома?

Оглядаючи пару розширень, я натрапив на такий код:

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

Я розумію, що комбінація ключів задається параметром схеми, і що можна створити XML-файл, що описує комбінацію. Чи є простіший спосіб зробити це?


Якщо ви створюєте розширення оболонки GNOME, ви, ймовірно, отримаєте кращі відповіді на http://stackoverflow.com/ . Позначте увагу модератора, і вони повинні перенести ваше запитання.
NobleUplift

Відповіді:


5

TL; DR

Ось клас:

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

І ось як ви це використовуєте:

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

Вам знадобиться імпорт:

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

Щоб перестати слухати:

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

Пояснення

Я можу страшенно помилятися, але це те, що я з'ясував за останні пару днів.

Перш за все, саме Муттер відповідає за прослуховування гарячих клавіш. Mutter - це основа для створення менеджерів вікон, це не сам менеджер вікон. У Gnome Shell є клас, написаний на JS і який називається "Window Manager" - це справжній Менеджер вікон, який використовує Mutter внутрішньо, щоб виконувати всі речі низького рівня. Mutter має об'єкт MetaDisplay. Це об'єкт, який ви використовуєте для запиту прослуховування гарячої клавіші. Але! Але Mutter зажадає, щоб менеджер вікон схвалив використання цієї гарячої клавіші. Отже, що відбувається при натисканні швидкої клавіші? - MetaDisplay генерує подію 'фільтр-прив'язка клавіш'. - Менеджер вікон у Gnome Shell перевіряє, чи дозволено обробляти цю гарячу клавішу. - Менеджер вікон повертає відповідне значення для MetaDisplay - Якщо йому дозволено обробляти цю гарячу клавішу, MetaDisplay генерує події 'accelerator-actived'


Я перевірив цей код лише в Gnome 3.22
p2t2p

Це фантастична відповідь, дуже дякую, що поділилися цим.
andy.holmes

Звідки береться глобальний? До якої бібліотеки вона входить?
borizzzzz

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.