ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/perl/background
Revision: 1.44
Committed: Sun Jun 10 11:31:22 2012 UTC (11 years, 11 months ago) by root
Branch: MAIN
Changes since 1.43: +16 -0 lines
Log Message:
center

File Contents

# User Rev Content
1 root 1.1 #! perl
2    
3 root 1.16 #:META:X_RESOURCE:%.expr:string:background expression
4 root 1.33 #:META:X_RESOURCE:%.border.:boolean:respect the terminal border
5    
6 root 1.35 #TODO: once, rootalign
7    
8 root 1.41 =head1 NAME
9 root 1.33
10 root 1.41 background - manage terminal background
11    
12     =head1 SYNOPSIS
13 root 1.33
14 root 1.36 urxvt --background-expr 'background expression'
15     --background-border
16 root 1.33
17 root 1.41 =head1 DESCRIPTION
18 root 1.33
19 root 1.36 This extension manages the terminal background by creating a picture that
20     is behind the text, replacing the normal background colour.
21    
22     It does so by evaluating a Perl expression that I<calculates> the image on
23     the fly, for example, by grabbing the root background or loading a file.
24    
25     While the full power of Perl is available, the operators have been design
26     to be as simple as possible.
27    
28     For example, to load an image and scale it to the window size, you would
29     use:
30    
31     urxvt --background-expr 'scale load "/path/to/mybg.png"'
32    
33     Or specified as a X resource:
34    
35     URxvt.background-expr: scale load "/path/to/mybg.png"
36    
37 root 1.41 =head1 THEORY OF OPERATION
38 root 1.36
39     At startup, just before the window is mapped for the first time, the
40     expression is evaluated and must yield an image. The image is then
41     extended as necessary to cover the whole terminal window, and is set as a
42     background pixmap.
43    
44     If the image contains an alpha channel, then it will be used as-is in
45     visuals that support alpha channels (for example, for a compositing
46     manager). In other visuals, the terminal background colour will be used to
47     replace any transparency.
48    
49     When the expression relies, directly or indirectly, on the window size,
50     position, the root pixmap, or a timer, then it will be remembered. If not,
51     then it will be removed.
52    
53     If any of the parameters that the expression relies on changes (when the
54     window is moved or resized, its position or size changes; when the root
55     pixmap is replaced by another one the root background changes; or when the
56     timer elapses), then the expression will be evaluated again.
57    
58     For example, an expression such as C<scale load "$HOME/mybg.png"> scales the
59     image to the window size, so it relies on the window size and will
60     be reevaluated each time it is changed, but not when it moves for
61     example. That ensures that the picture always fills the terminal, even
62     after it's size changes.
63    
64 root 1.41 =head2 EXPRESSIONS
65 root 1.36
66     Expressions are normal Perl expressions, in fact, they are Perl blocks -
67     which means you could use multiple lines and statements:
68    
69     again 3600;
70     if (localtime now)[6]) {
71     return scale load "$HOME/weekday.png";
72     } else {
73     return scale load "$HOME/sunday.png";
74     }
75    
76     This expression gets evaluated once per hour. It will set F<sunday.png> as
77 root 1.39 background on Sundays, and F<weekday.png> on all other days.
78 root 1.36
79     Fortunately, we expect that most expressions will be much simpler, with
80     little Perl knowledge needed.
81    
82     Basically, you always start with a function that "generates" an image
83     object, such as C<load>, which loads an image from disk, or C<root>, which
84     returns the root window background image:
85    
86     load "$HOME/mypic.png"
87    
88     The path is usually specified as a quoted string (the exact rules can be
89     found in the L<perlop> manpage). The F<$HOME> at the beginning of the
90     string is expanded to the home directory.
91    
92     Then you prepend one or more modifiers or filtering expressions, such as
93     C<scale>:
94    
95     scale load "$HOME/mypic.png"
96    
97     Just like a mathematical expression with functions, you should read these
98     expressions from right to left, as the C<load> is evaluated first, and
99     its result becomes the argument to the C<scale> function.
100    
101     Many operators also allow some parameters preceding the input image
102     that modify its behaviour. For example, C<scale> without any additional
103     arguments scales the image to size of the terminal window. If you specify
104 root 1.43 an additional argument, it uses it as a scale factor (multiply by 100 to
105     get a percentage):
106 root 1.36
107 root 1.43 scale 2, load "$HOME/mypic.png"
108 root 1.36
109     This enlarges the image by a factor of 2 (200%). As you can see, C<scale>
110     has now two arguments, the C<200> and the C<load> expression, while
111     C<load> only has one argument. Arguments are separated from each other by
112     commas.
113    
114     Scale also accepts two arguments, which are then separate factors for both
115     horizontal and vertical dimensions. For example, this halves the image
116     width and doubles the image height:
117    
118 root 1.43 scale 0.5, 2, load "$HOME/mypic.png"
119 root 1.36
120 root 1.39 Other effects than scalign are also readily available, for exmaple, you can
121     tile the image to fill the whole window, instead of resizing it:
122    
123     tile load "$HOME/mypic.png"
124    
125     In fact, images returned by C<load> are in C<tile> mode by default, so the C<tile> operator
126     is kind of superfluous.
127    
128     Another common effect is to mirror the image, so that the same edges touch:
129    
130     mirror load "$HOME/mypic.png"
131    
132     This is also a typical background expression:
133    
134     rootalign root
135    
136     It first takes a snapshot of the screen background image, and then
137     moves it to the upper left corner of the screen - the result is
138     pseudo-transparency, as the image seems to be static while the window is
139     moved around.
140 root 1.36
141 root 1.41 =head2 CYCLES AND CACHING
142 root 1.36
143 root 1.39 As has been mentioned before, the expression might be evaluated multiple
144     times. Each time the expression is reevaluated, a new cycle is said to
145     have begun. Many operators cache their results till the next cycle.
146    
147     For example, the C<load> operator keeps a copy of the image. If it is
148     asked to load the same image on the next cycle it will not load it again,
149     but return the cached copy.
150    
151     This only works for one cycle though, so as long as you load the same
152     image every time, it will always be cached, but when you load a different
153     image, it will forget about the first one.
154    
155     This allows you to either speed things up by keeping multiple images in
156     memory, or comserve memory by loading images more often.
157    
158     For example, you can keep two images in memory and use a random one like
159     this:
160    
161     my $img1 = load "img1.png";
162     my $img2 = load "img2.png";
163     (0.5 > rand) ? $img1 : $img2
164    
165     Since both images are "loaded" every time the expression is evaluated,
166     they are always kept in memory. Contrast this version:
167    
168     my $path1 = "img1.png";
169     my $path2 = "img2.png";
170     load ((0.5 > rand) ? $path1 : $path2)
171    
172     Here, a path is selected randomly, and load is only called for one image,
173     so keeps only one image in memory. If, on the next evaluation, luck
174     decides to use the other path, then it will have to load that image again.
175 root 1.36
176 root 1.41 =head1 REFERENCE
177 root 1.33
178 root 1.41 =head2 COMMAND LINE SWITCHES
179 root 1.36
180     =over 4
181    
182     =item --background-expr perl-expression
183    
184     Specifies the Perl expression to evaluate.
185    
186     =item --background-border
187    
188     By default, the expression creates an image that fills the full window,
189     overwriting borders and any other areas, such as the scrollbar.
190    
191     Specifying this flag changes the behaviour, so that the image only
192     replaces the background of the character area.
193    
194     =back
195    
196 root 1.33 =cut
197 root 1.12
198 root 1.36 our $HOME;
199 root 1.33 our ($self, $old, $new);
200 root 1.29 our ($x, $y, $w, $h);
201 root 1.3
202 root 1.16 # enforce at least this interval between updates
203 root 1.10 our $MIN_INTERVAL = 1/100;
204 root 1.9
205 root 1.1 {
206     package urxvt::bgdsl; # background language
207    
208 root 1.43 use List::Util qw(min max sum shuffle);
209    
210 root 1.15 =head2 PROVIDERS/GENERATORS
211    
212 root 1.31 These functions provide an image, by loading it from disk, grabbing it
213 sf-exg 1.32 from the root screen or by simply generating it. They are used as starting
214 root 1.31 points to get an image you can play with.
215    
216 root 1.15 =over 4
217    
218     =item load $path
219    
220 root 1.29 Loads the image at the given C<$path>. The image is set to plane tiling
221     mode.
222    
223 root 1.31 Loaded images will be cached for one cycle.
224 root 1.29
225 root 1.15 =cut
226    
227 root 1.2 sub load($) {
228 root 1.1 my ($path) = @_;
229    
230 root 1.33 $new->{load}{$path} = $old->{load}{$path} || $self->new_img_from_file ($path);
231 root 1.1 }
232    
233 root 1.31 =item root
234    
235     Returns the root window pixmap, that is, hopefully, the background image
236     of your screen. The image is set to extend mode.
237    
238     This function makes your expression root sensitive, that means it will be
239     reevaluated when the bg image changes.
240    
241     =cut
242    
243 root 1.2 sub root() {
244 root 1.9 $new->{rootpmap_sensitive} = 1;
245 root 1.1 die "root op not supported, exg, we need you";
246     }
247    
248 root 1.31 =item solid $colour
249    
250     =item solid $width, $height, $colour
251    
252     Creates a new image and completely fills it with the given colour. The
253     image is set to tiling mode.
254    
255 root 1.40 If C<$width> and C<$height> are omitted, it creates a 1x1 image, which is
256 root 1.31 useful for solid backgrounds or for use in filtering effects.
257    
258     =cut
259    
260 root 1.42 sub solid($;$$) {
261 root 1.31 my $colour = pop;
262    
263 root 1.33 my $img = $self->new_img (urxvt::PictStandardARGB32, $_[0] || 1, $_[1] || 1);
264 root 1.31 $img->fill ($colour);
265 root 1.15 $img
266     }
267    
268     =back
269    
270 root 1.20 =head2 VARIABLES
271    
272 root 1.41 The following functions provide variable data such as the terminal window
273     dimensions. They are not (Perl-) variables, they jsut return stuff that
274     varies. Most of them make your expression sensitive to some events, for
275     example using C<TW> (terminal width) means your expression is evaluated
276     again when the terminal is resized.
277 root 1.31
278 root 1.20 =over 4
279    
280 root 1.31 =item TX
281    
282     =item TY
283    
284     Return the X and Y coordinates of the terminal window (the terminal
285     window is the full window by default, and the character area only when in
286     border-respect mode).
287    
288     Using these functions make your expression sensitive to window moves.
289    
290     These functions are mainly useful to align images to the root window.
291    
292     Example: load an image and align it so it looks as if anchored to the
293     background.
294    
295     move -TX, -TY, load "mybg.png"
296    
297     =item TW
298    
299     Return the width (C<TW>) and height (C<TH>) of the terminal window (the
300     terminal window is the full window by default, and the character area only
301     when in border-respect mode).
302    
303     Using these functions make your expression sensitive to window resizes.
304    
305     These functions are mainly useful to scale images, or to clip images to
306     the window size to conserve memory.
307    
308     Example: take the screen background, clip it to the window size, blur it a
309     bit, align it to the window position and use it as background.
310    
311     clip move -TX, -TY, blur 5, root
312    
313 root 1.20 =cut
314    
315 root 1.30 sub TX() { $new->{position_sensitive} = 1; $x }
316     sub TY() { $new->{position_sensitive} = 1; $y }
317     sub TW() { $new->{size_sensitive} = 1; $w }
318     sub TH() { $new->{size_sensitive} = 1; $h }
319 root 1.20
320 root 1.33 =item now
321    
322     Returns the current time as (fractional) seconds since the epoch.
323    
324     Using this expression does I<not> make your expression sensitive to time,
325     but the next two functions do.
326    
327     =item again $seconds
328    
329     When this function is used the expression will be reevaluated again in
330     C<$seconds> seconds.
331    
332     Example: load some image and rotate it according to the time of day (as if it were
333 root 1.36 the hour pointer of a clock). Update this image every minute.
334 root 1.33
335     again 60; rotate TW, TH, 50, 50, (now % 86400) * -720 / 86400, scale load "myclock.png"
336    
337     =item counter $seconds
338    
339     Like C<again>, but also returns an increasing counter value, starting at
340     0, which might be useful for some simple animation effects.
341    
342     =cut
343    
344 root 1.20 sub now() { urxvt::NOW }
345    
346     sub again($) {
347     $new->{again} = $_[0];
348     }
349    
350     sub counter($) {
351     $new->{again} = $_[0];
352 root 1.33 $self->{counter} + 0
353 root 1.20 }
354    
355     =back
356    
357 root 1.28 =head2 TILING MODES
358    
359     The following operators modify the tiling mode of an image, that is, the
360     way that pixels outside the image area are painted when the image is used.
361 root 1.15
362     =over 4
363    
364 root 1.28 =item tile $img
365    
366     Tiles the whole plane with the image and returns this new image - or in
367     other words, it returns a copy of the image in plane tiling mode.
368    
369 root 1.34 Example: load an image and tile it over the background, without
370     resizing. The C<tile> call is superfluous because C<load> already defaults
371     to tiling mode.
372    
373     tile load "mybg.png"
374    
375 root 1.28 =item mirror $img
376    
377     Similar to tile, but reflects the image each time it uses a new copy, so
378     that top edges always touch top edges, right edges always touch right
379     edges and so on (with normal tiling, left edges always touch right edges
380     and top always touch bottom edges).
381    
382 root 1.36 Example: load an image and mirror it over the background, avoiding sharp
383 root 1.34 edges at the image borders at the expense of mirroring the image itself
384    
385     mirror load "mybg.png"
386    
387 root 1.28 =item pad $img
388    
389     Takes an image and modifies it so that all pixels outside the image area
390     become transparent. This mode is most useful when you want to place an
391     image over another image or the background colour while leaving all
392     background pixels outside the image unchanged.
393    
394 root 1.36 Example: load an image and display it in the upper left corner. The rest
395 root 1.34 of the space is left "empty" (transparent or wahtever your compisotr does
396     in alpha mode, else background colour).
397    
398     pad load "mybg.png"
399    
400 root 1.28 =item extend $img
401    
402     Extends the image over the whole plane, using the closest pixel in the
403     area outside the image. This mode is mostly useful when you more complex
404     filtering operations and want the pixels outside the image to have the
405     same values as the pixels near the edge.
406    
407 root 1.34 Example: just for curiosity, how does this pixel extension stuff work?
408    
409     extend move 50, 50, load "mybg.png"
410    
411 root 1.15 =cut
412    
413 root 1.28 sub pad($) {
414     my $img = $_[0]->clone;
415     $img->repeat_mode (urxvt::RepeatNone);
416     $img
417     }
418    
419     sub tile($) {
420     my $img = $_[0]->clone;
421     $img->repeat_mode (urxvt::RepeatNormal);
422     $img
423     }
424    
425     sub mirror($) {
426     my $img = $_[0]->clone;
427     $img->repeat_mode (urxvt::RepeatReflect);
428     $img
429     }
430 root 1.4
431 root 1.28 sub extend($) {
432 root 1.24 my $img = $_[0]->clone;
433 root 1.28 $img->repeat_mode (urxvt::RepeatPad);
434 root 1.24 $img
435     }
436    
437 root 1.28 =back
438    
439     =head2 PIXEL OPERATORS
440    
441     The following operators modify the image pixels in various ways.
442    
443     =over 4
444    
445     =item clone $img
446    
447     Returns an exact copy of the image.
448    
449     =cut
450    
451     sub clone($) {
452     $_[0]->clone
453     }
454    
455     =item clip $img
456    
457     =item clip $width, $height, $img
458    
459     =item clip $x, $y, $width, $height, $img
460    
461     Clips an image to the given rectangle. If the rectangle is outside the
462     image area (e.g. when C<$x> or C<$y> are negative) or the rectangle is
463     larger than the image, then the tiling mode defines how the extra pixels
464     will be filled.
465    
466     If C<$x> an C<$y> are missing, then C<0> is assumed for both.
467    
468     If C<$width> and C<$height> are missing, then the window size will be
469     assumed.
470    
471     Example: load an image, blur it, and clip it to the window size to save
472     memory.
473    
474     clip blur 10, load "mybg.png"
475    
476     =cut
477    
478 root 1.20 sub clip($;$$;$$) {
479 root 1.7 my $img = pop;
480 root 1.30 my $h = pop || TH;
481     my $w = pop || TW;
482 root 1.21 $img->sub_rect ($_[0], $_[1], $w, $h)
483 root 1.4 }
484    
485 root 1.28 =item scale $img
486    
487 root 1.43 =item scale $size_factor, $img
488 root 1.28
489 root 1.43 =item scale $width_factor, $height_factor, $img
490 root 1.28
491 root 1.43 Scales the image by the given factors in horizontal
492     (C<$width>) and vertical (C<$height>) direction.
493 root 1.28
494 root 1.43 If only one factor is give, it is used for both directions.
495 root 1.28
496 root 1.43 If no factors are given, scales the image to the window size without
497 root 1.28 keeping aspect.
498    
499     =item resize $width, $height, $img
500    
501     Resizes the image to exactly C<$width> times C<$height> pixels.
502    
503 root 1.43 =item fit $img
504    
505     =item fit $width, $height, $img
506    
507     Fits the image into the given C<$width> and C<$height> without changing
508     aspect, or the terminal size. That means it will be shrunk or grown until
509     the whole image fits into the given area, possibly leaving borders.
510    
511     =item cover $img
512    
513     =item cover $width, $height, $img
514    
515     Similar to C<fit>, but shrinks or grows until all of the area is covered
516     by the image, so instead of potentially leaving borders, it will cut off
517     image data that doesn't fit.
518    
519 root 1.28 =cut
520    
521 root 1.33 sub scale($;$;$) {
522 root 1.28 my $img = pop;
523    
524 root 1.43 @_ == 2 ? $img->scale ($_[0] * $img->w, $_[1] * $img->h)
525     : @_ ? $img->scale ($_[0] * $img->w, $_[0] * $img->h)
526 root 1.30 : $img->scale (TW, TH)
527 root 1.28 }
528    
529 root 1.2 sub resize($$$) {
530 root 1.7 my $img = pop;
531     $img->scale ($_[0], $_[1])
532 root 1.1 }
533    
534 root 1.43 sub fit($;$$) {
535     my $img = pop;
536     my $w = ($_[0] || TW) / $img->w;
537     my $h = ($_[1] || TH) / $img->h;
538     scale +(min $w, $h), $img
539     }
540    
541     sub cover($;$$) {
542     my $img = pop;
543     my $w = ($_[0] || TW) / $img->w;
544     my $h = ($_[1] || TH) / $img->h;
545     scale +(max $w, $h), $img
546     }
547    
548 root 1.36 =item move $dx, $dy, $img
549    
550     Moves the image by C<$dx> pixels in the horizontal, and C<$dy> pixels in
551     the vertical.
552    
553     Example: move the image right by 20 pixels and down by 30.
554    
555     move 20, 30, ...
556    
557 root 1.44 =item center $img
558    
559     =item center $width, $height, $img
560    
561     Centers the image, i.e. the center of the image is moved to the center of
562     the terminal window (or the box specified by C<$width> and C<$height> if
563     given).
564    
565 root 1.36 =item rootalign $img
566    
567     Moves the image so that it appears glued to the screen as opposed to the
568     window. This gives the illusion of a larger area behind the window. It is
569     exactly equivalent to C<move -TX, -TY>, that is, it moves the image to the
570     top left of the screen.
571    
572     Example: load a background image, put it in mirror mode and root align it.
573    
574     rootalign mirror load "mybg.png"
575    
576     Example: take the screen background and align it, giving the illusion of
577     transparency as long as the window isn't in front of other windows.
578    
579     rootalign root
580    
581     =cut
582    
583 root 1.7 sub move($$;$) {
584 root 1.20 my $img = pop->clone;
585     $img->move ($_[0], $_[1]);
586     $img
587 root 1.1 }
588    
589 root 1.44 sub center($;$$) {
590     my $img = pop;
591     my $w = $_[0] || TW;
592     my $h = $_[0] || TH;
593    
594     move 0.5 * ($w - $img->w), 0.5 * ($h - $img->h), $img
595     }
596    
597 root 1.36 sub rootalign($) {
598     move -TX, -TY, $_[0]
599 root 1.1 }
600    
601 root 1.36 =item contrast $factor, $img
602    
603     =item contrast $r, $g, $b, $img
604    
605     =item contrast $r, $g, $b, $a, $img
606    
607     Adjusts the I<contrast> of an image.
608    
609 root 1.38 #TODO#
610    
611 root 1.36 =item brightness $factor, $img
612    
613     =item brightness $r, $g, $b, $img
614    
615     =item brightness $r, $g, $b, $a, $img
616    
617 root 1.38 Adjusts the brightness of an image.
618    
619 root 1.36 =cut
620 root 1.1
621 root 1.2 sub contrast($$;$$;$) {
622 root 1.7 my $img = pop;
623     my ($r, $g, $b, $a) = @_;
624 root 1.4
625 root 1.1 ($g, $b) = ($r, $r) if @_ < 4;
626     $a = 1 if @_ < 5;
627 root 1.4
628 root 1.1 $img = $img->clone;
629 root 1.37 $img->contrast ($r, $g, $b, $a);
630 root 1.1 $img
631     }
632    
633 root 1.2 sub brightness($$;$$;$) {
634 root 1.7 my $img = pop;
635     my ($r, $g, $b, $a) = @_;
636 root 1.4
637 root 1.1 ($g, $b) = ($r, $r) if @_ < 4;
638     $a = 1 if @_ < 5;
639 root 1.4
640 root 1.1 $img = $img->clone;
641     $img->brightness ($r, $g, $b, $a);
642     $img
643     }
644    
645 root 1.38 =item blur $radius, $img
646    
647     =item blur $radius_horz, $radius_vert, $img
648    
649     Gaussian-blurs the image with (roughly) C<$radius> pixel radius. The radii
650     can also be specified separately.
651    
652 root 1.39 Blurring is often I<very> slow, at least compared or other
653     operators. Larger blur radii are slower than smaller ones, too, so if you
654     don't want to freeze your screen for long times, start experimenting with
655     low values for radius (<5).
656    
657 root 1.38 =cut
658    
659 root 1.36 sub blur($$;$) {
660     my $img = pop;
661     $img->blur ($_[0], @_ >= 2 ? $_[1] : $_[0])
662     }
663    
664 root 1.38 =item rotate $new_width, $new_height, $center_x, $center_y, $degrees
665    
666     Rotates the image by C<$degrees> degrees, counter-clockwise, around the
667 root 1.43 pointer at C<$center_x> and C<$center_y> (specified as factor of image
668 root 1.38 width/height), generating a new image with width C<$new_width> and height
669     C<$new_height>.
670    
671     #TODO# new width, height, maybe more operators?
672    
673     Example: rotate the image by 90 degrees
674    
675     =cut
676    
677 root 1.36 sub rotate($$$$$$) {
678     my $img = pop;
679     $img->rotate (
680     $_[0],
681     $_[1],
682 root 1.43 $_[2] * $img->w,
683     $_[3] * $img->h,
684 root 1.36 $_[4] * (3.14159265 / 180),
685     )
686     }
687    
688 root 1.15 =back
689    
690     =cut
691    
692 root 1.1 }
693    
694     sub parse_expr {
695     my $expr = eval "sub {\npackage urxvt::bgdsl;\n#line 0 'background expression'\n$_[0]\n}";
696     die if $@;
697     $expr
698     }
699    
700     # compiles a parsed expression
701     sub set_expr {
702     my ($self, $expr) = @_;
703    
704     $self->{expr} = $expr;
705     $self->recalculate;
706     }
707    
708     # evaluate the current bg expression
709     sub recalculate {
710 root 1.33 my ($arg_self) = @_;
711 root 1.1
712 root 1.10 # rate limit evaluation
713    
714 root 1.33 if ($arg_self->{next_refresh} > urxvt::NOW) {
715     $arg_self->{next_refresh_timer} = urxvt::timer->new->after ($arg_self->{next_refresh} - urxvt::NOW)->cb (sub {
716     $arg_self->recalculate;
717 root 1.9 });
718 root 1.12 return;
719 root 1.9 }
720    
721 root 1.33 $arg_self->{next_refresh} = urxvt::NOW + $MIN_INTERVAL;
722 root 1.9
723 root 1.10 # set environment to evaluate user expression
724 root 1.6
725 root 1.33 local $self = $arg_self;
726 root 1.1
727 root 1.36 local $HOME = $ENV{HOME};
728 root 1.3 local $old = $self->{state};
729     local $new = my $state = $self->{state} = {};
730 root 1.1
731 root 1.29 ($x, $y, $w, $h) =
732 root 1.33 $self->background_geometry ($self->{border});
733 root 1.22
734 root 1.10 # evaluate user expression
735    
736 root 1.1 my $img = eval { $self->{expr}->() };
737     warn $@ if $@;#d#
738 root 1.15 die if !UNIVERSAL::isa $img, "urxvt::img";
739 root 1.1
740 root 1.34 $state->{size_sensitive} = 1
741     if $img->repeat_mode != urxvt::RepeatNormal;
742    
743 root 1.10 # if the expression is sensitive to external events, prepare reevaluation then
744    
745 root 1.2 my $repeat;
746    
747 root 1.1 if (my $again = $state->{again}) {
748 root 1.2 $repeat = 1;
749 root 1.35 my $self = $self;
750 root 1.6 $state->{timer} = $again == $old->{again}
751     ? $old->{timer}
752 root 1.7 : urxvt::timer->new->after ($again)->interval ($again)->cb (sub {
753     ++$self->{counter};
754     $self->recalculate
755     });
756 root 1.1 }
757    
758 root 1.2 if (delete $state->{position_sensitive}) {
759     $repeat = 1;
760     $self->enable (position_change => sub { $_[0]->recalculate });
761     } else {
762     $self->disable ("position_change");
763     }
764    
765     if (delete $state->{size_sensitive}) {
766     $repeat = 1;
767     $self->enable (size_change => sub { $_[0]->recalculate });
768     } else {
769     $self->disable ("size_change");
770     }
771    
772 root 1.9 if (delete $state->{rootpmap_sensitive}) {
773     $repeat = 1;
774     $self->enable (rootpmap_change => sub { $_[0]->recalculate });
775     } else {
776     $self->disable ("rootpmap_change");
777     }
778    
779 root 1.10 # clear stuff we no longer need
780    
781 root 1.6 %$old = ();
782    
783 root 1.5 unless ($repeat) {
784     delete $self->{state};
785     delete $self->{expr};
786     }
787    
788 root 1.34 # set background pixmap
789 root 1.1
790 root 1.33 $self->set_background ($img, $self->{border});
791 root 1.1 $self->scr_recolour (0);
792     $self->want_refresh;
793     }
794    
795     sub on_start {
796     my ($self) = @_;
797    
798 root 1.33 my $expr = $self->x_resource ("background.expr")
799     or return;
800    
801     $self->set_expr (parse_expr $expr);
802     $self->{border} = $self->x_resource_boolean ("background.border");
803 root 1.1
804     ()
805     }
806