问题
I'm using this code to get the current wallpaper:
NSURL *imageURL = [[NSWorkspace sharedWorkspace] desktopImageURLForScreen:[NSScreen mainScreen]];
This works fine, but when i set a folder of pictures to be the wallpaper(As shown in the picture), the imageURL
is a directory, so how can i get the current wallpaper's USURL in this situation?
回答1:
I've been trying to do the exact same thing. You can get the current desktop picture URL by:
- Getting the current space UUID from the com.apple.spaces property list,
- Searching the com.apple.desktop property list for the matching space,
- Extracting the URL from the LastName property
I am still working on this, but the following code obtains the correct URL... sometimes. The main problem is that the property lists aren't updated frequently enough, and I haven't been able to force them to refresh (short of killing the dock). Let me know if you figure something out!
NSDictionary *spacesPLIST = (__bridge NSDictionary *)(CFPreferencesCopyAppValue(CFSTR("SpacesConfiguration"), CFSTR("com.apple.spaces")));
NSDictionary *desktopPLIST = (__bridge NSDictionary *)(CFPreferencesCopyAppValue(CFSTR("Background"), CFSTR("com.apple.desktop")));
NSArray *monitors = [spacesPLIST valueForKeyPath:@"Management Data.Monitors"];
NSInteger monitorIndex = 0;
if ([monitors count] > 1) {
//search for main (or ask user to select)
}
NSDictionary *monitor = [monitors objectAtIndex:monitorIndex];
NSDictionary *spaces = [desktopPLIST valueForKey:@"spaces"];
NSString *currentSpaceUUID = [monitor valueForKeyPath:@"Current Space.uuid"];
NSDictionary *currentSpace = [spaces valueForKey:currentSpaceUUID];
NSURL *desktopPicturesDirectory = [NSURL fileURLWithPath:[currentSpace valueForKeyPath:@"default.ChangePath"] isDirectory:true];
NSString *desktopPictureName = [currentSpace valueForKeyPath:@"default.LastName"];
NSURL *desktopPictureURL = [NSURL URLWithString:desktopPictureName relativeToURL:desktopPicturesDirectory];
[[NSWorkspace sharedWorkspace] selectFile:[desktopPictureURL path] inFileViewerRootedAtPath:@""];
回答2:
There is another way to get the image by taking a screenshot of the current wallpaper.
extension NSImage {
static func desktopPicture() -> NSImage {
let windows = CGWindowListCopyWindowInfo(
CGWindowListOption.OptionOnScreenOnly,
CGWindowID(0))! as NSArray
var index = 0
for var i = 0; i < windows.count; i++ {
let window = windows[i]
// we need windows owned by Dock
let owner = window["kCGWindowOwnerName"] as! String
if owner != "Dock" {
continue
}
// we need windows named like "Desktop Picture %"
let name = window["kCGWindowName"] as! String
if !name.hasPrefix("Desktop Picture") {
continue
}
// wee need the one which belongs to the current screen
let bounds = window["kCGWindowBounds"] as! NSDictionary
let x = bounds["X"] as! CGFloat
if x == NSScreen.mainScreen()!.frame.origin.x {
index = window["kCGWindowNumber"] as! Int
break
}
}
let cgImage = CGWindowListCreateImage(
CGRectZero,
CGWindowListOption(arrayLiteral: CGWindowListOption.OptionIncludingWindow),
CGWindowID(index),
CGWindowImageOption.Default)!
let image = NSImage(CGImage: cgImage, size: NSScreen.mainScreen()!.frame.size)
return image
}
}
This approach looks much simpler IMHO, if you need the picture, not the url.
Note that wallpaper is no longer defined in the com.apple.dektop plist: starting from Mavericks, the setting is moved to ~/Library/Application Support/Dock/desktoppicture.db. This is SQLite file, and the "data" table contains the url.
来源:https://stackoverflow.com/questions/14099363/get-the-current-wallpaper-in-cocoa