summaryrefslogtreecommitdiff
path: root/wx+/darkmode.cpp
diff options
context:
space:
mode:
authorB. Stack <bgstack15@gmail.com>2025-01-20 19:25:18 -0500
committerB. Stack <bgstack15@gmail.com>2025-01-20 19:25:18 -0500
commitde65d3c0295894f8eafc4c7582dfe180dc58c81e (patch)
tree3ba8ec770b81468ca4ad83d985b991c5f669de22 /wx+/darkmode.cpp
parentadd upstream 13.9 (diff)
downloadFreeFileSync-master.tar.gz
FreeFileSync-master.tar.bz2
FreeFileSync-master.zip
add upstream 14.0, depends on wx 3.3.0HEAD14.0master
Diffstat (limited to 'wx+/darkmode.cpp')
-rw-r--r--wx+/darkmode.cpp110
1 files changed, 110 insertions, 0 deletions
diff --git a/wx+/darkmode.cpp b/wx+/darkmode.cpp
new file mode 100644
index 00000000..c8a7ea28
--- /dev/null
+++ b/wx+/darkmode.cpp
@@ -0,0 +1,110 @@
+// *****************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: https://www.gnu.org/licenses/gpl-3.0 *
+// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved *
+// *****************************************************************************
+
+#include "darkmode.h"
+#include <zen/sys_version.h>
+#include <wx/settings.h>
+#include "color_tools.h"
+ #include <gtk/gtk.h>
+
+using namespace zen;
+
+
+bool zen::darkModeAvailable()
+{
+
+#if GTK_MAJOR_VERSION == 2
+ return false;
+#elif GTK_MAJOR_VERSION >= 3
+ return true;
+#else
+#error unknown GTK version!
+#endif
+
+}
+
+
+namespace
+{
+class SysColorsHook : public wxColorHook
+{
+public:
+
+ wxColor getColor(wxSystemColour index) const override
+ {
+ //fix contrast e.g. Ubuntu's Adwaita-Dark theme and macOS dark mode:
+ if (index == wxSYS_COLOUR_GRAYTEXT)
+ return colGreyTextEnhContrast_;
+#if 0
+ auto colToString = [](wxColor c)
+ {
+ const auto& [rh, rl] = hexify(c.Red ());
+ const auto& [gh, gl] = hexify(c.Green());
+ const auto& [bh, bl] = hexify(c.Blue ());
+ const auto& [ah, al] = hexify(c.Alpha());
+ return "#" + std::string({rh, rl, gh, gl, bh, bl, ah, al});
+ };
+ std::cerr << "wxSYS_COLOUR_GRAYTEXT " << colToString(wxSystemSettingsNative::GetColour(wxSYS_COLOUR_GRAYTEXT)) << "\n";
+#endif
+ return wxSystemSettingsNative::GetColour(index); //fallback
+ }
+
+private:
+ const wxColor colGreyTextEnhContrast_ =
+ enhanceContrast(wxSystemSettingsNative::GetColour(wxSYS_COLOUR_GRAYTEXT),
+ wxSystemSettingsNative::GetColour(wxSYS_COLOUR_WINDOWTEXT),
+ wxSystemSettingsNative::GetColour(wxSYS_COLOUR_WINDOW), 4.5 /*contrastRatioMin*/); //W3C recommends >= 4.5
+};
+
+
+std::optional<bool> globalDefaultThemeIsDark;
+}
+
+
+void zen::colorThemeInit(wxApp& app, ColorTheme colTheme) //throw FileError
+{
+ assert(!refGlobalColorHook());
+
+ globalDefaultThemeIsDark = wxSystemSettings::GetAppearance().AreAppsDark();
+ ZEN_ON_SCOPE_EXIT(if (!refGlobalColorHook()) refGlobalColorHook() = std::make_unique<SysColorsHook>()); //*after* SetAppearance() and despite errors
+
+ //caveat: on macOS there are more themes than light/dark: https://developer.apple.com/documentation/appkit/nsappearance/name-swift.struct
+ if (colTheme != ColorTheme::System && //"System" is already the default for macOS/Linux(GTK3)
+ darkModeAvailable())
+ changeColorTheme(colTheme); //throw FileError
+}
+
+
+void zen::colorThemeCleanup()
+{
+ assert(refGlobalColorHook());
+ refGlobalColorHook().reset();
+}
+
+
+bool zen::equalAppearance(ColorTheme colTheme1, ColorTheme colTheme2)
+{
+ if (colTheme1 == ColorTheme::System) colTheme1 = *globalDefaultThemeIsDark ? ColorTheme::Dark : ColorTheme::Light;
+ if (colTheme2 == ColorTheme::System) colTheme2 = *globalDefaultThemeIsDark ? ColorTheme::Dark : ColorTheme::Light;
+ return colTheme1 == colTheme2;
+}
+
+
+void zen::changeColorTheme(ColorTheme colTheme) //throw FileError
+{
+ if (colTheme == ColorTheme::System) //SetAppearance(System) isn't working reliably! surprise!?
+ colTheme = *globalDefaultThemeIsDark ? ColorTheme::Dark : ColorTheme::Light;
+
+ try
+ {
+ ZEN_ON_SCOPE_SUCCESS(refGlobalColorHook() = std::make_unique<SysColorsHook>()); //*after* SetAppearance()
+ if (wxApp::AppearanceResult rv = wxTheApp->SetAppearance(colTheme);
+ rv != wxApp::AppearanceResult::Ok)
+ throw SysError(formatSystemError("wxApp::SetAppearance",
+ rv == wxApp::AppearanceResult::CannotChange ? L"CannotChange" : L"Failure", L"" /*errorMsg*/));
+ }
+ catch (const SysError& e) { throw FileError(_("Failed to update the color theme."), e.toString()); }
+}
bgstack15