Extras/GrowlSafari/GrowlSafariLoader.m
author Peter Hosey <hg@boredzo.org>
Tue Sep 15 10:08:03 2009 -0700 (2009-09-15)
changeset 4401 24c2a3482ec3
parent 4400 3d6a80b674a0
child 4402 fc7016ea4fc2
permissions -rw-r--r--
Add support to GrowlSafari for the WebKit nightly-build launcher.
ingmarstein@2298
     1
//
ingmarstein@2298
     2
//  GrowlSafariLoader.m
ingmarstein@2298
     3
//  GrowlSafari
ingmarstein@2298
     4
//
hg@4299
     5
//  Created by Peter Hosey on 2009-06-14.
hg@4299
     6
//  Copyright 2009 Peter Hosey. All rights reserved.
ingmarstein@2298
     7
//
ingmarstein@2298
     8
ingmarstein@2298
     9
#import "GrowlSafariLoader.h"
ingmarstein@2298
    10
hg@4400
    11
#import "InterestingBundleIdentifiers.h"
hg@4299
    12
hg@4299
    13
@interface GrowlSafariLoader ()
hg@4299
    14
hg@4299
    15
- (void) workspaceDidLaunchApplication:(NSNotification *)notification;
hg@4299
    16
hg@4299
    17
@end
hg@4299
    18
ingmarstein@2298
    19
@implementation GrowlSafariLoader
ingmarstein@2298
    20
hg@4299
    21
- (id) init {
hg@4299
    22
	if((self = [super init])) {
hg@4299
    23
		workspace = [[NSWorkspace sharedWorkspace] retain];
hg@4299
    24
		NSNotificationCenter *nc = [workspace notificationCenter];
hg@4299
    25
		NSLog(@"Adding %@ as an observer on %@ for %@ with object %@", self, nc, NSWorkspaceDidLaunchApplicationNotification, workspace);
hg@4299
    26
		[nc addObserver:self
hg@4299
    27
			   selector:@selector(workspaceDidLaunchApplication:)
hg@4299
    28
				   name:NSWorkspaceDidLaunchApplicationNotification
hg@4299
    29
				 object:nil];
hg@4299
    30
	}
hg@4299
    31
	return self;
ingmarstein@2323
    32
}
ingmarstein@2323
    33
hg@4299
    34
- (void) dealloc {
hg@4299
    35
	NSNotificationCenter *nc = [workspace notificationCenter];
hg@4299
    36
	[nc removeObserver:self
hg@4299
    37
				  name:NSWorkspaceDidLaunchApplicationNotification
hg@4299
    38
				object:workspace];
hg@4299
    39
	[workspace release];
hg@4299
    40
hg@4299
    41
	[super dealloc];
hg@4299
    42
}
hg@4299
    43
hg@4299
    44
- (void) applicationDidFinishLaunching:(NSNotification *)notification {
hg@4299
    45
	//Scan for running Safari instances, and send ourselves messages as if NSWorkspace had posted notifications about them.
hg@4299
    46
	NSEnumerator *appsEnum = [[workspace launchedApplications] objectEnumerator];
hg@4299
    47
	NSDictionary *appDict;
hg@4299
    48
	while ((appDict = [appsEnum nextObject])) {
hg@4299
    49
		NSNotification *notification = [NSNotification notificationWithName:NSWorkspaceDidLaunchApplicationNotification object:workspace userInfo:appDict];
hg@4299
    50
		[self workspaceDidLaunchApplication:notification];
hg@4299
    51
	}
hg@4299
    52
}
hg@4299
    53
hg@4325
    54
- (BOOL) isOnSnowLeopardOrLater {
hg@4325
    55
	OSStatus err;
hg@4325
    56
hg@4325
    57
	SInt32 majorOSVersion = 10, minorOSVersion = 0;
hg@4325
    58
	err = Gestalt(gestaltSystemVersionMajor, &majorOSVersion);
hg@4325
    59
	NSAssert2(err == noErr, @"Could not get operating-system major version number: %li/%s", (long)err, GetMacOSStatusCommentString(err));
hg@4325
    60
	err = Gestalt(gestaltSystemVersionMinor, &minorOSVersion);
hg@4325
    61
	NSAssert2(err == noErr, @"Could not get operating-system minor version number: %li/%s", (long)err, GetMacOSStatusCommentString(err));
hg@4325
    62
hg@4325
    63
	return (majorOSVersion == 10 && minorOSVersion >= 6) || (majorOSVersion > 10);
hg@4325
    64
}
hg@4325
    65
hg@4299
    66
- (void) workspaceDidLaunchApplication:(NSNotification *)notification {
hg@4299
    67
	NSDictionary *launchedProcessInfo = [notification userInfo];
hg@4299
    68
	NSString *bundleID = [launchedProcessInfo objectForKey:@"NSApplicationBundleIdentifier"];
hg@4401
    69
	if (bundleID && ([bundleID caseInsensitiveCompare:SAFARI_BUNDLE_ID] == NSOrderedSame) || ([bundleID caseInsensitiveCompare:WEBKIT_LAUNCHER_BUNDLE_ID] == NSOrderedSame)) {
hg@4299
    70
		NSString *bundlePath = [[NSBundle bundleForClass:[self class]] pathForResource:@"GrowlSafari" ofType:@"bundle"];
hg@4299
    71
		if (bundlePath) {
hg@4299
    72
			NSNumber *PIDNum = [launchedProcessInfo objectForKey:@"NSApplicationProcessIdentifier"];
hg@4299
    73
			pid_t pid = [PIDNum intValue];
hg@4299
    74
			
hg@4325
    75
			NSArray *arguments = [NSArray arrayWithObjects:
hg@4325
    76
				@"-arch",
hg@4325
    77
#if defined(__i386__)
hg@4325
    78
				@"i386",
hg@4325
    79
#elif defined(__x86_64__)
hg@4325
    80
				//Safari did not exist in x86_64 before Snow Leopard, so, on older versions of Mac OS X, run the helper as i386.
hg@4325
    81
				[self isOnSnowLeopardOrLater] ? @"x86_64" : @"i386",
hg@4325
    82
#elif defined(__ppc__)
hg@4325
    83
				@"ppc",
hg@4325
    84
#else
hg@4325
    85
#error Unsupported architecture
hg@4325
    86
#endif
hg@4325
    87
				[[NSBundle bundleForClass:[self class]] pathForAuxiliaryExecutable:@"GrowlSafariHelper"],
hg@4325
    88
				[NSString stringWithFormat:@"%d", pid],
hg@4325
    89
				nil];
Rudy@4314
    90
			NSTask *task = [[[NSTask alloc] init] autorelease];
hg@4325
    91
			[task setLaunchPath:@"/usr/bin/arch"];
Rudy@4314
    92
			[task setArguments:arguments];
Rudy@4314
    93
			[task launch];
hg@4299
    94
		}
hg@4299
    95
	}
ingmarstein@2298
    96
}
ingmarstein@2298
    97
ingmarstein@2298
    98
@end