在OS X 10.7 Lion中更改所有桌面上的壁纸?

时间:2011-09-25 17:08:55

标签: cocoa desktop wallpaper osx-lion

我想在屏幕上更改所有桌面(以前称为“空格”)的壁纸。从OS X 10.6开始,NSWorkspace有一个允许设置壁纸的类别,但是,当我使用此功能时,只有当前桌面的壁纸被更改,所有其他桌面保持不变。

然后我查看了桌面首选项plist并编写了一个类来修改它以反映我想要的更改(基本上设置了一个新的图像文件路径)。保存新文件后,我发送了com.apple.desktop“BackgroundChanged”通知 - 谷歌,如果你不知道我在说什么,这就是人们在10.6天之前改变壁纸的方式。起初这没有产生任何结果,因此我在用户信息字典中输入了与nil相同的userInfo字典,就像你在设置中更改壁纸时所做的那样(订阅应用中的通知并更改壁纸)在设置应用程序中,您将看到它的样子)。 Luck在这里帮助了我,当我以某种原因发送通知时,Dock崩溃了,当它重新加载时,它加载了首选项文件中的设置,从而显示了我的更改。

这适用于10.7.1,但是,我会a)而不是码头崩溃和重新加载的糟糕用户体验,以及b)使用或多或少保证在未来版本中工作的路径。利用错误似乎不是一条稳定的道路。

有关如何更改所有桌面壁纸的其他想法?我也不确定NSWorkspace壁纸类别的当前行为是打算还是一个bug,但是,从壁纸首选项面板的行为来看,似乎前者就是这种情况。

1 个答案:

答案 0 :(得分:7)

没有用于为所有屏幕或所有空间设置相同壁纸的API,NSWorkspace setDesktopImageURL它实现为只为当前屏幕上的当前空间设置壁纸,这也是系统偏好设置的功能。

除了手动修改〜/ Library / Preferences / com.apple.desktop.plist(格式可能会改变)并使用通知重新加载它(你遇到崩溃)的易失性方法,你可以做的是将壁纸设置为空格当用户切换到它时,例如寻找NSWorkspaceActiveSpaceDidChangeNotification(如果你的应用程序并不总是在运行,你可以告诉用户切换到他想要壁纸应用的所有空间),可以说这些方法并不理想,但至少它们不易变。

-(void)setWallpaper
{
    NSWorkspace *sws = [NSWorkspace sharedWorkspace];
    NSURL *image = [NSURL fileURLWithPath:@"/Library/Desktop Pictures/Andromeda Galaxy.jpg"];
    NSError *err = nil;
    for (NSScreen *screen in [NSScreen screens]) {
        NSDictionary *opt = [sws desktopImageOptionsForScreen:screen];        
        [sws setDesktopImageURL:image forScreen:screen options:opt error:&err];
        if (err) {
            NSLog(@"%@",[err localizedDescription]);
        }else{
            NSNumber *scr = [[screen deviceDescription] objectForKey:@"NSScreenNumber"];
            NSLog(@"Set %@ for space %i on screen %@",[image path],[self spaceNumber],scr);
        }
    }
}

-(int)spaceNumber
{
    CFArrayRef windowsInSpace = CGWindowListCopyWindowInfo(kCGWindowListOptionAll | kCGWindowListOptionOnScreenOnly, kCGNullWindowID);      
    for (NSMutableDictionary *thisWindow in (NSArray *)windowsInSpace)    {
        if ([thisWindow objectForKey:(id)kCGWindowWorkspace]){
            return [[thisWindow objectForKey:(id)kCGWindowWorkspace] intValue];
        }
    }
    return -1;
}