如何遍历所有Mac桌面空间

时间:2016-03-23 18:03:25

标签: swift macos cocoa

我试图为所有屏幕和空格(预先存在和新的)设置桌面背景。但是,我似乎无法找到为所有现有空间设置背景的方法(并且创建的任何新空间都使用旧背景)。

这是我到目前为止所做的:

let sqlData = NSMutableArray()
let paths = NSSearchPathForDirectoriesInDomains(.ApplicationSupportDirectory, .UserDomainMask, true)
let appSupportDirectory = paths.first! as NSString
let dbPath = appSupportDirectory.stringByAppendingPathComponent("Dock/desktoppicture.db") as NSString

var db: COpaquePointer = nil
if sqlite3_open(dbPath.UTF8String, &db) == SQLITE_OK {
    var statement: COpaquePointer = nil

    if sqlite3_exec(db, "DELETE FROM data", nil, nil, nil) != SQLITE_OK {
        let errmsg = String.fromCString(sqlite3_errmsg(db))
        print("error deleting table row: \(errmsg)")
    }

    if sqlite3_exec(db, "INSERT INTO DATA (VALUE) VALUES ('\(getBackgroundImagePath())');", nil, nil, nil) != SQLITE_OK {
        let errmsg = String.fromCString(sqlite3_errmsg(db))
        print("error inserting table row: \(errmsg)")
    }

    let workspace = NSWorkspace.sharedWorkspace()

    for screen in NSScreen.screens()! {
        do {
            let options = workspace.desktopImageOptionsForScreen(screen)
            try workspace.setDesktopImageURL(NSURL(fileURLWithPath: getBackgroundImagePath()), forScreen: screen, options: options!)
        } catch let error as NSError {
            NSLog("\(error.localizedDescription)")
        }
    }

    system("/usr/bin/killall Dock")
}

sqlite3_close(db)

注意:我更新~/Library/Application Support/Dock/desktoppicture.db中的.db文件。由于这并没有实际更新背景,因此我继续循环浏览每个屏幕并手动设置它们。

虽然这会改变所有屏幕的背景,但不会更改任何非活动空间,并且创建的任何新空格都使用旧背景。

我在GitHub上制作的小应用程序中使用此代码,这是用户报告的问题。 You can find the issue here (with a terminal solution)

Apple有一个看似相关的项目here,但即便他们也不会更新多个空间。

此外,如果您通过默认的mac设置应用更新背景,它也不会更改预先存在的空间。这不可能吗?

1 个答案:

答案 0 :(得分:3)

OS X桌面图片全局更新空间

desktoppicture.dbupdate data查询可以在value表格上运行,其中包含新图片的路径(delete)。不应该insert然后data值,或使用循环。使用无范围查询调用update,这样做会更新func globalDesktopPicture(image: String) { let paths: [String] = NSSearchPathForDirectoriesInDomains(.ApplicationSupportDirectory, .UserDomainMask, true) let appSup: String = paths.first! let dbPath: String = (appSup as NSString).stringByAppendingPathComponent("Dock/desktoppicture.db") let dbase = try? Connection("\(dbPath)") let value = Expression<String?>("value") let table = Table("data") try! dbase!.run(table.update(value <- image)) system("/usr/bin/killall Dock") } 表中的每一行。

(以下示例使用SQLite.swift语言层,该层使用类型安全的纯Swift接口)

func legacyGlobalDesktopPicture(image: String) {

    let paths: [String] = NSSearchPathForDirectoriesInDomains(.ApplicationSupportDirectory,
                                                              .UserDomainMask, true)
    let appSup: String = paths.first!
    let dbPath: String = (appSup as NSString).stringByAppendingPathComponent("Dock/desktoppicture.db")

    var db: COpaquePointer = nil
    if sqlite3_open(dbPath, &db) == SQLITE_OK {

        if sqlite3_exec(db, "UPDATE DATA SET VALUE = ('\(image)');", nil, nil, nil) != SQLITE_OK {
            let errmsg = String.fromCString(sqlite3_errmsg(db))
            print("error inserting table row: \(errmsg)")
        }

        system("/usr/bin/killall Dock")
    }
    sqlite3_close(db)
}

如果您决定使用传统/遗留(桥接头)方法执行SQLite3查询,那么更新 db的相同概念/原则也适用相同:

   @RequestMapping(
            value = "/addUserProfile",
            method = RequestMethod.GET
            )
    public ModelAndView addUserProfile() {
        ModelAndView modelAndView = new ModelAndView(VIEW_ADD_USER_PROFILE);
        return modelAndView;
    }

@ModelAttribute("userProfile")
UserProfile userProfile() {
    return new UserProfile();
}

注意:上面的例子很小,应该包括一些错误检查等。

其他信息: