Improve macOS platform integration.

- Allow switching between themes without restart (except classic)
- Rework icon loading and recolouring logic to react to theme changes
- Automatically react to light/dark theme change
- Remove explicit selection of monochrome tray icon variant (selected
  automatically now)
- Update theme background colours for Big Sur
- Update application icon to match Big Sur HIG

The tray icon doesn't respond perfectly to theme changes yet on Big Sur,
since we need different icons for dark and light theme and cannot simply
let the OS recolour the icon for us (we do that, too, but only as an
additional fallback). At the moment, there is no signal to listen to
that would allow this.

This patch adds a few generic methods to OSUtils for detecting and
communicating theme changes, which are only stubs for Windows and Linux at
the moment and need to be implemented in future commits.

Fixes #4933
Fixes #5349
This commit is contained in:
Janek Bevendorff 2020-12-19 00:20:24 +01:00
parent 37dab85df7
commit 80c1b9be6a
32 changed files with 267 additions and 104 deletions

3
.gitattributes vendored
View File

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

BIN
share/macosx/keepassxc.ai Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 783 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

View File

@ -23,6 +23,7 @@
#include "core/Bootstrap.h"
#include "core/Config.h"
#include "core/Global.h"
#include "gui/Icons.h"
#include "gui/MainWindow.h"
#include "gui/MessageBox.h"
#include "gui/osutils/OSUtils.h"
@ -127,6 +128,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()
@ -174,15 +181,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

View File

@ -251,8 +251,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(icons()->trayIconAppearance());
if (trayIconIndex > 0) {

View File

@ -19,6 +19,8 @@
#include "Icons.h"
#include <QBitmap>
#include <QIconEngine>
#include <QPaintDevice>
#include <QPainter>
#include <QStyle>
@ -27,8 +29,24 @@
#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;
};
Icons* Icons::m_instance(nullptr);
Icons::Icons()
{
}
QIcon Icons::applicationIcon()
{
return icon("keepassxc", false);
@ -47,45 +65,102 @@ QString Icons::trayIconAppearance() const
return iconAppearance;
}
QIcon Icons::trayIcon()
QIcon Icons::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 Icons::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 Icons::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 Icons::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
@ -94,44 +169,25 @@ QIcon Icons::icon(const QString& name, bool recolor, const QColor& overrideColor
// 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
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 = {};
QString cacheName =
QString("%1:%2:%3").arg(recolor ? "1" : "0", overrideColor.isValid() ? overrideColor.name() : "#", name);
QIcon icon = m_iconCache.value(cacheName);
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 (!icon.isNull() && !overrideColor.isValid()) {
return icon;
}
icon = QIcon::fromTheme(name);
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;
}
@ -161,10 +217,6 @@ QIcon Icons::onOffIcon(const QString& name, bool recolor)
return icon;
}
Icons::Icons()
{
}
Icons* Icons::instance()
{
if (!m_instance) {

View File

@ -28,7 +28,7 @@ class Icons
{
public:
QIcon applicationIcon();
QIcon trayIcon();
QIcon trayIcon(QString style = "unlocked");
QIcon trayIconLocked();
QIcon trayIconUnlocked();
QString trayIconAppearance() const;

View File

@ -40,6 +40,7 @@
#include "gui/Icons.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"
@ -503,6 +504,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,10 +602,10 @@ MainWindow::MainWindow()
}
#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);
connect(qApp, SIGNAL(anotherInstanceStarted()), this, SLOT(bringToFront()));
connect(qApp, SIGNAL(applicationActivated()), this, SLOT(bringToFront()));
connect(qApp, SIGNAL(openFile(QString)), this, SLOT(openDatabase(QString)));
connect(qApp, SIGNAL(quitSignalReceived()), this, SLOT(appExit()), Qt::DirectConnection);
restoreConfigState();
}
@ -1757,8 +1760,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();
}
});

View File

@ -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).
*/
@ -61,6 +66,16 @@ public:
signals:
void globalShortcutTriggered(const QString& name);
/**
* 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();

View File

@ -20,6 +20,7 @@
#define KEEPASSX_APPKIT_H
#include <QObject>
#include <QColor>
#include <unistd.h>
class AppKit : public QObject
@ -37,12 +38,14 @@ public:
bool hideProcess(pid_t pid);
bool isHidden(pid_t pid);
bool isDarkMode();
bool isStatusBarDark();
bool enableAccessibility();
bool enableScreenRecording();
void toggleForegroundApp(bool foreground);
signals:
void lockDatabases();
void interfaceThemeChanged();
private:
void* self;

View File

@ -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;

View File

@ -17,7 +17,11 @@
*/
#import "AppKitImpl.h"
#include "AppKit.h"
#import <AppKit/NSStatusBar.h>
#import <AppKit/NSStatusItem.h>
#import <AppKit/NSStatusBarButton.h>
#import <AppKit/NSWorkspace.h>
#import <CoreVideo/CVPixelBuffer.h>
@ -26,17 +30,31 @@
- (id) initWithObject:(AppKit*)appkit
{
self = [super init];
if (self) {
m_appkit = appkit;
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:static_cast<id>(self)
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self
selector:@selector(didDeactivateApplicationObserver:)
name:NSWorkspaceDidDeactivateApplicationNotification
object:nil];
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:static_cast<id>(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<id>(self)];
[[NSDistributedNotificationCenter defaultCenter] removeObserver:static_cast<id>(self)];
[static_cast<id>(self) dealloc];
}
@ -216,6 +265,12 @@ bool AppKit::isDarkMode()
return [static_cast<id>(self) isDarkMode];
}
bool AppKit::isStatusBarDark()
{
return [static_cast<id>(self) isStatusBarDark];
}
bool AppKit::enableAccessibility()
{
return [static_cast<id>(self) enableAccessibility];

View File

@ -22,6 +22,7 @@
#include <QFile>
#include <QSettings>
#include <QStandardPaths>
#include <QTimer>
#include <ApplicationServices/ApplicationServices.h>
#include <CoreGraphics/CGEventSource.h>
@ -35,6 +36,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()
@ -95,6 +104,11 @@ bool MacUtils::isDarkMode() const
return m_appkit->isDarkMode();
}
bool MacUtils::isStatusBarDark() const
{
return m_appkit->isStatusBarDark();
}
QString MacUtils::getLaunchAgentFilename() const
{
auto launchAgentDir =

View File

@ -23,6 +23,7 @@
#include "gui/osutils/OSUtilsBase.h"
#include <Carbon/Carbon.h>
#include <QColor>
#include <QPointer>
#include <QScopedPointer>
#include <qwindowdefs.h>
@ -35,6 +36,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;

View File

@ -79,6 +79,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;

View File

@ -30,6 +30,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;

View File

@ -87,6 +87,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)

View File

@ -35,6 +35,7 @@ public:
static WinUtils* instance();
bool isDarkMode() const override;
bool isStatusBarDark() const override;
bool isLaunchAtStartupEnabled() const override;
void setLaunchAtStartup(bool enable) override;
bool isCapslockEnabled() override;

View File

@ -52,6 +52,10 @@
#include <QtMath>
#include <qdrawutil.h>
#ifdef Q_OS_MACOS
#include <QOperatingSystemVersion>
#endif
#include <cmath>
#include "gui/Icons.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,

View File

@ -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,

View File

@ -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)
palette.setColor(QPalette::All, QPalette::Window, QRgb(0x2F2F30));

View File

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