afrikapit
afrikapit

Reputation: 29

Script to find active wallpaper file in Finder under macOS Catalina

I used to use two AppleScript scripts to find out the file name of the actual wallpaper image from desktop 1 and desktop 2 (dual monitor mode) under macOS Mojave. One script for the main monitor and another one for the second monitor. Under macOS Catalina the scripts are not working anymore.

Here is the script:

tell application "System Events"
    set posix_path to (pictures folder of desktop 2)
    set picPath to (POSIX file posix_path) as string
end tell
set thePictures to (do shell script "sqlite3 ~/Library/Application\\ Support/Dock/desktoppicture.db \"SELECT data.value FROM preferences INNER JOIN data on preferences.key=16 and preferences.picture_id=7 and preferences.data_id=data.ROWID\"")
set fullPath to picPath as string
set rotationImage to fullPath & thePictures
tell application "Finder"
    try
        set aliasItem to item rotationImage
        if class of aliasItem is alias file then
            reveal original item of aliasItem
        end if
    end try
end tell

Here is the error message:

tell application "System Events"
    get pictures folder of desktop 1
        --> "/Users/peter/Library/Caches/com.apple.preference.desktopscreeneffect.desktop/69948584/DSKPhotosRootSource"
    get POSIX file "/Users/peter/Library/Caches/com.apple.preference.desktopscreeneffect.desktop/69948584/DSKPhotosRootSource"
        --> error number -1728 from POSIX file "/Users/peter/Library/Caches/com.apple.preference.desktopscreeneffect.desktop/69948584/DSKPhotosRootSource"
end tell
tell current application
    do shell script "sqlite3 ~/Library/Application\\ Support/Dock/desktoppicture.db \"SELECT data.value FROM preferences INNER JOIN data on preferences.key=16 and preferences.picture_id=1 and preferences.data_id=data.ROWID\""
        --> "13725B"
end tell
tell application "Finder"
    get item "Macintosh HD:Users:peter:Library:Caches:com.apple.preference.desktopscreeneffect.desktop:69948584:DSKPhotosRootSource13725B"
        --> error number -1728 from item "Macintosh HD:Users:peter:Library:Caches:com.apple.preference.desktopscreeneffect.desktop:69948584:DSKPhotosRootSource13725B"
end tell

Tried to find the problem but couldn't find a solution. I am not an experienced AppleScript writer. Hope somebody can help.

Upvotes: 0

Views: 1035

Answers (3)

bh222
bh222

Reputation: 11

On Catalina and Mojave, I'm able to get the current wallpaper by using a sqlite command similar to yours:

sqlite3 ~/Library/Application\ Support/Dock/desktoppicture.db "select * from data" | tail -2

Or in Applescript:

do shell script "sqlite3 ~/Library/Application\\ Support/Dock/desktoppicture.db 'select * from data' | tail -2"

On my Mac, the last 2 items in the data table appear to be some combination of the most recently set wallpaper and last 2 displays that were most recently set, so I tail the list. Like you, I'm also using a large folder of wallpapers and I have it set to change every 30 minutes. As long as I don't manually change a wallpaper, the last 2 items are consistently the names of the 2 active wallpapers because both monitors change at the same time every 30 minutes.

Something to note: When you are using a Folder with the "Change picture:" checkbox checked, the items returned from select * data is just the file name (i.e., wallpaper.jpg). If you've set the wallpaper to a single image, the item returned from the select command is the full path of the image (i.e., /path/to/folder/wallpaper.jpg). Since I'm using a folder, so I get just the image names in my select results. Then I can split the 2 names by newline to get each wallpaper name in an array and then open them. Here's my whole script:

#!/bin/bash

#reads and opens the last 2 items from the 'data' table in the desktoppicture.db sqlite db

last_two=`sqlite3 ~/Library/Application\ Support/Dock/desktoppicture.db "select * from data" | tail -2`
 
IFS=$'\n' read -rd '' -a y <<<"$last_two"

#echo "first is ${y[0]}"
#echo "second is ${y[1]}"

open /Users/myusername/Pictures/Desktop\ Pictures/${y[0]}
open /Users/myusername/Pictures/Desktop\ Pictures/${y[1]}

I realize you asked an AppleScript question and this is largely a bash script answer, but the do shell script item at the top of my answer should get you going enough to be able to capture and manipulate the image names inside of AppleScript.

Just to close this out, I use this bash script in Alfred using a keyword "retire" to retire a wallpaper I'm tired of. I type the keyword, this script runs to open the images in Preview, another script runs to open my Desktop Pictures folder and a Desktop Pictures Retired folder and then I manually move the photo into the Retired folder.

Upvotes: 1

CJK
CJK

Reputation: 6102

I can't guarantee the code below will fair any better than the solution already posted, but it should, in theory, target desktop images per screen (monitor) rather than by desktop (space). However, I don't have Mojave or Catalina, or a computer to test this out:

use framework "AppKit"

property NSScreen : a reference to NSScreen in the current application
property NSWorkspace : a reference to NSWorkspace in the current application

property currentScreen : a reference to the mainScreen of NSScreen

on screen(i as integer)
        local i

        if i = 0 then return the currentScreen()
        return NSScreen's screens()'s item i
end screen

on desktopImageURLForScreen:(i as integer)
        local i

        set S to screen(i)
        tell NSWorkspace's sharedWorkspace() to return the ¬
                desktopImageURLForScreen_(S) as «class furl»
end desktopImageURLForScreen:

return the POSIX path of my desktopImageURLForScreen:0

The bottom line is the one you will most likely want to experiment with, by changing the index number passed to the handler. If you have three monitors, then they would each be identified by one of the indices 1, 2, or 3 (I can't predict how index corresponds to arrangement of monitors). Index 0 will always refer to the screen that currently has keyboard focus.

Upvotes: 0

wch1zpink
wch1zpink

Reputation: 3142

If you currently have two monitors connected and you're simply looking to retrieve the names of the Desktop Wall Papers for each, this following Apple script code should be what you're looking for.

tell application "System Events"
    set everyDesktop to desktops
    set desktopOnePicture to picture of item 1 of everyDesktop
    set desktopTwoPicture to picture of item 2 of everyDesktop
end tell

Upvotes: 0

Related Questions