Fixed mouse grabbing preventing popups from being closed.
authorSamuel Rødal <samuel.rodal@nokia.com>
Mon, 18 Jun 2012 13:53:30 +0000 (15:53 +0200)
committerQt by Nokia <qt-info@nokia.com>
Wed, 20 Jun 2012 22:58:22 +0000 (00:58 +0200)
The pointer grabbing leads to fake Enter events being sent to the
Qt::Popup window, preventing it from closing since QWidget::underMouse()
returns true. We should only send Enter events if the mouse is actually
inside the widget.

Change-Id: I4ba3fb08943580f93ad4337ff0227becd647767e
Reviewed-by: Laszlo Agocs <laszlo.p.agocs@nokia.com>
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
src/widgets/kernel/qapplication.cpp
tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp

index 7999eeb..eecf590 100644 (file)
@@ -2480,6 +2480,8 @@ bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
 
     const bool graphicsWidget = nativeWidget->testAttribute(Qt::WA_DontShowOnScreen);
 
+    bool widgetUnderMouse = QRectF(receiver->rect()).contains(event->localPos());
+
     if (*buttonDown) {
         if (!graphicsWidget) {
             // Register the widget that shall receive a leave event
@@ -2489,7 +2491,7 @@ bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
             if (event->type() == QEvent::MouseButtonRelease && !event->buttons())
                 *buttonDown = 0;
         }
-    } else if (lastMouseReceiver) {
+    } else if (lastMouseReceiver && widgetUnderMouse) {
         // Dispatch enter/leave if we move:
         // 1) from an alien widget to another alien widget or
         //    from a native widget to an alien widget (first OR case)
index 2de2b1a..1dd855b 100644 (file)
@@ -68,6 +68,7 @@
 #include <QtGui/qguiapplication.h>
 #include <QtGui/qscreen.h>
 #include <qmenubar.h>
+#include <qcompleter.h>
 #include <qtableview.h>
 #include <qtreewidget.h>
 
@@ -170,6 +171,7 @@ private slots:
     void palettePropagation();
     void palettePropagation2();
     void enabledPropagation();
+    void popupEnterLeave();
 #ifndef QT_NO_DRAGANDDROP
     void acceptDropsPropagation();
 #endif
@@ -4725,6 +4727,51 @@ public:
     }                                                                   \
 }
 
+void tst_QWidget::popupEnterLeave()
+{
+    QWidget parent;
+    parent.setWindowFlags(Qt::FramelessWindowHint);
+    parent.setGeometry(10, 10, 200, 100);
+
+    ColorWidget alien(&parent, Qt::black);
+    alien.setGeometry(0, 0, 10, 10);
+    alien.show();
+
+    parent.show();
+
+    QTest::qWaitForWindowShown(parent.windowHandle());
+
+    QWindowSystemInterface::handleMouseEvent(parent.windowHandle(), QPointF(5, 5), QPointF(), Qt::LeftButton, Qt::NoModifier);
+    QTest::qWait(100);
+    QWindowSystemInterface::handleMouseEvent(parent.windowHandle(), QPointF(5, 5), QPointF(), Qt::NoButton, Qt::NoModifier);
+    QTest::qWait(100);
+
+    QStringList wordList;
+    wordList << "alpha" << "omega" << "omicron" << "zeta";
+
+    QLineEdit popup(&parent);
+
+    QCompleter completer(wordList);
+    completer.setCaseSensitivity(Qt::CaseInsensitive);
+    popup.setCompleter(&completer);
+    popup.setWindowFlags(Qt::Popup);
+    popup.setGeometry(20, 20, 80, 20);
+
+    popup.show();
+
+    QTest::qWaitForWindowShown(popup.windowHandle());
+
+    QTest::qWait(100);
+
+    QWindowSystemInterface::handleMouseEvent(popup.windowHandle(), QPointF(-5, -5), QPointF(), Qt::LeftButton, Qt::NoModifier);
+    QTest::qWait(100);
+    QWindowSystemInterface::handleMouseEvent(popup.windowHandle(), QPointF(-5, -5), QPointF(), Qt::NoButton, Qt::NoModifier);
+    QTest::qWait(100);
+
+    QTest::qWait(1000);
+    QVERIFY(!popup.underMouse());
+}
+
 void tst_QWidget::moveChild_data()
 {
     QTest::addColumn<QPoint>("offset");