Merge pull request #7463 from nextcloud/bugfix/revert-windows-dark-regressions

Revert dark mode regressions on Windows 10
This commit is contained in:
Matthieu Gallien 2024-11-19 14:13:31 +01:00 коммит произвёл GitHub
Родитель c1f9861265 011fcd04f7
Коммит 13e07faf74
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
7 изменённых файлов: 131 добавлений и 50 удалений

Просмотреть файл

@ -126,21 +126,6 @@ namespace {
// ----------------------------------------------------------------------------------
#ifdef Q_OS_WIN
class WindowsNativeEventFilter : public QAbstractNativeEventFilter {
public:
bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override {
const auto msg = static_cast<MSG *>(message);
if(msg->message == WM_SYSCOLORCHANGE || msg->message == WM_SETTINGCHANGE) {
if (const auto ptr = qobject_cast<QGuiApplication *>(QGuiApplication::instance())) {
emit ptr->paletteChanged(ptr->palette());
}
}
return false;
}
};
#endif
bool Application::configVersionMigration()
{
QStringList deleteKeys, ignoreKeys;
@ -237,9 +222,6 @@ Application::Application(int &argc, char **argv)
// Ensure OpenSSL config file is only loaded from app directory
QString opensslConf = QCoreApplication::applicationDirPath() + QString("/openssl.cnf");
qputenv("OPENSSL_CONF", opensslConf.toLocal8Bit());
// Set up event listener for Windows theme changing
installNativeEventFilter(new WindowsNativeEventFilter());
#endif
// TODO: Can't set this without breaking current config paths
@ -384,6 +366,8 @@ Application::Application(int &argc, char **argv)
_theme->setSystrayUseMonoIcons(ConfigFile().monoIcons());
connect(_theme, &Theme::systrayUseMonoIconsChanged, this, &Application::slotUseMonoIconsChanged);
connect(this, &Application::systemPaletteChanged,
_theme, &Theme::systemPaletteHasChanged);
#if defined(Q_OS_WIN)
_shellExtensionsServer.reset(new ShellExtensionsServer);
@ -1127,6 +1111,9 @@ bool Application::event(QEvent *event)
qCInfo(lcApplication) << errorParsingLocalFileEditingUrl;
showHint(errorParsingLocalFileEditingUrl.toStdString());
}
} else if (event->type() == QEvent::ApplicationPaletteChange) {
qCInfo(lcApplication) << "application palette changed";
emit systemPaletteChanged();
}
return SharedTools::QtSingleApplication::event(event);
}

Просмотреть файл

@ -96,6 +96,7 @@ signals:
void folderRemoved();
void folderStateChanged(OCC::Folder *);
void isShowingSettingsDialog();
void systemPaletteChanged();
protected slots:
void slotParseMessage(const QString &, QObject *);

Просмотреть файл

@ -35,8 +35,11 @@
#include <QMessageBox>
#include <QDebug>
#include <QQuickStyle>
#include <QStyle>
#include <QStyleFactory>
#include <QQuickWindow>
#include <QSurfaceFormat>
#include <QOperatingSystemVersion>
using namespace OCC;
@ -82,6 +85,12 @@ int main(int argc, char **argv)
QQuickStyle::setStyle(style);
QQuickStyle::setFallbackStyle(QStringLiteral("Fusion"));
#if defined Q_OS_WIN
if (QOperatingSystemVersion::current().version() < QOperatingSystemVersion::Windows11.version()) {
QApplication::setStyle(QStyleFactory::create("Fusion"));
}
#endif
OCC::Application app(argc, argv);
#ifndef Q_OS_WIN

Просмотреть файл

@ -13,11 +13,14 @@
<property name="windowTitle">
<string notr="true">Form</string>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="2" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>

Просмотреть файл

@ -32,6 +32,11 @@
#include <QPainter>
#include <QJsonDocument>
#include <QJsonArray>
#include <QLoggingCategory>
#ifdef Q_OS_WIN
#include <windows.h>
#endif
#include "nextcloudtheme.h"
@ -62,10 +67,18 @@ bool shouldPreferSvg()
return QByteArray(APPLICATION_ICON_SET).toUpper() == QByteArrayLiteral("SVG");
}
#ifdef Q_OS_WIN
bool isWindows11OrGreater() {
return QOperatingSystemVersion::current().version() >= QOperatingSystemVersion::Windows11.version();
}
#endif
}
namespace OCC {
Q_LOGGING_CATEGORY(lcTheme, "nextcloud.gui.theme", QtInfoMsg)
Theme *Theme::_instance = nullptr;
Theme *Theme::instance()
@ -354,30 +367,40 @@ Theme::Theme()
#if defined(Q_OS_WIN)
// Windows does not provide a dark theme for Win32 apps so let's come up with a palette
// Credit to https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle
reserveDarkPalette = qApp->palette();
reserveDarkPalette.setColor(QPalette::Window, QColor(53, 53, 53));
reserveDarkPalette.setColor(QPalette::WindowText, Qt::white);
reserveDarkPalette.setColor(QPalette::Disabled, QPalette::WindowText,
QColor(127, 127, 127));
reserveDarkPalette.setColor(QPalette::Button, QColor(127, 127, 127));
reserveDarkPalette.setColor(QPalette::Light, QColor(20, 20, 20));
reserveDarkPalette.setColor(QPalette::Midlight, QColor(78, 78, 78));
reserveDarkPalette.setColor(QPalette::Dark, QColor(191, 191, 191));
reserveDarkPalette.setColor(QPalette::Mid, QColor(95, 95, 95));
reserveDarkPalette.setColor(QPalette::Text, Qt::white);
reserveDarkPalette.setColor(QPalette::BrightText, Qt::red);
reserveDarkPalette.setColor(QPalette::ButtonText, Qt::white);
reserveDarkPalette.setColor(QPalette::Base, QColor(42, 42, 42));
reserveDarkPalette.setColor(QPalette::Window, QColor(53, 53, 53));
reserveDarkPalette.setColor(QPalette::Shadow, QColor(20, 20, 20));
reserveDarkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
reserveDarkPalette.setColor(QPalette::HighlightedText, Qt::white);
reserveDarkPalette.setColor(QPalette::Link, QColor(42, 130, 218));
reserveDarkPalette.setColor(QPalette::LinkVisited, QColor(42, 130, 218));
reserveDarkPalette.setColor(QPalette::AlternateBase, QColor(66, 66, 66));
reserveDarkPalette.setColor(QPalette::NoRole, QColor(127, 127, 127));
reserveDarkPalette.setColor(QPalette::ToolTipBase, Qt::white);
reserveDarkPalette.setColor(QPalette::ToolTipText, QColor(53, 53, 53));
reserveDarkPalette.setColor(QPalette::Text, Qt::white);
reserveDarkPalette.setColor(QPalette::PlaceholderText, QColor(44, 44, 44));
reserveDarkPalette.setColor(QPalette::Accent, QColor(127, 127, 200));
reserveDarkPalette.setColor(QPalette::Disabled, QPalette::Text, QColor(127, 127, 127));
reserveDarkPalette.setColor(QPalette::Dark, QColor(35, 35, 35));
reserveDarkPalette.setColor(QPalette::Shadow, QColor(20, 20, 20));
reserveDarkPalette.setColor(QPalette::Button, QColor(53, 53, 53));
reserveDarkPalette.setColor(QPalette::ButtonText, Qt::white);
reserveDarkPalette.setColor(QPalette::Disabled, QPalette::ButtonText,
QColor(127, 127, 127));
reserveDarkPalette.setColor(QPalette::BrightText, Qt::red);
reserveDarkPalette.setColor(QPalette::Link, QColor(42, 130, 218));
reserveDarkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
reserveDarkPalette.setColor(QPalette::Disabled, QPalette::Highlight, QColor(80, 80, 80));
reserveDarkPalette.setColor(QPalette::HighlightedText, Qt::white);
reserveDarkPalette.setColor(QPalette::Disabled, QPalette::HighlightedText,
QColor(127, 127, 127));
reserveDarkPalette.setColor(QPalette::Disabled, QPalette::WindowText,
QColor(127, 127, 127));
connectToPaletteSignal();
#endif
#ifdef APPLICATION_SERVER_URL_ENFORCE
@ -946,27 +969,74 @@ QColor Theme::defaultColor()
void Theme::connectToPaletteSignal()
{
if (!_paletteSignalsConnected) {
if (const auto ptr = qobject_cast<QGuiApplication *>(QGuiApplication::instance())) {
if (const auto ptr = qobject_cast<QGuiApplication*>(qApp)) {
connect(ptr->styleHints(), &QStyleHints::colorSchemeChanged, this, &Theme::darkModeChanged);
_paletteSignalsConnected = true;
}
}
}
bool Theme::darkMode()
QVariantMap Theme::systemPalette() const
{
connectToPaletteSignal();
switch (qGuiApp->styleHints()->colorScheme())
{
case Qt::ColorScheme::Dark:
return true;
case Qt::ColorScheme::Light:
return false;
case Qt::ColorScheme::Unknown:
return Theme::isDarkColor(QGuiApplication::palette().window().color());
auto systemPalette = QGuiApplication::palette();
#if defined(Q_OS_WIN)
if (darkMode() && !isWindows11OrGreater()) {
systemPalette = reserveDarkPalette;
qApp->setPalette(reserveDarkPalette);
}
#else
return false;
#endif
return QVariantMap {
{ QStringLiteral("base"), systemPalette.base().color() },
{ QStringLiteral("alternateBase"), systemPalette.alternateBase().color() },
{ QStringLiteral("text"), systemPalette.text().color() },
{ QStringLiteral("toolTipBase"), systemPalette.toolTipBase().color() },
{ QStringLiteral("toolTipText"), systemPalette.toolTipText().color() },
{ QStringLiteral("brightText"), systemPalette.brightText().color() },
{ QStringLiteral("buttonText"), systemPalette.buttonText().color() },
{ QStringLiteral("button"), systemPalette.button().color() },
{ QStringLiteral("highlightedText"), systemPalette.highlightedText().color() },
{ QStringLiteral("placeholderText"), systemPalette.placeholderText().color() },
{ QStringLiteral("windowText"), systemPalette.windowText().color() },
{ QStringLiteral("window"), systemPalette.window().color() },
{ QStringLiteral("dark"), systemPalette.dark().color() },
{ QStringLiteral("highlight"), systemPalette.highlight().color() },
{ QStringLiteral("light"), systemPalette.light().color() },
{ QStringLiteral("link"), systemPalette.link().color() },
{ QStringLiteral("midlight"), systemPalette.midlight().color() },
{ QStringLiteral("mid"), systemPalette.mid().color() },
{ QStringLiteral("linkVisited"), systemPalette.linkVisited().color() },
{ QStringLiteral("shadow"), systemPalette.shadow().color() },
};
}
bool Theme::darkMode() const
{
const auto isDarkFromStyle = [] {
switch (qGuiApp->styleHints()->colorScheme())
{
case Qt::ColorScheme::Dark:
return true;
case Qt::ColorScheme::Light:
return false;
case Qt::ColorScheme::Unknown:
return Theme::isDarkColor(QGuiApplication::palette().window().color());
}
return false;
};
#ifdef Q_OS_WIN
static const auto darkModeSubkey = QStringLiteral("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize");
if (!isWindows11OrGreater() &&
Utility::registryKeyExists(HKEY_CURRENT_USER, darkModeSubkey) &&
!Utility::registryGetKeyValue(HKEY_CURRENT_USER, darkModeSubkey, QStringLiteral("AppsUseLightTheme")).toBool()) {
return true;
}
#endif
return isDarkFromStyle();
}
void Theme::setOverrideServerUrl(const QString &overrideServerUrl)
@ -1010,4 +1080,14 @@ void Theme::setStartLoginFlowAutomatically(bool startLoginFlowAuto)
}
}
void Theme::systemPaletteHasChanged()
{
qCInfo(lcTheme()) << "system palette changed";
#ifdef Q_OS_WIN
if (darkMode() && !isWindows11OrGreater()) {
qApp->setPalette(reserveDarkPalette);
}
#endif
}
} // end namespace client

Просмотреть файл

@ -67,6 +67,7 @@ class OWNCLOUDSYNC_EXPORT Theme : public QObject
Q_PROPERTY(QColor defaultColor READ defaultColor CONSTANT)
Q_PROPERTY(QVariantMap systemPalette READ systemPalette NOTIFY systemPaletteChanged)
Q_PROPERTY(bool darkMode READ darkMode NOTIFY darkModeChanged)
public:
enum CustomMediaType {
@ -600,13 +601,15 @@ public:
static constexpr const char *themePrefix = ":/client/theme/";
bool darkMode();
[[nodiscard]] QVariantMap systemPalette() const;
[[nodiscard]] bool darkMode() const;
public slots:
void setOverrideServerUrl(const QString &overrideServerUrl);
void setForceOverrideServerUrl(bool forceOverride);
void setVfsEnabled(bool enabled);
void setStartLoginFlowAutomatically(bool startLoginFlowAuto);
void systemPaletteHasChanged();
protected:
#ifndef TOKEN_AUTH_ONLY
@ -624,6 +627,7 @@ protected:
signals:
void systrayUseMonoIconsChanged(bool);
void systemPaletteChanged(const QPalette &palette);
void darkModeChanged();
void overrideServerUrlChanged();
void forceOverrideServerUrlChanged();

Просмотреть файл

@ -8,20 +8,17 @@ QtObject {
readonly property int pixelSize: fontMetrics.font.pixelSize
readonly property bool darkMode: Theme.darkMode
property SystemPalette nativePalette: SystemPalette {
}
// Colors
readonly property color ncBlue: Theme.wizardHeaderBackgroundColor
readonly property color ncHeaderTextColor: Theme.wizardHeaderTitleColor
readonly property color ncTextColor: nativePalette.text
readonly property color ncTextColor: Theme.systemPalette.windowText
readonly property color ncTextBrightColor: "white"
readonly property color ncSecondaryTextColor: "#808080"
readonly property color lightHover: Theme.darkMode ? Qt.lighter(backgroundColor, 2) : Qt.darker(backgroundColor, 1.05)
readonly property color darkerHover: Theme.darkMode ? Qt.lighter(backgroundColor, 2.35) : Qt.darker(backgroundColor, 1.25)
readonly property color menuBorder: Theme.darkMode ? Qt.lighter(backgroundColor, 2.5) : Qt.darker(backgroundColor, 1.5)
readonly property color backgroundColor: nativePalette.window
readonly property color buttonBackgroundColor: nativePalette.button
readonly property color backgroundColor: Theme.systemPalette.window
readonly property color buttonBackgroundColor: Theme.systemPalette.button
readonly property color positiveColor: Qt.rgba(0.38, 0.74, 0.38, 1)
readonly property color currentUserHeaderColor: UserModel.currentUser ? UserModel.currentUser.headerColor : ncBlue