Implement automatic mouse grabbing on mouse button press.

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 <samuel.rodal@nokia.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
This commit is contained in:
Miikka Heikkinen 2012-06-25 16:56:16 +03:00 committed by Qt by Nokia
parent d3af02f190
commit 6b5bbc531b
3 changed files with 30 additions and 1 deletions

View File

@ -3153,6 +3153,8 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
d->toolTipGlobalPos = mouse->globalPos(); d->toolTipGlobalPos = mouse->globalPos();
d->toolTipWakeUp.start(d->toolTipFallAsleep.isActive()?20:700, this); d->toolTipWakeUp.start(d->toolTipFallAsleep.isActive()?20:700, this);
} }
d->handleAutomaticMouseGrab(w, mouse);
} }
bool eventAccepted = mouse->isAccepted(); bool eventAccepted = mouse->isAccepted();

View File

@ -167,6 +167,7 @@ public:
void openPopup(QWidget *popup); void openPopup(QWidget *popup);
static void setFocusWidget(QWidget *focus, Qt::FocusReason reason); static void setFocusWidget(QWidget *focus, Qt::FocusReason reason);
static QWidget *focusNextPrevChild_helper(QWidget *toplevel, bool next); static QWidget *focusNextPrevChild_helper(QWidget *toplevel, bool next);
void handleAutomaticMouseGrab(QWidget *widget, QMouseEvent *e);
#ifndef QT_NO_SESSIONMANAGER #ifndef QT_NO_SESSIONMANAGER
QSessionManager *session_manager; QSessionManager *session_manager;

View File

@ -74,7 +74,8 @@ QT_BEGIN_NAMESPACE
static QString appName; static QString appName;
static QString appFont; static QString appFont;
static bool popupGrabOk; static bool popupGrabOk = false;
static QPointer<QWidget> autoGrabber;
extern QWidget *qt_button_down; extern QWidget *qt_button_down;
extern QWidget *qt_popup_down; extern QWidget *qt_popup_down;
extern bool qt_replay_popup_mouse_event; extern bool qt_replay_popup_mouse_event;
@ -148,6 +149,28 @@ void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous)
QApplication::setActiveWindow(tlw); 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) static void ungrabKeyboardForPopup(QWidget *popup)
{ {
if (QWidget::keyboardGrabber()) if (QWidget::keyboardGrabber())
@ -169,6 +192,9 @@ static void grabForPopup(QWidget *popup)
Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created)); Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
popupGrabOk = qt_widget_private(popup)->stealKeyboardGrab(true); popupGrabOk = qt_widget_private(popup)->stealKeyboardGrab(true);
if (popupGrabOk) { if (popupGrabOk) {
if (autoGrabber)
qt_widget_private(autoGrabber)->stealMouseGrab(false);
autoGrabber = 0;
popupGrabOk = qt_widget_private(popup)->stealMouseGrab(true); popupGrabOk = qt_widget_private(popup)->stealMouseGrab(true);
if (!popupGrabOk) { if (!popupGrabOk) {
// transfer grab back to the keyboard grabber if any // transfer grab back to the keyboard grabber if any