user142019
user142019

Reputation:

How to make the dock reload all dock tile plugins?

I am making an application which uses a dock tile plug-in. However, when I recompile my dock tile plugin, the dock still uses the old one, even when I killall the dock. The only way to fix this is by rebooting my Mac, but I don't want to reboot it for every little code change I make. Also, dock tile plugins are poorly documented. Can anyone help me?

Upvotes: 1

Views: 1275

Answers (3)

James Boutcher
James Boutcher

Reputation: 2613

I have been battling with this recently, and it seems neither killing the Dock process or SystemUIServer process by themselves did the trick; I was having to kill them both.

Back to Apple's documentation on this subject:

When your application is removed from the Dock, the setDockTile: method is called with a nil parameter. Your setDockTile: method should release the Dock tile object, clean up any resources your Dock Tile plug-in allocated, and exit.

I've found that if you take the "and exit" from Apple's docs literally, these plugins don't linger around and unloading is clean. I feel a bit dirty doing this though (and have submitted feedback to Apple on this) because I believe my exit(0) is causing other apps' docktileplugins to be reloaded too. (I guess having to resort to killall Dock/SystemUIServer does the same)

The docs seem ambiguous too... Not sure why Apple would want you doing good memory management stuff and releasing objects when the next thing you do is kill the process.

    if(dockTile == nil) {
        NSLog(@"Docktile version %@ unloading", [[[NSBundle bundleForClass:[self class]] infoDictionary] valueForKey:@"CFBundleVersion"]);
        [_dockTile release], _dockTile = nil; // don't leak memory!
        exit(0); // ouch
    }

Upvotes: -1

SG1
SG1

Reputation: 2891

You can also do this in "Activity Monitor". Search for "dock" and force quit com.apple.dock.extra manually. This is the "mouse" alternative to the "keyboard" option above, and it doesn't do as much collateral damage.

I'd suggest that during development, for frequent code changes, you could wrap the above command in a Cocoa task:

- (BOOL)killall:(NSString *)process {
    //Configure
    NSString *toolPath = @"usr/bin/killall";
    NSArray *arguments = [NSArray arrayWithObject:process];

    //Create
    NSTask *task = [[[NSTask alloc] init] autorelease];
    [task setLaunchPath:toolPath];
    [task setArguments:arguments];

    //Run
    [task launch];
    [task waitUntilExit];

    //Return success
    return ([task terminationStatus] == 0);
}

Put this in a category on NSApplication, executed like so:

NSLog(@"MyApp: killed UI Server: %d", [NSApp killall:@"SystemUIServer"]); //Comment out for release

OR (recommended)

NSLog(@"MyApp: killed Dock plugins: %d", [NSApp killall:@"com.apple.dock.extra"]); //Comment out for release

Upvotes: 2

user142019
user142019

Reputation:

I found out using an NSAlert and Accessability Inspector that a process called SystemUIServer is responsible for dock tile plugins. Just do:

$ killall SystemUIServer

This will restart SystemUIServer and reload the dock tile plugins.

Upvotes: 2

Related Questions