diff --git a/External/RHStatusItemView b/External/RHStatusItemView
new file mode 160000
index 00000000..eb8b21e1
--- /dev/null
+++ b/External/RHStatusItemView
@@ -0,0 +1 @@
+Subproject commit eb8b21e117bfa5747d67394f06df400ac4c94279
diff --git a/MasterPassword/ObjC/MPConfig.m b/MasterPassword/ObjC/MPConfig.m
index 3e0cbd8c..1424d9d2 100644
--- a/MasterPassword/ObjC/MPConfig.m
+++ b/MasterPassword/ObjC/MPConfig.m
@@ -6,6 +6,7 @@
// Copyright (c) 2012 Lyndir. All rights reserved.
//
+#import "MPConfig.h"
#import "MPAppDelegate_Shared.h"
@implementation MPConfig
diff --git a/MasterPassword/ObjC/Mac/MPAppsWindow.xib b/MasterPassword/ObjC/Mac/MPAppsWindow.xib
index 4b0d19d5..5a9001f8 100644
--- a/MasterPassword/ObjC/Mac/MPAppsWindow.xib
+++ b/MasterPassword/ObjC/Mac/MPAppsWindow.xib
@@ -763,7 +763,7 @@
com.apple.InterfaceBuilder.CocoaPlugin
{{357, 418}, {480, 270}}
-
+
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
@@ -831,132 +831,7 @@
337
-
+
0
IBCocoaFramework
YES
diff --git a/MasterPassword/ObjC/Mac/MPMacAppDelegate.h b/MasterPassword/ObjC/Mac/MPMacAppDelegate.h
index 34bf5e28..4793f2b5 100644
--- a/MasterPassword/ObjC/Mac/MPMacAppDelegate.h
+++ b/MasterPassword/ObjC/Mac/MPMacAppDelegate.h
@@ -9,10 +9,11 @@
#import
#import "MPAppDelegate_Shared.h"
#import "MPPasswordWindowController.h"
+#import "RHStatusItemView.h"
@interface MPMacAppDelegate : MPAppDelegate_Shared
-@property(nonatomic, strong) NSStatusItem *statusItem;
+@property(nonatomic, strong) RHStatusItemView *statusView;
@property(nonatomic, strong) MPPasswordWindowController *passwordWindow;
@property(nonatomic, weak) IBOutlet NSMenuItem *lockItem;
@property(nonatomic, weak) IBOutlet NSMenuItem *showItem;
diff --git a/MasterPassword/ObjC/Mac/MPMacAppDelegate.m b/MasterPassword/ObjC/Mac/MPMacAppDelegate.m
index 44507644..402b6ff3 100644
--- a/MasterPassword/ObjC/Mac/MPMacAppDelegate.m
+++ b/MasterPassword/ObjC/Mac/MPMacAppDelegate.m
@@ -121,7 +121,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
[self updateMenuItems];
- [self.statusItem popUpStatusItemMenu:self.statusMenu];
+ [self.statusView popUpMenu];
}
- (IBAction)togglePreference:(NSMenuItem *)sender {
@@ -195,6 +195,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
- (IBAction)terminate:(id)sender {
+ NSLog(@"Closing: Terminating");
[self.passwordWindow close];
self.passwordWindow = nil;
@@ -205,6 +206,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://itunes.apple.com/app/id510296984"]];
+ NSLog(@"Closing: App Store");
[self.appWindowDontShow.window close];
self.appWindowDontShow = nil;
}
@@ -233,11 +235,12 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
} forKeyPath:@"storeManager.cloudAvailable" options:0 context:nil];
// Status item.
- self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
- self.statusItem.image = [NSImage imageNamed:@"menu-icon"];
- self.statusItem.highlightMode = YES;
- self.statusItem.target = self;
- self.statusItem.action = @selector(showMenu);
+ self.statusView = [[RHStatusItemView alloc] initWithStatusBarItem:
+ [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength]];
+ self.statusView.image = [NSImage imageNamed:@"menu-icon"];
+ self.statusView.menu = self.statusMenu;
+ self.statusView.target = self;
+ self.statusView.action = @selector(showMenu);
[[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidChangeNotification object:nil queue:nil usingBlock:
^(NSNotification *note) {
@@ -259,6 +262,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
if (![self.passwordWindow.window isVisible])
self.passwordWindow = nil;
else {
+ NSLog(@"Closing: dialogStyleHUD && passwordWindow.isVisible");
[self.passwordWindow close];
self.passwordWindow = nil;
[self showPasswordWindow:nil];
@@ -281,14 +285,20 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
if (status != noErr)
err(@"Error registering 'lock' hotkey: %d", status);
- // iOS App window
- if ([[MPMacConfig get].showAppWindow boolValue]) {
+ // Initial display.
+ [NSApp activateIgnoringOtherApps:YES];
+ if (YES || [[MPMacConfig get].showAppWindow boolValue]) {
[self.appsWindow = [[NSWindowController alloc] initWithWindowNibName:@"MPAppsWindow" owner:self] showWindow:self];
[[NSNotificationCenter defaultCenter] addObserverForName:NSWindowWillCloseNotification object:self.appsWindow.window queue:nil
usingBlock:^(NSNotification *note) {
[MPMacConfig get].showAppWindow = @(self.appWindowDontShow.state == NSOffState);
}];
}
+ [[NSOperationQueue mainQueue] addOperation:[NSBlockOperation blockOperationWithBlock:^{
+ if (YES || [[MPMacConfig get].firstRun boolValue]) {
+ [self showMenu];
+ }
+ }]];
}
- (void)setActiveUser:(MPUserEntity *)activeUser {
@@ -296,6 +306,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
BOOL reopenPasswordWindow = [self.passwordWindow.window isVisible];
if (![[self activeUserForThread].objectID isEqual:activeUser.objectID]) {
+ NSLog(@"Closing: activeUser changed: %@ -> %@, reopening: %d", [self activeUserForThread].objectID, activeUser.objectID, reopenPasswordWindow);
[self.passwordWindow close];
self.passwordWindow = nil;
[super setActiveUser:activeUser];
@@ -375,8 +386,10 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
- (IBAction)showPasswordWindow:(id)sender {
// If no user, can't activate.
- if (![self activeUserForThread])
+ if (YES || ![self activeUserForThread]) {
+ [[NSAlert alertWithMessageText:@"No User Selected" defaultButton:[PearlStrings get].commonButtonOkay alternateButton:nil otherButton:nil informativeTextWithFormat:@"Begin by selecting or creating your user from the status menu (●●●|) next to the clock.", nil] runModal];
return;
+ }
// Activate the app if not active.
if (![[NSApplication sharedApplication] isActive])
diff --git a/MasterPassword/ObjC/Mac/MPPasswordWindowController.m b/MasterPassword/ObjC/Mac/MPPasswordWindowController.m
index 7b9be2d1..299347af 100644
--- a/MasterPassword/ObjC/Mac/MPPasswordWindowController.m
+++ b/MasterPassword/ObjC/Mac/MPPasswordWindowController.m
@@ -30,6 +30,7 @@
- (void)windowDidLoad {
+ NSLog(@"DidLoad:\n%@", [NSThread callStackSymbols]);
if ([[MPMacConfig get].dialogStyleHUD boolValue])
self.window.styleMask = NSHUDWindowMask | NSTitledWindowMask | NSUtilityWindowMask | NSClosableWindowMask;
else
@@ -55,11 +56,13 @@
} forKeyPath:@"key" options:NSKeyValueObservingOptionInitial context:nil];
[[NSNotificationCenter defaultCenter]
addObserverForName:NSWindowDidBecomeKeyNotification object:self.window queue:nil usingBlock:^(NSNotification *note) {
+ NSLog(@"DidBecomeKey:\n%@", [NSThread callStackSymbols]);
[self checkLoadedAndUnlocked];
[self.siteField selectText:nil];
}];
[[NSNotificationCenter defaultCenter]
addObserverForName:NSWindowWillCloseNotification object:self.window queue:nil usingBlock:^(NSNotification *note) {
+ NSLog(@"WillClose:\n%@", [NSThread callStackSymbols]);
NSWindow *sheet = [self.window attachedSheet];
if (sheet)
[NSApp endSheet:sheet];
@@ -87,8 +90,10 @@
MPUserEntity *activeUser = [MPMacAppDelegate get].activeUserForThread;
if (activeUser && !activeUser.saveKey)
[self unlock];
- else
+ else {
+ NSLog(@"Closing: !inProgress && !key && (!activeUser || activeUser.saveKey)");
[self.window close];
+ }
}
}
@@ -160,6 +165,7 @@
- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
if (contextInfo == MPAlertIncorrectMP) {
+ NSLog(@"Closing: Incorrect MP, button: %ld", returnCode);
[self.window close];
return;
}
@@ -191,6 +197,7 @@
case NSAlertOtherReturn: {
// "Cancel" button.
+ NSLog(@"Closing: Unlock MP, button: %ld", (long)returnCode);
[self.window close];
return;
}
@@ -288,6 +295,7 @@
- (BOOL)control:(NSControl *)control textView:(NSTextView *)fieldEditor doCommandBySelector:(SEL)commandSelector {
if (commandSelector == @selector(cancel:)) { // Escape without completion.
+ NSLog(@"Closing: ESC without completion");
[self.window close];
return YES;
}
diff --git a/MasterPassword/ObjC/Mac/MasterPassword-Mac.xcodeproj/project.pbxproj b/MasterPassword/ObjC/Mac/MasterPassword-Mac.xcodeproj/project.pbxproj
index f392f7a1..914dc4c8 100644
--- a/MasterPassword/ObjC/Mac/MasterPassword-Mac.xcodeproj/project.pbxproj
+++ b/MasterPassword/ObjC/Mac/MasterPassword-Mac.xcodeproj/project.pbxproj
@@ -68,6 +68,9 @@
DA5E5D0C1724A667003798D8 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CC61724A667003798D8 /* main.m */; };
DA5E5D0D1724A667003798D8 /* MasterPassword.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CC71724A667003798D8 /* MasterPassword.xcdatamodeld */; };
DA5E5D551724F9C8003798D8 /* MasterPassword.iconset in Resources */ = {isa = PBXBuildFile; fileRef = DA5E5D541724F9C8003798D8 /* MasterPassword.iconset */; };
+ DABC6C02175D8C85000C15D4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; };
+ DABC6C15175D8CE1000C15D4 /* RHStatusItemView.m in Sources */ = {isa = PBXBuildFile; fileRef = DABC6C14175D8CE1000C15D4 /* RHStatusItemView.m */; };
+ DABC6C16175D8E3A000C15D4 /* libRHStatusItemView.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DABC6C01175D8C85000C15D4 /* libRHStatusItemView.a */; };
DAC6326D148680650075AEA5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; };
DAC77CAE148291A600BCF976 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; };
DACA22BB1705DE7D002C6C22 /* UbiquityStoreManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DACA22B71705DE7D002C6C22 /* UbiquityStoreManager.m */; };
@@ -188,6 +191,18 @@
};
/* End PBXContainerItemProxy section */
+/* Begin PBXCopyFilesBuildPhase section */
+ DABC6BFF175D8C85000C15D4 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "include/${PRODUCT_NAME}";
+ dstSubfolderSpec = 16;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
/* Begin PBXFileReference section */
93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Indexing.m"; sourceTree = ""; };
93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+Indexing.h"; sourceTree = ""; };
@@ -275,6 +290,9 @@
DA6701DD16406B7300B61001 /* Social.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Social.framework; path = System/Library/Frameworks/Social.framework; sourceTree = SDKROOT; };
DA672D2E14F92C6B004A189C /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
DABB981515100B4000B05417 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
+ DABC6C01175D8C85000C15D4 /* libRHStatusItemView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRHStatusItemView.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ DABC6C13175D8CE1000C15D4 /* RHStatusItemView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RHStatusItemView.h; sourceTree = ""; };
+ DABC6C14175D8CE1000C15D4 /* RHStatusItemView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RHStatusItemView.m; sourceTree = ""; };
DAC6326C148680650075AEA5 /* libjrswizzle.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjrswizzle.a; sourceTree = BUILT_PRODUCTS_DIR; };
DAC632871486D95D0075AEA5 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
DAC77CAD148291A600BCF976 /* libPearl.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPearl.a; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -407,6 +425,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ DABC6C16175D8E3A000C15D4 /* libRHStatusItemView.a in Frameworks */,
DA16B33F170661D4000A0EAB /* libUbiquityStoreManager.a in Frameworks */,
DA16B341170661DB000A0EAB /* Carbon.framework in Frameworks */,
DA16B342170661E0000A0EAB /* Security.framework in Frameworks */,
@@ -415,6 +434,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ DABC6BFE175D8C85000C15D4 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ DABC6C02175D8C85000C15D4 /* Foundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
DAC63269148680650075AEA5 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -455,6 +482,7 @@
DAC6326C148680650075AEA5 /* libjrswizzle.a */,
DA4425CB1557BED40052177D /* libUbiquityStoreManager.a */,
DA3EF17915A47744003ABF4E /* Tests.octest */,
+ DABC6C01175D8C85000C15D4 /* libRHStatusItemView.a */,
);
name = Products;
sourceTree = "";
@@ -563,6 +591,16 @@
path = Mac;
sourceTree = "";
};
+ DABC6C0E175D8CE1000C15D4 /* RHStatusItemView */ = {
+ isa = PBXGroup;
+ children = (
+ DABC6C13175D8CE1000C15D4 /* RHStatusItemView.h */,
+ DABC6C14175D8CE1000C15D4 /* RHStatusItemView.m */,
+ );
+ name = RHStatusItemView;
+ path = RHStatusItemView/RHStatusItemView;
+ sourceTree = "";
+ };
DAC77CAF148291A600BCF976 /* Pearl */ = {
isa = PBXGroup;
children = (
@@ -576,6 +614,7 @@
DACA22121705DDC5002C6C22 /* External */ = {
isa = PBXGroup;
children = (
+ DABC6C0E175D8CE1000C15D4 /* RHStatusItemView */,
DACA29751705E2BD002C6C22 /* jrswizzle */,
DACA22181705DE28002C6C22 /* Crashlytics.framework */,
DAC77CAF148291A600BCF976 /* Pearl */,
@@ -928,6 +967,23 @@
productReference = DA5BFA44147E415C00F98B1E /* Master Password.app */;
productType = "com.apple.product-type.application";
};
+ DABC6C00175D8C85000C15D4 /* RHStatusItemView */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = DABC6C0A175D8C85000C15D4 /* Build configuration list for PBXNativeTarget "RHStatusItemView" */;
+ buildPhases = (
+ DABC6BFD175D8C85000C15D4 /* Sources */,
+ DABC6BFE175D8C85000C15D4 /* Frameworks */,
+ DABC6BFF175D8C85000C15D4 /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = RHStatusItemView;
+ productName = RHStatusItemView;
+ productReference = DABC6C01175D8C85000C15D4 /* libRHStatusItemView.a */;
+ productType = "com.apple.product-type.library.static";
+ };
DAC6326B148680650075AEA5 /* jrswizzle */ = {
isa = PBXNativeTarget;
buildConfigurationList = DAC63274148680650075AEA5 /* Build configuration list for PBXNativeTarget "jrswizzle" */;
@@ -991,6 +1047,7 @@
DAC77CAC148291A600BCF976 /* Pearl */,
DAC6326B148680650075AEA5 /* jrswizzle */,
DA4425CA1557BED40052177D /* UbiquityStoreManager */,
+ DABC6C00175D8C85000C15D4 /* RHStatusItemView */,
DA3EF17815A47744003ABF4E /* Tests */,
);
};
@@ -1164,6 +1221,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ DABC6BFD175D8C85000C15D4 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ DABC6C15175D8CE1000C15D4 /* RHStatusItemView.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
DAC63268148680650075AEA5 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -1646,6 +1711,24 @@
};
name = "AppStore-Mac";
};
+ DABC6C0B175D8C85000C15D4 /* Debug-Mac */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ };
+ name = "Debug-Mac";
+ };
+ DABC6C0C175D8C85000C15D4 /* AdHoc-Mac */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ };
+ name = "AdHoc-Mac";
+ };
+ DABC6C0D175D8C85000C15D4 /* AppStore-Mac */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ };
+ name = "AppStore-Mac";
+ };
DAC63275148680650075AEA5 /* Debug-Mac */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -1747,6 +1830,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = "AdHoc-Mac";
};
+ DABC6C0A175D8C85000C15D4 /* Build configuration list for PBXNativeTarget "RHStatusItemView" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ DABC6C0B175D8C85000C15D4 /* Debug-Mac */,
+ DABC6C0C175D8C85000C15D4 /* AdHoc-Mac */,
+ DABC6C0D175D8C85000C15D4 /* AppStore-Mac */,
+ );
+ defaultConfigurationIsVisible = 0;
+ };
DAC63274148680650075AEA5 /* Build configuration list for PBXNativeTarget "jrswizzle" */ = {
isa = XCConfigurationList;
buildConfigurations = (
diff --git a/MasterPassword/Resources/Media/menu-icon.png b/MasterPassword/Resources/Media/menu-icon.png
index 23a59964..04b57986 100644
Binary files a/MasterPassword/Resources/Media/menu-icon.png and b/MasterPassword/Resources/Media/menu-icon.png differ
diff --git a/MasterPassword/Resources/Media/menu-icon@2x.png b/MasterPassword/Resources/Media/menu-icon@2x.png
index 9561860b..a2f8f80a 100644
Binary files a/MasterPassword/Resources/Media/menu-icon@2x.png and b/MasterPassword/Resources/Media/menu-icon@2x.png differ