I'm trying to set a desktop background for all screens AND spaces (preexisting and new). However, I can't seem to find a way to set the background for all the existing spaces (and any new spaces created use the old background).
Here is what I have so far:
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)
Note: I update the .db file found in ~/Library/Application Support/Dock/desktoppicture.db
. Since this doesn't actually update the background, I then proceed to loop through each screen and set them manually.
Although this changes all of the screen's backgrounds, any non-active spaces are not changed, and any new spaces created use the old background.
I'm using this code within a small app I made on GitHub, and this is an issue a user reported. You can find the issue here (with a terminal solution).
Apple has a seemingly relevant project here, but even they don't update multiple spaces.
Also, if you update the background through the default mac settings app, it also doesn't change pre-existing spaces. Is it impossible?
Move between spacesOn a trackpad, swipe left or right with three or four fingers. On a Magic Mouse, swipe with two fingers. Press the Control key and the Right or Left arrow key. Enter Mission Control, move the pointer to the top edge of the screen, then click a space in the Spaces bar.
If you want your desktop icons to be auto-arranged, you can do so by clicking on the View menu and then hold on the ALT key on the keyboard until you see the "Keep Arranged By" option show up on the View menu.
Using the Mouse: Switch between desktops by clicking on them in the top menu bar. Trackpad Gesture: Switching between desktops can also be done by swiping four fingers to the right or left on the trackpad. Keyboard Shortcut: Using the Control key along with the right or left arrow key will also switch between desktops.
Show or move all open windows Show all open windows for the current app: Press Control-Down Arrow. If App Exposé is selected in Trackpad preferences, you can also swipe down with three fingers. To return to the desktop, press the keys again or swipe up.
In desktoppicture.db
an update
query can be run on the data
table with the path of the new image (value
). It shouldn't be necessary to delete
and then insert
the values, or use loops. Using an unscoped query calls update, and by doing so it will update every row in the data
table.
(The example below uses the SQLite.swift language layer, which uses a type-safe pure Swift interface)
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")
}
The same concept/principle of updating the db applies just the same if you instead decide to use the traditional/legacy (bridging headers) method of doing SQLite3 queries:
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)
}
NOTE: The examples above are quite minimal and should include some error checking, etc.
Additional Info:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With