From 6b5bbc531b30d8ece25425e39843c6ae1af1d045 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 25 Jun 2012 16:56:16 +0300 Subject: Implement automatic mouse grabbing on mouse button press. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QWidget::grabMouse() documentation states that Qt automatically grabs the mouse when a button is pressed and ungrabs it when it is released. Implemented this functionality to make Qt5 behavior similar to Qt4. Task-number: QTBUG-25977 Change-Id: I17aa7e8190f4f5224ebc382d62970c86ae492bdb Reviewed-by: Samuel Rødal Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qapplication.cpp | 2 ++ src/widgets/kernel/qapplication_p.h | 1 + src/widgets/kernel/qapplication_qpa.cpp | 28 +++++++++++++++++++++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 2e64f0745f..997a663c27 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -3153,6 +3153,8 @@ bool QApplication::notify(QObject *receiver, QEvent *e) d->toolTipGlobalPos = mouse->globalPos(); d->toolTipWakeUp.start(d->toolTipFallAsleep.isActive()?20:700, this); } + + d->handleAutomaticMouseGrab(w, mouse); } bool eventAccepted = mouse->isAccepted(); diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h index e4670ca5bf..7b69129d29 100644 --- a/src/widgets/kernel/qapplication_p.h +++ b/src/widgets/kernel/qapplication_p.h @@ -167,6 +167,7 @@ public: void openPopup(QWidget *popup); static void setFocusWidget(QWidget *focus, Qt::FocusReason reason); static QWidget *focusNextPrevChild_helper(QWidget *toplevel, bool next); + void handleAutomaticMouseGrab(QWidget *widget, QMouseEvent *e); #ifndef QT_NO_SESSIONMANAGER QSessionManager *session_manager; diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp index 139c72f629..a4c4838717 100644 --- a/src/widgets/kernel/qapplication_qpa.cpp +++ b/src/widgets/kernel/qapplication_qpa.cpp @@ -74,7 +74,8 @@ QT_BEGIN_NAMESPACE static QString appName; static QString appFont; -static bool popupGrabOk; +static bool popupGrabOk = false; +static QPointer autoGrabber; extern QWidget *qt_button_down; extern QWidget *qt_popup_down; extern bool qt_replay_popup_mouse_event; @@ -148,6 +149,28 @@ void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous) QApplication::setActiveWindow(tlw); } +void QApplicationPrivate::handleAutomaticMouseGrab(QWidget *widget, QMouseEvent *e) +{ + // Grab the mouse automatically for current window when any button is pressed, + // unless there is an active mousegrabber or mouse is being grabbed for a popup. + if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease) { + if (e->buttons() == Qt::NoButton) { + // No buttons remain pressed, so release the grab unless grab has been acquired + // for some other reason in the meantime. + if (autoGrabber && !QWidget::mouseGrabber() && !popupGrabOk) + qt_widget_private(autoGrabber)->stealMouseGrab(false); + autoGrabber = 0; + } else { + // Some buttons are pressed, grab mouse input for current window, + // unless there is already an active grab. + if (!autoGrabber && !QWidget::mouseGrabber() && !popupGrabOk) { + autoGrabber = widget->window(); + qt_widget_private(autoGrabber)->stealMouseGrab(true); + } + } + } +} + static void ungrabKeyboardForPopup(QWidget *popup) { if (QWidget::keyboardGrabber()) @@ -169,6 +192,9 @@ static void grabForPopup(QWidget *popup) Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created)); popupGrabOk = qt_widget_private(popup)->stealKeyboardGrab(true); if (popupGrabOk) { + if (autoGrabber) + qt_widget_private(autoGrabber)->stealMouseGrab(false); + autoGrabber = 0; popupGrabOk = qt_widget_private(popup)->stealMouseGrab(true); if (!popupGrabOk) { // transfer grab back to the keyboard grabber if any -- cgit v1.2.3