Page 1 of 1

Set Desktop Wallpaper

Posted: Thu Aug 15, 2013 12:32 pm
by mikejs
This is my first real stab at programming on a Mac. Some things I can find already on the forum and this is very useful.

One thing I'd like to do that I can't find already answered is - how to set the desktop wallpaper programmaticaly. I can generate the image (sized for the desktop resolution) and save it. I think I need to do something with CocoaMessage, NSWorkspace and setDesktopImageURL, but can't seem to translate the apple docs into working PB code. I get things like "Object does not respond to method "SetDesktopImageURL", which means I'm doing something fundamentally wrong somewhere.

Here's the apple docs on it:

http://developer.apple.com/library/mac/ ... ons:error:

Anyone got code that already does this kind of thing?

Re: Set Desktop Wallpaper

Posted: Fri Aug 16, 2013 7:51 am
by wilbert

Code: Select all

Path.s = "MyWallpaper.jpg"

Workspace = CocoaMessage(0, 0, "NSWorkspace sharedWorkspace")
Screen = CocoaMessage(0, 0, "NSScreen mainScreen")
URL = CocoaMessage(0, 0, "NSURL fileURLWithPath:$", @Path)
If CocoaMessage(0, Workspace, "setDesktopImageURL:", URL, "forScreen:", Screen, "options:", #nil, "error:", #nil)
  Debug "Wallpaper has been set"
EndIf

Re: Set Desktop Wallpaper

Posted: Mon Aug 19, 2013 10:53 am
by mikejs
Thanks, that works. :D

I'd got close (and then found a different way of doing it with AppleScript, but this is better), but didn't have the $s in the right places. Didn't know about #nil either. The $ clearly means something, but I'm not clear on what it's for. e.g. why "NSURL fileURLWithPath:$" but "setDesktopImageURL:" (I've seen "whatever:@" in other example code).

Is this a PB thing when doing Cocoa stuff, or should I be looking for docs on that on the Apple side of things?

Re: Set Desktop Wallpaper

Posted: Mon Aug 19, 2013 11:32 am
by wilbert
mikejs wrote:Is this a PB thing when doing Cocoa stuff, or should I be looking for docs on that on the Apple side of things?
It's a PB thing :)
This post (or the PB docs) explains it
http://www.purebasic.fr/english/viewtop ... 29#p386829
In short, @ is required to pass something that isn't an integer value (or pointer).
$ is for your own convenience since it converts a PB string into a NSString before passing it.
You could use other Cocoa functions to create a NSString yourself but using $ is much easier and works both when the code is compiled in ascii or unicode mode.

Re: Set Desktop Wallpaper

Posted: Mon Aug 19, 2013 11:52 am
by mikejs
Thanks for that, it's starting to make a bit more sense :D

Re: Set Desktop Wallpaper

Posted: Mon Aug 19, 2013 4:38 pm
by WilliamL
Wow, this is fun! I tried the example and it works great but now I have to go back and set the desktop back. :-)

Re: Set Desktop Wallpaper

Posted: Mon Aug 19, 2013 6:47 pm
by Shardik
WilliamL wrote: I tried the example and it works great but now I have to go back and set the desktop back. :-)
William, please try this one... :wink:

Code: Select all

Dim BackgroundImageURL(1)

Workspace = CocoaMessage(0, 0, "NSWorkspace sharedWorkspace")
Screen = CocoaMessage(0, 0, "NSScreen mainScreen")

; ----- Save URL of current background image
BackgroundImageURL(0) = CocoaMessage(0, Workspace, "desktopImageURLForScreen:", Screen)

; ----- Create URL of new background image
NewBackgroundImage$ =  #PB_Compiler_Home + "Examples/3D/Data/Textures/Terrain_Texture.jpg"
BackgroundImageURL(1) = CocoaMessage(0, 0, "NSURL fileURLWithPath:$", @NewBackgroundImage$)

If CocoaMessage(0, Workspace, "setDesktopImageURL:", BackgroundImageURL(1),
  "forScreen:", Screen, "options:", 0, "error:", 0)
  MessageRequester("Info", "Switch back to previous background.")
  ; ----- Restore previous background image
  CocoaMessage(0, Workspace, "setDesktopImageURL:", BackgroundImageURL(0),
    "forScreen:", Screen, "options:", 0, "error:", 0)
EndIf

Re: Set Desktop Wallpaper

Posted: Mon Aug 19, 2013 8:48 pm
by WilliamL
hey Shardik,

That works! It makes it a bit easier to play with the code without having to find the old background. :)

If anyone wants to play with the code they can use this to find their files:

Code: Select all

NewBackgroundImage$ =OpenFileRequester(Title$, DefaultFile$, "", 0)

Re: Set Desktop Wallpaper

Posted: Wed Jan 08, 2014 3:20 pm
by bbanelli
Greetings,
wilbert wrote:

Code: Select all

Path.s = "MyWallpaper.jpg"

Workspace = CocoaMessage(0, 0, "NSWorkspace sharedWorkspace")
Screen = CocoaMessage(0, 0, "NSScreen mainScreen")
URL = CocoaMessage(0, 0, "NSURL fileURLWithPath:$", @Path)
If CocoaMessage(0, Workspace, "setDesktopImageURL:", URL, "forScreen:", Screen, "options:", #nil, "error:", #nil)
  Debug "Wallpaper has been set"
EndIf
so, in case I'd like to change wallpapers on all (or just some) "virtual desktops" (added from Mission Control), I would have to use screen class method instead of mainScreen in NSSCreen class refference.

However, as far as I see from the documentation, that is, example, return value becomes array of items (probably screens?).

How can I iterate through those screens, that is, create a PureBasic object to hold such array of returned screens?