Implement synchronous WS events by flushing.
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>
Tue, 24 Jul 2012 07:40:20 +0000 (09:40 +0200)
committerQt by Nokia <qt-info@nokia.com>
Tue, 31 Jul 2012 18:25:36 +0000 (20:25 +0200)
Previously synchronous window system events were
implemented by bypassing the queue and processing
the event immediately. This is not ideal since the
event order is not preserved - there might be "happened
before" events waiting in the queue.

Add QWindowSystemInterface::flushWindowSystemEvents
and change all handleSynchronous* to 1) queue the
event 2) call flushWindowSystemEvents.

flushWindowSystemEvents is almost identical to the
already existing sendWindowSystemEvents with the
exception that it does not call QApp::sendPostedEvents.
Move the common implementation to a new private function.

Task-number: QTBUG-20778

Change-Id: Ie98a83875bc0a14e335e36bed0dd9e0ed4a1dea0
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
src/gui/kernel/qwindowsysteminterface.cpp
src/gui/kernel/qwindowsysteminterface.h
src/plugins/platforms/windows/qwindowswindow.cpp
tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp

index a18f6d8..87aa0c6 100644 (file)
@@ -110,8 +110,8 @@ void QWindowSystemInterface::handleGeometryChange(QWindow *tlw, const QRect &new
 
 void QWindowSystemInterface::handleSynchronousGeometryChange(QWindow *tlw, const QRect &newRect)
 {
-    QWindowSystemInterfacePrivate::GeometryChangeEvent e(tlw,newRect);
-    QGuiApplicationPrivate::processWindowSystemEvent(&e); // send event immediately.
+    handleGeometryChange(tlw, newRect);
+    QWindowSystemInterface::flushWindowSystemEvents();
 }
 
 void QWindowSystemInterface::handleCloseEvent(QWindow *tlw)
@@ -126,8 +126,8 @@ void QWindowSystemInterface::handleCloseEvent(QWindow *tlw)
 void QWindowSystemInterface::handleSynchronousCloseEvent(QWindow *tlw)
 {
     if (tlw) {
-        QWindowSystemInterfacePrivate::CloseEvent e(tlw);
-        QGuiApplicationPrivate::processWindowSystemEvent(&e);
+        handleCloseEvent(tlw);
+        QWindowSystemInterface::flushWindowSystemEvents();
     }
 }
 
@@ -495,16 +495,24 @@ void QWindowSystemInterface::handleExposeEvent(QWindow *tlw, const QRegion &regi
 
 void QWindowSystemInterface::handleSynchronousExposeEvent(QWindow *tlw, const QRegion &region)
 {
-    QWindowSystemInterfacePrivate::ExposeEvent e(tlw, region);
-    QGuiApplicationPrivate::processWindowSystemEvent(&e); // send event immediately.
+    QWindowSystemInterface::handleExposeEvent(tlw, region);
+    QWindowSystemInterface::flushWindowSystemEvents();
+}
+
+void QWindowSystemInterface::flushWindowSystemEvents()
+{
+    sendWindowSystemEventsImplementation(QEventLoop::AllEvents);
 }
 
 bool QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::ProcessEventsFlags flags)
 {
-    int nevents = 0;
+    QCoreApplication::sendPostedEvents(); // handle gui and posted events
+    return sendWindowSystemEventsImplementation(flags);
+}
 
-    // handle gui and posted events
-    QCoreApplication::sendPostedEvents();
+bool QWindowSystemInterface::sendWindowSystemEventsImplementation(QEventLoop::ProcessEventsFlags flags)
+{
+    int nevents = 0;
 
     while (true) {
         QWindowSystemInterfacePrivate::WindowSystemEvent *event;
@@ -609,5 +617,4 @@ void QWindowSystemInterface::handleTabletLeaveProximityEvent(int device, int poi
     handleTabletLeaveProximityEvent(time, device, pointerType, uid);
 }
 
-
 QT_END_NAMESPACE
index fb1717b..3be863b 100644 (file)
@@ -179,7 +179,11 @@ public:
 
     // For event dispatcher implementations
     static bool sendWindowSystemEvents(QEventLoop::ProcessEventsFlags flags);
+    static void flushWindowSystemEvents();
     static int windowSystemEventsQueued();
+
+private:
+    static bool sendWindowSystemEventsImplementation(QEventLoop::ProcessEventsFlags flags);
 };
 
 QT_END_NAMESPACE
index 9d15240..cdf1c2b 100644 (file)
@@ -795,11 +795,11 @@ void QWindowsWindow::setVisible(bool visible)
     if (m_data.hwnd) {
         if (visible) {
             show_sys();
-            QWindowSystemInterface::handleSynchronousExposeEvent(window(),
-                                                                 QRect(QPoint(), geometry().size()));
+            QWindowSystemInterface::handleExposeEvent(window(),
+                                                      QRect(QPoint(), geometry().size()));
         } else {
             hide_sys();
-            QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRegion());
+            QWindowSystemInterface::handleExposeEvent(window(), QRegion());
         }
     }
 }
index a62f792..f5e5102 100644 (file)
@@ -1984,6 +1984,8 @@ void tst_QWidget::showFullScreen()
     QVERIFY(layouted.isFullScreen());
 
     layouted.showFullScreen();
+    if (m_platform == QStringLiteral("windows"))
+        QEXPECT_FAIL("", "QTBUG-26424", Continue);
     QVERIFY(!layouted.isMinimized());
     QVERIFY(layouted.isFullScreen());
     QVERIFY(layouted.isVisible());
@@ -3987,8 +3989,6 @@ void tst_QWidget::update()
 #ifdef Q_OS_MAC
     QEXPECT_FAIL(0, "Cocoa compositor says to paint this twice.", Continue);
 #endif
-    if (m_platform == QStringLiteral("windows"))
-        QEXPECT_FAIL("", "QTBUG-26424", Continue);
     QTRY_COMPARE(w.numPaintEvents, 1);
 
     QCOMPARE(w.visibleRegion(), QRegion(w.rect()));
@@ -7594,8 +7594,6 @@ void tst_QWidget::doubleRepaint()
    widget.show();
    QVERIFY(QTest::qWaitForWindowExposed(&widget));
    QTest::qWait(10);
-   if (m_platform == QStringLiteral("windows"))
-       QEXPECT_FAIL("", "QTBUG-26424", Continue);
    QTRY_COMPARE(widget.numPaintEvents, expectedRepaints);
    widget.numPaintEvents = 0;