Gnome Shell Extension Key Key Binding


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 เปลือกแล้วคุณอาจจะได้รับการตอบสนองที่ดีขึ้นใน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 เป็นเฟรมเวิร์กสำหรับสร้าง Window Managers ไม่ใช่ตัวจัดการหน้าต่างเอง Gnome Shell มีคลาสที่เขียนใน JS และเรียกว่า "Window Manager" - นี่คือตัวจัดการหน้าต่างจริงซึ่งใช้ Mutter ภายในเพื่อทำสิ่งที่ต่ำทั้งหมด Mutter มีวัตถุ MetaDisplay นี่คือวัตถุที่คุณใช้เพื่อขอฟังฮอต แต่! แต่ Mutter จะต้องใช้ Window Manager ในการอนุมัติการใช้ปุ่มลัดนี้ แล้วจะเกิดอะไรขึ้นเมื่อกดปุ่มลัด? - MetaDisplay สร้าง 'การกรองคีย์ - ตัวกรอง' ของเหตุการณ์ - Window Manager ใน Gnome Shell ตรวจสอบว่าฮอตคีย์นี้ได้รับอนุญาตให้ประมวลผลหรือไม่ - Window Manager คืนค่าที่เหมาะสมให้กับ MetaDisplay - หากได้รับอนุญาตให้ดำเนินการกับคีย์ลัดนี้ MetaDisplay จะสร้างเหตุการณ์ 'เร่งใช้งาน'


ฉันทดสอบโค้ดนี้เฉพาะใน Gnome 3.22
p2t2p

นี่คือคำตอบที่ยอดเยี่ยมขอบคุณมากสำหรับการแบ่งปัน
andy.holmes

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.