arkanath
arkanath

Reputation: 143

Redraw desktop background without restarting dock in OS X

I am updating the wallpaper using the following function:

- (void)updateWallpaper: (NSString *)path {
    NSError * aerror;
    NSURL *url = [[NSURL alloc] init];
    url = [NSURL fileURLWithPath:path];
    [[NSWorkspace sharedWorkspace] setDesktopImageURL:url forScreen:[NSScreen mainScreen] options:[NSDictionary dictionary] error:&aerror];
    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
    NSMutableDictionary* desktopDict = [NSMutableDictionary dictionaryWithDictionary:[defaults persistentDomainForName:@"com.apple.desktop"]];
    NSMutableDictionary* bgDict = [desktopDict objectForKey:@"Background"];
    NSMutableDictionary* spaces = [bgDict objectForKey:@"spaces"];
    [spaces enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSMutableDictionary* obj, BOOL *stop) {
        [obj enumerateKeysAndObjectsUsingBlock:^(id key, NSMutableDictionary* prefs, BOOL *stop) {
            [prefs setObject:path forKey:@"ImageFilePath"];
            [prefs setObject:path forKey:@"NewImageFilePath"];
            [prefs setObject:@"Never" forKey:@"Change"];
        }];
    }];

    //NSLog(@"%@", desktopDict);

    [defaults setPersistentDomain:desktopDict forName:@"com.apple.desktop"];
    if ([defaults synchronize] == NO) {
        NSLog(@"synchronize failed");

    }

}

However, the update is not always rendered, in the sense that the old image continues to remain. I have tried various workarounds, the best I could come up with is writing the image to a new file (new file path) for every update. This works when I am working in the desktop space, but not if I am working in some other full-screen app space. The only thing which fixes this is to reload the dock (by system ("/usr/bin/killall Dock");). This somehow redraws the wallpaper in between. But this causes the un-minimizing of all the minimized windows for all applications, which is not okay for my use. Is there some other way to reinforce the update?

Upvotes: 2

Views: 665

Answers (1)

Monolo
Monolo

Reputation: 18253

As a workaround, you can consider using AppleScript. It may not be the most elegant solution, but integrating AppleScript into apps is a documented technique, so it should be safe.

In OS X 10.11 you can change the wallpaper with a single line of script. Notice that you have to use a POSIX file, aliases do not seem to work.

To test it from the command line, try this in Terminal:

osascript -e 'tell application "Finder" to set desktop picture to POSIX file "<full path to image file>"'

This doc explains how to use AppleScript from an app.

Upvotes: 1

Related Questions