Gnomeシェル拡張キーバインディング


11

キーの組み合わせ(例<Super>+A)をgnomeシェル拡張の関数に(グローバルに)バインドする最も簡単な方法は何ですか?

いくつかの拡張機能を調べると、次のコードに遭遇しました。

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で記述された「ウィンドウマネージャー」と呼ばれるクラスがあります。これは、Mutterを内部的に使用してすべての低レベルの処理を行う実際のウィンドウマネージャーです。MutterにはオブジェクトMetaDisplayがあります。これは、ホットキーのリッスンを要求するために使用するオブジェクトです。だが!ただし、Mutterでは、このホットキーの使用を承認するためにウィンドウマネージャーが必要になります。では、ホットキーを押すとどうなりますか?-MetaDisplayは、イベント「filter-keybinding」を生成します。-Gnome Shellのウィンドウマネージャーは、このホットキーの処理が許可されているかどうかを確認します。-ウィンドウマネージャーは適切な値をMetaDisplayに返します-このホットキーの処理が許可されている場合、MetaDisplayはイベント「accelerator-actived」を生成します


このコードはGnome 3.22
p2t2p

これは素晴らしい答えです。これを共有してくれてありがとう。
andy.holmes

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.