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 <morten.sorvig@qt.io>
This commit is contained in:
parent
772d374ce7
commit
ff645479e7
@ -5,6 +5,18 @@
|
|||||||
#include <QtCore/qvariant.h>
|
#include <QtCore/qvariant.h>
|
||||||
#include <QFontDatabase>
|
#include <QFontDatabase>
|
||||||
#include <QList>
|
#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
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -12,9 +24,29 @@ using namespace Qt::StringLiterals;
|
|||||||
|
|
||||||
QWasmTheme::QWasmTheme()
|
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())
|
for (auto family : QFontDatabase::families())
|
||||||
if (QFontDatabase::isFixedPitch(family))
|
if (QFontDatabase::isFixedPitch(family))
|
||||||
fixedFont = new QFont(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()
|
QWasmTheme::~QWasmTheme()
|
||||||
@ -23,6 +55,35 @@ QWasmTheme::~QWasmTheme()
|
|||||||
delete fixedFont;
|
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
|
QVariant QWasmTheme::themeHint(ThemeHint hint) const
|
||||||
{
|
{
|
||||||
if (hint == QPlatformTheme::StyleNames)
|
if (hint == QPlatformTheme::StyleNames)
|
||||||
@ -40,4 +101,22 @@ const QFont *QWasmTheme::font(Font type) const
|
|||||||
return nullptr;
|
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
|
QT_END_NAMESPACE
|
||||||
|
@ -23,9 +23,22 @@ public:
|
|||||||
QWasmTheme();
|
QWasmTheme();
|
||||||
~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;
|
QVariant themeHint(ThemeHint hint) const override;
|
||||||
const QFont *font(Font type) const override;
|
const QFont *font(Font type) const override;
|
||||||
QFont *fixedFont = nullptr;
|
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
|
QT_END_NAMESPACE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user