Hooks: random wallpaper, panel on largest display

Bug #469114 reported by Toon Verwaest
10
This bug affects 1 person
Affects Status Importance Assigned to Milestone
disper
Triaged
Wishlist
Unassigned

Bug Description

Since gnome doesn't support wallpapers on multiple monitors it might be nice to let disper automatically generate and use multi-monitor wallpapers, for example from a randomly selected set of wallpapers from a directory with images. With imagemagick this is very easy to do in a few lines of code. I have my own ruby extension script over disper; but it might be useful for everybody using disper + gnome. Just an idea.

Tags: wishlist
Revision history for this message
Toon Verwaest (tverwaes) wrote :

Btw, this is what I do on my machine to fix my display. I set the gnome-bar on the largest display of the two and build a wallpaper which assumes the positions that disper -e gives them to be left/right with the external one on the right; and that there are only two monitors.

I guess for disper you will have to do a bit more magic but well... at least this works for me and my dualscreen doesn't look so gHorrible. Requires ruby and librmagick-ruby.

cheers,

require "RMagick"

# activate monitor
`disper -e`

DIR="#{ENV['HOME']}/.wallpaper"
WALLS=Dir.open(DIR).to_a.reject {|f| /^\./.match(f)}
OUTFILE = "#{DIR}/.wallpaper.jpg"
INFO = `disper -l`
LINES = INFO.to_a
SCREENS = LINES.count / 2

def getimage
    return "#{DIR}/#{WALLS[rand(WALLS.size)]}"
end

def resolution(id)
    line = LINES[id * 2 + 1]
    line =~ /.* ([0-9]+)x([0-9]+)/
    return $1.to_i, $2.to_i
end

def toolbarscreen(id)
    `gconftool-2 -t int --set /apps/panel/toplevels/top_panel_screen0/monitor #{id}`
end

if (SCREENS > 1)
    r1 = resolution(0)
    r2 = resolution(1)
    toolbarscreen(r1[0] < r2[0] ? 1:0)
    images = Magick::ImageList.new(getimage, getimage)
    images[0].crop_resized!(*r1)
    images[1].crop_resized!(*r2)
    images.append(false).write(OUTFILE)
else
    `cp #{getimage} #{OUTFILE}`
end

`gconftool-2 -t str --set /desktop/gnome/background/picture_filename #{OUTFILE}`

Revision history for this message
wvengen (wvengen) wrote :

Hi, nice idea, thanks! Its useful to have this script here for others to find.

In the future it may be nice to have a way to run user-defined commands on display change. This could be done in one of the following ways:
1. disper plugin system
2. dbus/udev/hal/xorg notification handler
3. display change daemon, separately or in something like
Ideally, the video card should post a system event on display change, and is picked up by one of the above. Something with dbus is probably a good idea (related to bug #364856 ).

Users who would really like to execute special actions on running disper (like changing the background image), please make it known here, so I can decide what to work on (time permitting).

wvengen (wvengen)
Changed in disper:
importance: Undecided → Wishlist
Revision history for this message
Michael Rooney (mrooney) wrote :

Having a hook sounds like an excellent idea for user scripts. One simple and usable approach I've seen is to check for the existence of a callback file and if so, execute it. So for example if ~/.disperCallback exists and is executable, run it. Then you could also ship some common scripts (such as switching gnome-panel to the largest screen like below, or the wallpaper one which can take a few arguments) somewhere like /usr/share/disper/scripts, and then all you have to do to enable them is throw each one you want in ~/.disperCallback.

Also, thanks for this great project, it is very excellent and works perfectly for my simple needs! I have a question but I'll ask it on LP Answers :)

Revision history for this message
Michael Rooney (mrooney) wrote :

I pushed a branch up at lp:~mrooney/disper/scriptable that simply calls a script at ~/.disperCallback if it exists, and passes it the disper action taken (such as list, extend, single) as the first argument. This allows for the beginnings of some cool stuff like shipping a set of useful scripts. Toon, if you don't mind, I'll break your script out into two, one for the wallpapers and one for the panel, and include them as well. As it happens, your scripts do exactly what I want, so thanks for them!

Revision history for this message
Michael Rooney (mrooney) wrote :

Okay, I updated my branch to include a scripts directory, included the broken out versions of Toon's ruby scripts in it, and updated the packaging to ship them in /usr/share/disper/scripts and depend on the necessary packages.

Now I have a ~/.disperCallback of:

#!/bin/sh
if [ "$1" = "extend" ]; then
    /usr/share/disper/scripts/move_panel_to_largest_display.rb
    /usr/share/disper/scripts/random_wallpaper.rb
fi

and it works!

The only issue I ran into was that if you run the wallpaper script after a "disper -s" or "disper -S" it still generates the split up version, but it ends up on one monitor of course. Ideally it would check if the second screen is actually enabled and if not, make it just one image of the correct resolution, or perhaps we need a "random_wallpaper_extend.rb" and "random_wallpaper_clone.rb".

Any thoughts on integrating this into trunk and/or the wallpaper script?

Revision history for this message
wvengen (wvengen) wrote :

Michael, thanks for your work! You made a good start and I'm thinking of a little more general plugin system. What about the following.

There are hook scripts in ~/.disper/hooks and /usr/share/disper/hooks. Each hook is either a program/shellscript, or a python script (identified by extension .py). Programs/shellscripts are executed as an external program, python scripts are executed within disper itself so as to easily access all the functionality.
Programs/shellscripts are run with the following variables set, with example values:
  # disper version
  DISPER_VERSION=0.2.3
  # log level: 0=quiet, 1=normal, 2=verbose
  DISPER_LOG_LEVEL=1
  # execution stage: prepare or switch. Only should act on "switch" usually (for future compatibility)
  DISPER_STAGE=switch
  # space-separated list of display id's that have output
  DISPER_DISPLAYS=DFP_0 CRT_0
  # one of: clone, left, right, top, bottom
  DISPER_LAYOUT=right
  # resolution and position for each display
  # should prbly be equal to xinerama info (xdpyinfo -ext XINERAMA)
  # you can easily get components in shellscript by temporarily changing IFS
  DISPER_RESOLUTION_DFP_0=800x600
  DISPER_POSITION_DFP_0=0,0
  DISPER_RESOLUTION_CRT_0=1024x768
  DISPER_POSITION_CRT_0=800,0
  # full bounding box resolution
  DISPER_BB_RESOLUTION=1824x768
All disper options are given to the hook command as well. For now the environment should be used to set hook configuration, but in the future maybe functionality might be included to add disper command-line parameters for hooks.

An extra disper parameter --hooks=foo,bar,blah activates the specified plugin.
The file ~/.disper/config has default command-line options (long names only, one per line, without dashes), this also enables one to activate a default set of hooks by including "hooks=foo,bar".

API for python hooks still to be determined.

So what would you think about this? Would it be convenient, not complete enough or too complex? Other comments?

Changed in disper:
assignee: nobody → wvengen (wvengen)
status: New → Confirmed
summary: - Gnome wallpaper
+ Hooks on display switch (gnome wallpaper)
Revision history for this message
Michael Rooney (mrooney) wrote : Re: Hooks on display switch (gnome wallpaper)

I like the idea of documenting and providing environment variables that a script can use, and as long as you can specify the default hooks in a file, that approach seems reasonable.

The ~/.disperCallback approach just seems like a very simple yet functional solution in that you can easily specify arbitrary code to execute including scripts, and have conditions based on the disper command.

Specifying hooks on the command line seems useful, but it seems like if a hook is common enough to want to do this a lot, maybe it should be integrated as a disper option (-w/--resize-wallpaper, -p/--move-panel for example). I imagine some core hooks would make sense as their own command line switch.

Revision history for this message
Toon Verwaest (tverwaes) wrote :

Cool that people are still looking at this!

I think the default /etc/profile.d strategy is kinda useful. If the script in a dir (like ~/.disper) is executable, it's executed, otherwise it's ignored. And for globally installed scripts you could indeed pass arguments or link the scripts in your local dir.

Revision history for this message
wvengen (wvengen) wrote :

To keep you posted, I just committed hook support to bzr trunk. Not yet completely finished, but probably ok for most use-cases. It'll take some more time to finish and test it until it is released.

Changed in disper:
status: Confirmed → In Progress
Revision history for this message
wvengen (wvengen) wrote :

Note to developers: still need to provide hooks for import/export. The idea is that at export, each callback can print lines that save state for the plugin. This is then exported as "plugin:<pluginname>:<pluginline>" (or something like that) in the export output. At import, for each line starting with "plugin:" it is passed to the related plugin so that it can restore its state.

Revision history for this message
wvengen (wvengen) wrote :

I'm planning to release disper 0.3.0 with hook functionality (currently in bzr trunk). This will _not_ yet work with import/export, nor will the location of each screen be available to hooks (DISPER_POSITION_XYZ). But it's really time for a new release. I do need to write some documentation though before it can be released.

Changed in disper:
milestone: none → 0.3.0
Revision history for this message
wvengen (wvengen) wrote :

If someone would like to (re)write the wallpaper-adaptation script in Python that would be great and serve as a good example hook (I'm not willing to introduce a ruby dependency just for this, sorry).

Revision history for this message
Toon Verwaest (tverwaes) wrote :

Cool!

Since in Ubuntu at least the wallpaper is now at least just displayed properly per-display I do not anymore generate combined wallpapers automatically on my system. I do still move the gnome-bar to the largest screen and change wallpaper to a random other wallpaper. I can write plugins in python that do just that.

Revision history for this message
wvengen (wvengen) wrote :

If you would like to, yes please! Please see refer to comment #6 and #11.

wvengen (wvengen)
summary: - Hooks on display switch (gnome wallpaper)
+ Hooks: random wallpaper, panel on largest display
Changed in disper:
milestone: 0.3.0 → none
wvengen (wvengen)
Changed in disper:
status: In Progress → Triaged
assignee: wvengen (wvengen) → nobody
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.