Themes: Do not force Fusion style, use macOS dark mode instead

We forced Fusion style on all platforms if the theme was a dark one, so
the dark appearance would be handled correctly even if the "native"
QStyle didn't.

On macOS, use the system's dark mode instead, which handles window
decoration correctly and uses native controls. Switching the QStyle also
messed up things like labels of standard buttons.

Remove the hardcoded "Fusion" style from all themes and set the
preferred style to Fusion automatically on Windows and Linux if the
theme states a DarkUserInterface and no PreferredStyles is set.

Fixes: QTCREATORBUG-22477
Change-Id: I91c9143a8703fcec7aa08201de9fc33d1799196d
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Eike Ziller
2021-10-27 11:47:17 +02:00
parent d1b78efaf6
commit 3e83122888
7 changed files with 39 additions and 24 deletions

View File

@@ -1,6 +1,6 @@
[General] [General]
ThemeName=Dark ThemeName=Dark
PreferredStyles=Fusion PreferredStyles=
DefaultTextEditorColorScheme=dark.xml DefaultTextEditorColorScheme=dark.xml
[Palette] [Palette]

View File

@@ -1,6 +1,6 @@
[General] [General]
ThemeName=Design Light ThemeName=Design Light
PreferredStyles=Fusion PreferredStyles=
[Palette] [Palette]

View File

@@ -1,6 +1,6 @@
[General] [General]
ThemeName=Design Dark ThemeName=Design Dark
PreferredStyles=Fusion PreferredStyles=
DefaultTextEditorColorScheme=creator-dark.xml DefaultTextEditorColorScheme=creator-dark.xml
[Palette] [Palette]

View File

@@ -1,6 +1,6 @@
[General] [General]
ThemeName=Flat Dark ThemeName=Flat Dark
PreferredStyles=Fusion PreferredStyles=
DefaultTextEditorColorScheme=creator-dark.xml DefaultTextEditorColorScheme=creator-dark.xml
[Palette] [Palette]

View File

@@ -67,13 +67,14 @@ void setThemeApplicationPalette()
QApplication::setPalette(m_creatorTheme->palette()); QApplication::setPalette(m_creatorTheme->palette());
} }
static void maybeForceMacOSLight(Theme *theme) static void setMacAppearance(Theme *theme)
{ {
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS
// Match the native UI theme and palette with the creator // Match the native UI theme and palette with the creator
// theme by forcing light aqua for light creator themes. // theme by forcing light aqua for light creator themes
if (theme && !theme->flag(Theme::DarkUserInterface)) // and dark aqua for dark themes.
Internal::forceMacOSLightAquaApperance(); if (theme)
Internal::forceMacAppearance(theme->flag(Theme::DarkUserInterface));
#else #else
Q_UNUSED(theme) Q_UNUSED(theme)
#endif #endif
@@ -96,7 +97,7 @@ void setCreatorTheme(Theme *theme)
delete m_creatorTheme; delete m_creatorTheme;
m_creatorTheme = theme; m_creatorTheme = theme;
maybeForceMacOSLight(theme); setMacAppearance(theme);
setThemeApplicationPalette(); setThemeApplicationPalette();
} }
@@ -120,6 +121,10 @@ Theme::~Theme()
QStringList Theme::preferredStyles() const QStringList Theme::preferredStyles() const
{ {
// Force Fusion style if we have a dark theme on Windows or Linux,
// because the default QStyle might not be up for it
if (!HostOsInfo::isMacHost() && d->preferredStyles.isEmpty() && flag(DarkUserInterface))
return {"Fusion"};
return d->preferredStyles; return d->preferredStyles;
} }
@@ -291,7 +296,7 @@ static QPalette copyPalette(const QPalette &p)
void Theme::setInitialPalette(Theme *initTheme) void Theme::setInitialPalette(Theme *initTheme)
{ {
macOSSystemIsDark(); // initialize value for system mode macOSSystemIsDark(); // initialize value for system mode
maybeForceMacOSLight(initTheme); setMacAppearance(initTheme);
initialPalette(); initialPalette();
} }

View File

@@ -28,7 +28,7 @@
namespace Utils { namespace Utils {
namespace Internal { namespace Internal {
void forceMacOSLightAquaApperance(); void forceMacAppearance(bool dark);
bool currentAppearanceIsDark(); bool currentAppearanceIsDark();
} // Internal } // Internal

View File

@@ -39,26 +39,36 @@
namespace Utils { namespace Utils {
namespace Internal { namespace Internal {
void forceMacOSLightAquaApperance() bool currentAppearanceMatches(bool dark)
{
#if __has_builtin(__builtin_available)
if (__builtin_available(macOS 10.14, *))
#else // Xcode 8
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 10, 14, 0))
#endif
NSApp.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua];
}
bool currentAppearanceIsDark()
{ {
#if __has_builtin(__builtin_available) #if __has_builtin(__builtin_available)
if (__builtin_available(macOS 10.14, *)) { if (__builtin_available(macOS 10.14, *)) {
auto appearance = [NSApp.effectiveAppearance auto appearance = [NSApp.effectiveAppearance
bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]]; bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]];
return [appearance isEqualToString:NSAppearanceNameDarkAqua]; return
[appearance isEqualToString:(dark ? NSAppearanceNameDarkAqua : NSAppearanceNameAqua)];
} }
#endif #endif
return false; return true;
}
void forceMacAppearance(bool dark)
{
if (currentAppearanceMatches(dark))
return;
#if __has_builtin(__builtin_available)
if (__builtin_available(macOS 10.14, *))
#else // Xcode 8
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 10, 14, 0))
#endif
NSApp.appearance = [NSAppearance
appearanceNamed:(dark ? NSAppearanceNameDarkAqua : NSAppearanceNameAqua)];
}
bool currentAppearanceIsDark()
{
// double negation, so we get "false" for macOS 10.13
return !currentAppearanceMatches(false /*==light*/);
} }
} // Internal } // Internal