diff options
author | Even Oscar Andersen <[email protected]> | 2024-10-03 12:15:23 +0200 |
---|---|---|
committer | Morten Johan Sørvig <[email protected]> | 2024-10-07 05:36:09 +0000 |
commit | ff645479e7489de5a88c71c0215748d84be3de9f (patch) | |
tree | edb3f04c6e35ed2ac876b96b1328c7e4ae472e1d | |
parent | 772d374ce715de9caaae4f026594d49f6da28dec (diff) |
wasm: Handle theme colors
Changing color themes did not work since the results from
qt_fusionPalette is cached by default.
The solution is to track changes and call qt_fusionPalette
when necessary.
Fixes: QTBUG-129399
Pick-to: 6.8
Change-Id: I77824098349be5e5264fa9e230a949e3ccd6f14f
Reviewed-by: Morten Johan Sørvig <[email protected]>
-rw-r--r-- | src/plugins/platforms/wasm/qwasmtheme.cpp | 79 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qwasmtheme.h | 13 |
2 files changed, 92 insertions, 0 deletions
diff --git a/src/plugins/platforms/wasm/qwasmtheme.cpp b/src/plugins/platforms/wasm/qwasmtheme.cpp index b188dcb4b6b..799d9b70d67 100644 --- a/src/plugins/platforms/wasm/qwasmtheme.cpp +++ b/src/plugins/platforms/wasm/qwasmtheme.cpp @@ -5,6 +5,18 @@ #include <QtCore/qvariant.h> #include <QFontDatabase> #include <QList> +#include <qpa/qwindowsysteminterface.h> + +#include <private/qstdweb_p.h> + +#include <emscripten.h> +#include <emscripten/bind.h> +#include <emscripten/val.h> + +Q_GUI_EXPORT QPalette qt_fusionPalette(); + +Qt::ColorScheme QWasmTheme::s_autoColorScheme = Qt::ColorScheme::Unknown; +bool QWasmTheme::s_autoPaletteIsDirty = false; QT_BEGIN_NAMESPACE @@ -12,9 +24,29 @@ using namespace Qt::StringLiterals; QWasmTheme::QWasmTheme() { + if (emscripten::val::global("window").call<emscripten::val>( + "matchMedia", + std::string("(prefers-color-scheme:dark)"))["matches"].as<bool>()) + s_autoColorScheme = Qt::ColorScheme::Dark; + else + s_autoColorScheme = Qt::ColorScheme::Light; + for (auto family : QFontDatabase::families()) if (QFontDatabase::isFixedPitch(family)) fixedFont = new QFont(family); + + m_palette = std::make_unique<QPalette>(); + m_paletteIsDirty = true; // Force update later + + const auto callback = [=](emscripten::val event) { QWasmTheme::onColorSchemeChange(event); }; + const emscripten::val window = emscripten::val::global("window"); + if (!window.isUndefined()) { + const emscripten::val matchMedia = window.call<emscripten::val>("matchMedia", emscripten::val("(prefers-color-scheme: dark)")); + if (!matchMedia.isUndefined()) { + static auto changeEvent = + std::make_unique<qstdweb::EventCallback>(matchMedia, "change", callback); + } + } } QWasmTheme::~QWasmTheme() @@ -23,6 +55,35 @@ QWasmTheme::~QWasmTheme() delete fixedFont; } +const QPalette *QWasmTheme::palette(Palette type) const +{ + if (type == SystemPalette) { + if (m_paletteIsDirty || s_autoPaletteIsDirty) { + m_paletteIsDirty = false; + s_autoPaletteIsDirty = false; + *m_palette = qt_fusionPalette(); + } + return m_palette.get(); + } + return nullptr; +} + +Qt::ColorScheme QWasmTheme::colorScheme() const +{ + if (m_colorScheme != Qt::ColorScheme::Unknown) + return m_colorScheme; + return s_autoColorScheme; +} + +void QWasmTheme::requestColorScheme(Qt::ColorScheme scheme) +{ + if (m_colorScheme != scheme) { + m_paletteIsDirty = true; + m_colorScheme = scheme; + QWindowSystemInterface::handleThemeChange<QWindowSystemInterface::SynchronousDelivery>(); + } +} + QVariant QWasmTheme::themeHint(ThemeHint hint) const { if (hint == QPlatformTheme::StyleNames) @@ -40,4 +101,22 @@ const QFont *QWasmTheme::font(Font type) const return nullptr; } +void QWasmTheme::onColorSchemeChange(emscripten::val event) +{ + const emscripten::val matches = event["matches"]; + if (!matches.isUndefined()) { + const auto oldAutoColorScheme = s_autoColorScheme; + if (matches.as<int>()) + s_autoColorScheme = Qt::ColorScheme::Dark; + else + s_autoColorScheme = Qt::ColorScheme::Light; + + if (oldAutoColorScheme != s_autoColorScheme) { + s_autoPaletteIsDirty = true; + QWindowSystemInterface::handleThemeChange<QWindowSystemInterface::SynchronousDelivery>(); + } + } +} + + QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmtheme.h b/src/plugins/platforms/wasm/qwasmtheme.h index 90ecbe6ddff..dce1632a5e3 100644 --- a/src/plugins/platforms/wasm/qwasmtheme.h +++ b/src/plugins/platforms/wasm/qwasmtheme.h @@ -23,9 +23,22 @@ public: QWasmTheme(); ~QWasmTheme(); + const QPalette *palette(Palette type = SystemPalette) const override; + Qt::ColorScheme colorScheme() const override; + void requestColorScheme(Qt::ColorScheme scheme) override; QVariant themeHint(ThemeHint hint) const override; const QFont *font(Font type) const override; QFont *fixedFont = nullptr; + + static void onColorSchemeChange(emscripten::val event); + +private: + Qt::ColorScheme m_colorScheme = Qt::ColorScheme::Unknown; + std::unique_ptr<QPalette> m_palette; + mutable bool m_paletteIsDirty = false; + + static Qt::ColorScheme s_autoColorScheme; + static bool s_autoPaletteIsDirty; }; QT_END_NAMESPACE |