Use a new approach to implement launch at login.

This commit is contained in:
Charlie Qiu
2017-01-12 23:44:29 +08:00
parent 29c6bf8c3a
commit f137d51cb2
8 changed files with 1178 additions and 68 deletions

View File

@ -27,7 +27,5 @@
@property(assign) BOOL launchAtLogin;
- (BOOL) willLaunchAtLogin: (NSURL*) itemURL;
- (void) setLaunchAtLogin: (BOOL) enabled forURL: (NSURL*) itemURL;
@end

View File

@ -23,24 +23,20 @@
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "LaunchAtLoginController.h"
#import <ServiceManagement/SMLoginItem.h>
static NSString *const StartAtLoginKey = @"launchAtLogin";
//static NSString *const StartAtLoginKey = @"launchAtLogin";
@interface LaunchAtLoginController () {
BOOL _enabled;
}
@interface LaunchAtLoginController ()
@property(assign) LSSharedFileListRef loginItems;
@end
@implementation LaunchAtLoginController
@synthesize loginItems;
#pragma mark Change Observing
void sharedFileListDidChange(LSSharedFileListRef inList, void *context)
{
LaunchAtLoginController *self = (__bridge id) context;
[self willChangeValueForKey:StartAtLoginKey];
[self didChangeValueForKey:StartAtLoginKey];
}
#pragma mark Initialization
@ -48,76 +44,29 @@ void sharedFileListDidChange(LSSharedFileListRef inList, void *context)
{
self = [super init];
if (self) {
loginItems = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
LSSharedFileListAddObserver(loginItems, CFRunLoopGetMain(),
(CFStringRef)NSDefaultRunLoopMode, sharedFileListDidChange, (__bridge void *)(self));
_enabled = [[NSUserDefaults standardUserDefaults] boolForKey: @"LaunchAtLogin"];
}
return self;
}
- (void) dealloc
{
LSSharedFileListRemoveObserver(loginItems, CFRunLoopGetMain(),
(CFStringRef)NSDefaultRunLoopMode, sharedFileListDidChange, (__bridge void *)(self));
CFRelease(loginItems);
}
#pragma mark Launch List Control
- (LSSharedFileListItemRef) findItemWithURL: (NSURL*) wantedURL inFileList: (LSSharedFileListRef) fileList
{
if (wantedURL == NULL || fileList == NULL)
return NULL;
NSArray *listSnapshot = ((__bridge NSArray *)(LSSharedFileListCopySnapshot(fileList, NULL)));
for (id itemObject in listSnapshot) {
LSSharedFileListItemRef item = (__bridge LSSharedFileListItemRef) itemObject;
UInt32 resolutionFlags = kLSSharedFileListNoUserInteraction | kLSSharedFileListDoNotMountVolumes;
CFURLRef currentItemURL = NULL;
currentItemURL = LSSharedFileListItemCopyResolvedURL(item, resolutionFlags, NULL);
if (currentItemURL && CFEqual(currentItemURL, (__bridge CFTypeRef)(wantedURL))) {
CFRelease(currentItemURL);
return item;
}
if (currentItemURL)
CFRelease(currentItemURL);
}
return NULL;
}
- (BOOL) willLaunchAtLogin: (NSURL*) itemURL
{
return !![self findItemWithURL:itemURL inFileList:loginItems];
}
- (void) setLaunchAtLogin: (BOOL) enabled forURL: (NSURL*) itemURL
{
LSSharedFileListItemRef appItem = [self findItemWithURL:itemURL inFileList:loginItems];
if (enabled && !appItem) {
LSSharedFileListInsertItemURL(loginItems, kLSSharedFileListItemBeforeFirst,
NULL, NULL, (__bridge CFURLRef)itemURL, NULL, NULL);
} else if (!enabled && appItem)
LSSharedFileListItemRemove(loginItems, appItem);
}
#pragma mark Basic Interface
- (NSURL*) appURL
{
return [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
}
- (void) setLaunchAtLogin: (BOOL) enabled
{
[self willChangeValueForKey:StartAtLoginKey];
[self setLaunchAtLogin:enabled forURL:[self appURL]];
[self didChangeValueForKey:StartAtLoginKey];
if (SMLoginItemSetEnabled(
(__bridge CFStringRef)@"com.qiuyuzhou.ShadowsocksX-NG.LaunchHelper"
, enabled)) {
_enabled = enabled;
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool: enabled forKey: @"LaunchAtLogin"];
}
}
- (BOOL) launchAtLogin
{
return [self willLaunchAtLogin:[self appURL]];
return _enabled;
}
@end