@implementation EnjoyableApplicationDelegate {
NSStatusItem *statusItem;
+ NSMutableArray *_errors;
}
- (void)didSwitchApplication:(NSNotification *)note {
- (void)eventSimulationStarted:(NSNotification *)note {
self.simulatingEventsButton.state = NSOnState;
statusItem.image = [NSImage imageNamed:@"Status Menu Icon"];
+ [NSProcessInfo.processInfo
+ disableAutomaticTermination:@"Event simulation running."];
[NSWorkspace.sharedWorkspace.notificationCenter
addObserver:self
selector:@selector(didSwitchApplication:)
- (void)eventSimulationStopped:(NSNotification *)note {
self.simulatingEventsButton.state = NSOffState;
statusItem.image = [NSImage imageNamed:@"Status Menu Icon Disabled"];
+ [NSProcessInfo.processInfo
+ enableAutomaticTermination:@"Event simulation running."];
[NSWorkspace.sharedWorkspace.notificationCenter
removeObserver:self
name:NSWorkspaceDidActivateApplicationNotification
return self.dockMenu;
}
+- (void)showNextError {
+ if (!self.window.attachedSheet && _errors.count) {
+ NSError *error = _errors.lastObject;
+ [_errors removeLastObject];
+ [NSApplication.sharedApplication activateIgnoringOtherApps:YES];
+ [self.window makeKeyAndOrderFront:nil];
+ [self.window presentError:error
+ modalForWindow:self.window
+ delegate:self
+ didPresentSelector:@selector(didPresentErrorWithRecovery:contextInfo:)
+ contextInfo:nil];
+ }
+}
+
+- (void)didPresentErrorWithRecovery:(BOOL)didRecover
+ contextInfo:(void *)contextInfo {
+ [self showNextError];
+}
+
+- (void)presentErrorSheet:(NSError *)error {
+ if (!_errors)
+ _errors = [[NSMutableArray alloc] initWithCapacity:1];
+ [_errors insertObject:error atIndex:0];
+ [self showNextError];
+}
+
- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename {
[self restoreToForeground:sender];
NSError *error;
[self.mvc endUpdates];
[self.ic activateMapping:mapping];
} else {
- [self.window presentError:error
- modalForWindow:self.window
- delegate:nil
- didPresentSelector:nil
- contextInfo:nil];
+ [self presentErrorSheet:error];
}
return !!mapping;
}
[self.mvc mappingTriggerClicked:self];
}
-- (void)loginItemPromptDidEnd:(NSWindow *)sheet
- returnCode:(int)returnCode
- contextInfo:(void *)contextInfo {
- if (returnCode == NSAlertDefaultReturn) {
- [NSRunningApplication.currentApplication addToLoginItems];
- // If we're going to automatically start, don't bug the user
- // about automatic updates next boot - they probably want it,
- // and if they don't they probably want a prompt for it less.
- SUUpdater.sharedUpdater.automaticallyChecksForUpdates = YES;
- }
-}
-
-- (void)loginItemPromptDidDismiss:(NSWindow *)sheet
- returnCode:(int)returnCode
- contextInfo:(void *)contextInfo {
- [NSUserDefaults.standardUserDefaults setBool:YES forKey:@"explained login items"];
- [self.window performClose:sheet];
-}
-
-- (BOOL)windowShouldClose:(NSWindow *)sender {
- if (sender != self.window
- || NSRunningApplication.currentApplication.isLoginItem
- || [NSUserDefaults.standardUserDefaults boolForKey:@"explained login items"])
- return YES;
- NSBeginAlertSheet(
- NSLocalizedString(@"login items prompt", @"alert prompt for adding to login items"),
- NSLocalizedString(@"login items add button", @"button to add to login items"),
- NSLocalizedString(@"login items don't add button", @"button to not add to login items"),
- nil, self.window, self,
- @selector(loginItemPromptDidEnd:returnCode:contextInfo:),
- @selector(loginItemPromptDidDismiss:returnCode:contextInfo:),
- NULL,
- NSLocalizedString(@"login items explanation", @"a brief explanation of login items")
- );
- for (int i = 0; i < 10; ++i)
- [self performSelector:@selector(flashStatusItem)
- withObject:self
- afterDelay:0.5 * i];
- return NO;
-}
-
- (void)importMappingClicked:(id)sender {
NSOpenPanel *panel = [NSOpenPanel openPanel];
panel.allowedFileTypes = @[ @"enjoyable", @"json", @"txt" ];
} else if (mapping) {
[self.ic addMapping:mapping];
} else {
- [self.window presentError:error
- modalForWindow:self.window
- delegate:nil
- didPresentSelector:nil
- contextInfo:nil];
+ [self presentErrorSheet:error];
}
}];
[panel close];
NSError *error;
if (![mapping writeToURL:panel.URL error:&error]) {
- [self.window presentError:error
- modalForWindow:self.window
- delegate:nil
- didPresentSelector:nil
- contextInfo:nil];
+ [self presentErrorSheet:error];
}
}];
}
}
- (void)inputController:(NJInputController *)ic didError:(NSError *)error {
- // Since the error shows the window, it can trigger another attempt
- // to re-open the HID manager, which will also probably fail and error,
- // so don't bother repeating ourselves.
- if (!self.window.attachedSheet) {
- [NSApplication.sharedApplication activateIgnoringOtherApps:YES];
- [self.window makeKeyAndOrderFront:nil];
- [self.window presentError:error
- modalForWindow:self.window
- delegate:nil
- didPresentSelector:nil
- contextInfo:nil];
- }
+ [self presentErrorSheet:error];
}
- (NSInteger)numberOfDevicesInDeviceList:(NJDeviceViewController *)dvc {