Windows: Compress Window Activation events.
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>
Fri, 11 May 2012 09:34:28 +0000 (11:34 +0200)
committerQt by Nokia <qt-info@nokia.com>
Fri, 11 May 2012 13:11:20 +0000 (15:11 +0200)
If the next active window is already known at the time a focus
out is received, pass it to QWindowSystemInterface.
Fixes a test and Qt Creator's locator bar.

Task-number: QTBUG-24186
Task-number: QTCREATORBUG-1

Change-Id: I0aed4c386c08ed182555c95640e1637c5b67f5ce
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
src/plugins/platforms/windows/qwindowscontext.cpp
src/plugins/platforms/windows/qwindowscontext.h
tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp

index f44ce38..0a1ca13 100644 (file)
@@ -259,6 +259,7 @@ struct QWindowsContextPrivate {
     const HRESULT m_oleInitializeResult;
     const QByteArray m_eventType;
     EventFilter m_eventFilters[EventFilterTypeCount];
+    QWindow *m_lastActiveWindow;
 };
 
 QWindowsContextPrivate::QWindowsContextPrivate() :
@@ -266,7 +267,8 @@ QWindowsContextPrivate::QWindowsContextPrivate() :
     m_displayContext(GetDC(0)),
     m_defaultDPI(GetDeviceCaps(m_displayContext,LOGPIXELSY)),
     m_oleInitializeResult(OleInitialize(NULL)),
-    m_eventType(QByteArrayLiteral("windows_generic_MSG"))
+    m_eventType(QByteArrayLiteral("windows_generic_MSG")),
+    m_lastActiveWindow(0)
 {
 #ifndef Q_OS_WINCE
     QWindowsContext::user32dll.init();
@@ -819,10 +821,8 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
     case QtWindows::TouchEvent:
         return d->m_mouseHandler.translateTouchEvent(platformWindow->window(), hwnd, et, msg, result);
     case QtWindows::FocusInEvent: // see QWindowsWindow::requestActivateWindow().
-        QWindowSystemInterface::handleWindowActivated(platformWindow->window());
-        return true;
     case QtWindows::FocusOutEvent:
-        QWindowSystemInterface::handleWindowActivated(0);
+        handleFocusEvent(et, platformWindow);
         return true;
     case QtWindows::ShowEvent:
         platformWindow->handleShown();
@@ -850,6 +850,31 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
     return false;
 }
 
+/* Compress activation events. If the next focus window is already known
+ * at the time the current one receives focus-out, pass that to
+ * QWindowSystemInterface instead of sending 0 and ignore its consecutive
+ * focus-in event.
+ * This helps applications that do handling in focus-out events. */
+void QWindowsContext::handleFocusEvent(QtWindows::WindowsEventType et,
+                                       QWindowsWindow *platformWindow)
+{
+    QWindow *nextActiveWindow = 0;
+    if (et == QtWindows::FocusInEvent) {
+        nextActiveWindow = platformWindow->window();
+    } else {
+        // Focus out: Is the next window known and different
+        // from the receiving the focus out.
+        if (const HWND nextActiveHwnd = GetActiveWindow())
+            if (QWindowsWindow *nextActivePlatformWindow = findPlatformWindow(nextActiveHwnd))
+                if (nextActivePlatformWindow != platformWindow)
+                    nextActiveWindow = nextActivePlatformWindow->window();
+    }
+    if (nextActiveWindow != d->m_lastActiveWindow) {
+         d->m_lastActiveWindow = nextActiveWindow;
+         QWindowSystemInterface::handleWindowActivated(nextActiveWindow);
+    }
+}
+
 /*!
     \brief Windows functions for actual windows.
 
index 983f940..123eb66 100644 (file)
@@ -179,6 +179,7 @@ public:
     static QByteArray comErrorString(HRESULT hr);
 
 private:
+    void handleFocusEvent(QtWindows::WindowsEventType et, QWindowsWindow *w);
     void unregisterWindowClasses();
 
     QScopedPointer<QWindowsContextPrivate> d;
index 29b65d1..c0242d9 100644 (file)
@@ -116,9 +116,6 @@ void tst_QGuiApplication::focusObject()
     QTest::qWaitForWindowShown(&window2);
     QTRY_COMPARE(app.focusWindow(), &window2);
     QCOMPARE(app.focusObject(), &obj3);
-#ifdef Q_OS_WIN
-    QEXPECT_FAIL("", "QTBUG-24186", Abort);
-#endif
     QCOMPARE(spy.count(), 1);
 
     // focus change on unfocused window does not show
@@ -241,9 +238,6 @@ void tst_QGuiApplication::changeFocusWindow()
     window2.requestActivateWindow();
     QTRY_COMPARE(app.focusWindow(), &window2);
     QCOMPARE(window1.windowDuringFocusAboutToChange, &window1);
-#ifdef Q_OS_WIN
-    QEXPECT_FAIL("", "QTBUG-24186", Abort);
-#endif
     QCOMPARE(window1.windowDuringFocusOut, &window2);
 }