Get the current wallpaper in Cocoa

前端 未结 2 632
深忆病人
深忆病人 2020-12-31 15:29

I\'m using this code to get the current wallpaper:

NSURL *imageURL = [[NSWorkspace sharedWorkspace] desktopImageURLForScreen:[NSScreen mainScreen]];
<         


        
相关标签:
2条回答
  • 2020-12-31 16:27

    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.

    0 讨论(0)
  • 2020-12-31 16:28

    I've been trying to do the exact same thing. You can get the current desktop picture URL by:

    1. Getting the current space UUID from the com.apple.spaces property list,
    2. Searching the com.apple.desktop property list for the matching space,
    3. 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:@""];
    
    0 讨论(0)
提交回复
热议问题