Fix theme issues on macOS

* Fix #5025 - Change edit entry widget title separator to the common bullet character • (U+2022)
* Fix #5307 and Fix #5347 - Remove transparent toolbar/window on macOS and properly color text in toolbar.
This commit is contained in:
Janek Bevendorff 2020-10-14 20:45:24 +02:00 committed by Jonathan White
parent b0e038e789
commit 389899e0c6
10 changed files with 84 additions and 22 deletions

View File

@ -499,9 +499,6 @@ MainWindow::MainWindow()
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS
setUnifiedTitleAndToolBarOnMac(true); setUnifiedTitleAndToolBarOnMac(true);
if (macUtils()->isDarkMode()) {
setStyleSheet("QToolButton {color:white;}");
}
#endif #endif
#ifdef WITH_XC_UPDATECHECK #ifdef WITH_XC_UPDATECHECK

View File

@ -800,12 +800,12 @@ void EditEntryWidget::loadEntry(Entry* entry,
connect(m_entry, &Entry::entryModified, this, [this] { m_entryModifiedTimer.start(); }); connect(m_entry, &Entry::entryModified, this, [this] { m_entryModifiedTimer.start(); });
if (history) { if (history) {
setHeadline(QString("%1 \u2B29 %2").arg(parentName, tr("Entry history"))); setHeadline(QString("%1 \u2022 %2").arg(parentName, tr("Entry history")));
} else { } else {
if (create) { if (create) {
setHeadline(QString("%1 \u2B29 %2").arg(parentName, tr("Add entry"))); setHeadline(QString("%1 \u2022 %2").arg(parentName, tr("Add entry")));
} else { } else {
setHeadline(QString("%1 \u2B29 %2 \u2B29 %3").arg(parentName, entry->title(), tr("Edit entry"))); setHeadline(QString("%1 \u2022 %2 \u2022 %3").arg(parentName, entry->title(), tr("Edit entry")));
} }
} }

View File

@ -37,6 +37,7 @@ public:
bool hideProcess(pid_t pid); bool hideProcess(pid_t pid);
bool isHidden(pid_t pid); bool isHidden(pid_t pid);
bool isDarkMode(); bool isDarkMode();
bool hasDarkMode();
bool enableAccessibility(); bool enableAccessibility();
bool enableScreenRecording(); bool enableScreenRecording();
void toggleForegroundApp(bool foreground); void toggleForegroundApp(bool foreground);

View File

@ -284,6 +284,17 @@ namespace Phantom
? highlightedOutlineOf(pal) ? highlightedOutlineOf(pal)
: Grad(pal.color(QPalette::WindowText), pal.color(QPalette::Window)).sample(0.5); : Grad(pal.color(QPalette::WindowText), pal.color(QPalette::Window)).sample(0.5);
} }
#ifdef Q_OS_MACOS
QColor tabBarBase(const QPalette& pal)
{
return hack_isLightPalette(pal) ? QRgb(0xD1D1D1) : QRgb(0x252525);
}
QColor tabBarBaseInactive(const QPalette& pal)
{
return hack_isLightPalette(pal) ? QRgb(0xF4F4F4) : QRgb(0x282828);
}
#endif
} // namespace DeriveColors } // namespace DeriveColors
namespace SwatchColors namespace SwatchColors
@ -330,6 +341,9 @@ namespace Phantom
S_itemView_headerOnLine, S_itemView_headerOnLine,
S_scrollbarGutter_disabled, S_scrollbarGutter_disabled,
S_tabBarBase,
S_tabBarBase_inactive,
// Aliases // Aliases
S_progressBar = S_highlight, S_progressBar = S_highlight,
S_progressBar_specular = S_highlight_specular, S_progressBar_specular = S_highlight_specular,
@ -342,7 +356,7 @@ namespace Phantom
enum enum
{ {
Num_SwatchColors = SwatchColors::S_scrollbarGutter_disabled + 1, Num_SwatchColors = SwatchColors::S_tabBarBase_inactive + 1,
Num_ShadowSteps = 3, Num_ShadowSteps = 3,
}; };
@ -445,6 +459,14 @@ namespace Phantom
colors[S_itemView_headerOnLine] = Dc::itemViewHeaderOnLineColorOf(pal); colors[S_itemView_headerOnLine] = Dc::itemViewHeaderOnLineColorOf(pal);
colors[S_scrollbarGutter_disabled] = colors[S_window]; colors[S_scrollbarGutter_disabled] = colors[S_window];
#ifdef Q_OS_MACOS
colors[S_tabBarBase] = Dc::tabBarBase(pal);
colors[S_tabBarBase_inactive] = Dc::tabBarBaseInactive(pal);
#else
colors[S_tabBarBase] = pal.color(QPalette::Active, QPalette::Window);
colors[S_tabBarBase_inactive] = pal.color(QPalette::Inactive, QPalette::Window);
#endif
brushes[S_none] = Qt::NoBrush; brushes[S_none] = Qt::NoBrush;
for (int i = S_none + 1; i < Num_SwatchColors; ++i) { for (int i = S_none + 1; i < Num_SwatchColors; ++i) {
// todo try to reuse // todo try to reuse
@ -1553,6 +1575,12 @@ void BaseStyle::drawPrimitive(PrimitiveElement elem,
auto tbb = qstyleoption_cast<const QStyleOptionTabBarBase*>(option); auto tbb = qstyleoption_cast<const QStyleOptionTabBarBase*>(option);
if (!tbb) if (!tbb)
break; break;
#ifdef Q_OS_MACOS
painter->fillRect(widget->rect(),
swatch.color(option->state & QStyle::State_Active ? S_tabBarBase : S_tabBarBase_inactive));
#endif
Qt::Edge edge = Qt::TopEdge; Qt::Edge edge = Qt::TopEdge;
switch (tbb->shape) { switch (tbb->shape) {
case QTabBar::RoundedNorth: case QTabBar::RoundedNorth:
@ -2255,6 +2283,21 @@ void BaseStyle::drawControl(ControlElement element,
auto toolBar = qstyleoption_cast<const QStyleOptionToolBar*>(option); auto toolBar = qstyleoption_cast<const QStyleOptionToolBar*>(option);
if (!toolBar) if (!toolBar)
break; break;
#ifdef Q_OS_MACOS
if (auto* mainWindow = qobject_cast<QMainWindow*>(widget->window())) {
// Fill toolbar background with transparent pixels to reveal the
// gradient background drawn by the Cocoa platform plugin.
// Inspired by qmacstyle_mac.mm.
if (m_drawNativeMacOsToolBar && toolBar && toolBar->toolBarArea == Qt::TopToolBarArea
&& mainWindow->unifiedTitleAndToolBarOnMac()) {
painter->setCompositionMode(QPainter::CompositionMode_Source);
painter->fillRect(option->rect, Qt::transparent);
break;
}
}
#endif
painter->fillRect(option->rect, option->palette.window().color()); painter->fillRect(option->rect, option->palette.window().color());
bool isFloating = false; bool isFloating = false;
if (auto tb = qobject_cast<const QToolBar*>(widget)) { if (auto tb = qobject_cast<const QToolBar*>(widget)) {

View File

@ -97,6 +97,15 @@ protected:
return {}; return {};
} }
#ifdef Q_OS_MACOS
/**
* Whether to draw a native macOS toolbar or fill it with a solid color instead.
* Can be set to false to avoid mixed themes if the OS theme isn't the same as
* the KeePassXC application theme.
*/
bool m_drawNativeMacOsToolBar = true;
#endif
BaseStylePrivate* d; BaseStylePrivate* d;
}; };

View File

@ -23,6 +23,14 @@
#include <QMenuBar> #include <QMenuBar>
#include <QToolBar> #include <QToolBar>
DarkStyle::DarkStyle()
: BaseStyle()
{
#ifdef Q_OS_MACOS
m_drawNativeMacOsToolBar = osUtils->isDarkMode();
#endif
}
QPalette DarkStyle::standardPalette() const QPalette DarkStyle::standardPalette() const
{ {
auto palette = BaseStyle::standardPalette(); auto palette = BaseStyle::standardPalette();
@ -105,13 +113,10 @@ void DarkStyle::polish(QWidget* widget)
|| qobject_cast<QToolBar*>(widget)) { || qobject_cast<QToolBar*>(widget)) {
auto palette = widget->palette(); auto palette = widget->palette();
#if defined(Q_OS_MACOS) #if defined(Q_OS_MACOS)
if (osUtils->isDarkMode()) { if (!osUtils->isDarkMode()) {
// Let the Cocoa platform plugin draw its own background palette.setColor(QPalette::Active, QPalette::Window, QRgb(0x252525));
palette.setColor(QPalette::All, QPalette::Window, Qt::transparent); palette.setColor(QPalette::Inactive, QPalette::Window, QRgb(0x282828));
} else { 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(0x2A2A2A));
} }
#elif defined(Q_OS_WIN) #elif defined(Q_OS_WIN)
// Register event filter for better dark mode support // Register event filter for better dark mode support

View File

@ -26,6 +26,7 @@ class DarkStyle : public BaseStyle
Q_OBJECT Q_OBJECT
public: public:
DarkStyle();
QPalette standardPalette() const override; QPalette standardPalette() const override;
using BaseStyle::polish; using BaseStyle::polish;

View File

@ -24,6 +24,14 @@
#include <QMenuBar> #include <QMenuBar>
#include <QToolBar> #include <QToolBar>
LightStyle::LightStyle()
: BaseStyle()
{
#ifdef Q_OS_MACOS
m_drawNativeMacOsToolBar = !osUtils->isDarkMode();
#endif
}
QPalette LightStyle::standardPalette() const QPalette LightStyle::standardPalette() const
{ {
auto palette = BaseStyle::standardPalette(); auto palette = BaseStyle::standardPalette();
@ -106,13 +114,10 @@ void LightStyle::polish(QWidget* widget)
|| qobject_cast<QToolBar*>(widget)) { || qobject_cast<QToolBar*>(widget)) {
auto palette = widget->palette(); auto palette = widget->palette();
#if defined(Q_OS_MACOS) #if defined(Q_OS_MACOS)
if (!osUtils->isDarkMode()) { if (osUtils->isDarkMode()) {
// Let the Cocoa platform plugin draw its own background palette.setColor(QPalette::Active, QPalette::Window, QRgb(0xD1D1D1));
palette.setColor(QPalette::All, QPalette::Window, Qt::transparent); palette.setColor(QPalette::Inactive, QPalette::Window, QRgb(0xF4F4F4));
} else { palette.setColor(QPalette::Disabled, QPalette::Window, QRgb(0xD1D1D1));
palette.setColor(QPalette::Active, QPalette::Window, QRgb(0xD6D6D6));
palette.setColor(QPalette::Inactive, QPalette::Window, QRgb(0xF6F6F6));
palette.setColor(QPalette::Disabled, QPalette::Window, QRgb(0xD4D4D4));
} }
#elif defined(Q_OS_WIN) #elif defined(Q_OS_WIN)
palette.setColor(QPalette::All, QPalette::Window, QRgb(0xFFFFFF)); palette.setColor(QPalette::All, QPalette::Window, QRgb(0xFFFFFF));

View File

@ -26,6 +26,7 @@ class LightStyle : public BaseStyle
Q_OBJECT Q_OBJECT
public: public:
LightStyle();
QPalette standardPalette() const override; QPalette standardPalette() const override;
using BaseStyle::polish; using BaseStyle::polish;

View File

@ -575,7 +575,7 @@ void TestGui::testSearchEditEntry()
// Check the path in header is "parent-group > entry" // Check the path in header is "parent-group > entry"
QCOMPARE(m_dbWidget->findChild<EditEntryWidget*>("editEntryWidget")->findChild<QLabel*>("headerLabel")->text(), QCOMPARE(m_dbWidget->findChild<EditEntryWidget*>("editEntryWidget")->findChild<QLabel*>("headerLabel")->text(),
QStringLiteral("Good \u2B29 Doggy \u2B29 Edit entry")); QStringLiteral("Good \u2022 Doggy \u2022 Edit entry"));
} }
void TestGui::testAddEntry() void TestGui::testAddEntry()