Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/keepassxreboot/keepassxc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJanek Bevendorff <janek@jbev.net>2020-12-19 02:20:24 +0300
committerJanek Bevendorff <janek@jbev.net>2021-01-07 17:22:48 +0300
commit80c1b9be6a09cee67411840ecde129bcab70ebe1 (patch)
tree9280eda76267e898830e79a871ab298bc67f91a5 /src/gui/osutils
parent37dab85df7e196c5596dd42d7fe09b95284507bd (diff)
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
Diffstat (limited to 'src/gui/osutils')
-rw-r--r--src/gui/osutils/OSUtilsBase.h15
-rw-r--r--src/gui/osutils/macutils/AppKit.h3
-rw-r--r--src/gui/osutils/macutils/AppKitImpl.h1
-rw-r--r--src/gui/osutils/macutils/AppKitImpl.mm61
-rw-r--r--src/gui/osutils/macutils/MacUtils.cpp14
-rw-r--r--src/gui/osutils/macutils/MacUtils.h2
-rw-r--r--src/gui/osutils/nixutils/NixUtils.cpp6
-rw-r--r--src/gui/osutils/nixutils/NixUtils.h1
-rw-r--r--src/gui/osutils/winutils/WinUtils.cpp6
-rw-r--r--src/gui/osutils/winutils/WinUtils.h1
10 files changed, 107 insertions, 3 deletions
diff --git a/src/gui/osutils/OSUtilsBase.h b/src/gui/osutils/OSUtilsBase.h
index 23f5b926e..5b97cd505 100644
--- a/src/gui/osutils/OSUtilsBase.h
+++ b/src/gui/osutils/OSUtilsBase.h
@@ -36,6 +36,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).
*/
virtual bool isLaunchAtStartupEnabled() const = 0;
@@ -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();
diff --git a/src/gui/osutils/macutils/AppKit.h b/src/gui/osutils/macutils/AppKit.h
index a6f7b3a12..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 <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;
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 <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;
}
@@ -55,6 +73,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)
//
- (pid_t) activeProcessId
@@ -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];
diff --git a/src/gui/osutils/macutils/MacUtils.cpp b/src/gui/osutils/macutils/MacUtils.cpp
index 73ee29627..9e85024d0 100644
--- a/src/gui/osutils/macutils/MacUtils.cpp
+++ b/src/gui/osutils/macutils/MacUtils.cpp
@@ -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 =
diff --git a/src/gui/osutils/macutils/MacUtils.h b/src/gui/osutils/macutils/MacUtils.h
index 0a3e0f6a4..717be27db 100644
--- a/src/gui/osutils/macutils/MacUtils.h
+++ b/src/gui/osutils/macutils/MacUtils.h
@@ -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;
diff --git a/src/gui/osutils/nixutils/NixUtils.cpp b/src/gui/osutils/nixutils/NixUtils.cpp
index 58a69dedc..cc9ff2c5b 100644
--- a/src/gui/osutils/nixutils/NixUtils.cpp
+++ b/src/gui/osutils/nixutils/NixUtils.cpp
@@ -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;
diff --git a/src/gui/osutils/nixutils/NixUtils.h b/src/gui/osutils/nixutils/NixUtils.h
index 4e0e5ca4a..bd659e210 100644
--- a/src/gui/osutils/nixutils/NixUtils.h
+++ b/src/gui/osutils/nixutils/NixUtils.h
@@ -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;
diff --git a/src/gui/osutils/winutils/WinUtils.cpp b/src/gui/osutils/winutils/WinUtils.cpp
index 26c8b955b..302c3914c 100644
--- a/src/gui/osutils/winutils/WinUtils.cpp
+++ b/src/gui/osutils/winutils/WinUtils.cpp
@@ -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)
diff --git a/src/gui/osutils/winutils/WinUtils.h b/src/gui/osutils/winutils/WinUtils.h
index d5e79f806..9e9f72684 100644
--- a/src/gui/osutils/winutils/WinUtils.h
+++ b/src/gui/osutils/winutils/WinUtils.h
@@ -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;