如何遍历所有Mac桌面空间

Jos*_*osa 14 macos cocoa swift

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

这是我到目前为止:

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)
Run Code Online (Sandbox Code Playgroud)

注意:我更新了找到的.db文件~/Library/Application Support/Dock/desktoppicture.db.由于这实际上并没有更新背景,因此我继续遍历每个屏幕并手动设置它们.

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

我在GitHub上制作的小应用程序中使用此代码,这是用户报告的问题.您可以在此处找到问题(使用终端解决方案).

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

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

l'L*_*L'l 3

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

可以在带有新图像路径的表上运行查询desktoppicture.db( )。没有必要对值进行 then操作,或者使用循环。使用无范围查询调用更新,这样它将更新表中的每一行。updatedatavaluedeleteinsertdata

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

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")
}
Run Code Online (Sandbox Code Playgroud)

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

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)
}
Run Code Online (Sandbox Code Playgroud)

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

附加信息: