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 <chennes@pioneerlibrarysystem.org>
This commit is contained in:
Benjamin Nauck
2024-11-04 17:55:27 +01:00
committed by GitHub
parent 6a8b9d0bd5
commit 4790cabca5
4 changed files with 84 additions and 0 deletions

View File

@@ -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})

View File

@@ -66,6 +66,7 @@
#include <QSpacerItem>
#include <QStackedWidget>
#include <QString>
#include <QStyleHints>
#include <QStyleOptionViewItem>
#include <QTimer>
#include <QToolButton>

View File

@@ -27,6 +27,7 @@
#include <QHBoxLayout>
#include <QLabel>
#include <QString>
#include <QStyleHints>
#include <QToolButton>
#endif
@@ -36,8 +37,59 @@
#include <Gui/Command.h>
#include <Gui/PreferencePackManager.h>
#ifdef FC_OS_MACOSX
#include <CoreFoundation/CoreFoundation.h>
#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<QToolButton*>(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("<N/A>");
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:

View File

@@ -57,6 +57,7 @@ private:
void setupUi();
void setupButtons(QBoxLayout* layout);
void onLinkActivated(const QString& link);
void preselectThemeFromSystemSettings();
QLabel* _titleLabel;
QLabel* _descriptionLabel;