From ThorxWiki
Jump to: navigation, search

GNOME's Wallpaper Intelligently Set

GWIS has been rewritten and renamed to Wallsmart, though the logic below is still largely relevant.

This is the script that I use to set my GNOME wallpaper, after I became dissatisfied with the automatic changers that were available.

This script is cronnable, and attempts to intelligently handle images that are bigger, smaller, taller and wider than the display. By looking at relative sizes, aspect ratios, and edge colours, it will set the image to the appropriate type, and specify the background colours and gradient to match.


First up, select an image. That much is easy. Working out how to display it is... tricky.

First up, some terminology of size

Image is smaller than display in both dimensions
Image is taller, but width is unstated
Image is wider, but height is unstated
Image is both taller and wider

...and aspect

Image aspect is shorter than display aspect
Image aspect is thinner than display aspect
Image aspect matches display aspect!

So! If the image is smaller, then we test edges. If all are the same, we center and set background solid. Otherwise, we scale it.

If taller, wider or bigger, then we scale it. However, if the scaled-size is within 10%(?) of the display size (% of pixels), then we stretch/zoom (configurable?) instead. (thus within 10% either way: d_aspect*.909 < image aspect < d_aspect*1.1)

Finally, if the image is too small (say: scaling would require more than 3x(?) upscale, we tile it (or ignore it and restart?) instead

Next up, setting the background shading.

Shading is only applicable to centered and scaled images. So we detect the edge colours of the image so we know what we're working with.

Centered - we only have centered if we're setting a solid background. scaled - if the visible edges are the same, then we set solid. Otherwise, we set a gradient across from one display-edge edge to the other. (ie: if image is shorter, then horizontal-gradient. if thinner, then vertical gradient)

to put it another way, we can end up with:

  • wallpaper (tiled)
    • if image is _too_ small
  • centered (image center matches display center, no resizing)
    • image is smaller, and edges are 'framed'
  • scaled (resize to fit inside display, retaining aspect).
    • image is smaller
    • image is bigger/taller/wider outside the 10% distortion/loss limit
    • Set shading as solid if visible edges are the same, otherwise shade from the edge-edges (along the visible edge)
  • zoom (resize to fit display inside image, retaining aspect)
    • image is bigger/taller/wider within the 10% distortion/loss limit
  • stretch (resize to match display, ignoring aspect)
    • image is bigger/taller/wider within the 10% distortion/loss limit

Note: this is tuned currently for a single monitor. Multiple monitors are assumed to all be the same resolution, and we only look at monitor res. Multimonitor setups can have 'spanned' However, the logic for spanned is the same as that for 'centered/scaled' - just with the display size across the WHOLE display, not just per-monitor.

Implementation?'s quite a crude bash script, but basically works :)

Personal tools

meta navigation
More thorx