2011-09-25 10 views
15

画面上のすべてのデスクトップ(以前の「スペース」)の壁紙を変更したいと思います。 OS X 10.6では、壁紙の設定を可能にするNSWorkspaceのカテゴリがありますが、この機能を使用すると、現在のデスクトップの壁紙だけが変更され、他のすべてのデスクトップは変更されません。OS X 10.7 Lionのすべてのデスクトップで壁紙を変更しますか?

次に、デスクトップの設定plistを見て、私が望む変更(基本的に新しいイメージファイルパスを設定)を反映するように変更するクラスを書きました。新しいファイルが保存された後、私はcom.apple.desktop "BackgroundChanged"通知を送った。あなたが私が何を話しているのか分からなければ、これは10.6日前に壁紙を変えた方法だった。最初はこれは何も結果をもたらさなかったので、userInfo辞書としての "nil"の代わりに、あなたが設定した壁紙を変更したときにAppleと同じuserInfo辞書を送りました(アプリ内の通知を購読して壁紙を変更しますあなたはそれがどのように見えるかを見るでしょう)。 Duckが何らかの理由で通知を送ったときにLuckが私を助け、Dockがクラッシュしてリロードしたときに、設定ファイルから設定をロードして変更を表示しました。

これは10.7.1で動作しますが、ドックのクラッシュと再読み込みのユーザーエクスペリエンスが悪くなく、b)将来のリリースでも動作することが保証されているパスを使用します。バグを悪用しようとしても、安定したパスのようには見えません。

すべてのデスクトップの壁紙を変更する方法に関する他のアイデアはありますか?私はまた、NSWorkspaceの壁紙カテゴリの現在の動作が意図されているのか、バグであるのか不明ですが、壁紙の設定パネルの動作から判断すると、前者が当てはまるようです。

答えて

7

すべての画面またはすべてのスペースに同じ壁紙を設定するためのAPIはありません。NSWorkspace setDesktopImageURLこれは、現在の画面上の現在のスペースの壁紙のみを設定するように実装されています。 。

〜/ライブラリ/ Preferences/com.apple.desktop.plist(形式が変更される可能性があります)を手作業で変更し、通知を使用して再読み込みする(慣れてしまった)揮発性の方法に加えて、壁紙をユーザーがそれに切り替えるときのスペース、たとえばNSWorkspaceActiveSpaceDidChangeNotificationを探してください(アプリケーションが常に動作しているとは限りませんが、壁紙を壁紙に適用することをユーザーに指示することができます)。おそらくこれらのメソッドは理想的ではありませんが、少なくともvolatileはありません。

-(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; 
} 
+0

ありがとうございましたvalexa、ActiveSpaceChanged通知は、実際に私が今まで使っていたものです。動作しますが、1つのコマンドでそれらをすべて設定できるだけでなく、エレガントではありません – Robin

関連する問題