#! perl
#:META:RESOURCE:%.expr:string:background expression
#:META:RESOURCE:%.border:boolean:respect the terminal border
#:META:RESOURCE:%.interval:seconds:minimum time between updates
#:META:RESOURCE:pixmap:file[;geom]:set image as background
#:META:RESOURCE:backgroundPixmap:file[;geom]:set image as background
#:META:RESOURCE:tr:boolean:set root pixmap as background
#:META:RESOURCE:transparent:boolean:set root pixmap as background
#:META:RESOURCE:tint:color:tint background with color
#:META:RESOURCE:tintColor:color:tint background with color
#:META:RESOURCE:sh:number:shade background by number %
#:META:RESOURCE:shading:number:shade background by number %
#:META:RESOURCE:blr:HxV:gaussian-blur background with radii
#:META:RESOURCE:blurRadius:HxV:gaussian-blur background with radii
=head1 NAME
background - manage terminal background
=head1 SYNOPSIS
urxvt --background-expr 'background expression'
--background-border
--background-interval seconds
=head1 QUICK AND DIRTY CHEAT SHEET
Just load a random jpeg image and tile the background with it without
scaling or anything else:
load "/path/to/img.jpg"
The same, but use mirroring/reflection instead of tiling:
mirror load "/path/to/img.jpg"
Load an image and scale it to exactly fill the terminal window:
scale keep { load "/path/to/img.jpg" }
Implement pseudo-transparency by using a suitably-aligned root pixmap
as window background:
rootalign root
Likewise, but keep a blurred copy:
rootalign keep { blur 10, root }
=head1 DESCRIPTION
This extension manages the terminal background by creating a picture that
is behind the text, replacing the normal background colour.
It does so by evaluating a Perl expression that I<calculates> the image on
the fly, for example, by grabbing the root background or loading a file.
While the full power of Perl is available, the operators have been design
to be as simple as possible.
For example, to load an image and scale it to the window size, you would
use:
urxvt --background-expr 'scale keep { load "/path/to/mybg.png" }'
Or specified as a X resource:
URxvt.background.expr: scale keep { load "/path/to/mybg.png" }
=head1 THEORY OF OPERATION
At startup, just before the window is mapped for the first time, the
expression is evaluated and must yield an image. The image is then
extended as necessary to cover the whole terminal window, and is set as a
background pixmap.
If the image contains an alpha channel, then it will be used as-is in
visuals that support alpha channels (for example, for a compositing
manager). In other visuals, the terminal background colour will be used to
replace any transparency.
When the expression relies, directly or indirectly, on the window size,
position, the root pixmap, or a timer, then it will be remembered. If not,
then it will be removed.
If any of the parameters that the expression relies on changes (when the
window is moved or resized, its position or size changes; when the root
pixmap is replaced by another one the root background changes; or when the
timer elapses), then the expression will be evaluated again.
For example, an expression such as C<scale keep { load "$HOME/mybg.png"
}> scales the image to the window size, so it relies on the window size
and will be reevaluated each time it is changed, but not when it moves for
example. That ensures that the picture always fills the terminal, even
after its size changes.
=head2 EXPRESSIONS
Expressions are normal Perl expressions, in fact, they are Perl blocks -
which means you could use multiple lines and statements:
scale keep {
again 3600;
if (localtime now)[6]) {
return load "$HOME/weekday.png";
} else {
return load "$HOME/sunday.png";
}
}
This inner expression is evaluated once per hour (and whenever the
terminal window is resized). It sets F<sunday.png> as background on
Sundays, and F<weekday.png> on all other days.
Fortunately, we expect that most expressions will be much simpler, with
little Perl knowledge needed.
Basically, you always start with a function that "generates" an image
object, such as C<load>, which loads an image from disk, or C<root>, which
returns the root window background image:
load "$HOME/mypic.png"
The path is usually specified as a quoted string (the exact rules can be
found in the L<perlop> manpage). The F<$HOME> at the beginning of the
string is expanded to the home directory.
Then you prepend one or more modifiers or filtering expressions, such as
C<scale>:
scale load "$HOME/mypic.png"
Just like a mathematical expression with functions, you should read these
expressions from right to left, as the C<load> is evaluated first, and
its result becomes the argument to the C<scale> function.
Many operators also allow some parameters preceding the input image
that modify its behaviour. For example, C<scale> without any additional
arguments scales the image to size of the terminal window. If you specify
an additional argument, it uses it as a scale factor (multiply by 100 to
get a percentage):
scale 2, load "$HOME/mypic.png"
This enlarges the image by a factor of 2 (200%). As you can see, C<scale>
has now two arguments, the C<2> and the C<load> expression, while
C<load> only has one argument. Arguments are separated from each other by
commas.
Scale also accepts two arguments, which are then separate factors for both
horizontal and vertical dimensions. For example, this halves the image
width and doubles the image height:
scale 0.5, 2, load "$HOME/mypic.png"
IF you try out these expressions, you might suffer from some sluggishness,
because each time the terminal is resized, it loads the PNG image again
and scales it. Scaling is usually fast (and unavoidable), but loading the
image can be quite time consuming. This is where C<keep> comes in handy:
scale 0.5, 2, keep { load "$HOME/mypic.png" }
The C<keep> operator executes all the statements inside the braces only
once, or when it thinks the outcome might change. In other cases it
returns the last value computed by the brace block.
This means that the C<load> is only executed once, which makes it much
faster, but also means that more memory is being used, because the loaded
image must be kept in memory at all times. In this expression, the
trade-off is likely worth it.
But back to effects: Other effects than scaling are also readily
available, for example, you can tile the image to fill the whole window,
instead of resizing it:
tile keep { load "$HOME/mypic.png" }
In fact, images returned by C<load> are in C<tile> mode by default, so the
C<tile> operator is kind of superfluous.
Another common effect is to mirror the image, so that the same edges
touch:
mirror keep { load "$HOME/mypic.png" }
Another common background expression is:
rootalign root
This one first takes a snapshot of the screen background image, and then
moves it to the upper left corner of the screen (as opposed to the upper
left corner of the terminal window)- the result is pseudo-transparency:
the image seems to be static while the window is moved around.
=head2 COLOUR SPECIFICATIONS
Whenever an operator expects a "
|