Showing posts tagged os x

An Applescript to Delete Your Current Wallpaper!

I spent the morning figuring out how to trash my current wallpaper and advance it to another in a directory named after my current display’s dimensions.

But we’re getting ahead of ourselves. To set the picture, come along with me…

I really like to have nice wallpapers. The first thing I do on almost any computer I have access to, after switching the keyboard layout to something sane, of course, is to find a decent wallpaper from Google or Interface Lift (did you know you can search Google images for a specific image dimension now? angelic choirs). Something about having something really nice to look at when I see the desktop makes me feel all warm and fuzzy inside, like a fresh baked peanut butter brownie.

OK… Hyperbole.

But still, it is really nice. It’s so nice, in fact, that I’ve been wanting to write a really killer cross-platform wallpaper management app for years now to make it easier on myself to manage all the wallpapers that I have. OS X does a decent job with their wallpaper management and features for controlling how often your desktop changes and where the source comes from but it’s not that good. Ideally, I’d want something like iPhoto for wallpaper, where you can easily tag wallpaper, rate it, group it, set different rotation schedules… /me rants for about 10 minutes about how awesome this app is going to be.

Oh, are you still here? I’ll get back to what I did today.

Long story short, I’m nowhere near writing that app, although I think I’d like to do it in Clojure as my first ‘real’ project there. Today, though, I finally got tired of wanting to be able to ditch the current desktop. I download a lot of wallpaper and sometimes it’s just not as killer as you thought it’d be. At least I get that a lot. I kept telling myself that there has to be an easy way to do this in Applescript.

Figured at most maybe 5-10 minutes.

Famous last words.

3 hours and many friendly hits on Google later, behold!

The ApplescriptThing That Deletes Your Current Wallpaper and Changes It To Something Else And Tells You About It In Growl

set screenHeight to (word 3 of (do shell script "defaults read /Library/Preferences/com.apple.windowserver | grep -w Height"))
set screenWidth to (word 3 of (do shell script "defaults read /Library/Preferences/com.apple.windowserver | grep -w Width"))
set wallpaperFolder to screenWidth & "x" & screenHeight & ":"
tell application "Finder"
    set randomImage to some file of folder wallpaperFolder of folder "Wallpaper" of folder "Pictures" of home as alias
end tell
tell application "System Events"
    tell current desktop
        set currentDesktop to (get picture as alias)
        set currentDesktopName to (get name of currentDesktop)
        tell application "Finder"
            delete currentDesktop
        end tell
    end tell
    set picture of current desktop to randomImage
end tell
do shell script "growlnotify 'Trashed Wallpaper' -m '" & currentDesktopName & ".'"

A blow by blow:

Remarkably, Apple does not seem to provide any simple way to

  1. Access your current display’s dimensions.
  2. Get your current wallpaper if your wallpaper is set to rotate automatically and randomly

That’s where a lot of the weirdness comes in.

Credit for the defaults read grepping goes to Mike Byrne of Raised Weird and his post about getting the current display’s dimensions using applescript. I extended it just a little by also getting the width.

Why would I do this? Simple answer is that I organize my wallpaper into dimension folders. So I’ve got a bunch of ~/Pictures/Wallpaper/WxH directories where W is something like 1920 and H is something like 1080. I do this because I hate having my wallpaper scaled. As good as it’s gotten soft scaling is still not all that nice. I prefer to download the wallpaper in all the dimensions I’d like and then have the display pull from the wallpaper directory that matches its dimensions. So, you guessed it! If you’d like to use this script you’ll either have to alter it or mirror my set up.

The current preferred way to set your wallpaper seems to be through the “System Events” application which, if I’m understanding things correctly was added in Leopard. However, that doesn’t get you a nice random image does it? This little trick came from the forums at macosx.com. Whew, can I just say that is nice!? set it to some file of. Good job! Of course, it’s also one of the gripes I have against Applescript. If a Lisp is all about removing the distance between the function you’re trying to apply and the way you express that function, applescript seems to be all about obfuscating it as far as possible away. This is the problem with programming languages that attempt to mimic natural language. Natural language is great for real time communication but awful for precision and transparency! If Apple didn’t provide some neat little trick for doing something, it’s dern hard to guess how you might do it.

Finally, a little shelling out to growlnotify and you’ve got a nice little app that you can run via QuickSilver, LaunchBar or the built-in Scripts menu.

The main problem with this script is that you can’t use it if you’ve in told System Preferences to rotate your desktops for you. The current desktop, for whatever reason, sticks as the last desktop you manually selected. So in order to get rotating images, you need a second script which mostly uses stuff from the first.

set screenHeight to (word 3 of (do shell script "defaults read /Library/Preferences/com.apple.windowserver | grep -w Height"))
set screenWidth to (word 3 of (do shell script "defaults read /Library/Preferences/com.apple.windowserver | grep -w Width"))
set wallpaperFolder to screenWidth & "x" & screenHeight & ":"
tell application "Finder"
    set randomImage to some file of folder wallpaperFolder of folder "Wallpaper" of folder "Pictures" of home as alias
    set randomImageName to (get name of randomImage)
end tell
tell application "System Events"
    set picture of current desktop to randomImage
end tell
do shell script "growlnotify 'Advanced Wallpaper' -m '" & randomImageName & ".'"

You stick this in your crontab executing it with osascript and you’re done.

By the by, if you don’t know about your crontab, it’s the utility provided on all *nixes (that I know of) for scheduling events. Anything that can be done from the command line, including Applescripts, can be scheduled to remarkable level of specificity. If you’re just getting into it, I would thoroughly recommend reading the Wikipedia Article and then immediately installing Cronnix. Cronnix is, in a word, the best way to edit your crontab if you’re not already a wizard at vim.

You can download the trashing script or the advancing script from my Github Page, where you can also find the project if you feel inclined to help out.

YMMV. Enjoy.