use defaults to read desktop wallpaper change value in mac - macos

Is there a way to obtain the current setting for desktop wallpaper change either using Apple Script or defaults read? Basically I want to know by looking at the plist file if the option of changing wallpaper every X minutes is enabled or not.

See the AppleScript dictionary for the Desktop Suite class of the System Events helper app. It contains the property:
picture rotation (integer) : never, using interval, using login, after sleep
There are separate values for each desktop, for instance, if you have more than one monitor active. For example:
tell application "System Events"
get picture rotation of its first desktop
end tell

Related

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

I would like to change the wallpaper on ALL desktops including spaces on Mac but without needing to call killall Dock each minute. (Dock restarting forces wallpaper refresh).
I have an AppleScript that changes the desktop wallpaper instantly:
tell application "System Events" to tell every desktop to set picture to wallpaperPath
but that only changes the wallpaper on the active space (meaning that if the main desktop is not active, its background will not change).
I found this question How to loop through all Mac desktop spaces which suggests updating wallpaper path values in the SQLite database located at ~/Library/Application Support/Dock/desktoppicture.db. This changes the wallpaper at every space which is great but it requires restart of the dock using killall Dock which is undesirable as it disrupts the workflow.
My question is - is there some way to combine these two approaches? Seamlessly change wallpapers on every desktop space?
Any suggestions would be appreciated. I have no preferred language, it can be in C, Swift, Python, Bash, AppleScript etc.
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!

MacOS: Determine which monitor any window application is on?

I'm currently attempting to have my system pipe audio to a specific output depending on which monitor that application is running on. For instance, if a web browser is playing videos on monitor A, sound comes out of output 1. If it is on monitor B, it comes out of output 2. Is there any way to poll which monitor any/all applications are located/active on macOS?
The question hasn't given many details, but in principle you can recover the position of the window using code like the:
tell application "System Events"
tell process "App Name"
set windowPos to position of first window
end tell
end tell
... and then compare that to the frame of each desktop to discover which display the window is in. If you need to determine the frame of each desktop programmatically (instead of hand-coding them in), that will take some extra work: either digging the values out of a system plist file or using AppleScriptObjC to get the frame dimensions from NSScreen. Let me know if you need that, and I'll update when I get a chance.

Where does macOS store the desktop picture change time?

I want to determine programmatically whether a user has enabled automatic desktop picture change in the background & screensaver preferences or not (and also the change time).
I know that recent versions of macOS store desktop picture information in the sqlite3 database ~/Library/Application Support/Dock/desktoppicture.db. But it lacks any details regarding the picture change settings.
In older versions of macOS there existed a plist file com.apple.desktop.plist, but it seems to be no longer in use.
Does anyone know where macOS stores this information nowadays?
Is AppleScript an option?
tell application "System Events"
set pictureRotation to picture rotation of desktops
set changeIntervals to change interval of desktops
end tell
Both results are a list because you can have multiple displays.
pictureRotation contains the information whether the user has checked "Change Picture" (0 or 1).
changeIntervals contains the interval in seconds.

Perform actions when background image changed on Mac

Is there any way to listen to, and trigger actions when user right click and click change desktop background OR when the background image is actually changed on OSX?
You can get the current desktop image in the shell like this:
osascript -e 'tell app "finder" to get posix path of (get desktop picture as alias)'
I presume, if you really wanted to, you could create a launchd script with launchctl and a corresponding plist to check every minute or so to see if it has changed and then do something...

Positioning windows with applescript on dual monitors

I have 2 air applications that I wrote. They auto fullscreen after 10 seconds. Before then, they need to be sent to their proper displays. "app_1" needs to run on display 1, "app_2" needs to run on display 2.
Essentially, I have this code:
do shell script "cd /Applications/app_1.app/Contents/MacOS/ ; open app_1;"
which works for me flawlessly. Both apps are launched that way, and there is some code for ensuring that the apps weren't already open, and closing them if they were.
I tried to add in a script to position the app after it is launched:
do shell script "cd /Applications/app_1.app/Contents/MacOS/ ; open app_1;"
tell first window of application "app_1" to set bounds to {0,0,1920,1080}
This gives me an error:
app_1 got an error: Can't set bounds of window 1 to {0,0,1920,1080}
I tried adding a delay of a couple seconds before the set bounds, in case the application hadn't yet launched when the set bounds fired off, however this didn't change anything.
I also tried setting the bounds to something like {100,100,200,200} just to see if I had the screen coordinates wrong or something, but still the exact same error, only with the {100,100,200,200} instead of the original 1920x1080 coordinates.
Anyone have any insight on this? I've been trying to find the solution on google for a couple of hours now.
It sounds like your app isn't exposing the standard "window" class. I don't know if AIR apps are supposed to automatically take care of this and it's not working—if so, you'll want to debug that.
But another alternative is to use UI Scripting to control its windows externally. Instead of this:
tell first window of application "app_1" to set bounds to {0,0,1920,1080}
Do this:
tell application "System Events"
set position of first window of application process "app_1" to {0, 0}
set size of first window of application process "app_1" to {1920,1080}
end tell
However, this will only work if you've gone to the Universal Access pane of System Preferences and checked "Enable access for assistive devices" (or done the same via API, "sudo touch /var/db/.AccessibilityAPIEnabled", etc.).

Resources