Execute script on wallpaper change event

My wallpaper is set to change every 30 mins.
How do I catch the wallpaper change event and execute a script when the wallpaper changes?

-R

Mac OS X (10.6.2)

Posted on Mar 8, 2010 3:07 PM

Reply
16 replies

Mar 8, 2010 3:35 PM in response to ryanrhee90

Simple - you don't.

There's nothing in AppleScript that will respond to this kind of trigger.

The closest you could come would be a background script that periodically checks the current desktop picture and compares it to what was seen previously. Any difference indicates that the desktop picture changed and you can react accordingly.

In other words, your script can poll the system to find the current setting, but the OS won't notify your script directly.

Mar 9, 2010 10:35 AM in response to ryanrhee90

Use a listener script that does not timeout, something like this.

Im not if this one will timeout or not though.




[code]
set change_status to false
repeat
with timeout of 0 seconds
tell application "Finder" to set current_pic to desktop picture
delay 3
tell application "Finder" to set recheck_name to desktop picture
if current_pic ≠ recheck_name then set change_status to true
if change_status = true then do_stuff()
if current_pic = recheck_name then set change_status to false
end timeout
end repeat





on do_stuff()
display dialog "DO STUFF HERE BECAUSE THE DESKTOP PICTURE WAS CHANGED"
end do_stuff

Mar 9, 2010 1:19 PM in response to handellphp

Objective-C sample


-(void)applicationActivity:(NSNotification *)notification
{
NSRunningApplication *app = [[notification userInfo] objectForKey:@"NSWorkspaceApplicationKey"];
if(app.localizedName isEqualToString:@"ScreenSaverEngine")
{
// Your code here
}
}
-(void)awakeFromNib
{
[[[NSWorkspace sharedWorkspace] notificationCenter]
addObserver:self
selector:@selector(applicationActivity:)
name:NSWorkspaceDidActivateApplicationNotification
object:nil];
}

Mar 9, 2010 3:30 PM in response to Craig.Williams

Sorry if this is a dumb question, but I'm not familiar with objective-C.

How does the code realize that the background has changed?
(Basically, I'm trying to avoid constantly polling the system to see if a particular value has changed, because that would use unnecessary resources.)

If instead the code waits for a system trigger already built into the OS, then you are a god-send and I'm definitely going to implement this. 🙂

-R

Mar 9, 2010 3:58 PM in response to handellphp

Your understanding/use of with timeout in incorrect.

with timeout tells AppleScript how long to wait for applications to execute the specified commands. Therefore in your example:

with timeout of 0 seconds
tell application "Finder" to set current_pic to desktop picture


You're saying 'wait indefinitely for the Finder to get the current desktop picture'. Under normal circumstances that task would take a few milliseconds, at worst, so setting a timeout doesn't make much sense. You're also checking the desktop picture twice per iteration, which is approximately double the amount of work you need to do.

Your script would be better written using an idle handler, like:

global old_pic

on run
tell application "Finder" to set old_pic to desktop picture as alias
end run

on idle
tell application "Finder" to set current_pic to desktop picture as alias
if current_pic is not old_pic then
display dialog "Desktop pattern is different"
set old_pic to current_pic
end if
return 10 -- check again in 10 seconds
end idle


In this way the desktop picture that's current when the script is launched is stored in a global variable. For each iteration of the idle handler the script gets the then-current desktop pattern and compares it against the original (so it only gets the desktop pattern once per iteration).
If they differ then the script posts a dialog (could be any action you want to take) and resets old_pic to reference the current desktop picture (so that next time around it compares the desktop to what we have now, not the original one when the script launched).
Finally the return 10 tells AppleScript to check again in 10 seconds (could be any time interval you like, depending on how soon you want to detect changes).

The ObjC solution is neater since it adds a hook into the system to call your code when the system environment changes. Not as clear/legible as AppleScript, of course, but it doesn't offer an even more elegant solution.

Mar 9, 2010 4:12 PM in response to Camelot

Camelot wrote:


The ObjC solution is neater since it adds a hook into the system to call your code when the system environment changes. Not as clear/legible as AppleScript, of course, but it doesn't offer an even more elegant solution.


Correct me if I'm wrong -- but I think you meant to say "it does offer a more elegant solution"?

At any rate, I'm sure the apple script will work. However, if I were to do that, I may as well use perl. 😉 I was looking for a not-so-crude way of catching a wallpaper change event.

P.S.
What is a hook, in Obj-C? I do know programming, just not familiar with this particular language.

Cheers,
-R

Mar 27, 2010 1:19 PM in response to ryanrhee90

hi everyone

check this app

http://developer.apple.com/mac/library/samplecode/EventMonitorTest/listing2.html

this app give u the ability to capture and look into systme events

BUTTTTT

it is not made specifically for desktop wallpaper change event

try to figure out this section of code

// get the event class
switch ( GetEventClass( inEvent ) )
{
case kEventClassKeyboard:
className = "Keyboard";
// get the keyboard event type

source code at http://developer.apple.com/mac/library/samplecode/EventMonitorTest/

i hope the GetEventClass( inEvent ) returns something in case of a wallpaper change

Inform me also when u figure this out.

Apr 16, 2010 12:05 AM in response to shakirzareen

Hello,

I'm glad I'm not the only one looking for this!

Your first link sounds cool, but is dead. 😟
Your second link is for 10.4 only. Unfortunately, I'm on the latest snow leopard (10.6.3).

Looking at the section of code you posted, I see that the 'event' is a keyboard event? I think this refers to a key-press event, so I don't know if that will be of much help.

Perhaps someone else could shed some light as to whether this is possible or not: I'd still love to execute things when the wallpaper changes while using OS X's built-in wallpaper changing function.

-R

Apr 17, 2010 4:16 AM in response to ryanrhee90

just as another example...
you would have to save this as an Applescript-Application with "stay open"-option checked.

global currentdesktoppicture

on run

tell application "Finder" to set currentdesktoppicture to desktop picture

end run

on idle

tell application "Finder"

if currentdesktoppicture ≠ desktop picture then

activate

set currentdesktoppicture to desktop picture

display dialog "Desktop Picture changed" giving up after 2

end if

end tell

return 1

end idle

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

Execute script on wallpaper change event

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.