From ebe66496834ea20ad5bb1d76f67c84c26d086550 Mon Sep 17 00:00:00 2001 From: varjolintu Date: Sun, 28 Apr 2019 11:08:20 +0300 Subject: [PATCH] Lock database on switching user in macOS --- src/CMakeLists.txt | 3 ++- src/gui/DatabaseTabWidget.cpp | 4 +++ src/gui/macutils/AppKit.h | 14 +++++----- src/gui/macutils/AppKitImpl.h | 5 ++++ src/gui/macutils/AppKitImpl.mm | 47 ++++++++++++++++++++++++++-------- src/gui/macutils/MacUtils.cpp | 2 +- src/gui/macutils/MacUtils.h | 6 +++-- 7 files changed, 60 insertions(+), 21 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 16d0ef89c..5e7a474d2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -168,7 +168,8 @@ if(APPLE) core/ScreenLockListenerMac.cpp core/MacPasteboard.cpp gui/macutils/MacUtils.cpp - gui/macutils/AppKitImpl.mm) + gui/macutils/AppKitImpl.mm + gui/macutils/AppKit.h) endif() if(UNIX AND NOT APPLE) set(keepassx_SOURCES diff --git a/src/gui/DatabaseTabWidget.cpp b/src/gui/DatabaseTabWidget.cpp index 313bfabb1..fb234795c 100644 --- a/src/gui/DatabaseTabWidget.cpp +++ b/src/gui/DatabaseTabWidget.cpp @@ -63,6 +63,10 @@ DatabaseTabWidget::DatabaseTabWidget(QWidget* parent) connect(autoType(), SIGNAL(autotypePerformed()), SLOT(relockPendingDatabase())); connect(autoType(), SIGNAL(autotypeRejected()), SLOT(relockPendingDatabase())); // clang-format on + +#ifdef Q_OS_MACOS + connect(macUtils(), SIGNAL(lockDatabases()), SLOT(lockDatabases())); +#endif } DatabaseTabWidget::~DatabaseTabWidget() diff --git a/src/gui/macutils/AppKit.h b/src/gui/macutils/AppKit.h index cdb822ffc..da81f6913 100644 --- a/src/gui/macutils/AppKit.h +++ b/src/gui/macutils/AppKit.h @@ -19,14 +19,15 @@ #ifndef KEEPASSX_APPKIT_H #define KEEPASSX_APPKIT_H +#include #include -extern "C" { - -class AppKit +class AppKit : public QObject { + Q_OBJECT + public: - AppKit(); + AppKit(QObject* parent = nullptr); ~AppKit(); pid_t lastActiveProcessId(); @@ -37,10 +38,11 @@ public: bool isHidden(pid_t pid); bool isDarkMode(); +signals: + void lockDatabases(); + private: void *self; }; -} // extern "C" - #endif // KEEPASSX_APPKIT_H diff --git a/src/gui/macutils/AppKitImpl.h b/src/gui/macutils/AppKitImpl.h index 3bf2d20ef..ca2506794 100644 --- a/src/gui/macutils/AppKitImpl.h +++ b/src/gui/macutils/AppKitImpl.h @@ -22,6 +22,10 @@ #import @interface AppKitImpl : NSObject +{ + AppKit *m_appkit; +} +- (id) initWithObject:(AppKit *)appkit; @property (strong) NSRunningApplication *lastActiveApplication; @@ -31,5 +35,6 @@ - (bool) hideProcess:(pid_t) pid; - (bool) isHidden:(pid_t) pid; - (bool) isDarkMode; +- (void) userSwitchHandler:(NSNotification*) notification; @end diff --git a/src/gui/macutils/AppKitImpl.mm b/src/gui/macutils/AppKitImpl.mm index cd709df27..4165e0d5e 100644 --- a/src/gui/macutils/AppKitImpl.mm +++ b/src/gui/macutils/AppKitImpl.mm @@ -22,19 +22,22 @@ @implementation AppKitImpl -AppKit::AppKit() +- (id) initWithObject:(AppKit *)appkit { - self = [[AppKitImpl alloc] init]; - [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:static_cast(self) + self = [super init]; + if (self) { + m_appkit = appkit; + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:static_cast(self) selector:@selector(didDeactivateApplicationObserver:) name:NSWorkspaceDidDeactivateApplicationNotification object:nil]; -} - -AppKit::~AppKit() -{ - [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:static_cast(self)]; - [static_cast(self) dealloc]; + + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:static_cast(self) + selector:@selector(userSwitchHandler:) + name:NSWorkspaceSessionDidResignActiveNotification + object:nil]; + } + return self; } // @@ -104,10 +107,34 @@ AppKit::~AppKit() && NSOrderedSame == [style caseInsensitiveCompare:@"dark"] ); } +// +// Notification for user switch +// +- (void) userSwitchHandler:(NSNotification*) notification +{ + if ([[notification name] isEqualToString:NSWorkspaceSessionDidResignActiveNotification] && m_appkit) + { + emit m_appkit->lockDatabases(); + } +} + +@end + // // ------------------------- C++ Trampolines ------------------------- // +AppKit::AppKit(QObject* parent) : QObject(parent) +{ + self = [[AppKitImpl alloc] initWithObject:this]; +} + +AppKit::~AppKit() +{ + [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:static_cast(self)]; + [static_cast(self) dealloc]; +} + pid_t AppKit::lastActiveProcessId() { return [static_cast(self) lastActiveApplication].processIdentifier; @@ -142,5 +169,3 @@ bool AppKit::isDarkMode() { return [static_cast(self) isDarkMode]; } - -@end diff --git a/src/gui/macutils/MacUtils.cpp b/src/gui/macutils/MacUtils.cpp index c362fe1bd..654923c31 100644 --- a/src/gui/macutils/MacUtils.cpp +++ b/src/gui/macutils/MacUtils.cpp @@ -24,7 +24,7 @@ MacUtils* MacUtils::m_instance = nullptr; MacUtils::MacUtils(QObject* parent) : QObject(parent) , m_appkit(new AppKit()) { - + connect(m_appkit.data(), SIGNAL(lockDatabases()), SIGNAL(lockDatabases())); } MacUtils::~MacUtils() diff --git a/src/gui/macutils/MacUtils.h b/src/gui/macutils/MacUtils.h index 39a06bd84..49644795e 100644 --- a/src/gui/macutils/MacUtils.h +++ b/src/gui/macutils/MacUtils.h @@ -39,14 +39,16 @@ public: bool isHidden(); bool isDarkMode(); +signals: + void lockDatabases(); + private: explicit MacUtils(QObject* parent = nullptr); ~MacUtils(); private: - std::unique_ptr m_appkit; + QScopedPointer m_appkit; static MacUtils* m_instance; - void* self; Q_DISABLE_COPY(MacUtils) };