그놈 쉘 확장 키 바인딩


11

키 조합 (예 <Super>+A:)을 gnome shell extension의 함수에 (전역 적으로) 바인딩하는 가장 간단한 방법은 무엇입니까 ?

몇 가지 확장을 검사하면 다음 코드가 발생했습니다.

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

키 조합은 스키마 매개 변수로 지정되며 조합을 설명하는 XML 파일을 작성할 수 있음을 이해합니다. 더 간단한 방법이 있습니까?


그놈 쉘 확장을 만드는 경우 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는이 핫키의 사용을 승인하기 위해 Window Manager가 필요합니다. 핫키를 누르면 어떻게됩니까? -MetaDisplay는 'filter-keybinding'이벤트를 생성합니다. -Gnome Shell의 창 관리자는이 핫키를 처리 할 수 ​​있는지 확인합니다. -Window Manager가 MetaDisplay에 적절한 값을 반환합니다.-이 핫키를 처리 할 수있는 경우 MetaDisplay는 'accelerator-actived'이벤트를 생성합니다.


나는이 코드를 Gnome 3.22에서만 테스트했습니다
p2t2p

이것은 환상적인 답변입니다. 이것을 공유해 주셔서 감사합니다.
andy.holmes

세계는 어디에서 왔습니까? 어느 도서관에 속합니까?
borizzzzz

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.