From 4790cabca597245669779c0bdecf47ec67856755 Mon Sep 17 00:00:00 2001 From: Benjamin Nauck Date: Mon, 4 Nov 2024 17:55:27 +0100 Subject: [PATCH] macOS+win+qt6.4+: Hide classic and auto choose light or dark mode depending on os setting (#17410) * mac, win, qt6.4+: Hide classic and auto choose light or dark mode * Add dark mode qt6.5 check * Start: Add QStyleHints to PreCompiled.h --------- Co-authored-by: Chris Hennes --- src/Mod/Start/Gui/CMakeLists.txt | 10 ++++ src/Mod/Start/Gui/PreCompiled.h | 1 + src/Mod/Start/Gui/ThemeSelectorWidget.cpp | 72 +++++++++++++++++++++++ src/Mod/Start/Gui/ThemeSelectorWidget.h | 1 + 4 files changed, 84 insertions(+) diff --git a/src/Mod/Start/Gui/CMakeLists.txt b/src/Mod/Start/Gui/CMakeLists.txt index cf1e8e2376..ea7c1c5d43 100644 --- a/src/Mod/Start/Gui/CMakeLists.txt +++ b/src/Mod/Start/Gui/CMakeLists.txt @@ -88,6 +88,16 @@ if (FREECAD_USE_PCH) ADD_MSVC_PRECOMPILED_HEADER(StartGui PreCompiled.h PreCompiled.cpp PCH_SRCS) endif (FREECAD_USE_PCH) +# Add CoreFoundation to StartGui_LIBS on macOS +if (APPLE) + find_library(COREFOUNDATION_LIBRARY CoreFoundation) + if (COREFOUNDATION_LIBRARY) + list(APPEND StartGui_LIBS ${COREFOUNDATION_LIBRARY}) + else() + message(SEND_ERROR "CoreFoundation not found. Please ensure you're building on macOS.") + endif() +endif() + add_library(StartGui SHARED ${StartGui_SRCS} ${StartGuiIcon_SVG} ${StartGuiThumbnail_PNG}) # target_link_libraries(StartGui ${StartGui_LIBS} Qt::Quick Qt::Qml Qt::QuickWidgets) target_link_libraries(StartGui ${StartGui_LIBS}) diff --git a/src/Mod/Start/Gui/PreCompiled.h b/src/Mod/Start/Gui/PreCompiled.h index 4904248ac4..73af2c30b8 100644 --- a/src/Mod/Start/Gui/PreCompiled.h +++ b/src/Mod/Start/Gui/PreCompiled.h @@ -66,6 +66,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Mod/Start/Gui/ThemeSelectorWidget.cpp b/src/Mod/Start/Gui/ThemeSelectorWidget.cpp index 424ab30c89..83a9043caf 100644 --- a/src/Mod/Start/Gui/ThemeSelectorWidget.cpp +++ b/src/Mod/Start/Gui/ThemeSelectorWidget.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #endif @@ -36,8 +37,59 @@ #include #include +#ifdef FC_OS_MACOSX +#include +#endif + using namespace StartGui; + +static bool isSystemInDarkMode() +{ + // Auto-detect system setting and default to light mode +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) + // https://www.qt.io/blog/dark-mode-on-windows-11-with-qt-6.5 + const auto scheme = QGuiApplication::styleHints()->colorScheme(); + return scheme == Qt::ColorScheme::Dark; +#elif QT_VERSION >= QT_VERSION_CHECK(6, 4, 0) + // https://www.qt.io/blog/dark-mode-on-windows-11-with-qt-6.5 + const QPalette defaultPalette; + const auto text = defaultPalette.color(QPalette::WindowText); + const auto window = defaultPalette.color(QPalette::Window); + return text.lightness() > window.lightness(); +#else +#ifdef FC_OS_MACOSX + auto key = CFSTR("AppleInterfaceStyle"); + if (auto value = CFPreferencesCopyAppValue(key, kCFPreferencesAnyApplication)) { + // If the value is "Dark", Dark Mode is enabled + if (CFGetTypeID(value) == CFStringGetTypeID()) { + if (CFStringCompare((CFStringRef)value, CFSTR("Dark"), kCFCompareCaseInsensitive) + == kCFCompareEqualTo) { + CFRelease(value); + return true; + } + } + CFRelease(value); + } +#endif // FC_OS_MACOSX +#endif // QT_VERSION >= 6.4+ + return false; +} + + +static bool shouldHideClassicTheme() +{ + // Classic on macOS and windows 11 with qt6(.4+?) doesn't work when system + // is in dark mode and to make matter worse, on macOS there's a setting that + // changes mode depending on time of day. +#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0) || defined(FC_OS_MACOSX) || defined(FC_OS_WIN32) + return true; +#else + return false; +#endif +} + + ThemeSelectorWidget::ThemeSelectorWidget(QWidget* parent) : QWidget(parent) , _titleLabel {nullptr} @@ -45,6 +97,9 @@ ThemeSelectorWidget::ThemeSelectorWidget(QWidget* parent) , _buttons {nullptr, nullptr, nullptr} { setObjectName(QLatin1String("ThemeSelectorWidget")); + if (shouldHideClassicTheme()) { + preselectThemeFromSystemSettings(); + } setupUi(); qApp->installEventFilter(this); } @@ -67,6 +122,11 @@ void ThemeSelectorWidget::setupButtons(QBoxLayout* layout) auto styleSheetName = QString::fromStdString(hGrp->GetASCII("StyleSheet")); for (const auto& theme : themeMap) { auto button = gsl::owner(new QToolButton()); + + if (theme.first == Theme::Classic && shouldHideClassicTheme()) { + button->setVisible(false); + } + button->setCheckable(true); button->setAutoExclusive(true); button->setToolButtonStyle(Qt::ToolButtonStyle::ToolButtonTextUnderIcon); @@ -126,6 +186,18 @@ void ThemeSelectorWidget::onLinkActivated(const QString& link) Gui::Application::Instance->commandManager().runCommandByName("Std_AddonMgr"); } +void ThemeSelectorWidget::preselectThemeFromSystemSettings() +{ + auto nullStyle(""); + auto hGrp = App::GetApplication().GetParameterGroupByPath( + "User parameter:BaseApp/Preferences/MainWindow"); + auto styleSheetName = QString::fromStdString(hGrp->GetASCII("StyleSheet", nullStyle)); + if (styleSheetName == QString::fromStdString(nullStyle)) { + auto theme = isSystemInDarkMode() ? Theme::Dark : Theme::Light; + themeChanged(theme); + } +} + void ThemeSelectorWidget::themeChanged(Theme newTheme) { // Run the appropriate preference pack: diff --git a/src/Mod/Start/Gui/ThemeSelectorWidget.h b/src/Mod/Start/Gui/ThemeSelectorWidget.h index 3535849f66..0819d34aba 100644 --- a/src/Mod/Start/Gui/ThemeSelectorWidget.h +++ b/src/Mod/Start/Gui/ThemeSelectorWidget.h @@ -57,6 +57,7 @@ private: void setupUi(); void setupButtons(QBoxLayout* layout); void onLinkActivated(const QString& link); + void preselectThemeFromSystemSettings(); QLabel* _titleLabel; QLabel* _descriptionLabel;