全球alt +空间热键抓取 - 奇怪的键盘焦点行为

时间:2013-01-28 00:13:30

标签: c++ c qt x11 xcb

我使用Alt+Space抓取xcb_grab_key全局热键,如下所示:

xcb_key_symbols_t *keysyms = xcb_key_symbols_alloc(c);
xcb_keycode_t *keycodes = xcb_key_symbols_get_keycode(keysyms, XK_space), keycode;

// add bindings for all screens
xcb_screen_iterator_t iter;
iter = xcb_setup_roots_iterator (xcb_get_setup (c));
for (; iter.rem; xcb_screen_next (&iter)) {
    int i = 0;
    while(keycodes[i] != XCB_NO_SYMBOL) {
        keycode = keycodes[i];
        xcb_grab_key(c, true, iter.data->root, XCB_MOD_MASK_ANY, keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_SYNC);
        i += 1;
    }
}

然后在Qt的QAbstractNativeEventFilter子类中,我处理它并在密钥匹配Alt+Space时发出Qt信号:

xcb_keycode_t *keycodes = xcb_key_symbols_get_keycode(keysyms, XK_space);
int i = 0;
bool found = false;
while(keycodes[i] != XCB_NO_SYMBOL) {
    if(event->detail == keycodes[i]) {
        if(event->state & GetModifier(c, keysyms, XK_Alt_L) || event->state & GetModifier(c, keysyms,  XK_Alt_R)) {
            xcb_allow_events(c, XCB_ALLOW_ASYNC_KEYBOARD, event->time);
            emit gotHotKey();
            found = true;
        } else {
            xcb_allow_events(c, XCB_ALLOW_REPLAY_KEYBOARD, event->time);
        }
        break;
    }
    i += 1;
}
if(found) return true;

GetModifiercopied from VLC,但我认为这部分无关紧要,因为Alt-key匹配正确)

我遇到的问题是,在按下热键后show()主窗口之后,键盘大部分时间 1 未正确聚焦。我可以输入,但是光标不可见,输入的边框没有突出显示,并且用于退出的快捷方式Ctrl+Q不起作用。它可以通过移动窗口或按空格来解决 - 然后恢复焦点 - 光标+边框重新出现并且Ctrl+Q起作用。可能导致此行为的原因是什么?

我正在使用Qt 5.0.0和xcb 1.8.1。可以下载完整的应用程序以编译from github

1 这意味着有时候问题是不可重现的 - 即使对于重复的窗口隐藏/显示,焦点也能正确设置,但有时候它会在一行隐藏/显示中多次出现。它经常发生,而不是总体而言。

(编辑:我实现了一个(非常难看......)解决方法,所以为了重现github项目的问题,需要删除以下代码)

#ifndef WIN32
    // Very ugly workaround for the problem described at http://stackoverflow.com/questions/14553810/
    // (just show and hide a modal dialog box, which for some reason restores proper keyboard focus)
    hackDialog.setGeometry(0, 0, 0, 0);
    hackDialog.setModal(true);
    hackDialog.show();
    QTimer::singleShot(100, &hackDialog, SLOT(reject()));
#endif

0 个答案:

没有答案