Liên kết khóa mở rộng Gnome Shell


11

Cách đơn giản nhất để (trên toàn cầu) liên kết một tổ hợp khóa (ví dụ <Super>+A) với một chức năng trong một phần mở rộng vỏ gnome là gì?

Kiểm tra một vài phần mở rộng, tôi chạy vào đoạn mã sau:

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

Tôi hiểu rằng tổ hợp khóa được chỉ định bởi tham số lược đồ và có thể tạo tệp XML mô tả kết hợp. Có cách nào đơn giản hơn để làm điều này?


Nếu bạn đang tạo tiện ích mở rộng vỏ Gnome thì có lẽ bạn sẽ nhận được phản hồi tốt hơn trên http://stackoverflow.com/ . Đánh dấu sự chú ý của người điều hành và họ sẽ chuyển câu hỏi của bạn.
NobleUplift

Câu trả lời:


5

TL; DR

Đây là một lớp học:

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)
        }
    }
})

Và đó là cách bạn sử dụng nó:

let keyManager = new KeyManager()
keyManager.listenFor("<ctrl><shift>a", function(){
    log("Hot keys are working!!!")
})

Bạn sẽ cần nhập khẩu:

const Lang = imports.lang
const Meta = imports.gi.Meta
const Shell = imports.gi.Shell
const Main = imports.ui.main

Để ngừng nghe:

for (let it of keyManager.grabbers) {
    global.display.ungrab_accelerator(it[1].action)
    Main.wm.allowKeybinding(it[1].name, Shell.ActionMode.NONE)
}

Giải trình

Tôi có thể sai lầm khủng khiếp, nhưng đó là những gì tôi đã tìm ra trong vài ngày qua.

Trước hết, đó là Mutter, người chịu trách nhiệm lắng nghe các phím nóng. Mutter là một khung để tạo Trình quản lý cửa sổ, bản thân nó không phải là trình quản lý cửa sổ. Gnome Shell có một lớp được viết bằng JS và được gọi là "Trình quản lý cửa sổ" - đây là Trình quản lý cửa sổ thực sự sử dụng Mutter bên trong để thực hiện tất cả các công cụ cấp thấp. Mutter có một đối tượng MetaDisplay. Đây là đối tượng bạn sử dụng để yêu cầu nghe một phím nóng. Nhưng! Nhưng Mutter sẽ yêu cầu Window Manager phê duyệt việc sử dụng phím nóng này. Vậy điều gì xảy ra khi nhấn phím nóng? - MetaDisplay tạo ra sự kiện 'bộ lọc khóa'. - Trình quản lý cửa sổ trong Gnome Shell kiểm tra xem phím nóng này có được phép xử lý không. - Trình quản lý cửa sổ trả về giá trị phù hợp cho MetaDisplay - Nếu được phép xử lý phím nóng này, MetaDisplay sẽ tạo ra sự kiện 'kích hoạt trình tăng tốc'


Tôi đã chỉ kiểm tra mã này trong Gnome 3.22
p2t2p

Đây là một câu trả lời tuyệt vời, cảm ơn rất nhiều vì đã chia sẻ điều này.
andy.holmes

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.