VirtualBox

Changeset 61945 in vbox


Ignore:
Timestamp:
Jun 30, 2016 6:04:58 AM (8 years ago)
Author:
vboxsync
Message:

bugref:8151: FE/Qt: improve X11 keyboard capturing: always use full keyboard capturing on X11 hosts. Do a passive grab of mouse button one as well to detect mouse clicks outside of our window and release the keyboard before the application clicked on potentially tries to grab it itself: most window managers refuse to drag windows if they cannot grab the keyboard.

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

Legend:

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

    r61745 r61945  
    315315         * S.a. UIKeyboardHandler::eventFilter for more information. */
    316316
    317 #elif defined(VBOX_WS_X11)
     317#elif defined(VBOX_WS_X11) && QT_VERSION < 0x050000
    318318
    319319        /* On X11, we are using passive XGrabKey for normal (windowed) mode
     
    328328            case UIVisualStateType_Scale:
    329329            {
    330 # if QT_VERSION >= 0x050000
    331                 xcb_grab_key_checked(QX11Info::connection(), 0, m_windows.value(uScreenId)->winId(), XCB_MOD_MASK_ANY, XCB_GRAB_ANY, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
    332 # else /* QT_VERSION < 0x050000 */
    333330                XGrabKey(QX11Info::display(), AnyKey, AnyModifier, m_windows[uScreenId]->winId(), False, GrabModeAsync, GrabModeAsync);
    334 # endif /* QT_VERSION < 0x050000 */
    335331                break;
    336332            }
     
    339335            case UIVisualStateType_Seamless:
    340336            {
    341 # if QT_VERSION >= 0x050000
    342                 xcb_grab_keyboard(QX11Info::connection(), 0, m_windows.value(uScreenId)->winId(), XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
    343 # else /* QT_VERSION < 0x050000 */
    344337                /* Keyboard grabbing can fail because of some keyboard shortcut is still grabbed by window manager.
    345338                 * We can't be sure this shortcut will be released at all, so we will retry to grab keyboard for 50 times,
     
    357350                           CurrentTime))
    358351                        --cTriesLeft;
    359 # endif /* QT_VERSION < 0x050000 */
    360352                break;
    361353            }
     
    369361        /* On other platforms we are just praying Qt method to work: */
    370362        m_views[uScreenId]->grabKeyboard();
     363#if defined(VBOX_WS_X11) && QT_VERSION >= 0x050000
     364        /* Mouse capture hack for when the keyboard is captured.  We do not
     365         * check for failure as we do not currently implement a back-up plan. */
     366        if (!uisession()->isMouseCaptured())
     367            xcb_grab_button_checked(QX11Info::connection(), 0, QX11Info::appRootWindow(), XCB_EVENT_MASK_BUTTON_PRESS, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE, XCB_BUTTON_INDEX_1, XCB_MOD_MASK_ANY);
     368#endif /* defined(VBOX_WS_X11) && QT_VERSION >= 0x050000 */
    371369
    372370#endif
     
    414412         * S.a. UIKeyboardHandler::eventFilter for more information. */
    415413
    416 #elif defined(VBOX_WS_X11)
     414#elif defined(VBOX_WS_X11) && QT_VERSION < 0x050000
    417415
    418416        /* On X11, we are using passive XGrabKey for normal (windowed) mode
     
    427425            case UIVisualStateType_Scale:
    428426            {
    429 # if QT_VERSION >= 0x050000
    430                 xcb_ungrab_key(QX11Info::connection(), XCB_GRAB_ANY, m_windows.value(m_iKeyboardCaptureViewIndex)->winId(), XCB_MOD_MASK_ANY);
    431 # else /* QT_VERSION < 0x050000 */
    432427                XUngrabKey(QX11Info::display(), AnyKey, AnyModifier, m_windows[m_iKeyboardCaptureViewIndex]->winId());
    433 # endif /* QT_VERSION < 0x050000 */
    434428                break;
    435429            }
     
    438432            case UIVisualStateType_Seamless:
    439433            {
    440 # if QT_VERSION >= 0x050000
    441                 xcb_ungrab_keyboard(QX11Info::connection(), CurrentTime);
    442 # else /* QT_VERSION < 0x050000 */
    443434                XUngrabKeyboard(QX11Info::display(), CurrentTime);
    444 # endif /* QT_VERSION < 0x050000 */
    445435                break;
    446436            }
     
    454444        /* On other platforms we are just praying Qt method to work: */
    455445        m_views[m_iKeyboardCaptureViewIndex]->releaseKeyboard();
     446#if defined(VBOX_WS_X11) && QT_VERSION >= 0x050000
     447        /* Mouse capture hack for when the keyboard is captured. */
     448        if (!uisession()->isMouseCaptured())
     449            xcb_ungrab_button_checked(QX11Info::connection(), XCB_BUTTON_INDEX_1, QX11Info::appRootWindow(), XCB_MOD_MASK_ANY);
     450#endif /* defined(VBOX_WS_X11) && QT_VERSION >= 0x050000 */
    456451
    457452#endif
     
    13861381            fResult = keyEvent(ks, uScan, iflags, uScreenId);
    13871382
     1383            break;
     1384        }
     1385        /* If we see a mouse press outside of our views while the mouse is not
     1386         * captured, release the keyboard before letting the event owner see it.
     1387         * This is because some owners cannot deal with failures to grab the
     1388         * keyboard themselves (e.g. window managers dragging windows).  Only
     1389         * works if we have passively grabbed the mouse button. */
     1390        case XCB_BUTTON_PRESS:
     1391        {
     1392            /* Cast to XCB key-event: */
     1393            xcb_button_press_event_t *pButtonEvent = static_cast<xcb_button_press_event_t*>(pMessage);
     1394            QWidget *pWidget = qApp->widgetAt(pButtonEvent->root_x, pButtonEvent->root_y);
     1395
     1396            if (uisession()->isMouseCaptured())
     1397                break;
     1398            if (pWidget)
     1399            {
     1400                QPoint pos = pWidget->mapFromGlobal(QPoint(pButtonEvent->root_x, pButtonEvent->root_y));
     1401                pButtonEvent->event = pWidget->effectiveWinId();
     1402                pButtonEvent->event_x = pos.x();
     1403                pButtonEvent->event_y = pos.y();
     1404                xcb_allow_events_checked(QX11Info::connection(), XCB_ALLOW_REPLAY_POINTER, pButtonEvent->time);
     1405                break;
     1406            }
     1407            m_views[m_iKeyboardCaptureViewIndex]->releaseKeyboard();
     1408            xcb_allow_events_checked(QX11Info::connection(), XCB_ALLOW_REPLAY_POINTER, pButtonEvent->time);
    13881409            break;
    13891410        }
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp

    r61242 r61945  
    19091909        case XCB_KEY_PRESS:
    19101910        case XCB_KEY_RELEASE:
    1911         {
    1912             /* Delegate key-event handling to the keyboard-handler: */
     1911        case XCB_BUTTON_PRESS:
     1912        {
     1913            /* Delegate key-event handling to the keyboard-handler and let it
     1914             * filter out button presses out of the view windows: */
    19131915            return machineLogic()->keyboardHandler()->nativeEventPostprocessor(pMessage, screenId());
    19141916        }
Note: See TracChangeset for help on using the changeset viewer.

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