From d96f00286cd570d70d9e8829e665a38928aefc20 Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Wed, 13 Jan 2021 11:41:41 +0100 Subject: Fix setting active window as application's focus widget MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When setting the application's focus widget we search for the next child widget that can hold the focus and call its setFocus() method, which also updates focus widgets of all its parent wigets. In case if the focus widget is the active window itself, we only set it as the application's focus widget, but we don't update the focus widget of the active window itself. Because of this the focusWidget() method always results nullptr for the active window. This prevents from setting the focus back to active window after the focus has changed (for example after a context menu is closed, as in the bugreport). Transfer the focus to active window by calling the setFocus() method, as it is done in case of transferring the focus to any other widget. Fixes: QTBUG-85846 Change-Id: I91ebf182fd5bb7d451a1186e2f3e38c8d48acc4e Reviewed-by: Tor Arne Vestbø Reviewed-by: Volker Hilsheimer (cherry picked from commit 154573929a76d9051920756b19ed033c4b2ac649) Reviewed-by: Qt Cherry-pick Bot --- .../kernel/qapplication/tst_qapplication.cpp | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'tests/auto/widgets') diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index 750810724c..0aa915cc47 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -58,6 +58,7 @@ #include #include #include +#include #include #include @@ -120,6 +121,7 @@ private slots: void setActiveWindow(); + void focusWidget(); void focusChanged(); void focusOut(); void focusMouseClick(); @@ -1551,6 +1553,44 @@ void tst_QApplication::setActiveWindow() delete w; } +void tst_QApplication::focusWidget() +{ + int argc = 0; + QApplication app(argc, nullptr); + + // The focus widget is the active window itself + { + QTextEdit te; + te.show(); + + QApplication::setActiveWindow(&te); + QVERIFY(QTest::qWaitForWindowActive(&te)); + + const auto focusWidget = QApplication::focusWidget(); + QVERIFY(focusWidget); + QVERIFY(focusWidget->hasFocus()); + QVERIFY(te.hasFocus()); + QCOMPARE(focusWidget, te.focusWidget()); + } + + // The focus widget is a child of the active window + { + QWidget w; + QTextEdit te(&w); + w.show(); + + QApplication::setActiveWindow(&w); + QVERIFY(QTest::qWaitForWindowActive(&w)); + + const auto focusWidget = QApplication::focusWidget(); + QVERIFY(focusWidget); + QVERIFY(focusWidget->hasFocus()); + QVERIFY(!w.hasFocus()); + QVERIFY(te.hasFocus()); + QCOMPARE(te.focusWidget(), w.focusWidget()); + QCOMPARE(focusWidget, w.focusWidget()); + } +} /* This might fail on some X11 window managers? */ void tst_QApplication::focusChanged() -- cgit v1.2.3