aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeddy Wing2016-12-02 13:00:19 -0500
committerTeddy Wing2016-12-02 13:00:19 -0500
commita77a053f90a7b2588dbaabedbf25f908680f2f30 (patch)
treeb1dcf8706c1e6a82e8505f2fa09dc22e0a197ecd
parent055471fad0187e654302034a0875a417e73e089f (diff)
downloadLow-Battery-Yup-a77a053f90a7b2588dbaabedbf25f908680f2f30.tar.bz2
Add "Start at login" checkbox that [un]installs launch agent
A new checkbox in the UI that asks whether the app should start at login. Checking and unchecking the box moves a LaunchAgent plist into and out of `~/Library/LaunchAgents/`. This plist file will define instructions to start the daemon on login. Also add a `DaemonLauncher` class that will launch or quit the daemon when the checkbox is clicked. Bug: Currently the app always starts with the checkbox checked. That's not what should happen. Instead, we should save the checkbox value to `NSUserDefaults` so that it has the previous value when the program is launched.
-rw-r--r--Low Battery Yup.d.xcodeproj/project.pbxproj16
-rw-r--r--Low Battery Yup/AppDelegate.h4
-rw-r--r--Low Battery Yup/AppDelegate.m21
-rw-r--r--Low Battery Yup/DaemonLauncher.h13
-rw-r--r--Low Battery Yup/DaemonLauncher.m13
-rw-r--r--Low Battery Yup/LaunchAgentManager.h20
-rw-r--r--Low Battery Yup/LaunchAgentManager.m52
-rw-r--r--Low Battery Yup/com.teddywing.Low-Battery-Yup.StartAtLogin.plist5
-rw-r--r--Low Battery Yup/en.lproj/MainMenu.xib23
9 files changed, 165 insertions, 2 deletions
diff --git a/Low Battery Yup.d.xcodeproj/project.pbxproj b/Low Battery Yup.d.xcodeproj/project.pbxproj
index f1c9910..b625f3b 100644
--- a/Low Battery Yup.d.xcodeproj/project.pbxproj
+++ b/Low Battery Yup.d.xcodeproj/project.pbxproj
@@ -8,6 +8,7 @@
/* Begin PBXBuildFile section */
D123F5A81DDF9D2400A27B7A /* DDHotKeyCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D123F5A71DDF9D2400A27B7A /* DDHotKeyCenter.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
+ D131EB381DF1E8AB00504A74 /* com.teddywing.Low-Battery-Yup.StartAtLogin.plist in Resources */ = {isa = PBXBuildFile; fileRef = D131EB371DF1E8AB00504A74 /* com.teddywing.Low-Battery-Yup.StartAtLogin.plist */; };
D15D90B71DF0465E001700CD /* ShortcutView.m in Sources */ = {isa = PBXBuildFile; fileRef = D15D90B61DF0465E001700CD /* ShortcutView.m */; };
D1871D071DE094AB00B8030D /* DDHotKeyTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = D1871D061DE094AB00B8030D /* DDHotKeyTextField.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
D1871D081DE094C200B8030D /* DDHotKeyUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = D1A37AF01DE001770022434D /* DDHotKeyUtilities.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
@@ -21,6 +22,8 @@
D18C94C51DDC355400E03F87 /* Mouse.m in Sources */ = {isa = PBXBuildFile; fileRef = D18C94C41DDC355400E03F87 /* Mouse.m */; };
D195AE5F1DDC776000A53A18 /* MASShortcut.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D195AE5A1DDC774300A53A18 /* MASShortcut.framework */; };
D195AE601DDC776F00A53A18 /* MASShortcut.framework in Resources */ = {isa = PBXBuildFile; fileRef = D195AE5A1DDC774300A53A18 /* MASShortcut.framework */; };
+ D19DF20F1DF1AD3D0094C50F /* LaunchAgentManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D19DF20E1DF1AD3D0094C50F /* LaunchAgentManager.m */; };
+ D19DF2121DF1AD480094C50F /* DaemonLauncher.m in Sources */ = {isa = PBXBuildFile; fileRef = D19DF2111DF1AD480094C50F /* DaemonLauncher.m */; };
D1A37AEE1DE0012C0022434D /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D1A37AED1DE0012C0022434D /* Carbon.framework */; };
D1A37AF11DE001770022434D /* DDHotKeyUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = D1A37AF01DE001770022434D /* DDHotKeyUtilities.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
D1F809E11DDC6AA0001671E9 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D18C94A21DDC33CF00E03F87 /* Cocoa.framework */; };
@@ -58,6 +61,7 @@
/* Begin PBXFileReference section */
D123F5A61DDF9D2400A27B7A /* DDHotKeyCenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DDHotKeyCenter.h; path = DDHotKey/DDHotKeyCenter.h; sourceTree = "<group>"; };
D123F5A71DDF9D2400A27B7A /* DDHotKeyCenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DDHotKeyCenter.m; path = DDHotKey/DDHotKeyCenter.m; sourceTree = "<group>"; };
+ D131EB371DF1E8AB00504A74 /* com.teddywing.Low-Battery-Yup.StartAtLogin.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "com.teddywing.Low-Battery-Yup.StartAtLogin.plist"; sourceTree = "<group>"; };
D15D90B51DF0465E001700CD /* ShortcutView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShortcutView.h; sourceTree = "<group>"; };
D15D90B61DF0465E001700CD /* ShortcutView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShortcutView.m; sourceTree = "<group>"; };
D1871D051DE094AB00B8030D /* DDHotKeyTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DDHotKeyTextField.h; path = DDHotKey/DDHotKeyTextField.h; sourceTree = "<group>"; };
@@ -78,6 +82,10 @@
D18C94C41DDC355400E03F87 /* Mouse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Mouse.m; sourceTree = "<group>"; };
D195AE4F1DDC774200A53A18 /* MASShortcut.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MASShortcut.xcodeproj; path = MASShortcut/MASShortcut.xcodeproj; sourceTree = "<group>"; };
D19DF1F41DF09CF30094C50F /* Constants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Constants.h; sourceTree = "<group>"; };
+ D19DF20D1DF1AD3D0094C50F /* LaunchAgentManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LaunchAgentManager.h; sourceTree = "<group>"; };
+ D19DF20E1DF1AD3D0094C50F /* LaunchAgentManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LaunchAgentManager.m; sourceTree = "<group>"; };
+ D19DF2101DF1AD480094C50F /* DaemonLauncher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DaemonLauncher.h; sourceTree = "<group>"; };
+ D19DF2111DF1AD480094C50F /* DaemonLauncher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DaemonLauncher.m; sourceTree = "<group>"; };
D1A37AED1DE0012C0022434D /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
D1A37AEF1DE001770022434D /* DDHotKeyUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DDHotKeyUtilities.h; path = DDHotKey/DDHotKeyUtilities.h; sourceTree = "<group>"; };
D1A37AF01DE001770022434D /* DDHotKeyUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DDHotKeyUtilities.m; path = DDHotKey/DDHotKeyUtilities.m; sourceTree = "<group>"; };
@@ -207,6 +215,10 @@
D195AE4F1DDC774200A53A18 /* MASShortcut.xcodeproj */,
D1F809EE1DDC6AA0001671E9 /* AppDelegate.h */,
D1F809EF1DDC6AA0001671E9 /* AppDelegate.m */,
+ D19DF20D1DF1AD3D0094C50F /* LaunchAgentManager.h */,
+ D19DF20E1DF1AD3D0094C50F /* LaunchAgentManager.m */,
+ D19DF2101DF1AD480094C50F /* DaemonLauncher.h */,
+ D19DF2111DF1AD480094C50F /* DaemonLauncher.m */,
D19DF1F41DF09CF30094C50F /* Constants.h */,
D15D90B51DF0465E001700CD /* ShortcutView.h */,
D15D90B61DF0465E001700CD /* ShortcutView.m */,
@@ -224,6 +236,7 @@
D1F809E81DDC6AA0001671E9 /* main.m */,
D1F809EA1DDC6AA0001671E9 /* Low Battery Yup-Prefix.pch */,
D1F809EB1DDC6AA0001671E9 /* Credits.rtf */,
+ D131EB371DF1E8AB00504A74 /* com.teddywing.Low-Battery-Yup.StartAtLogin.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
@@ -346,6 +359,7 @@
D1F809ED1DDC6AA0001671E9 /* Credits.rtf in Resources */,
D1F809F31DDC6AA0001671E9 /* MainMenu.xib in Resources */,
D195AE601DDC776F00A53A18 /* MASShortcut.framework in Resources */,
+ D131EB381DF1E8AB00504A74 /* com.teddywing.Low-Battery-Yup.StartAtLogin.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -374,6 +388,8 @@
D1871D081DE094C200B8030D /* DDHotKeyUtilities.m in Sources */,
D1871D091DE0955E00B8030D /* DDHotKeyCenter.m in Sources */,
D15D90B71DF0465E001700CD /* ShortcutView.m in Sources */,
+ D19DF20F1DF1AD3D0094C50F /* LaunchAgentManager.m in Sources */,
+ D19DF2121DF1AD480094C50F /* DaemonLauncher.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/Low Battery Yup/AppDelegate.h b/Low Battery Yup/AppDelegate.h
index cc38038..4ae3e9c 100644
--- a/Low Battery Yup/AppDelegate.h
+++ b/Low Battery Yup/AppDelegate.h
@@ -9,13 +9,17 @@
#import <Cocoa/Cocoa.h>
#import <MASShortcut/MASShortcut.h>
#import "ShortcutView.h"
+#import "LaunchAgentManager.h"
@interface AppDelegate : NSObject <NSApplicationDelegate> {
IBOutlet NSWindow *window;
IBOutlet ShortcutView *_shortcut_view;
IBOutlet NSButton *_start_at_login;
+
+ LaunchAgentManager *_launchagent;
}
- (void)initializeShortcutView;
+- (IBAction)performStartAtLogin:(id)sender;
@end
diff --git a/Low Battery Yup/AppDelegate.m b/Low Battery Yup/AppDelegate.m
index 1c77f41..365b1bf 100644
--- a/Low Battery Yup/AppDelegate.m
+++ b/Low Battery Yup/AppDelegate.m
@@ -11,14 +11,25 @@
@implementation AppDelegate
+- (id)init
+{
+ self = [super init];
+ if (self) {
+ _launchagent = [[LaunchAgentManager alloc] init];
+ }
+ return self;
+}
+
- (void)dealloc
{
+ [_launchagent release];
[super dealloc];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[self initializeShortcutView];
+ [self performStartAtLogin:self];
}
- (void)initializeShortcutView
@@ -33,6 +44,16 @@
}
}
+- (IBAction)performStartAtLogin:(id)sender
+{
+ if ([_start_at_login state] == NSOnState) {
+ [_launchagent install];
+ }
+ else {
+ [_launchagent uninstall];
+ }
+}
+
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
{
return YES;
diff --git a/Low Battery Yup/DaemonLauncher.h b/Low Battery Yup/DaemonLauncher.h
new file mode 100644
index 0000000..a62a256
--- /dev/null
+++ b/Low Battery Yup/DaemonLauncher.h
@@ -0,0 +1,13 @@
+//
+// DaemonLauncher.h
+// Low Battery Yup.d
+//
+// Created by TW on 12/2/16.
+// Copyright (c) 2016 TW. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface DaemonLauncher : NSObject
+
+@end
diff --git a/Low Battery Yup/DaemonLauncher.m b/Low Battery Yup/DaemonLauncher.m
new file mode 100644
index 0000000..4c6449c
--- /dev/null
+++ b/Low Battery Yup/DaemonLauncher.m
@@ -0,0 +1,13 @@
+//
+// DaemonLauncher.m
+// Low Battery Yup.d
+//
+// Created by TW on 12/2/16.
+// Copyright (c) 2016 TW. All rights reserved.
+//
+
+#import "DaemonLauncher.h"
+
+@implementation DaemonLauncher
+
+@end
diff --git a/Low Battery Yup/LaunchAgentManager.h b/Low Battery Yup/LaunchAgentManager.h
new file mode 100644
index 0000000..5a9fa44
--- /dev/null
+++ b/Low Battery Yup/LaunchAgentManager.h
@@ -0,0 +1,20 @@
+//
+// LaunchAgentManager.h
+// Low Battery Yup.d
+//
+// Created by TW on 12/2/16.
+// Copyright (c) 2016 TW. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#define LAUNCH_AGENTS_PATH @"~/Library/LaunchAgents"
+
+@interface LaunchAgentManager : NSObject {
+ NSFileManager *_file_manager;
+}
+
+- (BOOL)install;
+- (BOOL)uninstall;
+
+@end
diff --git a/Low Battery Yup/LaunchAgentManager.m b/Low Battery Yup/LaunchAgentManager.m
new file mode 100644
index 0000000..fd75795
--- /dev/null
+++ b/Low Battery Yup/LaunchAgentManager.m
@@ -0,0 +1,52 @@
+//
+// LaunchAgentManager.m
+// Low Battery Yup.d
+//
+// Created by TW on 12/2/16.
+// Copyright (c) 2016 TW. All rights reserved.
+//
+
+#import "LaunchAgentManager.h"
+
+@implementation LaunchAgentManager
+
+- (id)init
+{
+ self = [super init];
+ if (self) {
+ _file_manager = [NSFileManager defaultManager];
+ }
+ return self;
+}
+
+- (BOOL)install
+{
+ NSBundle *main_bundle = [NSBundle mainBundle];
+ NSURL *launchagents_url = [NSURL fileURLWithPath:
+ [[LAUNCH_AGENTS_PATH stringByAppendingString:@"/com.teddywing.Low-Battery-Yup.StartAtLogin.plist"] stringByExpandingTildeInPath]
+ isDirectory:YES];
+
+ NSError *error;
+ BOOL success = [_file_manager copyItemAtURL:
+ [main_bundle URLForResource:@"com.teddywing.Low-Battery-Yup.StartAtLogin" withExtension:@"plist"]
+ toURL:launchagents_url
+ error:&error];
+
+ if (!success) {
+ NSLog(@"%@", error);
+ }
+
+ return success;
+}
+
+- (BOOL)uninstall
+{
+ return [[NSWorkspace sharedWorkspace]
+ performFileOperation:NSWorkspaceRecycleOperation
+ source:[LAUNCH_AGENTS_PATH stringByExpandingTildeInPath]
+ destination:@""
+ files:[NSArray arrayWithObject:@"com.teddywing.Low-Battery-Yup.StartAtLogin.plist"]
+ tag:nil];
+}
+
+@end
diff --git a/Low Battery Yup/com.teddywing.Low-Battery-Yup.StartAtLogin.plist b/Low Battery Yup/com.teddywing.Low-Battery-Yup.StartAtLogin.plist
new file mode 100644
index 0000000..0c67376
--- /dev/null
+++ b/Low Battery Yup/com.teddywing.Low-Battery-Yup.StartAtLogin.plist
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict/>
+</plist>
diff --git a/Low Battery Yup/en.lproj/MainMenu.xib b/Low Battery Yup/en.lproj/MainMenu.xib
index e649cab..5e48c4e 100644
--- a/Low Battery Yup/en.lproj/MainMenu.xib
+++ b/Low Battery Yup/en.lproj/MainMenu.xib
@@ -1358,7 +1358,7 @@
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="489226571"/>
</object>
- <string key="NSScreenRect">{{0, 0}, {2560, 1578}}</string>
+ <string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
<string key="NSMinSize">{480, 207}</string>
<string key="NSMaxSize">{480, 207}</string>
<bool key="NSWindowIsRestorable">YES</bool>
@@ -2068,6 +2068,14 @@
</object>
<int key="connectionID">544</int>
</object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performStartAtLogin:</string>
+ <reference key="source" ref="976324537"/>
+ <reference key="destination" ref="1065652370"/>
+ </object>
+ <int key="connectionID">545</int>
+ </object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
@@ -3256,13 +3264,24 @@
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
- <int key="maxID">544</int>
+ <int key="maxID">545</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">AppDelegate</string>
<string key="superclassName">NSObject</string>
+ <object class="NSMutableDictionary" key="actions">
+ <string key="NS.key.0">performStartAtLogin:</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <string key="NS.key.0">performStartAtLogin:</string>
+ <object class="IBActionInfo" key="NS.object.0">
+ <string key="name">performStartAtLogin:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_shortcut_view">ShortcutView</string>
<string key="_start_at_login">NSButton</string>