--- rxvt-unicode/src/perl/background 2019/09/17 18:17:14 1.97 +++ rxvt-unicode/src/perl/background 2022/11/29 04:44:27 1.106 @@ -13,6 +13,8 @@ #: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 +#:META:OSC:20:change/query background image +#:META:OSC:705:change transparent background tint colour =head1 NAME @@ -26,8 +28,8 @@ =head1 QUICK AND DIRTY CHEAT SHEET -Just load a random jpeg image and tile the background with it without -scaling or anything else: +Load a random jpeg image and tile the background with it without scaling +or anything else: load "/path/to/img.jpg" @@ -56,8 +58,8 @@ It does so by evaluating a Perl expression that I 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. +While the full power of Perl is available, the operators have been +designed to be as simple as possible. For example, to load an image and scale it to the window size, you would use: @@ -261,7 +263,7 @@ =head2 COMMAND LINE SWITCHES -=over 4 +=over =item --background-expr perl-expression @@ -312,7 +314,7 @@ from the root screen or by simply generating it. They are used as starting points to get an image you can play with. -=over 4 +=over =item load $path @@ -441,7 +443,7 @@ The following operators modify the tiling mode of an image, that is, the way that pixels outside the image area are painted when the image is used. -=over 4 +=over =item tile $img @@ -526,7 +528,7 @@ example using C (terminal width) means your expression is evaluated again when the terminal is resized. -=over 4 +=over =item TX @@ -629,7 +631,7 @@ The following operators modify the shape, size or position of the image. -=over 4 +=over =item clip $img @@ -826,7 +828,7 @@ The following operators change the pixels of the image. -=over 4 +=over =item tint $color, $img @@ -986,7 +988,7 @@ if FOCUS; my $fade = @_ >= 1 ? $_[0] : defined $self->resource ("fade") ? $self->resource ("fade") * 0.01 : 0; - my $color = @_ >= 2 ? $_[1] : $self->resource ("color+" . urxvt::Color_fade); + my $color = @_ >= 2 ? $_[1] : $self->resource ("color+" . &urxvt::Color_fade ()); # Color_fade not always available $img = $img->tint ($color) if $color ne "rgb:00/00/00"; $img = $img->muladd (1 - $fade, 0) if $fade; @@ -1001,7 +1003,7 @@ Anything that didn't fit any of the other categories, even after applying force and closing our eyes. -=over 4 +=over =item keep { ... } @@ -1044,7 +1046,7 @@ =head2 OPTIONS AND RESOURCES -=over 4 +=over =item B<-pixmap> I @@ -1056,7 +1058,7 @@ command line option, as C<;> is usually a metacharacter in shells. Supported operations are: -=over 4 +=over =item B @@ -1083,7 +1085,7 @@ Alternatively, a predefined set of templates can be used to achieve the most common setups: -=over 4 +=over =item B @@ -1151,7 +1153,14 @@ =head2 OSC sequences -=over 4 +This extension will react to the following OSC sequences. Note that +this extension will not be autoloaded when these are used currently, +so to make urxvt recognize them, you have to enable the C +extension. One way to achieve that is to use the C<--background-expr ''> +command line argument or by specifying an empty C> +resource. + +=over =item B<< C >> Change transparent background tint colour to B<< C >>. @@ -1159,7 +1168,7 @@ parameters: the value of B<< C >> can be one of the following commands: -=over 4 +=over =item B<< C >> @@ -1216,13 +1225,23 @@ } sub parse_expr { - my $expr = eval - "sub {\n" - . "package urxvt::bgdsl;\n" - . "#line 0 'background expression'\n" - . "$_[0]\n" - . "}"; - die if $@; + my ($expr) = @_; + + # an empty expression is valid and represents the default background + if ($expr !~ /\S/) { + $expr = sub { + undef + }; + } else { + $expr = eval + "sub {\n" + . "package urxvt::bgdsl;\n" + . "#line 0 'background expression'\n" + . "$expr\n" + . "}"; + die if $@; + } + $expr } @@ -1305,7 +1324,7 @@ $arg_self->{next_refresh} = urxvt::NOW + $MIN_INTERVAL; unless ($arg_self->has_render) { - warn "background extension needs RENDER extension 0.10 or higher, ignoring background-expr.\n"; + warn "background extension needs RENDER extension 0.11 or higher, ignoring background-expr.\n"; return; } @@ -1323,27 +1342,33 @@ my @img = eval { $self->{expr}->() }; die $@ if $@; die "background-expr did not return anything.\n" unless @img; - die "background-expr: expected image(s), got something else.\n" - if grep { !UNIVERSAL::isa $_, "urxvt::img" } @img; - my $img = urxvt::bgdsl::merge @img; + if ($img[0]) { + die "background-expr: expected image(s), got something else.\n" + if grep { !UNIVERSAL::isa $_, "urxvt::img" } @img; - $frame->[FR_AGAIN]{size} = 1 - if $img->repeat_mode != urxvt::RepeatNormal; + my $img = urxvt::bgdsl::merge @img; - # if the expression is sensitive to external events, prepare reevaluation then - $self->compile_frame ($frame, sub { $arg_self->recalculate }); + $frame->[urxvt::bgdsl::FR_AGAIN]{size} = 1 + if $img->repeat_mode != urxvt::RepeatNormal; - # clear stuff we no longer need + # if the expression is sensitive to external events, prepare reevaluation then + $self->compile_frame ($frame, sub { $arg_self->recalculate }); + + # clear stuff we no longer need # unless (%{ $frame->[FR_STATE] }) { # delete $self->{state}; # delete $self->{expr}; # } - # set background pixmap + # set background pixmap + + $self->set_background ($img, $self->{border}); + } else { + $self->clr_background; + } - $self->set_background ($img, $self->{border}); $self->scr_recolor (0); $self->want_refresh; } @@ -1429,7 +1454,7 @@ # support binary NULs in string. sub q0 { (my $str = shift) =~ s/\x00//g; # make sure there really aren't any embedded NULs - "q\x00$str\x00" + "q\x00\Q$str\E\x00" } sub old_bg_expr { @@ -1512,34 +1537,6 @@ $expr } -sub on_osc_seq { - my ($self, $op, $arg) = @_; - - $self->{bg_opts} or return; - - $op =~ /^(?:20|705)$/ or return; - - if ($op eq "20") { - if ($arg eq "?") { - my $h_scale = $self->{bg_opts}->{h_scale}; - my $v_scale = $self->{bg_opts}->{v_scale}; - my $h_align = $self->{bg_opts}->{h_align}; - my $v_align = $self->{bg_opts}->{v_align}; - $self->cmd_parse ("\033]2;[${h_scale}x${v_scale}+${h_align}+${v_align}]\007"); - } else { - $self->old_bg_opts ($arg); - my $expr = $self->old_bg_expr; - $self->set_expr (parse_expr $expr) if $expr; - } - } elsif ($op eq "705") { - $self->{bg_opts}->{tint} = $arg; - my $expr = $self->old_bg_expr; - $self->set_expr (parse_expr $expr) if $expr; - } - - 1 -} - sub find_resource { my ($self, $res, $opt) = @_; @@ -1549,7 +1546,7 @@ $v } -sub on_start { +sub parse_bgopts { my ($self) = @_; my $expr = $self->x_resource ("%.expr"); @@ -1567,13 +1564,47 @@ $expr = $self->old_bg_expr; } - $expr or return; - $self->set_expr (parse_expr $expr); $self->{border} = $self->x_resource_boolean ("%.border"); $MIN_INTERVAL = $self->x_resource ("%.interval"); +} + +sub on_start { + my ($self) = @_; + + $self->parse_bgopts; () } +sub on_osc_seq { + my ($self, $op, $arg) = @_; + + $op eq "20" or $op eq "706" + or return; + + $self->{bg_opts} + or $self->parse_bgopts; + + if ($op eq "20") { + if ($arg eq "?") { + my $h_scale = $self->{bg_opts}{h_scale}; + my $v_scale = $self->{bg_opts}{v_scale}; + my $h_align = $self->{bg_opts}{h_align}; + my $v_align = $self->{bg_opts}{v_align}; + $self->cmd_parse ("\033]2;[${h_scale}x${v_scale}+${h_align}+${v_align}]\007"); + } else { + $self->old_bg_opts ($arg); + my $expr = $self->old_bg_expr; + $self->set_expr (parse_expr $expr) if $expr; + } + } elsif ($op eq "705") { + $self->{bg_opts}{tint} = $arg; + my $expr = $self->old_bg_expr; + $self->set_expr (parse_expr $expr) if $expr; + } + + 1 +} +