Set Desktop Wallpaper

Mac OSX specific forum
mikejs
Enthusiast
Enthusiast
Posts: 175
Joined: Thu Oct 21, 2010 9:46 pm

Set Desktop Wallpaper

Post 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?
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Set Desktop Wallpaper

Post 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
Windows (x64)
Raspberry Pi OS (Arm64)
mikejs
Enthusiast
Enthusiast
Posts: 175
Joined: Thu Oct 21, 2010 9:46 pm

Re: Set Desktop Wallpaper

Post 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?
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Set Desktop Wallpaper

Post 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.
Windows (x64)
Raspberry Pi OS (Arm64)
mikejs
Enthusiast
Enthusiast
Posts: 175
Joined: Thu Oct 21, 2010 9:46 pm

Re: Set Desktop Wallpaper

Post by mikejs »

Thanks for that, it's starting to make a bit more sense :D
WilliamL
Addict
Addict
Posts: 1252
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: Set Desktop Wallpaper

Post 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. :-)
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Set Desktop Wallpaper

Post 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
WilliamL
Addict
Addict
Posts: 1252
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: Set Desktop Wallpaper

Post 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)
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
User avatar
bbanelli
Enthusiast
Enthusiast
Posts: 544
Joined: Tue May 28, 2013 10:51 pm
Location: Europe
Contact:

Re: Set Desktop Wallpaper

Post 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?
"If you lie to the compiler, it will get its revenge."
Henry Spencer
https://www.pci-z.com/
Post Reply