diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 502cecd67f..6627f99f16 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1912,7 +1912,6 @@ QWidget *qt_tlw_for_window(QWindow *wnd) void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous) { - Q_UNUSED(previous); #ifndef Q_OS_MACOS // Some delayed focus event to ignore, unless we are on cocoa where // popups can be opened via right-click on inactive applications @@ -1929,6 +1928,20 @@ void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous) if (widget->inherits("QAxHostWidget")) widget->setFocus(Qt::ActiveWindowFocusReason); } + + // QApplication::setActiveWindow() will deliver window activation events for + // QWidgetWindows. But for other subclasses of QWindow (like QQuickWindow), we + // need to send them explicitly, like we do from the base class implementation. + if (previous && !qobject_cast(previous)) { + QEvent de(QEvent::WindowDeactivate); + QCoreApplication::sendEvent(previous, &de); + } + + if (focusWindow && !qobject_cast(focusWindow)) { + QEvent ae(QEvent::WindowActivate); + QCoreApplication::sendEvent(focusWindow, &ae); + } + // don't call base class to avoid double delivery of WindowActivate/Deactivate events } diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index 107c5fdb84..dfcedc065d 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -125,6 +125,7 @@ private slots: void desktopSettingsAware(); void setActiveWindow(); + void activateDeactivateEvent(); void focusWidget(); void focusChanged(); @@ -1563,6 +1564,53 @@ void tst_QApplication::setActiveWindow() delete w; } +void tst_QApplication::activateDeactivateEvent() +{ + // Ensure that QWindows (other than QWidgetWindow) + // are activated / deactivated. + class Window : public QWindow + { + public: + using QWindow::QWindow; + + int activateCount = 0; + int deactivateCount = 0; + protected: + bool event(QEvent *e) + { + switch (e->type()) { + case QEvent::WindowActivate: + ++activateCount; + break; + case QEvent::WindowDeactivate: + ++deactivateCount; + break; + default: + break; + } + return QWindow::event(e); + } + }; + + int argc = 0; + QApplication app(argc, nullptr); + + Window w1; + Window w2; + + w1.show(); + w1.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&w1)); + QCOMPARE(w1.activateCount, 1); + QCOMPARE(w1.deactivateCount, 0); + + w2.show(); + w2.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&w2)); + QCOMPARE(w1.deactivateCount, 1); + QCOMPARE(w2.activateCount, 1); +} + void tst_QApplication::focusWidget() { int argc = 0;