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]
ThemeName=Dark
PreferredStyles=Fusion
PreferredStyles=
DefaultTextEditorColorScheme=dark.xml
[Palette]

View File

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

View File

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

View File

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

View File

@@ -67,13 +67,14 @@ void setThemeApplicationPalette()
QApplication::setPalette(m_creatorTheme->palette());
}
static void maybeForceMacOSLight(Theme *theme)
static void setMacAppearance(Theme *theme)
{
#ifdef Q_OS_MACOS
// Match the native UI theme and palette with the creator
// theme by forcing light aqua for light creator themes.
if (theme && !theme->flag(Theme::DarkUserInterface))
Internal::forceMacOSLightAquaApperance();
// theme by forcing light aqua for light creator themes
// and dark aqua for dark themes.
if (theme)
Internal::forceMacAppearance(theme->flag(Theme::DarkUserInterface));
#else
Q_UNUSED(theme)
#endif
@@ -96,7 +97,7 @@ void setCreatorTheme(Theme *theme)
delete m_creatorTheme;
m_creatorTheme = theme;
maybeForceMacOSLight(theme);
setMacAppearance(theme);
setThemeApplicationPalette();
}
@@ -120,6 +121,10 @@ Theme::~Theme()
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;
}
@@ -291,7 +296,7 @@ static QPalette copyPalette(const QPalette &p)
void Theme::setInitialPalette(Theme *initTheme)
{
macOSSystemIsDark(); // initialize value for system mode
maybeForceMacOSLight(initTheme);
setMacAppearance(initTheme);
initialPalette();
}

View File

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

View File

@@ -39,26 +39,36 @@
namespace Utils {
namespace Internal {
void forceMacOSLightAquaApperance()
{
#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()
bool currentAppearanceMatches(bool dark)
{
#if __has_builtin(__builtin_available)
if (__builtin_available(macOS 10.14, *)) {
auto appearance = [NSApp.effectiveAppearance
bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]];
return [appearance isEqualToString:NSAppearanceNameDarkAqua];
return
[appearance isEqualToString:(dark ? NSAppearanceNameDarkAqua : NSAppearanceNameAqua)];
}
#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