From 63fc3175b499beb64888f3bf9d57d4703ea17a6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20S=C3=B8rvig?= Date: Thu, 12 Oct 2023 15:26:05 +0200 Subject: [PATCH] wasm: Add QLocale backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a simple backend based on navigator.languages, which gives us a prioritized list of languages in the form '["en-US", "zh-CN", "ja-JP"]'. Use this to implement QSystemLocale::query() for UILanguages and QSystemLocale::fallbackLocale(). Register an event handler for the native QWindow:languagechange event in the QSystemLocale constructor. This event handler stays active for the lifetime of the QSystemLocale object. Task-number: QTBUG-116613 Change-Id: Ibd176748377e891b63a3f1d57605af0c2a49edb3 Reviewed-by: Edward Welbourne Reviewed-by: Morten Johan Sørvig --- src/corelib/CMakeLists.txt | 7 +++- src/corelib/text/qlocale.cpp | 11 +++++++ src/corelib/text/qlocale_p.h | 7 ++++ src/corelib/text/qlocale_wasm.cpp | 54 +++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 src/corelib/text/qlocale_wasm.cpp diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt index 868513513e..e7d93e63ac 100644 --- a/src/corelib/CMakeLists.txt +++ b/src/corelib/CMakeLists.txt @@ -797,7 +797,7 @@ qt_internal_extend_target(Core CONDITION APPLE text/qlocale_mac.mm ) -qt_internal_extend_target(Core CONDITION UNIX AND NOT APPLE +qt_internal_extend_target(Core CONDITION UNIX AND NOT APPLE AND NOT WASM SOURCES text/qlocale_unix.cpp ) @@ -807,6 +807,11 @@ qt_internal_extend_target(Core CONDITION WIN32 text/qlocale_win.cpp ) +qt_internal_extend_target(Core CONDITION WASM + SOURCES + text/qlocale_wasm.cpp +) + # On MS-Win, clang has two flavors, one of which immitates MSVC (so claims to be it) qt_internal_extend_target(Core CONDITION MSVC LIBRARIES diff --git a/src/corelib/text/qlocale.cpp b/src/corelib/text/qlocale.cpp index 7004ad9f0a..adaa1774ee 100644 --- a/src/corelib/text/qlocale.cpp +++ b/src/corelib/text/qlocale.cpp @@ -720,6 +720,17 @@ QSystemLocale::QSystemLocale() : next(_systemLocale) _systemLocale = this; systemLocaleData.m_language_id = 0; + +#ifdef Q_OS_WASM + onLanguageChanged = std::make_unique( + emscripten::val::global("window"), "languagechange", [](emscripten::val) { + systemLocaleData.m_language_id = 0; + QEvent languageChangeEvent(QEvent::LanguageChange); + QCoreApplication::sendEvent(qApp, &languageChangeEvent); + QEvent localeChangeEvent(QEvent::LocaleChange); + QCoreApplication::sendEvent(qApp, &localeChangeEvent); + }); +#endif } /*! diff --git a/src/corelib/text/qlocale_p.h b/src/corelib/text/qlocale_p.h index f8814c4417..aa429e1e3b 100644 --- a/src/corelib/text/qlocale_p.h +++ b/src/corelib/text/qlocale_p.h @@ -25,6 +25,9 @@ #include #include #include +#ifdef Q_OS_WASM +#include +#endif #include #include @@ -103,6 +106,10 @@ struct QLocaleData; class Q_CORE_EXPORT QSystemLocale { QSystemLocale *next = nullptr; // Maintains a stack. +#ifdef Q_OS_WASM + std::unique_ptr onLanguageChanged; +#endif + public: QSystemLocale(); virtual ~QSystemLocale(); diff --git a/src/corelib/text/qlocale_wasm.cpp b/src/corelib/text/qlocale_wasm.cpp new file mode 100644 index 0000000000..e67eccb122 --- /dev/null +++ b/src/corelib/text/qlocale_wasm.cpp @@ -0,0 +1,54 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qlocale_p.h" + +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_SYSTEMLOCALE + +namespace { + +QStringList navigatorLanguages() +{ + using emscripten::val; + const val navigator = val::global("navigator"); + const auto languages = emscripten::vecFromJSArray(navigator["languages"]); + QStringList qtLanguages; + for (const std::string& language : languages) + qtLanguages.append(QString::fromStdString(language)); + return qtLanguages; +} + +} + +QVariant QSystemLocale::query(QueryType query, QVariant in) const +{ + Q_UNUSED(in); + + switch (query) { + case QSystemLocale::UILanguages: + return QVariant(navigatorLanguages()); + default: + break; + } + + return QVariant(); +} + +QLocale QSystemLocale::fallbackLocale() const +{ + const QStringList languages = navigatorLanguages(); + if (languages.isEmpty()) + return QLocale(u"en-US"); + return QLocale(languages[0]); +} + +#endif // QT_NO_SYSTEMLOCALE + +QT_END_NAMESPACE