VirtualBox

Ignore:
Timestamp:
Oct 24, 2014 6:47:02 AM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
96671
Message:

FE/Qt: Do not try to grab the keyboard in full-screen mode if there are more focus events for the grabbing window in the queue.

Location:
trunk/src/VBox/Frontends/VirtualBox/src/runtime
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp

    r53119 r53138  
    168168}
    169169
     170#ifdef Q_WS_X11
     171struct CHECKFORX11FOCUSEVENTSDATA
     172{
     173    Window hWindow;
     174    bool fEventFound;
     175};
     176
     177static Bool checkForX11FocusEventsWorker(Display *pDisplay, XEvent *pEvent,
     178                                         XPointer pArg)
     179{
     180    NOREF(pDisplay);
     181    struct CHECKFORX11FOCUSEVENTSDATA *pStruct;
     182   
     183    pStruct = (struct CHECKFORX11FOCUSEVENTSDATA *)pArg;
     184    if (   pEvent->xany.type == XFocusIn
     185        || pEvent->xany.type == XFocusOut)
     186        if (pEvent->xany.window == pStruct->hWindow)
     187            pStruct->fEventFound = true;
     188    return false;
     189}
     190
     191bool UIKeyboardHandler::checkForX11FocusEvents(Window hWindow)
     192{
     193    XEvent dummy;
     194    struct CHECKFORX11FOCUSEVENTSDATA data;
     195
     196    data.hWindow = hWindow;
     197    data.fEventFound = false;
     198    XCheckIfEvent(QX11Info::display(), &dummy, checkForX11FocusEventsWorker,
     199                  (XPointer)&data);
     200    return data.fEventFound;
     201}
     202#endif /* Q_WS_X11 */
     203
    170204void UIKeyboardHandler::captureKeyboard(ulong uScreenId)
    171205{
     
    208242                 * and after we will just ignore that issue: */
    209243                int cTriesLeft = 50;
    210 
    211                 if (m_cMonitors > 1)
    212                 {
    213                     /* Do this hack only for multimonitor VMs. */
    214                     XEvent dummy;
    215 
    216                     /* If a grab succeeds, X11 will insert a FocusIn event for this
    217                      * window into the event queue.  If there is already a FocusOut
    218                      * event pending we do not want this to happen (this can
    219                      * actually cause two machine windows to fight for the focus).
    220                      * It would be nicer to put the event back to the right place
    221                      * in the queue, but X11 doesn't help us there, and even Qt
    222                      * does it like this. */
    223                     if (XCheckTypedWindowEvent(QX11Info::display(),
    224                                 m_windows[m_iKeyboardCaptureViewIndex]->winId(),
    225                                 XFocusOut, &dummy))
    226                     {
    227                         XPutBackEvent(QX11Info::display(), &dummy);
    228                         break;
    229                     }
    230                 }
    231 
    232                 while (cTriesLeft && XGrabKeyboard(QX11Info::display(), m_windows[m_iKeyboardCaptureViewIndex]->winId(), False, GrabModeAsync, GrabModeAsync, CurrentTime)) { --cTriesLeft; }
     244                Window hWindow;
     245
     246                /* Only do our keyboard grab if there are no other focus events
     247                 * for this window on the queue.  This can prevent problems
     248                 * including two windows fighting to grab the keyboard. */
     249                hWindow = m_windows[m_iKeyboardCaptureViewIndex]->winId();
     250                if (!checkForX11FocusEvents(hWindow))
     251                    while (cTriesLeft && XGrabKeyboard(QX11Info::display(),
     252                           hWindow, False, GrabModeAsync, GrabModeAsync,
     253                           CurrentTime))
     254                        --cTriesLeft;
    233255                break;
    234256            }
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.h

    r53119 r53138  
    6767
    6868    /* Commands to capture/release keyboard: */
     69#ifdef Q_WS_X11
     70    bool checkForX11FocusEvents(unsigned long hWindow);
     71#endif
    6972    void captureKeyboard(ulong uScreenId);
    7073    void releaseKeyboard();
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette