How to Loop Through All MAC Desktop Spaces

How to loop through all Mac desktop spaces

OS X Desktop Picture Global Updating Across Spaces

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:

  • How to get the path to the current space wallpaper?
  • SQLite.swift Documentation : Updating Rows
  • SQLite.swift / A type-safe, Swift-language layer over SQLite3

Seamlessly change all desktop spaces' wallpaper on Mac without killall Dock

I figured it out.

I am looping through all available screens and setting the wallpaper using setDesktopImageURL:forScreen:options:error::

for screen in NSScreen.screens {
try! NSWorkspace.shared.setDesktopImageURL(url, for: screen, options: [:])
}

This changes the wallpapers seamlessly, without the need for killall Dock on all the screens but only if the desktop is the active space.

To make sure the wallpaper is changed when I am on another space (usually a fullscreen app), I added an observer for NSWorkspace.activeSpaceDidChangeNotification on the NSWorkspace.shared.notificationCenter which sets the desktop images again (using the code above). So whenever I go back to the desktop, this notification is invoked and the wallpaper is seamlessly updated.

I even went one step further and added the same observer also for the NSWorkspace.didWakeNotification which updates the wallpaper as soon as the device wakes up which is cool!

How to assign application to all desktops (spaces) of Mac OS X Lion using Objective C?

You can use method setCollectionBehavior: of NSWindow with the NSWindowCollectionBehaviorCanJoinAllSpaces bitwise flag.

It will make the window visible on all spaces.

NSUInteger collectionBehavior;

// Gets the current collection behavior of the window
collectionBehavior = [ myWindow collectionBehavior ];

// Adds the option to make the window visible on all spaces
collectionBehavior |= NSWindowCollectionBehaviorCanJoinAllSpaces;

// Sets the new collection behaviour
[ myWindow setCollectionBehavior: collectionBehavior ];

Note

This method was introduced in Mac OS X 10.6.

On Mac OS X 10.5, you'll need to use the canBeVisibleOnAllSpaces: method of NSWindow.

Desktop spaces are moving by their own

Go to System Preferencies > Mission Control

Here check and (if enabled) disable Automatically rearrange Spaces



Related Topics



Leave a reply



Submit