From 250d5f55deb0febb9ea94090332bbbbd91d1af5c Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Mon, 31 Jul 2023 23:22:53 +0200 Subject: [PATCH] DolphinQt: Switch dark/light theme when Windows theme changes. --- Source/Core/DolphinQt/Main.cpp | 17 +---------------- Source/Core/DolphinQt/MainWindow.cpp | 24 ++++++++++++++++++++++++ Source/Core/DolphinQt/MainWindow.h | 5 +++++ Source/Core/DolphinQt/Settings.cpp | 18 ++++++++++++++++++ Source/Core/DolphinQt/Settings.h | 1 + 5 files changed, 49 insertions(+), 16 deletions(-) diff --git a/Source/Core/DolphinQt/Main.cpp b/Source/Core/DolphinQt/Main.cpp index 611efe47ed..aa1697c6a7 100644 --- a/Source/Core/DolphinQt/Main.cpp +++ b/Source/Core/DolphinQt/Main.cpp @@ -7,8 +7,6 @@ #include #include - -#include #endif #ifdef __linux__ @@ -248,20 +246,7 @@ int main(int argc, char* argv[]) DolphinAnalytics::Instance().ReportDolphinStart("qt"); MainWindow win{std::move(boot), static_cast(options.get("movie"))}; - -#ifdef _WIN32 - // Check if the system is set to dark mode so we can set the default theme and window - // decorations accordingly. - { - using namespace winrt::Windows::UI::ViewManagement; - const UISettings settings; - const auto& color = settings.GetColorValue(UIColorType::Foreground); - - const bool is_system_dark = 5 * color.G + 2 * color.R + color.B > 8 * 128; - Settings::Instance().SetSystemDark(is_system_dark); - } -#endif - + Settings::Instance().UpdateSystemDark(); Settings::Instance().SetCurrentUserStyle(Settings::Instance().GetCurrentUserStyle()); win.Show(); diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index b193fe15c7..1f5223179c 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -1715,6 +1715,30 @@ QSize MainWindow::sizeHint() const return QSize(800, 600); } +#ifdef _WIN32 +bool MainWindow::nativeEvent(const QByteArray& eventType, void* message, qintptr* result) +{ + auto* msg = reinterpret_cast(message); + if (msg && msg->message == WM_SETTINGCHANGE && msg->lParam != NULL && + std::wstring_view(L"ImmersiveColorSet") + .compare(reinterpret_cast(msg->lParam)) == 0) + { + // Windows light/dark theme has changed. Update our flag and refresh the theme. + auto& settings = Settings::Instance(); + const bool was_dark_before = settings.IsSystemDark(); + settings.UpdateSystemDark(); + if (settings.IsSystemDark() != was_dark_before) + settings.SetCurrentUserStyle(settings.GetCurrentUserStyle()); + + // TODO: When switching from light to dark, the window decorations remain light. Qt seems very + // convinced that it needs to change these in response to this message, so even if we set them + // to dark here, Qt sets them back to light afterwards. + } + + return false; +} +#endif + void MainWindow::OnBootGameCubeIPL(DiscIO::Region region) { StartGame(std::make_unique(BootParameters::IPL{region})); diff --git a/Source/Core/DolphinQt/MainWindow.h b/Source/Core/DolphinQt/MainWindow.h index 4654202ed7..5b5de92fd8 100644 --- a/Source/Core/DolphinQt/MainWindow.h +++ b/Source/Core/DolphinQt/MainWindow.h @@ -210,6 +210,11 @@ private: void dropEvent(QDropEvent* event) override; QSize sizeHint() const override; +#ifdef _WIN32 + // This gets called for each event from the Windows message queue. + bool nativeEvent(const QByteArray& eventType, void* message, qintptr* result) override; +#endif + #ifdef HAVE_XRANDR std::unique_ptr m_xrr_config; #endif diff --git a/Source/Core/DolphinQt/Settings.cpp b/Source/Core/DolphinQt/Settings.cpp index 2a7b7b41fb..e35be9a8ba 100644 --- a/Source/Core/DolphinQt/Settings.cpp +++ b/Source/Core/DolphinQt/Settings.cpp @@ -19,6 +19,8 @@ #include +#include + #include #include #endif @@ -127,6 +129,22 @@ QString Settings::GetCurrentUserStyle() const return QFileInfo(GetQSettings().value(QStringLiteral("userstyle/path")).toString()).fileName(); } +void Settings::UpdateSystemDark() +{ +#ifdef _WIN32 + // Check if the system is set to dark mode so we can set the default theme and window + // decorations accordingly. + { + using namespace winrt::Windows::UI::ViewManagement; + const UISettings settings; + const auto& color = settings.GetColorValue(UIColorType::Foreground); + + const bool is_system_dark = 5 * color.G + 2 * color.R + color.B > 8 * 128; + Settings::Instance().SetSystemDark(is_system_dark); + } +#endif +} + void Settings::SetSystemDark(bool dark) { s_system_dark = dark; diff --git a/Source/Core/DolphinQt/Settings.h b/Source/Core/DolphinQt/Settings.h index ae58aca8a5..1e1e4b1d7e 100644 --- a/Source/Core/DolphinQt/Settings.h +++ b/Source/Core/DolphinQt/Settings.h @@ -52,6 +52,7 @@ public: // UI void SetThemeName(const QString& theme_name); + void UpdateSystemDark(); void SetSystemDark(bool dark); bool IsSystemDark(); void SetCurrentUserStyle(const QString& stylesheet_name);