diff --git a/Mute Me Now/AppDelegate.m b/Mute Me Now/AppDelegate.m index a307553..85f9a72 100644 --- a/Mute Me Now/AppDelegate.m +++ b/Mute Me Now/AppDelegate.m @@ -1,6 +1,5 @@ #import "AppDelegate.h" #import "TouchBar.h" -#import #import "TouchButton.h" #import "TouchDelegate.h" @@ -28,16 +27,6 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { [NSTouchBarItem addSystemTrayItem:mute]; DFRElementSetControlStripPresenceForIdentifier(muteIdentifier, YES); - - [self enableLoginAutostart]; - -} - --(void) enableLoginAutostart { - BOOL state = [[NSUserDefaults standardUserDefaults] boolForKey:@"auto_login"]; - if(!SMLoginItemSetEnabled((__bridge CFStringRef)@"Pixel-Point.Mute-Me-Now-Launcher", !state)) { - NSLog(@"The login was not succesfull"); - } } - (void)applicationWillTerminate:(NSNotification *)aNotification { diff --git a/Mute Me Now/Base.lproj/Main.storyboard b/Mute Me Now/Base.lproj/Main.storyboard index 94cea72..b192378 100644 --- a/Mute Me Now/Base.lproj/Main.storyboard +++ b/Mute Me Now/Base.lproj/Main.storyboard @@ -1,5 +1,5 @@ - + @@ -716,9 +716,6 @@ - - - diff --git a/Mute Me Now/MMNLaunchAtLoginController.h b/Mute Me Now/MMNLaunchAtLoginController.h new file mode 100644 index 0000000..e618d2e --- /dev/null +++ b/Mute Me Now/MMNLaunchAtLoginController.h @@ -0,0 +1,16 @@ +// +// MMNLaunchAtLoginController.h +// Mute Me +// +// Created by Dmitry Rodionov on 17/06/2017. +// Copyright © 2017 Pixel Point. All rights reserved. +// + +#import + +@interface MMNLaunchAtLoginController : NSObject +@property (readwrite) BOOL shouldLaunchOnLogin; + ++ (instancetype)sharedController; + +@end diff --git a/Mute Me Now/MMNLaunchAtLoginController.m b/Mute Me Now/MMNLaunchAtLoginController.m new file mode 100644 index 0000000..2006b15 --- /dev/null +++ b/Mute Me Now/MMNLaunchAtLoginController.m @@ -0,0 +1,59 @@ +// +// MMNLaunchAtLoginController.m +// Mute Me +// +// Created by Dmitry Rodionov on 17/06/2017. +// Copyright © 2017 Pixel Point. All rights reserved. +// + +#import "MMNLaunchAtLoginController.h" +#import + +static NSString *const kLauncherBundleID = @"Pixel-Point.Mute-Me-Now-Launcher"; + +@implementation MMNLaunchAtLoginController + ++ (instancetype)sharedController +{ + static id shared = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + shared = [[self alloc] init]; + }); + + return shared; +} + +- (BOOL)shouldLaunchOnLogin +{ + // SMCopyAllJobDictionaries() was deprecated back in 10.10, but as Apple says in + // their own documentation: + // + // > For the specific use of testing the state of a login item that may have been + // > enabled with SMLoginItemSetEnabled() in order to show that state to the + // > user, this function remains the recommended API. A replacement API for this + // > specific use will be provided before this function is removed. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated" + NSArray *jobs = (__bridge NSArray *)(SMCopyAllJobDictionaries(kSMDomainUserLaunchd)); +#pragma clang diagnostic pop + if (jobs.count == 0) { + return NO; + } + // Look for a launchd job with the same bundle ID as our launcher application + NSUInteger idx = [jobs indexOfObjectPassingTest:^BOOL(NSDictionary *job, NSUInteger idx, BOOL *stop) { + return [job[@"Label"] isEqualToString:kLauncherBundleID]; + }]; + return (idx != NSNotFound); +} + + +- (void)setShouldLaunchOnLogin:(BOOL)state +{ + BOOL set = SMLoginItemSetEnabled((__bridge CFStringRef)(kLauncherBundleID), state); + if (!set) { + NSLog(@"Unable to toggle the login item"); + } +} + +@end diff --git a/Mute Me Now/Mute Me Now Launcher/Mute Me Now Launcher.xcodeproj/project.pbxproj b/Mute Me Now/Mute Me Now Launcher/Mute Me Now Launcher.xcodeproj/project.pbxproj index 8f56d0e..b3d2115 100644 --- a/Mute Me Now/Mute Me Now Launcher/Mute Me Now Launcher.xcodeproj/project.pbxproj +++ b/Mute Me Now/Mute Me Now Launcher/Mute Me Now Launcher.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 0ADD25F01EF5750B00E095AB /* Mute Me Now Launcher.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Mute Me Now Launcher.entitlements"; sourceTree = ""; }; 11B86E751EDEAC970069D254 /* Mute Me Now Launcher.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Mute Me Now Launcher.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 11B86E781EDEAC970069D254 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 11B86E791EDEAC970069D254 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -56,6 +57,7 @@ 11B86E771EDEAC970069D254 /* Mute Me Now Launcher */ = { isa = PBXGroup; children = ( + 0ADD25F01EF5750B00E095AB /* Mute Me Now Launcher.entitlements */, 11B86E781EDEAC970069D254 /* AppDelegate.h */, 11B86E791EDEAC970069D254 /* AppDelegate.m */, 11B86E7E1EDEAC970069D254 /* ViewController.h */, @@ -264,7 +266,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_ENTITLEMENTS = ""; + CODE_SIGN_ENTITLEMENTS = "Mute Me Now Launcher/Mute Me Now Launcher.entitlements"; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = "Mute Me Now Launcher/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; @@ -278,7 +280,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_ENTITLEMENTS = ""; + CODE_SIGN_ENTITLEMENTS = "Mute Me Now Launcher/Mute Me Now Launcher.entitlements"; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = "Mute Me Now Launcher/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; diff --git a/Mute Me Now/Mute Me Now Launcher/Mute Me Now Launcher/Mute Me Now Launcher.entitlements b/Mute Me Now/Mute Me Now Launcher/Mute Me Now Launcher/Mute Me Now Launcher.entitlements new file mode 100644 index 0000000..852fa1a --- /dev/null +++ b/Mute Me Now/Mute Me Now Launcher/Mute Me Now Launcher/Mute Me Now Launcher.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/Mute Me Now/ViewController.m b/Mute Me Now/ViewController.m index d11f7de..d41fa33 100644 --- a/Mute Me Now/ViewController.m +++ b/Mute Me Now/ViewController.m @@ -1,4 +1,5 @@ #import "ViewController.h" +#import "MMNLaunchAtLoginController.h" static NSString *githubURL = @"https://github.com/pixel-point/mute-me"; static NSString *projectURL = @"https://muteme.pixelpoint.io/"; @@ -9,8 +10,11 @@ @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; - BOOL state = [[NSUserDefaults standardUserDefaults] boolForKey:@"auto_login"]; - [self.autoLoginState setState: !state]; + // Bind "Launch at login" checkbox state to the corresponding value in the controller object + [self.autoLoginState bind:NSValueBinding + toObject:[MMNLaunchAtLoginController sharedController] + withKeyPath:@"shouldLaunchOnLogin" + options:nil]; } -(void)viewDidAppear { @@ -36,16 +40,6 @@ - (IBAction)onGithubPressed:(id)sender { - (IBAction)onWebsitePressed:(id)sender { [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:projectURL]]; } -- (IBAction)onLoginStartChanged:(id)sender { - NSInteger state = [self.autoLoginState state]; - BOOL enableState = NO; - if(state == NSOnState) { - enableState = YES; - } - if(SMLoginItemSetEnabled((__bridge CFStringRef)@"Pixel-Point.Mute-Me-Now-Launcher", enableState)) { - [[NSUserDefaults standardUserDefaults] setBool:!enableState forKey:@"auto_login"]; - } -} - (IBAction)onMainWebsitePressed:(id)sender { [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:companyURL]]; } diff --git a/Mute Me.xcodeproj/project.pbxproj b/Mute Me.xcodeproj/project.pbxproj index 85ba44b..1fd4ae1 100644 --- a/Mute Me.xcodeproj/project.pbxproj +++ b/Mute Me.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 0A9EAC491EF54250002CA9B0 /* MMNLaunchAtLoginController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A9EAC481EF54250002CA9B0 /* MMNLaunchAtLoginController.m */; }; 1141FDF21EEFF6DD00CA5B30 /* TouchButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 1141FDF11EEFF6DD00CA5B30 /* TouchButton.m */; }; 11B86E521EDE9B4D0069D254 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 11B86E511EDE9B4D0069D254 /* AppDelegate.m */; }; 11B86E551EDE9B4D0069D254 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 11B86E541EDE9B4D0069D254 /* main.m */; }; @@ -51,6 +52,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 0A9EAC471EF54250002CA9B0 /* MMNLaunchAtLoginController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMNLaunchAtLoginController.h; sourceTree = ""; }; + 0A9EAC481EF54250002CA9B0 /* MMNLaunchAtLoginController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMNLaunchAtLoginController.m; sourceTree = ""; }; 1141FDF01EEFF6DD00CA5B30 /* TouchButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TouchButton.h; sourceTree = ""; }; 1141FDF11EEFF6DD00CA5B30 /* TouchButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TouchButton.m; sourceTree = ""; }; 1141FDF51EEFFA0000CA5B30 /* TouchDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TouchDelegate.h; sourceTree = ""; }; @@ -113,6 +116,8 @@ 11B86E511EDE9B4D0069D254 /* AppDelegate.m */, 11B86E561EDE9B4D0069D254 /* ViewController.h */, 11B86E571EDE9B4D0069D254 /* ViewController.m */, + 0A9EAC471EF54250002CA9B0 /* MMNLaunchAtLoginController.h */, + 0A9EAC481EF54250002CA9B0 /* MMNLaunchAtLoginController.m */, 11B86E591EDE9B4D0069D254 /* Assets.xcassets */, 11B86E5B1EDE9B4D0069D254 /* Main.storyboard */, 11B86E5E1EDE9B4D0069D254 /* Info.plist */, @@ -249,6 +254,7 @@ 11B86E581EDE9B4D0069D254 /* ViewController.m in Sources */, 11B86E551EDE9B4D0069D254 /* main.m in Sources */, 11B86E521EDE9B4D0069D254 /* AppDelegate.m in Sources */, + 0A9EAC491EF54250002CA9B0 /* MMNLaunchAtLoginController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };