简体   繁体   English

从X11接收到抓取的钥匙时,如何防止窗口失去焦点

[英]How to prevent window from loosing focus when receiving a grabbed key from X11

My window calls hide() when a QEvent::FocusOut is received. 当收到QEvent::FocusOut时,我的窗口调用hide() Simultaniously I want its visibility to be toggled if a hotkey is pressed. 同时,如果要按下热键,我希望切换其可见性。 Now I have the following problem: Pressing the hotkey, registered with XGrabKex(...) seems to steel the focus of my app. 现在,我XGrabKex(...)了以下问题:按下向XGrabKex(...)注册的热键似乎可以使我的应用程序更加专注。 Resulting in an unwanted behaviour. 导致不必要的行为。 If my app is visible the hotkeyevent steels focus, which results in a QEvent::FocusOut , which hides my app, and after that the hotkey is received which toggles visibility (shows) my app. 如果可见我的应用程序,则hotkeyevent会突出显示焦点,这将导致QEvent::FocusOut ,隐藏我的应用程序,然后接收到热键,以切换(显示)我的应用程序的可见性。 Ie my app does not hide when pressing the hotkey. 即按快捷键时我的应用程序不会隐藏。

Is there a way to tell the x window system to not steel the focus when a grabbed key is pressed? 有没有一种方法可以告诉x窗口系统在按下抓取的键时不要强化焦点? Or are there other possible solutions to this problem? 还是对此问题有其他可能的解决方案?

A couple of different methods. 几种不同的方法。

  1. Use XQueryKeymap to see which keys are pressed. 使用XQueryKeymap查看按下了哪些键。 For instance, when you get a FocusOut event, call XQueryKeymap and see if your hotkey is pressed. 例如,当您收到一个FocusOut事件时,调用XQueryKeymap并查看是否按下了您的热键。 If it is not, hide the window; 如果不是,请隐藏窗口;否则,请关闭窗口。 if it is, don't hide it and wait for the hotkey event. 如果是这样,请不要将其隐藏并等待热键事件。
  2. Delay hiding on FocusOut by 100 or so milliseconds. 将隐藏在FocusOut上的FocusOut延迟100毫秒左右。 Cancel hiding if you either get the hot key or get your focus back during this time interval. 如果您在此时间间隔内获得热键或重新获得焦点,请取消隐藏。

Look also here for useful info. 在这里也可以找到有用的信息。

Finally got it to work in a "proper" way: 最终使它以“适当”的方式工作:

bool MainWidget::nativeEvent(const QByteArray &eventType, void *message, long *)
{
#ifdef Q_OS_LINUX
    if (eventType == "xcb_generic_event_t")
    {
        xcb_generic_event_t* event = static_cast<xcb_generic_event_t *>(message);
        switch (event->response_type & 127)
        {
        case XCB_FOCUS_OUT: {
            xcb_focus_out_event_t *fe = (xcb_focus_out_event_t *)event;
            if ((fe->mode==XCB_NOTIFY_MODE_GRAB && fe->detail==XCB_NOTIFY_DETAIL_NONLINEAR)
                    || (fe->mode==XCB_NOTIFY_MODE_NORMAL && fe->detail==XCB_NOTIFY_DETAIL_NONLINEAR ))
                hide();
            break;
        }
        }
    }
#endif
return false;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM