diff --git a/.gitattributes b/.gitattributes index 9df1af791..afc11a7bb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -11,3 +11,6 @@ AppImage-Recipe.sh export-ignore # github-linguist language hints *.h linguist-language=C++ *.cpp linguist-language=C++ + +# binary files +*.ai binary diff --git a/src/core/Resources.cpp b/src/core/Resources.cpp index ae8c0d46a..26c63ab1c 100644 --- a/src/core/Resources.cpp +++ b/src/core/Resources.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -30,6 +31,18 @@ #include "gui/MainWindow.h" #include "gui/osutils/OSUtils.h" +class AdaptiveIconEngine : public QIconEngine +{ +public: + explicit AdaptiveIconEngine(QIcon baseIcon); + void paint(QPainter* painter, const QRect& rect, QIcon::Mode mode, QIcon::State state) override; + QPixmap pixmap(const QSize& size, QIcon::Mode mode, QIcon::State state) override; + QIconEngine* clone() const override; + +private: + QIcon m_baseIcon; +}; + Resources* Resources::m_instance(nullptr); QString Resources::dataPath(const QString& name) const @@ -114,45 +127,103 @@ QString Resources::trayIconAppearance() const return iconAppearance; } -QIcon Resources::trayIcon() +QIcon Resources::trayIcon(QString style) { - return trayIconUnlocked(); + if (style == "unlocked") { + style.clear(); + } + if (!style.isEmpty()) { + style = "-" + style; + } + + auto iconApperance = trayIconAppearance(); + if (!iconApperance.startsWith("monochrome")) { + return icon(QString("keepassxc%1").arg(style), false); + } + + QIcon i; +#ifdef Q_OS_MACOS + if (osUtils->isStatusBarDark()) { + i = icon(QString("keepassxc-monochrome-light%1").arg(style), false); + } else { + i = icon(QString("keepassxc-monochrome-dark%1").arg(style), false); + } +#else + i = icon(QString("keepassxc-%1%2").arg(iconApperance, style), false); +#endif +#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) + // Set as mask to allow the operating system to recolour the tray icon. This may look weird + // if we failed to detect the status bar background colour correctly, but it is certainly + // better than a barely visible icon and even if we did guess correctly, it allows for better + // integration should the system's preferred colours not be 100% black or white. + i.setIsMask(true); +#endif + return i; } QIcon Resources::trayIconLocked() { - auto iconApperance = trayIconAppearance(); - - if (iconApperance == "monochrome-light") { - return icon("keepassxc-monochrome-light-locked", false); - } - if (iconApperance == "monochrome-dark") { - return icon("keepassxc-monochrome-dark-locked", false); - } - return icon("keepassxc-locked", false); + return trayIcon("locked"); } QIcon Resources::trayIconUnlocked() { - auto iconApperance = trayIconAppearance(); + return trayIcon("unlocked"); +} - if (iconApperance == "monochrome-light") { - return icon("keepassxc-monochrome-light", false); + +AdaptiveIconEngine::AdaptiveIconEngine(QIcon baseIcon) + : QIconEngine() + , m_baseIcon(std::move(baseIcon)) +{ +} + +void AdaptiveIconEngine::paint(QPainter* painter, const QRect& rect, QIcon::Mode mode, QIcon::State state) +{ +#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) + double dpr = !kpxcApp->testAttribute(Qt::AA_UseHighDpiPixmaps) ? 1.0 : painter->device()->devicePixelRatioF(); +#else + double dpr = !kpxcApp->testAttribute(Qt::AA_UseHighDpiPixmaps) ? 1.0 : painter->device()->devicePixelRatio(); +#endif + QSize pixmapSize = rect.size() * dpr; + + painter->save(); + painter->drawPixmap(rect, m_baseIcon.pixmap(pixmapSize, mode, state)); + + if (getMainWindow()) { + QPalette palette = getMainWindow()->palette(); + painter->setCompositionMode(QPainter::CompositionMode_SourceAtop); + + if (mode == QIcon::Active) { + painter->fillRect(rect, palette.color(QPalette::Active, QPalette::ButtonText)); + } else if (mode == QIcon::Selected) { + painter->fillRect(rect, palette.color(QPalette::Active, QPalette::HighlightedText)); + } else if (mode == QIcon::Disabled) { + painter->fillRect(rect, palette.color(QPalette::Disabled, QPalette::WindowText)); + } else { + painter->fillRect(rect, palette.color(QPalette::Normal, QPalette::WindowText)); + } } - if (iconApperance == "monochrome-dark") { - return icon("keepassxc-monochrome-dark", false); - } - return icon("keepassxc", false); + painter->restore(); +} + +QPixmap AdaptiveIconEngine::pixmap(const QSize& size, QIcon::Mode mode, QIcon::State state) +{ + QImage img(size, QImage::Format_ARGB32_Premultiplied); + img.fill(0); + QPainter painter(&img); + paint(&painter, QRect(0, 0, size.width(), size.height()), mode, state); + return QPixmap::fromImage(img, Qt::NoFormatConversion); +} + +QIconEngine* AdaptiveIconEngine::clone() const +{ + return new AdaptiveIconEngine(m_baseIcon); } QIcon Resources::icon(const QString& name, bool recolor, const QColor& overrideColor) { - QIcon icon = m_iconCache.value(name); - - if (!icon.isNull() && !overrideColor.isValid()) { - return icon; - } - +#ifdef Q_OS_LINUX // Resetting the application theme name before calling QIcon::fromTheme() is required for hacky // QPA platform themes such as qt5ct, which randomly mess with the configured icon theme. // If we do not reset the theme name here, it will become empty at some point, causing @@ -161,44 +232,25 @@ QIcon Resources::icon(const QString& name, bool recolor, const QColor& overrideC // See issue #4963: https://github.com/keepassxreboot/keepassxc/issues/4963 // and qt5ct issue #80: https://sourceforge.net/p/qt5ct/tickets/80/ QIcon::setThemeName("application"); +#endif + + QString cacheName = + QString("%1:%2:%3").arg(recolor ? "1" : "0", overrideColor.isValid() ? overrideColor.name() : "#", name); + QIcon icon = m_iconCache.value(cacheName); + + if (!icon.isNull() && !overrideColor.isValid()) { + return icon; + } icon = QIcon::fromTheme(name); - if (getMainWindow() && recolor) { - const QRect rect(0, 0, 48, 48); - QImage img = icon.pixmap(rect.width(), rect.height()).toImage(); - img = img.convertToFormat(QImage::Format_ARGB32_Premultiplied); - icon = {}; - - QPainter painter(&img); - painter.setCompositionMode(QPainter::CompositionMode_SourceAtop); - - if (!overrideColor.isValid()) { - QPalette palette = getMainWindow()->palette(); - painter.fillRect(rect, palette.color(QPalette::Normal, QPalette::WindowText)); - icon.addPixmap(QPixmap::fromImage(img), QIcon::Normal); - - painter.fillRect(rect, palette.color(QPalette::Active, QPalette::ButtonText)); - icon.addPixmap(QPixmap::fromImage(img), QIcon::Active); - - painter.fillRect(rect, palette.color(QPalette::Active, QPalette::HighlightedText)); - icon.addPixmap(QPixmap::fromImage(img), QIcon::Selected); - - painter.fillRect(rect, palette.color(QPalette::Disabled, QPalette::WindowText)); - icon.addPixmap(QPixmap::fromImage(img), QIcon::Disabled); - } else { - painter.fillRect(rect, overrideColor); - icon.addPixmap(QPixmap::fromImage(img), QIcon::Normal); - } - + if (recolor) { + icon = QIcon(new AdaptiveIconEngine(icon)); #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) icon.setIsMask(true); #endif } - if (!overrideColor.isValid()) { - m_iconCache.insert(name, icon); - } - + m_iconCache.insert(cacheName, icon); return icon; } diff --git a/src/core/Resources.h b/src/core/Resources.h index b76818150..6cadb5996 100644 --- a/src/core/Resources.h +++ b/src/core/Resources.h @@ -31,7 +31,7 @@ public: QString pluginPath(const QString& name) const; QString wordlistPath(const QString& name) const; QIcon applicationIcon(); - QIcon trayIcon(); + QIcon trayIcon(QString style = "unlocked"); QIcon trayIconLocked(); QIcon trayIconUnlocked(); QString trayIconAppearance() const; diff --git a/src/gui/Application.cpp b/src/gui/Application.cpp index 0c389706f..784528294 100644 --- a/src/gui/Application.cpp +++ b/src/gui/Application.cpp @@ -22,6 +22,7 @@ #include "autotype/AutoType.h" #include "core/Config.h" #include "core/Global.h" +#include "core/Resources.h" #include "gui/MainWindow.h" #include "gui/osutils/OSUtils.h" #include "gui/styles/dark/DarkStyle.h" @@ -131,6 +132,12 @@ Application::Application(int& argc, char** argv) qWarning() << QObject::tr("The lock file could not be created. Single-instance mode disabled.").toUtf8().constData(); } + + connect(osUtils, &OSUtilsBase::interfaceThemeChanged, this, [this]() { + if (config()->get(Config::GUI_ApplicationTheme).toString() != "classic") { + applyTheme(); + } + }); } Application::~Application() @@ -153,15 +160,15 @@ void Application::applyTheme() } #endif } - + QPixmapCache::clear(); if (appTheme == "light") { - setStyle(new LightStyle); - // Workaround Qt 5.15+ bug - setPalette(style()->standardPalette()); + auto* s = new LightStyle; + setPalette(s->standardPalette()); + setStyle(s); } else if (appTheme == "dark") { - setStyle(new DarkStyle); - // Workaround Qt 5.15+ bug - setPalette(style()->standardPalette()); + auto* s = new DarkStyle; + setPalette(s->standardPalette()); + setStyle(s); m_darkTheme = true; } else { // Classic mode, don't check for dark theme on Windows diff --git a/src/gui/ApplicationSettingsWidget.cpp b/src/gui/ApplicationSettingsWidget.cpp index cf09df39b..0d9829229 100644 --- a/src/gui/ApplicationSettingsWidget.cpp +++ b/src/gui/ApplicationSettingsWidget.cpp @@ -250,8 +250,12 @@ void ApplicationSettingsWidget::loadSettings() } m_generalUi->trayIconAppearance->clear(); +#ifdef Q_OS_MACOS + m_generalUi->trayIconAppearance->addItem(tr("Monochrome"), "monochrome"); +#else m_generalUi->trayIconAppearance->addItem(tr("Monochrome (light)"), "monochrome-light"); m_generalUi->trayIconAppearance->addItem(tr("Monochrome (dark)"), "monochrome-dark"); +#endif m_generalUi->trayIconAppearance->addItem(tr("Colorful"), "colorful"); int trayIconIndex = m_generalUi->trayIconAppearance->findData(resources()->trayIconAppearance()); if (trayIconIndex > 0) { diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 7f0f3bf6f..c08f6e677 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -39,6 +39,7 @@ #include "gui/DatabaseWidget.h" #include "gui/MessageBox.h" #include "gui/SearchWidget.h" +#include "gui/osutils/OSUtils.h" #include "keys/CompositeKey.h" #include "keys/FileKey.h" #include "keys/PasswordKey.h" @@ -496,6 +497,8 @@ MainWindow::MainWindow() connect(m_ui->actionOnlineHelp, SIGNAL(triggered()), SLOT(openOnlineHelp())); connect(m_ui->actionKeyboardShortcuts, SIGNAL(triggered()), SLOT(openKeyboardShortcuts())); + connect(osUtils, &OSUtilsBase::statusbarThemeChanged, this, &MainWindow::updateTrayIcon); + #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // Install event filter for empty-area drag auto* eventFilter = new MainWindowEventFilter(this); @@ -599,6 +602,11 @@ MainWindow::MainWindow() config()->set(Config::Messages_Qt55CompatibilityWarning, true); } #endif + + QObject::connect(qApp, SIGNAL(anotherInstanceStarted()), this, SLOT(bringToFront())); + QObject::connect(qApp, SIGNAL(applicationActivated()), this, SLOT(bringToFront())); + QObject::connect(qApp, SIGNAL(openFile(QString)), this, SLOT(openDatabase(QString))); + QObject::connect(qApp, SIGNAL(quitSignalReceived()), this, SLOT(appExit()), Qt::DirectConnection); } MainWindow::~MainWindow() @@ -1737,8 +1745,10 @@ void MainWindow::initViewMenu() connect(themeActions, &QActionGroup::triggered, this, [this, theme](QAction* action) { config()->set(Config::GUI_ApplicationTheme, action->data()); - if (action->data() != theme) { + if ((action->data() == "classic" || theme == "classic") && action->data() != theme) { restartApp(tr("You must restart the application to apply this setting. Would you like to restart now?")); + } else { + kpxcApp->applyTheme(); } }); diff --git a/src/gui/osutils/OSUtilsBase.h b/src/gui/osutils/OSUtilsBase.h index 340e9bf7e..0389b667c 100644 --- a/src/gui/osutils/OSUtilsBase.h +++ b/src/gui/osutils/OSUtilsBase.h @@ -35,6 +35,11 @@ public: */ virtual bool isDarkMode() const = 0; + /** + * @return OS task / menu bar is dark. + */ + virtual bool isStatusBarDark() const = 0; + /** * @return KeePassXC set to launch at system startup (autostart). */ @@ -50,6 +55,17 @@ public: */ virtual bool isCapslockEnabled() = 0; +signals: + /** + * Indicates platform UI theme change (light mode to dark mode). + */ + void interfaceThemeChanged(); + + /* + * Indicates a change in the tray / statusbar theme. + */ + void statusbarThemeChanged(); + protected: explicit OSUtilsBase(QObject* parent = nullptr); virtual ~OSUtilsBase(); diff --git a/src/gui/osutils/macutils/AppKit.h b/src/gui/osutils/macutils/AppKit.h index 02121683d..9ce4c01db 100644 --- a/src/gui/osutils/macutils/AppKit.h +++ b/src/gui/osutils/macutils/AppKit.h @@ -20,6 +20,7 @@ #define KEEPASSX_APPKIT_H #include +#include #include class AppKit : public QObject @@ -37,13 +38,14 @@ public: bool hideProcess(pid_t pid); bool isHidden(pid_t pid); bool isDarkMode(); - bool hasDarkMode(); + bool isStatusBarDark(); bool enableAccessibility(); bool enableScreenRecording(); void toggleForegroundApp(bool foreground); signals: void lockDatabases(); + void interfaceThemeChanged(); private: void* self; diff --git a/src/gui/osutils/macutils/AppKitImpl.h b/src/gui/osutils/macutils/AppKitImpl.h index 5dadc31dd..5e7a2fbae 100644 --- a/src/gui/osutils/macutils/AppKitImpl.h +++ b/src/gui/osutils/macutils/AppKitImpl.h @@ -35,6 +35,7 @@ - (bool) hideProcess:(pid_t) pid; - (bool) isHidden:(pid_t) pid; - (bool) isDarkMode; +- (bool) isStatusBarDark; - (void) userSwitchHandler:(NSNotification*) notification; - (bool) enableAccessibility; - (bool) enableScreenRecording; diff --git a/src/gui/osutils/macutils/AppKitImpl.mm b/src/gui/osutils/macutils/AppKitImpl.mm index 077dd71a6..faf061106 100644 --- a/src/gui/osutils/macutils/AppKitImpl.mm +++ b/src/gui/osutils/macutils/AppKitImpl.mm @@ -17,7 +17,11 @@ */ #import "AppKitImpl.h" +#include "AppKit.h" +#import +#import +#import #import #import @@ -26,17 +30,31 @@ - (id) initWithObject:(AppKit*)appkit { self = [super init]; + if (self) { m_appkit = appkit; - [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:static_cast(self) + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(didDeactivateApplicationObserver:) name:NSWorkspaceDidDeactivateApplicationNotification object:nil]; - [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:static_cast(self) + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(userSwitchHandler:) name:NSWorkspaceSessionDidResignActiveNotification object:nil]; + + [[NSDistributedNotificationCenter defaultCenter] addObserver:self + selector:@selector(interfaceThemeChanged:) + name:@"AppleInterfaceThemeChangedNotification" + object:nil]; + + // Unfortunately, there is no notification for a wallpaper change, which affects + // the status bar colour on macOS Big Sur, but we can at least subscribe to this. + [[NSDistributedNotificationCenter defaultCenter] addObserver:self + selector:@selector(interfaceThemeChanged:) + name:@"AppleColorPreferencesChangedNotification" + object:nil]; + } return self; } @@ -54,6 +72,18 @@ } } +// +// Light / dark theme toggled +// +- (void) interfaceThemeChanged:(NSNotification*) notification +{ + Q_UNUSED(notification); + if (m_appkit) { + emit m_appkit->interfaceThemeChanged(); + } +} + + // // Get process id of frontmost application (-> keyboard input) // @@ -108,6 +138,23 @@ && NSOrderedSame == [style caseInsensitiveCompare:@"dark"] ); } + +// +// Get global menu bar theme state +// +- (bool) isStatusBarDark +{ + if (@available(macOS 10.17, *)) { + // This is an ugly hack, but I couldn't find a way to access QTrayIcon's NSStatusItem. + NSStatusItem* dummy = [[NSStatusBar systemStatusBar] statusItemWithLength:0]; + NSString* appearance = [dummy.button.effectiveAppearance.name lowercaseString]; + [[NSStatusBar systemStatusBar] removeStatusItem:dummy]; + return [appearance containsString:@"dark"]; + } + + return [self isDarkMode]; +} + // // Notification for user switch // @@ -170,7 +217,8 @@ // ------------------------- C++ Trampolines ------------------------- // -AppKit::AppKit(QObject* parent) : QObject(parent) +AppKit::AppKit(QObject* parent) + : QObject(parent) { self = [[AppKitImpl alloc] initWithObject:this]; } @@ -178,6 +226,7 @@ AppKit::AppKit(QObject* parent) : QObject(parent) AppKit::~AppKit() { [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:static_cast(self)]; + [[NSDistributedNotificationCenter defaultCenter] removeObserver:static_cast(self)]; [static_cast(self) dealloc]; } @@ -216,6 +265,12 @@ bool AppKit::isDarkMode() return [static_cast(self) isDarkMode]; } +bool AppKit::isStatusBarDark() +{ + return [static_cast(self) isStatusBarDark]; +} + + bool AppKit::enableAccessibility() { return [static_cast(self) enableAccessibility]; diff --git a/src/gui/osutils/macutils/MacUtils.cpp b/src/gui/osutils/macutils/MacUtils.cpp index d32a15612..ebcc627e0 100644 --- a/src/gui/osutils/macutils/MacUtils.cpp +++ b/src/gui/osutils/macutils/MacUtils.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -33,6 +34,14 @@ MacUtils::MacUtils(QObject* parent) , m_appkit(new AppKit()) { connect(m_appkit.data(), SIGNAL(lockDatabases()), SIGNAL(lockDatabases())); + connect(m_appkit.data(), SIGNAL(interfaceThemeChanged()), SIGNAL(interfaceThemeChanged())); + connect(m_appkit.data(), &AppKit::interfaceThemeChanged, this, [this]() { + // Emit with delay, since isStatusBarDark() still returns the old value + // if we call it too fast after a theme change. + QTimer::singleShot(100, [this]() { + emit statusbarThemeChanged(); + }); + }); } MacUtils::~MacUtils() @@ -93,6 +102,11 @@ bool MacUtils::isDarkMode() const return m_appkit->isDarkMode(); } +bool MacUtils::isStatusBarDark() const +{ + return m_appkit->isStatusBarDark(); +} + QString MacUtils::getLaunchAgentFilename() const { auto launchAgentDir = QDir(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QStringLiteral("/../LaunchAgents")); diff --git a/src/gui/osutils/macutils/MacUtils.h b/src/gui/osutils/macutils/MacUtils.h index 281c5438c..52270f6a7 100644 --- a/src/gui/osutils/macutils/MacUtils.h +++ b/src/gui/osutils/macutils/MacUtils.h @@ -22,6 +22,7 @@ #include "gui/osutils/OSUtilsBase.h" #include "AppKit.h" +#include #include #include #include @@ -34,6 +35,7 @@ public: static MacUtils* instance(); bool isDarkMode() const override; + bool isStatusBarDark() const override; bool isLaunchAtStartupEnabled() const override; void setLaunchAtStartup(bool enable) override; bool isCapslockEnabled() override; diff --git a/src/gui/osutils/nixutils/NixUtils.cpp b/src/gui/osutils/nixutils/NixUtils.cpp index d412aa813..eacb20060 100644 --- a/src/gui/osutils/nixutils/NixUtils.cpp +++ b/src/gui/osutils/nixutils/NixUtils.cpp @@ -62,6 +62,12 @@ bool NixUtils::isDarkMode() const return qApp->style()->standardPalette().color(QPalette::Window).toHsl().lightness() < 110; } +bool NixUtils::isStatusBarDark() const +{ + // TODO: implement + return isDarkMode(); +} + QString NixUtils::getAutostartDesktopFilename(bool createDirs) const { QDir autostartDir; diff --git a/src/gui/osutils/nixutils/NixUtils.h b/src/gui/osutils/nixutils/NixUtils.h index c91580796..bc1be9975 100644 --- a/src/gui/osutils/nixutils/NixUtils.h +++ b/src/gui/osutils/nixutils/NixUtils.h @@ -29,6 +29,7 @@ public: static NixUtils* instance(); bool isDarkMode() const override; + bool isStatusBarDark() const override; bool isLaunchAtStartupEnabled() const override; void setLaunchAtStartup(bool enable) override; bool isCapslockEnabled() override; diff --git a/src/gui/osutils/winutils/WinUtils.cpp b/src/gui/osutils/winutils/WinUtils.cpp index 61e913c93..ab5562b7b 100644 --- a/src/gui/osutils/winutils/WinUtils.cpp +++ b/src/gui/osutils/winutils/WinUtils.cpp @@ -85,6 +85,12 @@ bool WinUtils::isDarkMode() const return settings.value("AppsUseLightTheme", 1).toInt() == 0; } +bool WinUtils::isStatusBarDark() const +{ + // TODO: implement + return isDarkMode(); +} + bool WinUtils::isLaunchAtStartupEnabled() const { return QSettings(R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run)", QSettings::NativeFormat) diff --git a/src/gui/osutils/winutils/WinUtils.h b/src/gui/osutils/winutils/WinUtils.h index c19040274..d8f9a10ea 100644 --- a/src/gui/osutils/winutils/WinUtils.h +++ b/src/gui/osutils/winutils/WinUtils.h @@ -33,6 +33,7 @@ public: static void registerEventFilters(); bool isDarkMode() const override; + bool isStatusBarDark() const override; bool isLaunchAtStartupEnabled() const override; void setLaunchAtStartup(bool enable) override; bool isCapslockEnabled() override; diff --git a/src/gui/styles/base/BaseStyle.cpp b/src/gui/styles/base/BaseStyle.cpp index 90c515871..26a251dc2 100644 --- a/src/gui/styles/base/BaseStyle.cpp +++ b/src/gui/styles/base/BaseStyle.cpp @@ -52,6 +52,10 @@ #include #include +#ifdef Q_OS_MACOS +#include +#endif + #include #include "core/Resources.h" @@ -288,10 +292,16 @@ namespace Phantom #ifdef Q_OS_MACOS QColor tabBarBase(const QPalette& pal) { - return hack_isLightPalette(pal) ? QRgb(0xD1D1D1) : QRgb(0x252525); + if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSBigSur) { + return hack_isLightPalette(pal) ? QRgb(0xD4D4D4) : QRgb(0x2A2A2A); + } + return hack_isLightPalette(pal) ? QRgb(0xDD1D1D1) : QRgb(0x252525); } QColor tabBarBaseInactive(const QPalette& pal) { + if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSBigSur) { + return hack_isLightPalette(pal) ? QRgb(0xF5F5F5) : QRgb(0x2D2D2D); + } return hack_isLightPalette(pal) ? QRgb(0xF4F4F4) : QRgb(0x282828); } #endif @@ -4571,27 +4581,6 @@ QStyle::SubControl BaseStyle::hitTestComplexControl(ComplexControl cc, return QCommonStyle::hitTestComplexControl(cc, opt, pt, w); } -QPixmap BaseStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap& pixmap, const QStyleOption* opt) const -{ - // Default icon highlight is way too subtle - if (iconMode == QIcon::Selected) { - QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied); - QPainter painter(&img); - - painter.setCompositionMode(QPainter::CompositionMode_SourceAtop); - - QColor color = - Phantom::DeriveColors::adjustLightness(opt->palette.color(QPalette::Normal, QPalette::Highlight), .25); - color.setAlphaF(0.25); - painter.fillRect(0, 0, img.width(), img.height(), color); - - painter.end(); - - return QPixmap::fromImage(img); - } - return QCommonStyle::generatedIconPixmap(iconMode, pixmap, opt); -} - int BaseStyle::styleHint(StyleHint hint, const QStyleOption* option, const QWidget* widget, diff --git a/src/gui/styles/base/BaseStyle.h b/src/gui/styles/base/BaseStyle.h index d3c20915c..e9bdcbdc8 100644 --- a/src/gui/styles/base/BaseStyle.h +++ b/src/gui/styles/base/BaseStyle.h @@ -70,7 +70,6 @@ public: const QStyleOptionComplex* opt, SubControl sc, const QWidget* widget) const override; - QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap& pixmap, const QStyleOption* opt) const override; int styleHint(StyleHint hint, const QStyleOption* option = nullptr, const QWidget* widget = nullptr, diff --git a/src/gui/styles/dark/DarkStyle.cpp b/src/gui/styles/dark/DarkStyle.cpp index 25f75e5ab..491f18d1f 100644 --- a/src/gui/styles/dark/DarkStyle.cpp +++ b/src/gui/styles/dark/DarkStyle.cpp @@ -114,9 +114,9 @@ void DarkStyle::polish(QWidget* widget) auto palette = widget->palette(); #if defined(Q_OS_MACOS) if (!osUtils->isDarkMode()) { - palette.setColor(QPalette::Active, QPalette::Window, QRgb(0x252525)); - palette.setColor(QPalette::Inactive, QPalette::Window, QRgb(0x282828)); - palette.setColor(QPalette::Disabled, QPalette::Window, QRgb(0x252525)); + palette.setColor(QPalette::Active, QPalette::Window, QRgb(0x2A2A2A)); + palette.setColor(QPalette::Inactive, QPalette::Window, QRgb(0x2D2D2D)); + palette.setColor(QPalette::Disabled, QPalette::Window, QRgb(0x2D2D2D)); } #elif defined(Q_OS_WIN) // Register event filter for better dark mode support diff --git a/src/gui/styles/light/LightStyle.cpp b/src/gui/styles/light/LightStyle.cpp index f1f0cb997..483e1323b 100644 --- a/src/gui/styles/light/LightStyle.cpp +++ b/src/gui/styles/light/LightStyle.cpp @@ -115,9 +115,9 @@ void LightStyle::polish(QWidget* widget) auto palette = widget->palette(); #if defined(Q_OS_MACOS) if (osUtils->isDarkMode()) { - palette.setColor(QPalette::Active, QPalette::Window, QRgb(0xD1D1D1)); - palette.setColor(QPalette::Inactive, QPalette::Window, QRgb(0xF4F4F4)); - palette.setColor(QPalette::Disabled, QPalette::Window, QRgb(0xD1D1D1)); + palette.setColor(QPalette::Active, QPalette::Window, QRgb(0xD4D4D4)); + palette.setColor(QPalette::Inactive, QPalette::Window, QRgb(0xF5F5F5)); + palette.setColor(QPalette::Disabled, QPalette::Window, QRgb(0xF5F5F5)); } #elif defined(Q_OS_WIN) palette.setColor(QPalette::All, QPalette::Window, QRgb(0xFFFFFF));