Изменить обои на всех рабочих столах в OS X 10.7 Lion?

Я хотел бы изменить обои всех рабочих столов (ранее «пробелы») на экране. Начиная с OS X 10.6, в NSWorkspace есть категория, которая позволяет устанавливать обои, однако, когда я использую эту функцию, изменяются только обои текущего рабочего стола, а все остальные рабочие столы остаются неизменными.

Затем я просмотрел список настроек рабочего стола и написал класс, который модифицирует его, чтобы отразить нужные мне изменения (по сути, установить новый путь к файлу изображения). После того, как новый файл был сохранен, я отправил уведомление com.apple.desktop «BackgroundChanged» — Google, если вы не знаете, о чем я говорю, это было то, как люди меняли обои до 10,6 дней. Сначала это не дало никакого результата, поэтому вместо «nil» в качестве словаря userInfo я отправил точно такой же словарь userInfo, как это делает Apple, когда вы меняете обои в своих настройках (подписывайтесь на уведомление в приложении и меняйте обои в приложении настроек, и вы увидите, как это выглядит). Здесь мне помогла удача, когда я отправил уведомление таким образом, Док почему-то завис, а при перезагрузке загрузил настройки из файла настроек, отобразив мои изменения.

Это работает на 10.7.1, однако я бы предпочел: а) не иметь плохого пользовательского опыта при сбое и перезагрузке дока и б) использовать путь, который более или менее гарантированно будет работать и в будущих выпусках. Использование ошибки не похоже на стабильный путь.

Любые другие идеи о том, как изменить обои всех рабочих столов? Я также не уверен, предназначено ли текущее поведение категории обоев NSWorkspace или является ошибкой, однако, судя по поведению панели настроек обоев, кажется, что первое имеет место.


person Robin    schedule 25.09.2011    source источник


Ответы (1)


Не существует 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;
}
person valexa    schedule 01.03.2012
comment
Спасибо, valexa, уведомления ActiveSpaceChanged — это то, что я использовал на данный момент. Работает, но не так элегантно, как просто установить их все одной командой - person Robin; 03.03.2012