Changeset 64831 in vbox
- Timestamp:
- Dec 12, 2016 11:14:22 AM (8 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox/src/runtime
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp
r64181 r64831 366 366 * This stuff is a part of the active keyboard grabbing functionality. 367 367 * Active keyboard grabbing causes a problems on many window managers - a window cannot 368 * be moved using the mouse. So we additionally grabbing the mouse as well to detect that 369 * user is trying to click outside of internal window geometry. */ 370 371 /* Grab the mouse button if the cursor is outside of our views. 368 * be moved using the mouse. So we additionally grab the mouse buttons as well to detect 369 * that the user is trying to click outside of the internal window geometry and release 370 * the keyboard before the target window sees the click. (GNOME Shell's hot corner has 371 * the same problem. At present we just let that problem be.) */ 372 373 /* Grab the mouse button. 372 374 * We do not check for failure as we do not currently implement a back-up plan. */ 373 if (!isItListenedView(QApplication::widgetAt(QCursor::pos()))) 374 xcb_grab_button_checked(QX11Info::connection(), 0, QX11Info::appRootWindow(), 375 XCB_EVENT_MASK_BUTTON_PRESS, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, 376 XCB_NONE, XCB_NONE, XCB_BUTTON_INDEX_ANY, XCB_MOD_MASK_ANY); 375 xcb_grab_button_checked(QX11Info::connection(), 0, QX11Info::appRootWindow(), 376 XCB_EVENT_MASK_BUTTON_PRESS, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, 377 XCB_NONE, XCB_NONE, XCB_BUTTON_INDEX_ANY, XCB_MOD_MASK_ANY); 377 378 /* And grab the keyboard, using XCB directly, as Qt does not report failure. */ 378 379 xcb_grab_keyboard_cookie_t xcbGrabCookie = xcb_grab_keyboard(QX11Info::connection(), false, m_views[m_iKeyboardCaptureViewIndex]->winId(), … … 1774 1775 break; 1775 1776 } 1776 #if defined(VBOX_WS_X11) && QT_VERSION >= 0x0500001777 case QEvent::Enter:1778 {1779 /* Release the mouse button grab.1780 * We do not check for failure as we do not currently implement a back-up plan. */1781 xcb_ungrab_button_checked(QX11Info::connection(), XCB_BUTTON_INDEX_ANY,1782 QX11Info::appRootWindow(), XCB_MOD_MASK_ANY);1783 1784 break;1785 }1786 case QEvent::Leave:1787 {1788 /* Grab the mouse button if the keyboard is captured.1789 * We do not check for failure as we do not currently implement a back-up plan. */1790 if (m_fIsKeyboardCaptured)1791 xcb_grab_button_checked(QX11Info::connection(), 0, QX11Info::appRootWindow(),1792 XCB_EVENT_MASK_BUTTON_PRESS, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC,1793 XCB_NONE, XCB_NONE, XCB_BUTTON_INDEX_ANY, XCB_MOD_MASK_ANY);1794 1795 break;1796 }1797 #endif /* VBOX_WS_X11 && QT_VERSION >= 0x050000 */1798 1777 case QEvent::KeyPress: 1799 1778 case QEvent::KeyRelease: -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.cpp
r63601 r64831 375 375 break; 376 376 377 /* If we see a mouse press outside of our views while the mouse is not 378 * captured, release the keyboard before letting the event owner see it. 379 * This is because some owners cannot deal with failures to grab the 380 * keyboard themselves (e.g. window managers dragging windows). 381 * Only works if we have passively grabbed the mouse button. */ 377 /* If we see a mouse press from a grab while the mouse is not captured, 378 * release the keyboard before letting the event owner see it. This is 379 * because some owners cannot deal with failures to grab the keyboard 380 * themselves (e.g. window managers dragging windows). */ 382 381 383 382 /* Cast to XCB button-event: */ 384 383 xcb_button_press_event_t *pButtonEvent = static_cast<xcb_button_press_event_t*>(pMessage); 385 384 386 /* Detect the widget which should receive the event actually: */ 387 const QWidget *pWidget = qApp->widgetAt(pButtonEvent->root_x, pButtonEvent->root_y); 388 if (pWidget) 385 /* If this event is from our button grab then it will be reported relative to the root 386 * window and not to ours. In that case release the keyboard capture, re-capture it 387 * delayed, which will fail if we have lost the input focus in the mean-time, replay 388 * the button event for normal delivery (possibly straight back to us, but not relative 389 * to root this time) and tell Qt not to further process this event: */ 390 if (pButtonEvent->event == pButtonEvent->root) 389 391 { 390 /* Redirect the event to corresponding widget: */ 391 const QPoint pos = pWidget->mapFromGlobal(QPoint(pButtonEvent->root_x, pButtonEvent->root_y)); 392 pButtonEvent->event = pWidget->effectiveWinId(); 393 pButtonEvent->event_x = pos.x(); 394 pButtonEvent->event_y = pos.y(); 395 xcb_ungrab_pointer_checked(QX11Info::connection(), pButtonEvent->time); 396 break; 392 machineLogic()->keyboardHandler()->releaseKeyboard(); 393 /** @todo It would be nicer to do this in the normal Qt button event 394 * handler to avoid avoidable races if the event was not for us. */ 395 machineLogic()->keyboardHandler()->captureKeyboard(uScreenId); 396 /* Re-send the event so that the window which it was meant for gets it: */ 397 xcb_allow_events_checked(QX11Info::connection(), XCB_ALLOW_REPLAY_POINTER, pButtonEvent->time); 398 /* Do not let Qt see the event: */ 399 return true; 397 400 } 398 /* Else if the event happened outside of our view areas then release the keyboard,399 * but capture it again (delayed) immediately. If the event causes us to loose the400 * focus then the delayed capture will not happen: */401 machineLogic()->keyboardHandler()->releaseKeyboard();402 machineLogic()->keyboardHandler()->captureKeyboard(uScreenId);403 /* And re-send the event so that the window which it was meant for actually gets it: */404 xcb_allow_events_checked(QX11Info::connection(), XCB_ALLOW_REPLAY_POINTER, pButtonEvent->time);405 break;406 401 } 407 402 default: … … 761 756 { 762 757 QMouseEvent *pMouseEvent = static_cast<QMouseEvent*>(pEvent); 758 #if defined(VBOX_WS_X11) && QT_VERSION >= 0x050000 759 /* When the keyboard is captured, we also capture mouse button 760 * events, and release the keyboard and re-capture it delayed 761 * on every mouse click. When the click is inside our window 762 * area though the delay is not needed or wanted. Calling 763 * finaliseCaptureKeyboard() skips the delay if a delayed 764 * capture is in progress and has no effect if not: */ 765 if (pEvent->type() == QEvent::MouseButtonPress) 766 machineLogic()->keyboardHandler()->finaliseCaptureKeyboard(); 767 #endif /* VBOX_WS_X11 && QT_VERSION >= 0x050000 */ 763 768 m_iLastMouseWheelDelta = 0; 764 769 if (mouseEvent(pMouseEvent->type(), uScreenId,
Note:
See TracChangeset
for help on using the changeset viewer.