Windows: Compress Window Activation events.

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>
This commit is contained in:
Friedemann Kleint 2012-05-11 11:34:28 +02:00 committed by Qt by Nokia
parent 0909c01b2f
commit e3bbfe00d1
3 changed files with 30 additions and 10 deletions

View File

@ -259,6 +259,7 @@ struct QWindowsContextPrivate {
const HRESULT m_oleInitializeResult; const HRESULT m_oleInitializeResult;
const QByteArray m_eventType; const QByteArray m_eventType;
EventFilter m_eventFilters[EventFilterTypeCount]; EventFilter m_eventFilters[EventFilterTypeCount];
QWindow *m_lastActiveWindow;
}; };
QWindowsContextPrivate::QWindowsContextPrivate() : QWindowsContextPrivate::QWindowsContextPrivate() :
@ -266,7 +267,8 @@ QWindowsContextPrivate::QWindowsContextPrivate() :
m_displayContext(GetDC(0)), m_displayContext(GetDC(0)),
m_defaultDPI(GetDeviceCaps(m_displayContext,LOGPIXELSY)), m_defaultDPI(GetDeviceCaps(m_displayContext,LOGPIXELSY)),
m_oleInitializeResult(OleInitialize(NULL)), m_oleInitializeResult(OleInitialize(NULL)),
m_eventType(QByteArrayLiteral("windows_generic_MSG")) m_eventType(QByteArrayLiteral("windows_generic_MSG")),
m_lastActiveWindow(0)
{ {
#ifndef Q_OS_WINCE #ifndef Q_OS_WINCE
QWindowsContext::user32dll.init(); QWindowsContext::user32dll.init();
@ -819,10 +821,8 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
case QtWindows::TouchEvent: case QtWindows::TouchEvent:
return d->m_mouseHandler.translateTouchEvent(platformWindow->window(), hwnd, et, msg, result); return d->m_mouseHandler.translateTouchEvent(platformWindow->window(), hwnd, et, msg, result);
case QtWindows::FocusInEvent: // see QWindowsWindow::requestActivateWindow(). case QtWindows::FocusInEvent: // see QWindowsWindow::requestActivateWindow().
QWindowSystemInterface::handleWindowActivated(platformWindow->window());
return true;
case QtWindows::FocusOutEvent: case QtWindows::FocusOutEvent:
QWindowSystemInterface::handleWindowActivated(0); handleFocusEvent(et, platformWindow);
return true; return true;
case QtWindows::ShowEvent: case QtWindows::ShowEvent:
platformWindow->handleShown(); platformWindow->handleShown();
@ -850,6 +850,31 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
return false; 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. \brief Windows functions for actual windows.

View File

@ -179,6 +179,7 @@ public:
static QByteArray comErrorString(HRESULT hr); static QByteArray comErrorString(HRESULT hr);
private: private:
void handleFocusEvent(QtWindows::WindowsEventType et, QWindowsWindow *w);
void unregisterWindowClasses(); void unregisterWindowClasses();
QScopedPointer<QWindowsContextPrivate> d; QScopedPointer<QWindowsContextPrivate> d;

View File

@ -116,9 +116,6 @@ void tst_QGuiApplication::focusObject()
QTest::qWaitForWindowShown(&window2); QTest::qWaitForWindowShown(&window2);
QTRY_COMPARE(app.focusWindow(), &window2); QTRY_COMPARE(app.focusWindow(), &window2);
QCOMPARE(app.focusObject(), &obj3); QCOMPARE(app.focusObject(), &obj3);
#ifdef Q_OS_WIN
QEXPECT_FAIL("", "QTBUG-24186", Abort);
#endif
QCOMPARE(spy.count(), 1); QCOMPARE(spy.count(), 1);
// focus change on unfocused window does not show // focus change on unfocused window does not show
@ -241,9 +238,6 @@ void tst_QGuiApplication::changeFocusWindow()
window2.requestActivateWindow(); window2.requestActivateWindow();
QTRY_COMPARE(app.focusWindow(), &window2); QTRY_COMPARE(app.focusWindow(), &window2);
QCOMPARE(window1.windowDuringFocusAboutToChange, &window1); QCOMPARE(window1.windowDuringFocusAboutToChange, &window1);
#ifdef Q_OS_WIN
QEXPECT_FAIL("", "QTBUG-24186", Abort);
#endif
QCOMPARE(window1.windowDuringFocusOut, &window2); QCOMPARE(window1.windowDuringFocusOut, &window2);
} }