그놈 쉘 확장 키 바인딩


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.