Gnome Shell扩展键绑定


11

将全局组合键(例如<Super>+A)绑定到gnome shell扩展中的函数的最简单方法是什么?

检查几个扩展,我遇到了以下代码:

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

我知道键组合是由schema参数指定的,并且可以创建描述该组合的XML文件。有没有更简单的方法可以做到这一点?


如果要创建GNOME Shell扩展,则可能会在http://stackoverflow.com/上获得更好的响应。标记主持人的注意力,他们应该转移您的问题。
NobleUplift 2013年

Answers:


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编写的类,称为“窗口管理器”-这是真正的窗口管理器,它在内部使用Mutter来做所有低级的事情。杂音有一个对象MetaDisplay。该对象用于请求侦听热键。但!但是Mutter将需要Window Manager批准使用此热键。那么当按下热键时会发生什么呢?-MetaDisplay生成事件'filter-keybinding'。-Gnome Shell中的窗口管理器检查是否允许处理此热键。-窗口管理器将适当的值返回给MetaDisplay-如果允许处理此热键,则MetaDisplay会生成事件“加速器激活”


我仅在Gnome 3.22中测试了此代码
p2t2p

这是一个很棒的答案,非常感谢您的分享。
andy.holmes

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.