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


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, который отвечает за прослушивание горячих клавиш. Mutter - это основа для создания оконных менеджеров, а не оконный менеджер. В Gnome Shell есть класс, написанный на JS и называемый «Window Manager» - это настоящий Window Manager, который использует Mutter для выполнения всех низкоуровневых задач. У Муттера есть объект MetaDisplay. Это объект, который вы используете, чтобы запросить прослушивание горячей клавиши. Но! Но Mutter потребует, чтобы Window Manager одобрил использование этой горячей клавиши. Так что же происходит при нажатии горячей клавиши? - MetaDisplay генерирует событие «связывание фильтра». - Менеджер окон в Gnome Shell проверяет, разрешена ли эта горячая клавиша для обработки. - Window Manager возвращает соответствующее значение в MetaDisplay. - Если разрешено обрабатывать эту горячую клавишу, MetaDisplay генерирует событие «accelerator-actived».


Я тестировал этот код только в Gnome 3.22
p2t2p

Это фантастический ответ, большое спасибо за то, что поделились этим.
Andy.holmes

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.