QPA: Set focus reason when window activation changes focus

QApplication hides the fact that the reason is never set by several
QPA plugins, but Quick items don't receive the correct reason on
Windows, Android, the offscreen plugin, and other platforms.

Add relevant scenario to the QFocusEvent test case, and fix the
plugins to always set the focus reason when handling window activation
changes. Exclude the minimal plugin from the test, it seems largely
unmaintained anyway.

Task-number: QTBUG-75862
Change-Id: I5404a225b387fc9a3851b6968d0777c687127ed1
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit c034ad03ac6896b9fba8a72e01a1b7ec34cf0cd5)
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Volker Hilsheimer 2021-11-30 17:46:56 +01:00
parent f783bc4a3b
commit ec0e11201e
7 changed files with 46 additions and 10 deletions

View File

@ -158,7 +158,7 @@ void QAndroidPlatformScreen::addWindow(QAndroidPlatformWindow *window)
}
QWindow *w = topWindow();
QWindowSystemInterface::handleWindowActivated(w);
QWindowSystemInterface::handleWindowActivated(w, Qt::ActiveWindowFocusReason);
topWindowChanged(w);
}
@ -178,7 +178,7 @@ void QAndroidPlatformScreen::removeWindow(QAndroidPlatformWindow *window)
}
QWindow *w = topWindow();
QWindowSystemInterface::handleWindowActivated(w);
QWindowSystemInterface::handleWindowActivated(w, Qt::ActiveWindowFocusReason);
topWindowChanged(w);
}
@ -195,7 +195,7 @@ void QAndroidPlatformScreen::raise(QAndroidPlatformWindow *window)
setDirty(window->geometry());
}
QWindow *w = topWindow();
QWindowSystemInterface::handleWindowActivated(w);
QWindowSystemInterface::handleWindowActivated(w, Qt::ActiveWindowFocusReason);
topWindowChanged(w);
}
@ -212,7 +212,7 @@ void QAndroidPlatformScreen::lower(QAndroidPlatformWindow *window)
setDirty(window->geometry());
}
QWindow *w = topWindow();
QWindowSystemInterface::handleWindowActivated(w);
QWindowSystemInterface::handleWindowActivated(w, Qt::ActiveWindowFocusReason);
topWindowChanged(w);
}

View File

@ -209,7 +209,7 @@ void QDirectFbInput::handleEnterLeaveEvents(const DFBEvent &event)
void QDirectFbInput::handleGotFocusEvent(const DFBEvent &event)
{
QWindow *tlw = m_tlwMap.value(event.window.window_id);
QWindowSystemInterface::handleWindowActivated(tlw);
QWindowSystemInterface::handleWindowActivated(tlw, Qt::ActiveWindowFocusReason);
}
void QDirectFbInput::handleCloseEvent(const DFBEvent &event)

View File

@ -265,7 +265,7 @@ void QEglFSWindow::requestActivateWindow()
QOpenGLCompositor::instance()->moveToTop(this);
#endif
QWindow *wnd = window();
QWindowSystemInterface::handleWindowActivated(wnd);
QWindowSystemInterface::handleWindowActivated(wnd, Qt::ActiveWindowFocusReason);
QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size()));
}

View File

@ -122,7 +122,7 @@ void QOffscreenWindow::setVisible(bool visible)
if (visible) {
if (window()->type() != Qt::ToolTip)
QWindowSystemInterface::handleWindowActivated(window());
QWindowSystemInterface::handleWindowActivated(window(), Qt::ActiveWindowFocusReason);
if (m_pendingGeometryChangeOnShow) {
m_pendingGeometryChangeOnShow = false;
@ -158,7 +158,7 @@ void QOffscreenWindow::setVisible(bool visible)
void QOffscreenWindow::requestActivateWindow()
{
if (m_visible)
QWindowSystemInterface::handleWindowActivated(window());
QWindowSystemInterface::handleWindowActivated(window(), Qt::ActiveWindowFocusReason);
}
WId QOffscreenWindow::winId() const

View File

@ -742,7 +742,7 @@ void QQnxScreenEventHandler::handleKeyboardFocusPropertyEvent(screen_window_t wi
}
if (focus && focusWindow != QGuiApplication::focusWindow())
QWindowSystemInterface::handleWindowActivated(focusWindow);
QWindowSystemInterface::handleWindowActivated(focusWindow, Qt::ActiveWindowFocusReason);
else if (!focus && focusWindow == QGuiApplication::focusWindow())
m_focusLostTimer = startTimer(50);
}

View File

@ -1542,7 +1542,7 @@ void QWindowsContext::handleFocusEvent(QtWindows::WindowsEventType et,
}
if (nextActiveWindow != d->m_lastActiveWindow) {
d->m_lastActiveWindow = nextActiveWindow;
QWindowSystemInterface::handleWindowActivated(nextActiveWindow);
QWindowSystemInterface::handleWindowActivated(nextActiveWindow, Qt::ActiveWindowFocusReason);
}
}

View File

@ -369,6 +369,42 @@ void tst_QFocusEvent::checkReason_ActiveWindow()
QVERIFY( childFocusWidgetOne->hasFocus() );
QVERIFY( childFocusWidgetOne->focusInEventRecieved );
QCOMPARE( childFocusWidgetOne->focusInEventReason, (int)Qt::ActiveWindowFocusReason);
const bool windowActivationReasonFail =
QGuiApplication::platformName().toLower() == "minimal";
struct Window : public QWindow
{
Qt::FocusReason lastReason = Qt::NoFocusReason;
protected:
void focusInEvent(QFocusEvent *event) override
{
lastReason = event->reason();
}
void focusOutEvent(QFocusEvent *event) override
{
lastReason = event->reason();
}
};
Window window;
window.show();
window.requestActivate();
QVERIFY(QTest::qWaitForWindowActive(&window));
if (windowActivationReasonFail)
QEXPECT_FAIL("", "Platform doesn't set window activation reason for QWindow", Continue);
QCOMPARE(window.lastReason, Qt::ActiveWindowFocusReason);
window.lastReason = Qt::NoFocusReason;
Window window2;
window2.show();
window2.requestActivate();
QVERIFY(QTest::qWaitForWindowActive(&window2));
if (windowActivationReasonFail)
QEXPECT_FAIL("", "Platform doesn't set window activation reason for QWindow", Continue);
QCOMPARE(window.lastReason, Qt::ActiveWindowFocusReason);
}