Add status item. Disable automatic termination, but still hide from the dock when...
authorJoe Wreschnig <joe.wreschnig@gmail.com>
Fri, 8 Mar 2013 23:03:03 +0000 (00:03 +0100)
committerJoe Wreschnig <joe.wreschnig@gmail.com>
Fri, 8 Mar 2013 23:03:03 +0000 (00:03 +0100)
Classes/EnjoyableApplicationDelegate.h
Classes/EnjoyableApplicationDelegate.m
Enjoyable.xcodeproj/project.pbxproj
Resources/English.lproj/MainMenu.xib
Resources/Status Menu Icon Disabled.png [new file with mode: 0644]
Resources/Status Menu Icon Disabled@2x.png [new file with mode: 0644]
Resources/Status Menu Icon.png [new file with mode: 0644]
Resources/Status Menu Icon@2x.png [new file with mode: 0644]

index dfb82fc..c4d8e3b 100644 (file)
 @class NJMappingsController;
 
 @interface EnjoyableApplicationDelegate : NSObject <NSApplicationDelegate> {
-    IBOutlet NSMenu *dockMenuBase;
+    IBOutlet NSMenu *dockMenu;
+    IBOutlet NSMenu *statusItemMenu;
+    IBOutlet NSMenu *mappingsMenu;
     IBOutlet NSWindow *window;
 }
 
 @property (nonatomic, strong) IBOutlet NJDeviceController *inputController;
 @property (nonatomic, strong) IBOutlet NJMappingsController *mappingsController;
 
+- (IBAction)restoreToForeground:(id)sender;
+
 @end
index 78b930b..aaa9f00 100644 (file)
@@ -13,7 +13,9 @@
 #import "NJOutputController.h"
 #import "NJEvents.h"
 
-@implementation EnjoyableApplicationDelegate
+@implementation EnjoyableApplicationDelegate {
+    NSStatusItem *statusItem;
+}
 
 - (void)didSwitchApplication:(NSNotification *)note {
     NSRunningApplication *activeApp = note.userInfo[NSWorkspaceApplicationKey];
@@ -21,7 +23,7 @@
         [self.mappingsController activateMappingForProcess:activeApp];
 }
 
-- (void)applicationDidFinishLaunching:(NSNotification *)notification {
+- (void)applicationWillFinishLaunching:(NSNotification *)notification {
     [NSNotificationCenter.defaultCenter
         addObserver:self
         selector:@selector(mappingDidChange:)
         name:NJEventTranslationDeactivated
         object:nil];
 
-    [self.inputController setup];
     [self.mappingsController load];
+
+    statusItem = [NSStatusBar.systemStatusBar statusItemWithLength:36];
+    statusItem.image = [NSImage imageNamed:@"Status Menu Icon Disabled"];
+    statusItem.highlightMode = YES;
+    statusItem.menu = statusItemMenu;
+    statusItem.target = self;
 }
 
-- (void)applicationDidBecomeActive:(NSNotification *)notification {
+- (void)applicationDidFinishLaunching:(NSNotification *)notification {
+    [self.inputController setup];
     [window makeKeyAndOrderFront:nil];
 }
 
 - (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication
                     hasVisibleWindows:(BOOL)flag {
-    [window makeKeyAndOrderFront:nil];
+    [self restoreToForeground:theApplication];
+    return NO;
+}
+
+- (void)restoreToForeground:(id)sender {
+    ProcessSerialNumber psn = { 0, kCurrentProcess };
+    TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+    [NSApplication.sharedApplication activateIgnoringOtherApps:YES];
+    [window makeKeyAndOrderFront:sender];
+    [NSObject cancelPreviousPerformRequestsWithTarget:self
+                                             selector:@selector(transformIntoElement:)
+                                               object:self];
+}
+
+- (void)transformIntoElement:(id)sender {
+    ProcessSerialNumber psn = { 0, kCurrentProcess };
+    TransformProcessType(&psn, kProcessTransformToUIElementApplication);
+}
+
+- (void)flashStatusItem {
+    if ([statusItem.image.name isEqualToString:@"Status Menu Icon"]) {
+        statusItem.image = [NSImage imageNamed:@"Status Menu Icon Disabled"];
+    } else {
+        statusItem.image = [NSImage imageNamed:@"Status Menu Icon"];
+    }
+    
+}
+
+- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication {
+    [theApplication hide:theApplication];
+    // If we turn into a UIElement right away, the application cancels
+    // the deactivation events. The dock icon disappears, but an
+    // unresponsive menu bar remains until the user clicks somewhere.
+    // So delay just long enough to be past the end handling that.
+    [self performSelector:@selector(transformIntoElement:) withObject:self afterDelay:0.001];
     return NO;
 }
 
 - (void)eventTranslationActivated:(NSNotification *)note {
-    [NSProcessInfo.processInfo disableAutomaticTermination:@"Input translation is active."];
+    [dockMenu itemAtIndex:0].state = NSOnState;
+    [statusItemMenu itemAtIndex:0].state = NSOnState;
+    statusItem.image = [NSImage imageNamed:@"Status Menu Icon"];
     [NSWorkspace.sharedWorkspace.notificationCenter
         addObserver:self
         selector:@selector(didSwitchApplication:)
         name:NSWorkspaceDidActivateApplicationNotification
         object:nil];
-    NSLog(@"Listening for application changes.");
 }
 
 - (void)eventTranslationDeactivated:(NSNotification *)note {
-    [NSProcessInfo.processInfo enableAutomaticTermination:@"Input translation is active."];
+    [dockMenu itemAtIndex:0].state = NSOffState;
+    [statusItemMenu itemAtIndex:0].state = NSOffState;
+    statusItem.image = [NSImage imageNamed:@"Status Menu Icon Disabled"];
     [NSWorkspace.sharedWorkspace.notificationCenter
         removeObserver:self
         name:NSWorkspaceDidActivateApplicationNotification
         object:nil];
-    NSLog(@"Ignoring application changes.");
 }
 
-- (void)mappingListDidChange:(NSNotification *)note {
-    NSArray *mappings = note.object;
-    while (dockMenuBase.lastItem.representedObject)
-        [dockMenuBase removeLastItem];
+- (void)restoreWindowAndShowMappings:(id)sender {
+    [self restoreToForeground:sender];
+    [self.mappingsController mappingPressed:sender];
+}
+
+- (void)addMappingsToMenu:(NSMenu *)menu withKeys:(BOOL)withKeys atIndex:(NSInteger)index {
+    static const NSUInteger MAXIMUM_ITEMS = 5;
     int added = 0;
-    for (NJMapping *mapping in mappings) {
-        NSString *keyEquiv = ++added < 10 ? @(added).stringValue : @"";
+    for (NJMapping *mapping in self.mappingsController) {
+        NSString *keyEquiv = (++added < 10 && withKeys) ? @(added).stringValue : @"";
         NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:mapping.name
                                                       action:@selector(chooseMapping:)
                                                keyEquivalent:keyEquiv];
         item.representedObject = mapping;
         item.state = mapping == self.mappingsController.currentMapping;
-        [dockMenuBase addItem:item];
-    }
+        [menu insertItem:item atIndex:index++];
+        if (added == MAXIMUM_ITEMS && self.mappingsController.mappings.count > MAXIMUM_ITEMS + 1) {
+            NSMenuItem *end = [[NSMenuItem alloc] initWithTitle:@"…"
+                                                         action:@selector(restoreWindowAndShowMappings:)
+                                                  keyEquivalent:@""];
+            end.target = self;
+            [menu insertItem:end atIndex:index++];
+            break;
+        }
+    }    
+}
+
+- (void)mappingListDidChange:(NSNotification *)note {
+    while (mappingsMenu.lastItem.representedObject)
+        [mappingsMenu removeLastItem];
+    [self addMappingsToMenu:mappingsMenu withKeys:YES atIndex:mappingsMenu.numberOfItems];
+    while ([statusItemMenu itemAtIndex:2].representedObject)
+        [statusItemMenu removeItemAtIndex:2];
+    [self addMappingsToMenu:statusItemMenu withKeys:NO atIndex:2];
 }
 
 - (void)mappingDidChange:(NSNotification *)note {
     NJMapping *current = note.object;
-    for (NSMenuItem *item in dockMenuBase.itemArray)
+    for (NSMenuItem *item in mappingsMenu.itemArray)
+        if (item.representedObject)
+            item.state = item.representedObject == current;
+    for (NSMenuItem *item in statusItemMenu.itemArray)
         if (item.representedObject)
             item.state = item.representedObject == current;
+    
+    if (!window.isVisible)
+        for (int i = 0; i < 4; ++i)
+            [self performSelector:@selector(flashStatusItem)
+                       withObject:self
+                       afterDelay:0.2 * i];
 }
 
 - (void)chooseMapping:(NSMenuItem *)sender {
 }
 
 - (NSMenu *)applicationDockMenu:(NSApplication *)sender {
-    NSMenu *menu = [[NSMenu alloc] init];
-    int added = 0;
-    for (NJMapping *mapping in self.mappingsController) {
-        NSString *keyEquiv = ++added < 10 ? @(added).stringValue : @"";
-        NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:mapping.name
-                                                      action:@selector(chooseMapping:)
-                                               keyEquivalent:keyEquiv];
-        item.representedObject = mapping;
-        item.state = mapping == self.mappingsController.currentMapping;
-        [menu addItem:item];
-    }
-    return menu;
+    while (dockMenu.lastItem.representedObject)
+        [dockMenu removeLastItem];
+    [self addMappingsToMenu:dockMenu withKeys:NO atIndex:dockMenu.numberOfItems];
+    return dockMenu;
 }
 
 - (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename {
+    [self restoreToForeground:sender];
     NSURL *url = [NSURL fileURLWithPath:filename];
     [self.mappingsController addMappingWithContentsOfURL:url];
     return YES;
index bf9c0d9..bf04acf 100644 (file)
@@ -9,6 +9,10 @@
 /* Begin PBXBuildFile section */
                8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
                D594BF000FAE7397007A85F2 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D594BEFF0FAE7397007A85F2 /* IOKit.framework */; };
+               EE3D897A16EA7EFC00596D1F /* Status Menu Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = EE3D897916EA7EFC00596D1F /* Status Menu Icon@2x.png */; };
+               EE3D897C16EA806E00596D1F /* Status Menu Icon Disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = EE3D897B16EA806E00596D1F /* Status Menu Icon Disabled@2x.png */; };
+               EE3D897F16EA817E00596D1F /* Status Menu Icon Disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = EE3D897D16EA817E00596D1F /* Status Menu Icon Disabled.png */; };
+               EE3D898016EA817E00596D1F /* Status Menu Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = EE3D897E16EA817E00596D1F /* Status Menu Icon.png */; };
                EE6A122E16E8F46300EDBD32 /* Icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = EE6A122D16E8F46300EDBD32 /* Icon.icns */; };
                EEE73B1616EA42E5009D9D99 /* NSRunningApplication+NJPossibleNames.m in Sources */ = {isa = PBXBuildFile; fileRef = EEE73B1516EA42E5009D9D99 /* NSRunningApplication+NJPossibleNames.m */; };
                EEF17D1916E8E21A00D7DC4D /* com.yukkurigames.Enjoyable.mapping.icns in Resources */ = {isa = PBXBuildFile; fileRef = EEF17D1716E8E21A00D7DC4D /* com.yukkurigames.Enjoyable.mapping.icns */; };
                8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
                8D1107320486CEB800E47090 /* Enjoyable.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Enjoyable.app; sourceTree = BUILT_PRODUCTS_DIR; };
                D594BEFF0FAE7397007A85F2 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
+               EE3D897916EA7EFC00596D1F /* Status Menu Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Status Menu Icon@2x.png"; path = "Resources/Status Menu Icon@2x.png"; sourceTree = "<group>"; };
+               EE3D897B16EA806E00596D1F /* Status Menu Icon Disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Status Menu Icon Disabled@2x.png"; path = "Resources/Status Menu Icon Disabled@2x.png"; sourceTree = "<group>"; };
+               EE3D897D16EA817E00596D1F /* Status Menu Icon Disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Status Menu Icon Disabled.png"; path = "Resources/Status Menu Icon Disabled.png"; sourceTree = "<group>"; };
+               EE3D897E16EA817E00596D1F /* Status Menu Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Status Menu Icon.png"; path = "Resources/Status Menu Icon.png"; sourceTree = "<group>"; };
                EE6A122D16E8F46300EDBD32 /* Icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Icon.icns; sourceTree = "<group>"; };
                EEE73B1416EA42E5009D9D99 /* NSRunningApplication+NJPossibleNames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSRunningApplication+NJPossibleNames.h"; path = "Categories/NSRunningApplication+NJPossibleNames.h"; sourceTree = "<group>"; };
                EEE73B1516EA42E5009D9D99 /* NSRunningApplication+NJPossibleNames.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSRunningApplication+NJPossibleNames.m"; path = "Categories/NSRunningApplication+NJPossibleNames.m"; sourceTree = "<group>"; };
                29B97317FDCFA39411CA2CEA /* Resources */ = {
                        isa = PBXGroup;
                        children = (
+                               EE3D897D16EA817E00596D1F /* Status Menu Icon Disabled.png */,
+                               EE3D897E16EA817E00596D1F /* Status Menu Icon.png */,
+                               EE3D897B16EA806E00596D1F /* Status Menu Icon Disabled@2x.png */,
+                               EE3D897916EA7EFC00596D1F /* Status Menu Icon@2x.png */,
                                EE6A122D16E8F46300EDBD32 /* Icon.icns */,
                                EEF17D2116E8E24400D7DC4D /* Help */,
                                EEF17D1B16E8E23A00D7DC4D /* InfoPlist.strings */,
                                EEF17D2016E8E23A00D7DC4D /* MainMenu.xib in Resources */,
                                EEF17D2216E8E24400D7DC4D /* Help in Resources */,
                                EE6A122E16E8F46300EDBD32 /* Icon.icns in Resources */,
+                               EE3D897A16EA7EFC00596D1F /* Status Menu Icon@2x.png in Resources */,
+                               EE3D897C16EA806E00596D1F /* Status Menu Icon Disabled@2x.png in Resources */,
+                               EE3D897F16EA817E00596D1F /* Status Menu Icon Disabled.png in Resources */,
+                               EE3D898016EA817E00596D1F /* Status Menu Icon.png in Resources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 895e1d2..22b83f7 100644 (file)
                                                                        <reference key="NSOnImage" ref="35465992"/>
                                                                        <reference key="NSMixedImage" ref="502551668"/>
                                                                </object>
-                                                               <object class="NSMenuItem" id="342932134">
+                                                               <object class="NSMenuItem" id="466839429">
                                                                        <reference key="NSMenu" ref="110575045"/>
-                                                                       <string key="NSTitle">Hide Others</string>
-                                                                       <string key="NSKeyEquiv">h</string>
-                                                                       <int key="NSKeyEquivModMask">1572864</int>
+                                                                       <string key="NSTitle">Hide From Dock</string>
+                                                                       <string key="NSKeyEquiv">w</string>
+                                                                       <int key="NSKeyEquivModMask">1048576</int>
                                                                        <int key="NSMnemonicLoc">2147483647</int>
                                                                        <reference key="NSOnImage" ref="35465992"/>
                                                                        <reference key="NSMixedImage" ref="502551668"/>
                                                                </object>
-                                                               <object class="NSMenuItem" id="908899353">
+                                                               <object class="NSMenuItem" id="342932134">
                                                                        <reference key="NSMenu" ref="110575045"/>
-                                                                       <string key="NSTitle">Show All</string>
-                                                                       <string key="NSKeyEquiv"/>
-                                                                       <int key="NSKeyEquivModMask">1048576</int>
+                                                                       <string key="NSTitle">Hide Others</string>
+                                                                       <string key="NSKeyEquiv">h</string>
+                                                                       <int key="NSKeyEquivModMask">1572864</int>
                                                                        <int key="NSMnemonicLoc">2147483647</int>
                                                                        <reference key="NSOnImage" ref="35465992"/>
                                                                        <reference key="NSMixedImage" ref="502551668"/>
                                                                        <reference key="NSOnImage" ref="35465992"/>
                                                                        <reference key="NSMixedImage" ref="502551668"/>
                                                                </object>
-                                                               <object class="NSMenuItem" id="625202149">
-                                                                       <reference key="NSMenu" ref="835318025"/>
-                                                                       <string key="NSTitle">Bring All to Front</string>
-                                                                       <string key="NSKeyEquiv"/>
-                                                                       <int key="NSKeyEquivModMask">1048576</int>
-                                                                       <int key="NSMnemonicLoc">2147483647</int>
-                                                                       <reference key="NSOnImage" ref="35465992"/>
-                                                                       <reference key="NSMixedImage" ref="502551668"/>
-                                                               </object>
                                                        </array>
                                                        <string key="NSName">_NSWindowsMenu</string>
                                                </object>
@@ -1110,7 +1101,7 @@ aW5nLg</string>
                                <bool key="NSWindowIsRestorable">YES</bool>
                        </object>
                        <object class="NSCustomView" id="671181514">
-                               <nil key="NSNextResponder"/>
+                               <reference key="NSNextResponder"/>
                                <int key="NSvFlags">256</int>
                                <array class="NSMutableArray" key="NSSubviews">
                                        <object class="NSScrollView" id="443618264">
@@ -1126,7 +1117,8 @@ aW5nLg</string>
                                                                                <int key="NSvFlags">256</int>
                                                                                <string key="NSFrameSize">{198, 198}</string>
                                                                                <reference key="NSSuperview" ref="947403733"/>
-                                                                               <reference key="NSNextKeyView" ref="553414014"/>
+                                                                               <reference key="NSWindow"/>
+                                                                               <reference key="NSNextKeyView" ref="968378655"/>
                                                                                <bool key="NSEnabled">YES</bool>
                                                                                <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
                                                                                <bool key="NSControlAllowsExpansionToolTips">YES</bool>
@@ -1183,6 +1175,7 @@ aW5nLg</string>
                                                                </array>
                                                                <string key="NSFrame">{{1, 1}, {198, 198}}</string>
                                                                <reference key="NSSuperview" ref="443618264"/>
+                                                               <reference key="NSWindow"/>
                                                                <reference key="NSNextKeyView" ref="762432499"/>
                                                                <reference key="NSDocView" ref="762432499"/>
                                                                <reference key="NSBGColor" ref="834857663"/>
@@ -1193,6 +1186,7 @@ aW5nLg</string>
                                                                <int key="NSvFlags">-2147483392</int>
                                                                <string key="NSFrame">{{306, 1}, {15, 403}}</string>
                                                                <reference key="NSSuperview" ref="443618264"/>
+                                                               <reference key="NSWindow"/>
                                                                <reference key="NSNextKeyView" ref="861276216"/>
                                                                <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
                                                                <reference key="NSTarget" ref="443618264"/>
@@ -1204,6 +1198,7 @@ aW5nLg</string>
                                                                <int key="NSvFlags">-2147483392</int>
                                                                <string key="NSFrame">{{-100, -100}, {366, 16}}</string>
                                                                <reference key="NSSuperview" ref="443618264"/>
+                                                               <reference key="NSWindow"/>
                                                                <reference key="NSNextKeyView" ref="947403733"/>
                                                                <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
                                                                <int key="NSsFlags">1</int>
@@ -1214,7 +1209,8 @@ aW5nLg</string>
                                                </array>
                                                <string key="NSFrame">{{0, 20}, {200, 200}}</string>
                                                <reference key="NSSuperview" ref="671181514"/>
-                                               <reference key="NSNextKeyView" ref="947403733"/>
+                                               <reference key="NSWindow"/>
+                                               <reference key="NSNextKeyView" ref="553414014"/>
                                                <int key="NSsFlags">150034</int>
                                                <reference key="NSVScroller" ref="968378655"/>
                                                <reference key="NSHScroller" ref="553414014"/>
@@ -1229,6 +1225,7 @@ aW5nLg</string>
                                                <int key="NSvFlags">268</int>
                                                <string key="NSFrame">{{66, -1}, {68, 23}}</string>
                                                <reference key="NSSuperview" ref="671181514"/>
+                                               <reference key="NSWindow"/>
                                                <reference key="NSNextKeyView" ref="1023366520"/>
                                                <string key="NSReuseIdentifierKey">_NS:22</string>
                                                <bool key="NSEnabled">YES</bool>
@@ -1257,6 +1254,7 @@ aW5nLg</string>
                                                <int key="NSvFlags">292</int>
                                                <string key="NSFrame">{{0, -1}, {34, 23}}</string>
                                                <reference key="NSSuperview" ref="671181514"/>
+                                               <reference key="NSWindow"/>
                                                <reference key="NSNextKeyView" ref="456935010"/>
                                                <bool key="NSEnabled">YES</bool>
                                                <object class="NSButtonCell" key="NSCell" id="867532725">
@@ -1283,6 +1281,8 @@ aW5nLg</string>
                                                <int key="NSvFlags">292</int>
                                                <string key="NSFrame">{{166, -1}, {34, 23}}</string>
                                                <reference key="NSSuperview" ref="671181514"/>
+                                               <reference key="NSWindow"/>
+                                               <reference key="NSNextKeyView"/>
                                                <bool key="NSEnabled">YES</bool>
                                                <object class="NSButtonCell" key="NSCell" id="828611353">
                                                        <int key="NSCellFlags">67108864</int>
@@ -1304,6 +1304,7 @@ aW5nLg</string>
                                                <int key="NSvFlags">292</int>
                                                <string key="NSFrame">{{133, -1}, {34, 23}}</string>
                                                <reference key="NSSuperview" ref="671181514"/>
+                                               <reference key="NSWindow"/>
                                                <reference key="NSNextKeyView" ref="1043784903"/>
                                                <bool key="NSEnabled">YES</bool>
                                                <object class="NSButtonCell" key="NSCell" id="57592747">
@@ -1326,6 +1327,7 @@ aW5nLg</string>
                                                <int key="NSvFlags">292</int>
                                                <string key="NSFrame">{{33, -1}, {34, 23}}</string>
                                                <reference key="NSSuperview" ref="671181514"/>
+                                               <reference key="NSWindow"/>
                                                <reference key="NSNextKeyView" ref="149148392"/>
                                                <bool key="NSEnabled">YES</bool>
                                                <object class="NSButtonCell" key="NSCell" id="1008023024">
@@ -1349,6 +1351,8 @@ aW5nLg</string>
                                        </object>
                                </array>
                                <string key="NSFrameSize">{200, 220}</string>
+                               <reference key="NSSuperview"/>
+                               <reference key="NSWindow"/>
                                <reference key="NSNextKeyView" ref="443618264"/>
                                <string key="NSClassName">NSView</string>
                        </object>
@@ -1373,6 +1377,78 @@ aW5nLg</string>
                                <double key="NSContentHeight">0.0</double>
                                <bool key="NSAnimates">YES</bool>
                        </object>
+                       <object class="NSMenu" id="388664617">
+                               <string key="NSTitle"/>
+                               <array class="NSMutableArray" key="NSMenuItems">
+                                       <object class="NSMenuItem" id="679462300">
+                                               <reference key="NSMenu" ref="388664617"/>
+                                               <string key="NSTitle">Enable</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="35465992"/>
+                                               <reference key="NSMixedImage" ref="502551668"/>
+                                       </object>
+                                       <object class="NSMenuItem" id="462014786">
+                                               <reference key="NSMenu" ref="388664617"/>
+                                               <bool key="NSIsDisabled">YES</bool>
+                                               <bool key="NSIsSeparator">YES</bool>
+                                               <string key="NSTitle"/>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="35465992"/>
+                                               <reference key="NSMixedImage" ref="502551668"/>
+                                       </object>
+                                       <object class="NSMenuItem" id="937740972">
+                                               <reference key="NSMenu" ref="388664617"/>
+                                               <bool key="NSIsDisabled">YES</bool>
+                                               <bool key="NSIsSeparator">YES</bool>
+                                               <string key="NSTitle"/>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="35465992"/>
+                                               <reference key="NSMixedImage" ref="502551668"/>
+                                       </object>
+                                       <object class="NSMenuItem" id="548842355">
+                                               <reference key="NSMenu" ref="388664617"/>
+                                               <string key="NSTitle">Show Enjoyable</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="35465992"/>
+                                               <reference key="NSMixedImage" ref="502551668"/>
+                                       </object>
+                                       <object class="NSMenuItem" id="567028745">
+                                               <reference key="NSMenu" ref="388664617"/>
+                                               <string key="NSTitle">Quit Enjoyable</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="35465992"/>
+                                               <reference key="NSMixedImage" ref="502551668"/>
+                                       </object>
+                               </array>
+                       </object>
+                       <object class="NSMenu" id="330397624">
+                               <string key="NSTitle"/>
+                               <array class="NSMutableArray" key="NSMenuItems">
+                                       <object class="NSMenuItem" id="803553950">
+                                               <reference key="NSMenu" ref="330397624"/>
+                                               <string key="NSTitle">Enable</string>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="35465992"/>
+                                               <reference key="NSMixedImage" ref="502551668"/>
+                                       </object>
+                                       <object class="NSMenuItem" id="598206649">
+                                               <reference key="NSMenu" ref="330397624"/>
+                                               <bool key="NSIsDisabled">YES</bool>
+                                               <bool key="NSIsSeparator">YES</bool>
+                                               <string key="NSTitle"/>
+                                               <string key="NSKeyEquiv"/>
+                                               <int key="NSMnemonicLoc">2147483647</int>
+                                               <reference key="NSOnImage" ref="35465992"/>
+                                               <reference key="NSMixedImage" ref="502551668"/>
+                                       </object>
+                               </array>
+                       </object>
                </array>
                <object class="IBObjectContainer" key="IBDocument.Objects">
                        <array class="NSMutableArray" key="connectionRecords">
@@ -1408,6 +1484,14 @@ aW5nLg</string>
                                        </object>
                                        <int key="connectionID">870</int>
                                </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">terminate:</string>
+                                               <reference key="source" ref="1050"/>
+                                               <reference key="destination" ref="567028745"/>
+                                       </object>
+                                       <int key="connectionID">937</int>
+                               </object>
                                <object class="IBConnectionRecord">
                                        <object class="IBActionConnection" key="connection">
                                                <string key="label">orderFrontStandardAboutPanel:</string>
@@ -1424,14 +1508,6 @@ aW5nLg</string>
                                        </object>
                                        <int key="connectionID">37</int>
                                </object>
-                               <object class="IBConnectionRecord">
-                                       <object class="IBActionConnection" key="connection">
-                                               <string key="label">arrangeInFront:</string>
-                                               <reference key="source" ref="1014"/>
-                                               <reference key="destination" ref="625202149"/>
-                                       </object>
-                                       <int key="connectionID">39</int>
-                               </object>
                                <object class="IBConnectionRecord">
                                        <object class="IBActionConnection" key="connection">
                                                <string key="label">performZoom:</string>
@@ -1458,11 +1534,11 @@ aW5nLg</string>
                                </object>
                                <object class="IBConnectionRecord">
                                        <object class="IBActionConnection" key="connection">
-                                               <string key="label">unhideAllApplications:</string>
-                                               <reference key="source" ref="1014"/>
-                                               <reference key="destination" ref="908899353"/>
+                                               <string key="label">performClose:</string>
+                                               <reference key="source" ref="808667431"/>
+                                               <reference key="destination" ref="466839429"/>
                                        </object>
-                                       <int key="connectionID">370</int>
+                                       <int key="connectionID">941</int>
                                </object>
                                <object class="IBConnectionRecord">
                                        <object class="IBOutletConnection" key="connection">
@@ -1536,14 +1612,6 @@ aW5nLg</string>
                                        </object>
                                        <int key="connectionID">915</int>
                                </object>
-                               <object class="IBConnectionRecord">
-                                       <object class="IBOutletConnection" key="connection">
-                                               <string key="label">dockMenuBase</string>
-                                               <reference key="source" ref="207406104"/>
-                                               <reference key="destination" ref="720053764"/>
-                                       </object>
-                                       <int key="connectionID">726</int>
-                               </object>
                                <object class="IBConnectionRecord">
                                        <object class="IBOutletConnection" key="connection">
                                                <string key="label">inputController</string>
@@ -1568,6 +1636,38 @@ aW5nLg</string>
                                        </object>
                                        <int key="connectionID">865</int>
                                </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">statusItemMenu</string>
+                                               <reference key="source" ref="207406104"/>
+                                               <reference key="destination" ref="388664617"/>
+                                       </object>
+                                       <int key="connectionID">928</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">dockMenu</string>
+                                               <reference key="source" ref="207406104"/>
+                                               <reference key="destination" ref="330397624"/>
+                                       </object>
+                                       <int key="connectionID">930</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBOutletConnection" key="connection">
+                                               <string key="label">mappingsMenu</string>
+                                               <reference key="source" ref="207406104"/>
+                                               <reference key="destination" ref="720053764"/>
+                                       </object>
+                                       <int key="connectionID">931</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">restoreToForeground:</string>
+                                               <reference key="source" ref="207406104"/>
+                                               <reference key="destination" ref="548842355"/>
+                                       </object>
+                                       <int key="connectionID">939</int>
+                               </object>
                                <object class="IBConnectionRecord">
                                        <object class="IBActionConnection" key="connection">
                                                <string key="label">removePressed:</string>
@@ -1880,6 +1980,22 @@ aW5nLg</string>
                                        </object>
                                        <int key="connectionID">880</int>
                                </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performClick:</string>
+                                               <reference key="source" ref="385218002"/>
+                                               <reference key="destination" ref="803553950"/>
+                                       </object>
+                                       <int key="connectionID">932</int>
+                               </object>
+                               <object class="IBConnectionRecord">
+                                       <object class="IBActionConnection" key="connection">
+                                               <string key="label">performClick:</string>
+                                               <reference key="source" ref="385218002"/>
+                                               <reference key="destination" ref="679462300"/>
+                                       </object>
+                                       <int key="connectionID">933</int>
+                               </object>
                        </array>
                        <object class="IBMutableOrderedSet" key="objectRecords">
                                <array key="orderedObjects">
@@ -1962,13 +2078,13 @@ aW5nLg</string>
                                                <array class="NSMutableArray" key="children">
                                                        <reference ref="238522557"/>
                                                        <reference ref="755159360"/>
-                                                       <reference ref="908899353"/>
                                                        <reference ref="632727374"/>
                                                        <reference ref="646227648"/>
                                                        <reference ref="304266470"/>
                                                        <reference ref="1046388886"/>
                                                        <reference ref="1056857174"/>
                                                        <reference ref="342932134"/>
+                                                       <reference ref="466839429"/>
                                                </array>
                                                <reference key="parent" ref="694149608"/>
                                        </object>
@@ -1982,16 +2098,11 @@ aW5nLg</string>
                                                <reference key="object" ref="755159360"/>
                                                <reference key="parent" ref="110575045"/>
                                        </object>
-                                       <object class="IBObjectRecord">
-                                               <int key="objectID">150</int>
-                                               <reference key="object" ref="908899353"/>
-                                               <reference key="parent" ref="110575045"/>
-                                       </object>
                                        <object class="IBObjectRecord">
                                                <int key="objectID">136</int>
                                                <reference key="object" ref="632727374"/>
                                                <reference key="parent" ref="110575045"/>
-                                               <string key="objectName">Quit Enjoy</string>
+                                               <string key="objectName">Quit Enjoyable</string>
                                        </object>
                                        <object class="IBObjectRecord">
                                                <int key="objectID">144</int>
@@ -2031,7 +2142,6 @@ aW5nLg</string>
                                                <reference key="object" ref="835318025"/>
                                                <array class="NSMutableArray" key="children">
                                                        <reference ref="299356726"/>
-                                                       <reference ref="625202149"/>
                                                        <reference ref="575023229"/>
                                                        <reference ref="1011231497"/>
                                                </array>
@@ -2042,11 +2152,6 @@ aW5nLg</string>
                                                <reference key="object" ref="299356726"/>
                                                <reference key="parent" ref="835318025"/>
                                        </object>
-                                       <object class="IBObjectRecord">
-                                               <int key="objectID">5</int>
-                                               <reference key="object" ref="625202149"/>
-                                               <reference key="parent" ref="835318025"/>
-                                       </object>
                                        <object class="IBObjectRecord">
                                                <int key="objectID">239</int>
                                                <reference key="object" ref="575023229"/>
@@ -2594,6 +2699,70 @@ aW5nLg</string>
                                                <reference key="object" ref="158646067"/>
                                                <reference key="parent" ref="290995057"/>
                                        </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">918</int>
+                                               <reference key="object" ref="388664617"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="679462300"/>
+                                                       <reference ref="462014786"/>
+                                                       <reference ref="548842355"/>
+                                                       <reference ref="567028745"/>
+                                                       <reference ref="937740972"/>
+                                               </array>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">Status Item Menu</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">919</int>
+                                               <reference key="object" ref="679462300"/>
+                                               <reference key="parent" ref="388664617"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">922</int>
+                                               <reference key="object" ref="462014786"/>
+                                               <reference key="parent" ref="388664617"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">923</int>
+                                               <reference key="object" ref="330397624"/>
+                                               <array class="NSMutableArray" key="children">
+                                                       <reference ref="598206649"/>
+                                                       <reference ref="803553950"/>
+                                               </array>
+                                               <reference key="parent" ref="0"/>
+                                               <string key="objectName">Dock Menu</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">926</int>
+                                               <reference key="object" ref="548842355"/>
+                                               <reference key="parent" ref="388664617"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">924</int>
+                                               <reference key="object" ref="598206649"/>
+                                               <reference key="parent" ref="330397624"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">925</int>
+                                               <reference key="object" ref="803553950"/>
+                                               <reference key="parent" ref="330397624"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">936</int>
+                                               <reference key="object" ref="567028745"/>
+                                               <reference key="parent" ref="388664617"/>
+                                               <string key="objectName">Quit Enjoyable</string>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">938</int>
+                                               <reference key="object" ref="937740972"/>
+                                               <reference key="parent" ref="388664617"/>
+                                       </object>
+                                       <object class="IBObjectRecord">
+                                               <int key="objectID">940</int>
+                                               <reference key="object" ref="466839429"/>
+                                               <reference key="parent" ref="110575045"/>
+                                       </object>
                                </array>
                        </object>
                        <dictionary class="NSMutableDictionary" key="flattenedProperties">
@@ -2607,7 +2776,6 @@ aW5nLg</string>
                                <string key="144.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
                                <string key="145.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
                                <string key="149.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
-                               <string key="150.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
                                <string key="19.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
                                <string key="23.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
                                <string key="236.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -2630,7 +2798,6 @@ aW5nLg</string>
                                <string key="479.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
                                <string key="482.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
                                <string key="487.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
-                               <string key="5.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
                                <object class="NSMutableDictionary" key="507.IBAttributePlaceholdersKey">
                                        <string key="NS.key.0">ToolTip</string>
                                        <object class="IBToolTipAttribute" key="NS.object.0">
@@ -2769,28 +2936,51 @@ aW5nLg</string>
                                <string key="914.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
                                <string key="916.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
                                <string key="917.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="918.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="919.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
                                <string key="92.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="922.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="923.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="924.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="925.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="926.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="936.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="938.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+                               <string key="940.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
                        </dictionary>
                        <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
                        <nil key="activeLocalization"/>
                        <dictionary class="NSMutableDictionary" key="localizations"/>
                        <nil key="sourceID"/>
-                       <int key="maxID">917</int>
+                       <int key="maxID">941</int>
                </object>
                <object class="IBClassDescriber" key="IBDocument.Classes">
                        <array class="NSMutableArray" key="referencedPartialClassDescriptions">
                                <object class="IBPartialClassDescription">
                                        <string key="className">EnjoyableApplicationDelegate</string>
                                        <string key="superclassName">NSObject</string>
+                                       <object class="NSMutableDictionary" key="actions">
+                                               <string key="NS.key.0">restoreToForeground:</string>
+                                               <string key="NS.object.0">id</string>
+                                       </object>
+                                       <object class="NSMutableDictionary" key="actionInfosByName">
+                                               <string key="NS.key.0">restoreToForeground:</string>
+                                               <object class="IBActionInfo" key="NS.object.0">
+                                                       <string key="name">restoreToForeground:</string>
+                                                       <string key="candidateClassName">id</string>
+                                               </object>
+                                       </object>
                                        <dictionary class="NSMutableDictionary" key="outlets">
-                                               <string key="dockMenuBase">NSMenu</string>
+                                               <string key="dockMenu">NSMenu</string>
                                                <string key="inputController">NJDeviceController</string>
                                                <string key="mappingsController">NJMappingsController</string>
+                                               <string key="mappingsMenu">NSMenu</string>
+                                               <string key="statusItemMenu">NSMenu</string>
                                                <string key="window">NSWindow</string>
                                        </dictionary>
                                        <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
-                                               <object class="IBToOneOutletInfo" key="dockMenuBase">
-                                                       <string key="name">dockMenuBase</string>
+                                               <object class="IBToOneOutletInfo" key="dockMenu">
+                                                       <string key="name">dockMenu</string>
                                                        <string key="candidateClassName">NSMenu</string>
                                                </object>
                                                <object class="IBToOneOutletInfo" key="inputController">
@@ -2801,6 +2991,14 @@ aW5nLg</string>
                                                        <string key="name">mappingsController</string>
                                                        <string key="candidateClassName">NJMappingsController</string>
                                                </object>
+                                               <object class="IBToOneOutletInfo" key="mappingsMenu">
+                                                       <string key="name">mappingsMenu</string>
+                                                       <string key="candidateClassName">NSMenu</string>
+                                               </object>
+                                               <object class="IBToOneOutletInfo" key="statusItemMenu">
+                                                       <string key="name">statusItemMenu</string>
+                                                       <string key="candidateClassName">NSMenu</string>
+                                               </object>
                                                <object class="IBToOneOutletInfo" key="window">
                                                        <string key="name">window</string>
                                                        <string key="candidateClassName">NSWindow</string>
diff --git a/Resources/Status Menu Icon Disabled.png b/Resources/Status Menu Icon Disabled.png
new file mode 100644 (file)
index 0000000..8523aae
Binary files /dev/null and b/Resources/Status Menu Icon Disabled.png differ
diff --git a/Resources/Status Menu Icon Disabled@2x.png b/Resources/Status Menu Icon Disabled@2x.png
new file mode 100644 (file)
index 0000000..0e150b0
Binary files /dev/null and b/Resources/Status Menu Icon Disabled@2x.png differ
diff --git a/Resources/Status Menu Icon.png b/Resources/Status Menu Icon.png
new file mode 100644 (file)
index 0000000..2b26cf6
Binary files /dev/null and b/Resources/Status Menu Icon.png differ
diff --git a/Resources/Status Menu Icon@2x.png b/Resources/Status Menu Icon@2x.png
new file mode 100644 (file)
index 0000000..850151d
Binary files /dev/null and b/Resources/Status Menu Icon@2x.png differ