From 9029c5586460950b4fa6773a5d08c67e5ba16e8a Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 13 Feb 2020 15:33:00 +0100 Subject: Send the LanguageChange event to all top level windows, not just widgets By sending it to all top level windows it will make it possible for non widget based controls to listen for this event if it cares about it so it can handle translation updates as appropriate. Task-number: QTBUG-78141 Task-number: QTBUG-82020 Change-Id: I8f35cdcccd81a199ff780c3f4f3d2c663480d638 Reviewed-by: Mitch Curtis --- src/gui/kernel/qguiapplication.cpp | 4 ++ src/widgets/kernel/qapplication.cpp | 5 ++- tests/auto/widgets/kernel/qwidget/hellotr_la.qm | Bin 0 -> 237 bytes tests/auto/widgets/kernel/qwidget/qwidget.qrc | 1 + tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 51 ++++++++++++++++++++++ 5 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 tests/auto/widgets/kernel/qwidget/hellotr_la.qm diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 67b1ed15c5..bbcb7d9cc5 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1882,6 +1882,10 @@ bool QGuiApplication::event(QEvent *e) { if(e->type() == QEvent::LanguageChange) { setLayoutDirection(qt_detectRTLLanguage()?Qt::RightToLeft:Qt::LeftToRight); + for (auto *topLevelWindow : QGuiApplication::topLevelWindows()) { + if (topLevelWindow->flags() != Qt::Desktop) + postEvent(topLevelWindow, new QEvent(QEvent::LanguageChange)); + } } else if (e->type() == QEvent::Quit) { // Close open windows. This is done in order to deliver de-expose // events while the event loop is still running. diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 2d7919e874..f49461b2d0 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1904,9 +1904,12 @@ bool QApplication::event(QEvent *e) } if(e->type() == QEvent::LanguageChange) { + // QGuiApplication::event does not account for the cases where + // there is a top level widget without a window handle. So they + // need to have the event posted here const QWidgetList list = topLevelWidgets(); for (auto *w : list) { - if (!(w->windowType() == Qt::Desktop)) + if (!w->windowHandle() && (w->windowType() != Qt::Desktop)) postEvent(w, new QEvent(QEvent::LanguageChange)); } } diff --git a/tests/auto/widgets/kernel/qwidget/hellotr_la.qm b/tests/auto/widgets/kernel/qwidget/hellotr_la.qm new file mode 100644 index 0000000000..25c0aad583 Binary files /dev/null and b/tests/auto/widgets/kernel/qwidget/hellotr_la.qm differ diff --git a/tests/auto/widgets/kernel/qwidget/qwidget.qrc b/tests/auto/widgets/kernel/qwidget/qwidget.qrc index 1399c4c9db..597ea872a5 100644 --- a/tests/auto/widgets/kernel/qwidget/qwidget.qrc +++ b/tests/auto/widgets/kernel/qwidget/qwidget.qrc @@ -3,5 +3,6 @@ geometry.dat geometry-maximized.dat geometry-fullscreen.dat + hellotr_la.qm diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 9c16b1a00a..d8f4881ffa 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -410,6 +410,7 @@ private slots: void closeWithChildWindow(); void winIdAfterClose(); + void receivesLanguageChangeEvent(); private: bool ensureScreenSize(int width, int height); @@ -11360,5 +11361,55 @@ void tst_QWidget::winIdAfterClose() delete spy; } +class LanguageChangeEventWidget : public QWidget +{ +public: + LanguageChangeEventWidget(QWidget *parent = nullptr) : QWidget(parent) {} + int languageChangeCount = 0; +protected: + bool event(QEvent *e) override + { + if (e->type() == QEvent::LanguageChange) + languageChangeCount++; + return QWidget::event(e); + } +}; + +class LanguageChangeEventWindow : public QWindow +{ +public: + LanguageChangeEventWindow(QWindow *parent = nullptr) : QWindow(parent) {} + int languageChangeCount = 0; +protected: + bool event(QEvent *e) override + { + if (e->type() == QEvent::LanguageChange) + languageChangeCount++; + return QWindow::event(e); + } +}; + +void tst_QWidget::receivesLanguageChangeEvent() +{ + // Confirm that any QWindow or QWidget only gets a single + // LanguageChange event when a translator is installed + LanguageChangeEventWidget topLevel; + auto childWidget = new LanguageChangeEventWidget(&topLevel); + topLevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + LanguageChangeEventWindow ww; + ww.show(); + QVERIFY(QTest::qWaitForWindowExposed(&ww)); + LanguageChangeEventWidget topLevelNotShown; + QTranslator t; + QVERIFY(t.load("hellotr_la.qm", ":/")); + QVERIFY(qApp->installTranslator(&t)); + QCoreApplication::sendPostedEvents(0, QEvent::LanguageChange); + QCOMPARE(topLevel.languageChangeCount, 1); + QCOMPARE(topLevelNotShown.languageChangeCount, 1); + QCOMPARE(childWidget->languageChangeCount, 1); + QCOMPARE(ww.languageChangeCount, 1); +} + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc" -- cgit v1.2.3