From d9122859195999b1270c3b050d87a3325922d709 Mon Sep 17 00:00:00 2001 From: michael starke Date: Tue, 3 Jan 2017 14:50:08 +0100 Subject: [PATCH] Reworked use of DDHotKey to prevent unwanted deregistration. --- MacPass/DDHotKey+MacPassAdditions.h | 12 +++-- MacPass/DDHotKey+MacPassAdditions.m | 43 ++++++++-------- MacPass/MPAutotypeDaemon.m | 58 ++++++++++------------ MacPass/MPIntegrationSettingsController.m | 2 +- MacPass/MPSettingsHelper.m | 2 +- MacPass/de.lproj/Localizable.strings | Bin 14854 -> 15046 bytes MacPass/en.lproj/Localizable.strings | Bin 13846 -> 14006 bytes MacPass/fr.lproj/Localizable.strings | Bin 15186 -> 15320 bytes MacPass/it.lproj/Localizable.strings | Bin 14486 -> 14620 bytes MacPass/nl.lproj/Localizable.strings | Bin 14408 -> 14542 bytes MacPass/ru.lproj/Localizable.strings | Bin 14610 -> 14744 bytes MacPass/zh-Hans.lproj/Localizable.strings | Bin 11888 -> 12022 bytes 12 files changed, 61 insertions(+), 56 deletions(-) diff --git a/MacPass/DDHotKey+MacPassAdditions.h b/MacPass/DDHotKey+MacPassAdditions.h index 5ae2442c..3ebcf040 100644 --- a/MacPass/DDHotKey+MacPassAdditions.h +++ b/MacPass/DDHotKey+MacPassAdditions.h @@ -12,11 +12,17 @@ @property (readonly, copy) NSData *keyData; + +/** + Use this method to retrieve the data, since deallocation of a hotkey unregisters it, this could yield unwanted behaviour! + @return data for the default hot key. +*/ ++ (NSData *)hotKeyDataWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInteger)flags; ++ (NSData *)defaultHotKeyData; + (instancetype)defaultHotKey; + (instancetype)defaultHotKeyWithTask:(DDHotKeyTask)task; - -- (instancetype)initWithKeyData:(NSData *)data task:(DDHotKeyTask)task; -- (instancetype)initWithKeyData:(NSData *)data; ++ (instancetype)hotKeyWithKeyData:(NSData *)data task:(DDHotKeyTask)task; ++ (instancetype)hotKeyWithKeyData:(NSData *)data; @end diff --git a/MacPass/DDHotKey+MacPassAdditions.m b/MacPass/DDHotKey+MacPassAdditions.m index db1fc74d..40ed2281 100644 --- a/MacPass/DDHotKey+MacPassAdditions.m +++ b/MacPass/DDHotKey+MacPassAdditions.m @@ -14,45 +14,48 @@ @implementation DDHotKey (MPKeydata) ++ (NSData *)hotKeyDataWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInteger)flags { + NSMutableData *data = [[NSMutableData alloc] init]; + NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; + [archiver encodeInt:keyCode forKey:NSStringFromSelector(@selector(keyCode))]; + [archiver encodeInteger:flags forKey:NSStringFromSelector(@selector(modifierFlags))]; + [archiver finishEncoding]; + return [data copy]; +} + ++ (NSData *)defaultHotKeyData { + return [self hotKeyDataWithKeyCode:kVK_ANSI_M modifierFlags:kCGEventFlagMaskControl|kCGEventFlagMaskAlternate]; +} + + (instancetype)defaultHotKey { return [DDHotKey defaultHotKeyWithTask:nil]; } + (instancetype)defaultHotKeyWithTask:(DDHotKeyTask)task { - return [[DDHotKey alloc] initWithKeyData:nil task:task]; + return [DDHotKey hotKeyWithKeyData:nil task:task]; } -- (instancetype)initWithKeyData:(NSData *)data { - self = [self initWithKeyData:data task:nil]; - return self; ++ (instancetype)hotKeyWithKeyData:(NSData *)data { + return [self hotKeyWithKeyData:data task:nil]; } -- (instancetype)initWithKeyData:(NSData *)data task:(DDHotKeyTask)task{ ++ (instancetype)hotKeyWithKeyData:(NSData *)data task:(DDHotKeyTask)task { NSUInteger modifierFlags; unsigned short keyCode; if(!data) { - self = [DDHotKey hotKeyWithKeyCode:kVK_ANSI_M modifierFlags:kCGEventFlagMaskControl|kCGEventFlagMaskAlternate task:task]; + return [DDHotKey hotKeyWithKeyCode:kVK_ANSI_M modifierFlags:kCGEventFlagMaskControl|kCGEventFlagMaskAlternate task:task]; } - else if([self _getKeyCode:&keyCode modifierFlags:&modifierFlags fromData:data]) { - self = [DDHotKey hotKeyWithKeyCode:keyCode modifierFlags:modifierFlags task:task]; + if([self _getKeyCode:&keyCode modifierFlags:&modifierFlags fromData:data]) { + return [DDHotKey hotKeyWithKeyCode:keyCode modifierFlags:modifierFlags task:task]; } - else { - self = nil; - } - return self; + return nil; } - (NSData *)keyData { - NSMutableData *data = [[NSMutableData alloc] init]; - NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; - [archiver encodeInt:self.keyCode forKey:NSStringFromSelector(@selector(keyCode))]; - [archiver encodeInteger:self.modifierFlags forKey:NSStringFromSelector(@selector(modifierFlags))]; - [archiver finishEncoding]; - return [data copy]; + return [self.class hotKeyDataWithKeyCode:self.keyCode modifierFlags:self.modifierFlags]; } - -- (BOOL)_getKeyCode:(unsigned short *)keyCode modifierFlags:(NSUInteger *)modifierFlags fromData:(NSData *)data { ++ (BOOL)_getKeyCode:(unsigned short *)keyCode modifierFlags:(NSUInteger *)modifierFlags fromData:(NSData *)data { if(keyCode == NULL || modifierFlags == NULL || data == nil) { return NO; } diff --git a/MacPass/MPAutotypeDaemon.m b/MacPass/MPAutotypeDaemon.m index 715bf69e..db48fc4c 100644 --- a/MacPass/MPAutotypeDaemon.m +++ b/MacPass/MPAutotypeDaemon.m @@ -147,16 +147,32 @@ static MPAutotypeDaemon *_sharedInstance; return; // We do not perform Autotype on ourselves } - NSArray *documents = [self _findAutotypeDocuments]; + /* find autotype documents */ + NSArray *documents = [NSApp orderedDocuments]; + /* No open document, inform the user and return without any action */ if(documents.count == 0) { - /* We do not have a document. This can be - a) there is none - nothing happens - b) there is at least one, but locked - we get called again after the document has been unlocked - */ + NSUserNotification *notification = [[NSUserNotification alloc] init]; + notification.title = NSApp.applicationName; + notification.informativeText = NSLocalizedString(@"AUTOTYPE_OVERLAY_NO_DOCUMENTS", ""); + [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; return; } + NSPredicate *filterPredicate = [NSPredicate predicateWithBlock:^BOOL(id _Nonnull evaluatedObject, NSDictionary * _Nullable bindings) { + MPDocument *document = evaluatedObject; + return !document.encrypted;}]; + NSArray *unlockedDocuments = [documents filteredArrayUsingPredicate:filterPredicate]; + /* We look for all unlocked documents, if all open documents are locked, we pop the front most and try to search again */ + if(unlockedDocuments.count == 0) { + [NSApp activateIgnoringOtherApps:YES]; + [NSApp.mainWindow makeKeyAndOrderFront:self]; + /* show the actual document window to the user */ + [documents.firstObject showWindows]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didUnlockDatabase:) name:MPDocumentDidUnlockDatabaseNotification object:nil]; + return; // wait for the unlock to happen + } + MPAutotypeContext *context = [self _autotypeContextForDocuments:documents forWindowTitle:self.targetWindowTitle preferredEntry:entryOrNil]; - /* TODO: that's popping up if the mulit seleciton dialog goes up! */ + /* TODO: that's popping up if the mulit selection dialog goes up! */ if(!entryOrNil) { NSUserNotification *notification = [[NSUserNotification alloc] init]; notification.title = NSApp.applicationName; @@ -171,22 +187,6 @@ static MPAutotypeDaemon *_sharedInstance; [self _performAutotypeForContext:context]; } -- (NSArray *)_findAutotypeDocuments { - - NSArray *documents = [NSApp orderedDocuments]; - NSPredicate *filterPredicate = [NSPredicate predicateWithBlock:^BOOL(id _Nonnull evaluatedObject, NSDictionary * _Nullable bindings) { - MPDocument *document = evaluatedObject; - return !document.encrypted;}]; - NSArray *unlockedDocuments = [documents filteredArrayUsingPredicate:filterPredicate]; - /* We look for all unlocked documents, if all open documents are locked, we pop the front most and try to search again */ - if(unlockedDocuments.count == 0 && documents.count > 0) { - [NSApp activateIgnoringOtherApps:YES]; - [NSApp.mainWindow makeKeyAndOrderFront:self]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didUnlockDatabase:) name:MPDocumentDidUnlockDatabaseNotification object:nil]; - } - return unlockedDocuments; -} - - (MPAutotypeContext *)_autotypeContextForDocuments:(NSArray *)documents forWindowTitle:(NSString *)windowTitle preferredEntry:(KPKEntry *)entry { /* Query the document to generate a autotype command list for the window title @@ -230,22 +230,18 @@ static MPAutotypeDaemon *_sharedInstance; #pragma mark - #pragma mark Hotkey Registration - (void)_registerHotKey { + if(!self.hotKeyData) { + return; + } __weak MPAutotypeDaemon *welf = self; DDHotKeyTask aTask = ^(NSEvent *event) { [welf _didPressHotKey]; }; - DDHotKey *storedHotkey; - if(nil == self.hotKeyData) { - storedHotkey = [DDHotKey defaultHotKeyWithTask:aTask]; - } - else { - storedHotkey = [[DDHotKey alloc] initWithKeyData:self.hotKeyData task:aTask]; - } - self.registredHotKey = [[DDHotKeyCenter sharedHotKeyCenter] registerHotKey:storedHotkey]; + self.registredHotKey = [[DDHotKeyCenter sharedHotKeyCenter] registerHotKey:[DDHotKey hotKeyWithKeyData:self.hotKeyData task:aTask]]; } - (void)_unregisterHotKey { - if(nil != self.registredHotKey) { + if(self.registredHotKey) { [[DDHotKeyCenter sharedHotKeyCenter] unregisterHotKey:self.registredHotKey]; self.registredHotKey = nil; } diff --git a/MacPass/MPIntegrationSettingsController.m b/MacPass/MPIntegrationSettingsController.m index 895d0042..9c417465 100644 --- a/MacPass/MPIntegrationSettingsController.m +++ b/MacPass/MPIntegrationSettingsController.m @@ -58,7 +58,7 @@ } - (void)willShowTab { - _hotKey = [[DDHotKey alloc] initWithKeyData:[[NSUserDefaults standardUserDefaults] dataForKey:kMPSettingsKeyGlobalAutotypeKeyDataKey]]; + _hotKey = [DDHotKey hotKeyWithKeyData:[[NSUserDefaults standardUserDefaults] dataForKey:kMPSettingsKeyGlobalAutotypeKeyDataKey]]; /* Change any invalid hotkeys to valid ones? */ self.hotKeyTextField.hotKey = self.hotKey; } diff --git a/MacPass/MPSettingsHelper.m b/MacPass/MPSettingsHelper.m index b04243ce..a0bb06d5 100644 --- a/MacPass/MPSettingsHelper.m +++ b/MacPass/MPSettingsHelper.m @@ -110,7 +110,7 @@ NSString *const kMPDeprecatedSettingsKeyDefaultPasswordRounds = @"Ke kMPSettingsKeyRememberKeyFilesForDatabases: @NO, kMPSettingsKeySendCommandForControlKey: @YES, kMPSettingsKeyEnableGlobalAutotype: @NO, - kMPSettingsKeyGlobalAutotypeKeyDataKey: [[DDHotKey defaultHotKey] keyData], + kMPSettingsKeyGlobalAutotypeKeyDataKey: [DDHotKey defaultHotKeyData], kMPSettingsKeyDefaultGlobalAutotypeSequence: @"{USERNAME}{TAB}{PASSWORD}{ENTER}", kMPSettingsKeyAutotypeMatchTitle: @YES, kMPSettingsKeyAutotypeMatchURL: @NO, diff --git a/MacPass/de.lproj/Localizable.strings b/MacPass/de.lproj/Localizable.strings index 1429fa87d70c33946eee7da248eb861caf9e0f2b..ec6fb88f3739aef167ae4a5ab47fb6326128763b 100644 GIT binary patch delta 132 zcmZoGIaazMNKMd%!JomIA(X+F!Ii;}A%r1#@_HTd#BU5~K$ypn3d9Nw!3>!|mI4rG zg2faVTo@7=O2B*_pm-@mE|7F*$YIE5NCL{_0C|o;(GnoPgrSn50Ia(TD53z=4-&81 JEUorh7yzA%93KDx delta 12 TcmX?B+E%h5NNux_`W9gTCIkf$ diff --git a/MacPass/en.lproj/Localizable.strings b/MacPass/en.lproj/Localizable.strings index 7c31619999b6cdb052c43b426d6f6c17130fd355..d8d1f6415045de846df46b8be5f78f9481e20e9a 100644 GIT binary patch delta 96 zcmbQ1vn_W6hYGt3gFk~aL+Ip-RbodPO844Iu8S)qu7!rXvjUkgE2gp}oC}GG4 rlBEpAV4gcrG@l^}s3vFfLQ`Q@MFu4X>&YL*#V4nz2yA9j5fK6aLe>?M delta 12 Tcmdm%J1u7ehsx#^Dttl!Bs2t} diff --git a/MacPass/fr.lproj/Localizable.strings b/MacPass/fr.lproj/Localizable.strings index abb3da39dc3ce46d5aad0cddec88d16333c7c3f4..8693e62d6abcf540d7c4c5ae1b6e5544e14a78ac 100644 GIT binary patch delta 74 zcmcaqcB6bloVuh7gFk~aLnwnUgDZm{LkL4KgA#)RgDr!?WO-@P$!F9B#QlIO;u$d1 OP2Q-ky*WbtmoNa2&=E-h delta 12 TcmcaneyMCjociV`>R*HbE*=Jw diff --git a/MacPass/it.lproj/Localizable.strings b/MacPass/it.lproj/Localizable.strings index 500a3d72767c765a2154086f9b044948b876309d..3b37c573f7a0abf80e15098bc9d308ee7dd2caf1 100644 GIT binary patch delta 64 zcmbPMIHzdCK2>%X27d-;hS14{{Nj^YBn2kxsR@Yt0mb4OpfU`;46Y1*3?U4`lP5|_ MgXA~wP`xJv03at2Pyhe` delta 12 TcmbPJG_7#MKGn@GYBz)cC~5_; diff --git a/MacPass/nl.lproj/Localizable.strings b/MacPass/nl.lproj/Localizable.strings index cee037247ce28464efc70b63ffef798409412f91..9965b1611ece308513609ba5fd289ef4c443346b 100644 GIT binary patch delta 70 zcmX?6aISE}2USTI27d-;hEN7y23H0@h7g8e1|wUR;(kEccm@nLlMU6h KH@{Mi69NEM2@l8s delta 12 TcmX?Cc%op#2i47GY7s&JEyxA- diff --git a/MacPass/ru.lproj/Localizable.strings b/MacPass/ru.lproj/Localizable.strings index 5d672103b47a775ef1227e78de7932915a743874..64c9406e43427b2fca73c984fb17c5b0fd182223 100644 GIT binary patch delta 74 zcmbPKG^2P!hMJ@cgFk~aLnwnUgDZm{LkL4KgA#)RgDr!?WPK^o$*0r=#QlIO;u$d1 OO{mT diff --git a/MacPass/zh-Hans.lproj/Localizable.strings b/MacPass/zh-Hans.lproj/Localizable.strings index d82179ae528fca5625f5de13aac1590a0a0471fe..ef2175c08db3ebfb69ed9b535f29d97f2c6e5358 100644 GIT binary patch delta 74 zcmewm^DTD6JUK}h27d-;hEN7y23H0@h7g8e1|