Programmatically changing wallpaper

Paul Johnson pauljohn32 at gmail.com
Tue May 29 19:33:31 CEST 2012


On Tue, May 29, 2012 at 11:36 AM, Zenwalker <shailesh.zenwalk at gmail.com> wrote:
> You can make a script of the command xfdesktop --reload and run it every
> interval of time as per your needs. I know its not the best solution.
>

I use compiz as the window manager and I have a script exactly like
this. It separately tells each workspace to change backgrounds.

You don't use compiz, but from the attached you should be able to
deduce what's going on. THere is one program that randomly selects an
image and puts it on a workspace (that's in Perl) and then a second
one that calls that script every now and then.

This changes backgrounds every 10minutes

#!/bin/bash
while i==1; do

pjcompizbackground.pl -w 1 -W 1 -d /usr/local/share/Backgrounds
pjcompizbackground.pl -w 2 -W 1 -d /usr/local/share/Backgrounds
pjcompizbackground.pl -w 3 -W 1 -d /usr/local/share/Backgrounds
pjcompizbackground.pl -w 4 -W 1 -d /usr/local/share/Backgrounds
pjcompizbackground.pl -w 5 -W 1  -d /usr/local/share/Backgrounds
pjcompizbackground.pl -w 6 -W 1  -d /usr/local/share/Backgrounds
pjcompizbackground.pl -w 7 -W 1  -d /usr/local/share/Backgrounds
pjcompizbackground.pl -w 8 -W 1  -d /usr/local/share/Backgrounds

sleep 10m

done


############

The script to select the backgrounds and tell compiz to use them is:



#!/usr/bin/perl


### Paul Johnson <pauljohn at ku.edu> 2008-11-21

### This Perl script will choose images at random from a directory structure
### and present them on the compiz backgrounds.  It works by running dbus
### commands in the shell and managing the answers (which are text strings).
### I'd like to learn how to use DBus.pm to do this, but am too
### slow-witted (so far).
###
### With the release of Ubuntu 8.1, the compiz framework management of
### wallpapers changed.  The wallpaper plugin is now included in the
### distribution, and the cube's management of backgrounds has been
### eliminated.  That necessitates some changes in this script.

#################################################################

### Quick Examples:

### ./pjcompizbackground.pl -d /usr/local/share/Backgrounds

### (That will try to reset all background images in your existing image array.
### If no image array exists, it should not do anything.)

### ./pjcompizbackground.pl -d /usr/local/share/Backgrounds -w 3 -p 2

### (That will try to set the 3rd workspace with a "2 page" (dual head) image.)

###  ./pjcompizbackground.pl -d /usr/local/share/Backgrounds -w 999
### (Hopefully 999 is larger than the number of workspaces you have. If so, the
### the script should notice you chose a number larger than the number
of existing
### workspaces, and it will try to put an image for each workspace.)


##################################################################
### More detailed explanation:



### Understand this about Compiz. The number of available background
### images can be different from the number of desktops. Compiz can
### have 10 workspaces (virtual desktops, sides of "cube", whatever)
### and it also has an array of background images, and the two numbers
### don't have to match.  If the array is only 2 images, but there are
### 10 workspaces, then the images are "recycled," used over and over
### again. If you have more images in the array than workspaces, then
### the extra ones are not used.


### The command line options are -d, -w, and -p. NO EQUAL SIGNS! Use
### like so

### ./pjcompizbackground.pl -d /usr/local/share/Backgrounds -w 3 -p 2

### The meanings of the options.

### -d

### which represents the top level of the directory structure where
### you want to search.  If you forget to specify, it will look in
### /usr/share/backgrounds.

### -w

### which indicates which, or how many workspaces, you want set.

### -w 0 Will cause the script to try to figure how many background
### -images you currently have set on workspaces and it will replace
### -them all.

### -w (any number smaller than the current number of workspace images)

### (such as -w 3) Will cause the script to scan your existing
### background images and replace the third one in the list.  If you
### currently only have 1 background image, and you tell it -w=5, it
### will just add one image to your array of images, so that will only
### affect workspace 2.

### -w (any number greater than your current number of workspaces)

### Will cause the script to try to figure out how many workspaces you
### are currently using in compiz and it will put new images on all of
### them.


### -p refers to the "page width" of your desired background.

### If it is left blank or set to 1 (with -p 1) , result is the same:
### 1 image per "workspace" p=2 is for dual head displays.  The
### program takes 2 images and uses ImageMagick to paste them
### together, side by side, and that double-wide "dual" image is sent
### to the background.  I just stash the images under /tmp, but it is
### easy to change that if you don't like it.

### So -p 2  means "treat as a double wide workspace, so
### put 2 images side by side".

### The -W option has been eliminated because in Ubuntu 8.1, there
### is no need for it.  All workspace background management is done
### by the wallpaper plugin.


use File::Find; #to get all files under mainDir
use Getopt::Std;  # command line processing


our ($opt_w, $opt_d, $opt_p, $opt_D);

getopts('p:w:d:W:s:') || die "Invalid argument\n";

if ($opt_w =~ /\D/) { die "w is not a digit";}

@images = ();

if ( $opt_w ) {
    $workspace = $opt_w;
}


sub process_file{
    $filename = $File::Find::name;
    if ( -f $filename ){
	push(@images, qq[$filename] );
    }
}


if ( $opt_d ) {
	$basedir = $opt_d;
    }else{
   $basedir = "/usr/share/backgrounds";
}

if ( $opt_p ) {
	$numpages = $opt_p;
}else{
    $numpages = 1;
}


find(\&process_file, $basedir);



srand;


sub
getMyImage {
    my $wspace = shift;
    my $chosenImage;

   print "getMyImage is working on workspace $wspace with $numpages images \n";

    if ($numpages <= 1){
	my $index=int(rand(@images));
	$chosenImage = qq^$images[$index]^;
	$chosenImage =~ s/\ ([;<>@\*\|`\&\$!#\(\)\[\]\{\}:'"])/\\$1/g;
    }else{
	my $index=int(rand(@images));
	my $index2 = int(rand(@images));
	my $j = 1;
	my $newfn = "/tmp/dual$wspace$j.jpg";
	### Don't want to step on pre-existing workspace image right away, may be
	### needed. So create new name now, and let the next runs clean out old images.
        ### Needed because of possible mismatch between Compiz
#bg_images and #workspaces
	### following will create dual11.jpg, dual12.jpg, or dual13.jpg, if
none exists.

	while ( (-e $newfn) && ($j <  4)){
	    ### if image exists, create a new filname.
	    my $mynewj = ($j % 3) + 1;
	    $newfn="/tmp/dual$wspace$mynewj.jpg";
	    $nextj = (($j+1) % 3 ) + 1;
	    $nextfn = "/tmp/dual$wspace$nextj.jpg";
	    # print "while: j = $j mynewj=$mynewj $newfn nextj=$nextj: $nextfn\n";
	    $j++;
	}
	
	if ( -e $nextfn ){
	    ###remove the oldest one. This makes room for the next iteration.
	    my $cmd1 = "rm $nextfn";
	    ###remove that old one, make open space in array for next time!
	    system $cmd1;
	    # print "remove nextfn=$nextfn";
	}
	
	$chosenImage = "$newfn";
	## print "getMyImage($wspace) selected $chosenImage\n";
	my $image1 = qq^$images[$index]^;
	my $image2 = qq^$images[$index2]^;
	$image1 =~ s/\ ([;<>@\*\|`&\$!#\(\)\[\]\{\}:'"])/\\$1/g;
	$image2 =~ s/\ ([;<>@\*\|`&\$!#\(\)\[\]\{\}:'"])/\\$1/g;


	my $commandString = qq^montage "$image1"  "$image2" -tile 2x1
-geometry 1280x1024+0+0 -background darkgreen $newfn^;

	system $commandString;
    }
    print "\n chosenImage" . $chosenImage . "\n" ;
    return $chosenImage;
}





### Figure out how many workspaces there are.

my $numWorkspacesGet =  `dbus-send --print-reply --type=method_call
--dest=org.freedesktop.compiz
/org/freedesktop/compiz/core/screen0/hsize
org.freedesktop.compiz.get`;

###Chop twice, remove new line then grab number workspaces
chop($numWorkspacesGet);
my $numWorkspaces = chop($numWorkspacesGet);

my $existingBG;


## The wallpaper plugin is in use, do this to get background list:
my $getBG = "dbus-send --print-reply --type=method_call
--dest=org.freedesktop.compiz
/org/freedesktop/compiz/wallpaper/screen0/bg_image
org.freedesktop.compiz.get";
$existingBG = `$getBG`;
print "\n You added -W 1, meaning you want to use Compiz  Wallpaper
plugin \n\n";



print "Pre-Existing background image array from Compiz: \n $existingBG";

print "existingBG[0] is: \n " . $existingBG[0] . "\n";

my @imageArray;

##while($existingBG =~ m/(\".*\")/g) {

while ($existingBG =~ m/(string.*)/g){
    my $img = $1;
    $img =~ s/string\ //;
#    $img =~ s/\ ([;<>@\*\|`&\$!#\(\)\[\]\{\}:'"])/\\$1/g;
    push @imageArray, $img;
}

print "Here is the image array that came From compiz \n";
print "@imageArray";
### Suppose $workspace > number of existing workspaces.
### You asked for more workspaces than you have, so that must
### means you want them all set:

if ( $workspace > $numWorkspaces){
    print "You want to reset All $numWorkspaces Workspaces: \n";
    for ($count=0; $count< $numWorkspaces; $count++){
	my $wspace = $count + 1;
	$imageArray[$count] = getMyImage($wspace);
#	print  "getMyImage: " .  $imageArray[$count]. "\n";
    }
    $myImages =  join ",", @imageArray;

## Don't want to do all workspaces?  Just replace all EXISTING
## images?   DO THIS!
} elsif ( $workspace == 0 ){

    print "You set workspace = 0, meaning you want to change " .
@imageArray . " existing images in the background array.\n";
    my $count = 0;
    foreach (@imageArray){
	my $wspace = $count + 1;
	$imageArray[$count] = getMyImage($wspace);
	$count++;
    }

    $myImages =  join ",", @imageArray;


}else{
    print "Resetting only the image on workspace: $workspace? OK!\n";

    if ($workspace > @imageArray) {
	print "You currently have $numWorkspaces workspaces, but only " .
@imageArray . " images set.\n";
	print "But you asked me to set the image on workspace $workspace\n";
	print "What the heck do you expect me to do?";
	print "We will just tack one on the end of your existing array.";
    }


    #print "\n Unchanged array is:" . $workspace ."array is: \n";
    #print "@imageArray";
    @imageArray[$workspace-1] = "\"" . getMyImage($workspace) . "\"";
    print "\n Changed Workspace Array :" . $workspace ."array is: \n";
    print "@imageArray" . "\n";
    $myImages =  join ",", @imageArray;
}

### 2011-12-30 Problem was compiz image array was getting too long
### Don't know why,
### Maybe push inserted extraneous elements into the image array.
###
while ( $#myImages > $numWorkspaces ) {
    pop(@myImages)
}

print "Number of Workspaces was " . $numWorkspaces . "\n";

### Whew. Done fiddling the image array. Now tell compiz to draw it.

my $commandString = qq[dbus-send --print-reply --type=method_call
--dest=org.freedesktop.compiz
/org/freedesktop/compiz/wallpaper/screen0/bg_image
org.freedesktop.compiz.set array:string:$myImages];

##    print "commandString: $commandString \n";
    system $commandString;



my $commandString = qq[ dbus-send --print-reply --type=method_call
--dest=org.freedesktop.compiz
/org/freedesktop/compiz/wallpaper/screen0/bg_image_pos
org.freedesktop.compiz.set array:int32:0,0,0,0,0,0,0,0  ];

system $commandString

######################################

Of course, your "commandString" part needs to be different because you
want to tell kdesktop what to do.  But the essence of it is the same.
Choose an image at random, tell whatever program to draw it on a
particular workspace.



-- 
Paul E. Johnson
Professor, Political Science    Assoc. Director
1541 Lilac Lane, Room 504     Center for Research Methods
University of Kansas               University of Kansas
http://pj.freefaculty.org            http://quant.ku.edu


More information about the Xfce mailing list