ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/perl/clickthrough
Revision: 1.3
Committed: Sun Jan 1 17:39:56 2023 UTC (16 months, 3 weeks ago) by root
Branch: MAIN
Changes since 1.2: +5 -0 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #! perl
2    
3     #:META:RESOURCE:clickthrough:string:clickthrough disable/off/on
4    
5     =head1 NAME
6    
7     clickthrough - make window "transparent" with respect to input events
8    
9 root 1.3 =head1 SYNOPSIS
10    
11     # create a transparent non-interactable overlay
12     urxvt -override-redirect -depth 32 -bg "[0]black" -clickthrough on -e top
13    
14 root 1.1 =head1 DESCRIPTION
15    
16     This extension can toggle the terminal window between "normal" and
17 sf-exg 1.2 "clickthrough" states. In the latter state, input events such as clicks
18     will go "through" the window, as if it weren't there. This can be used to
19 root 1.1 put a (preferably partially transparent) window in front of other windows
20     and let clicks and other events go through the underlying window.
21    
22     See L<https://shallowsky.com/blog/2017/Apr/06/> for an example.
23    
24     This extension is loaded automatically when the C<-clickthrough mode>
25     command line argument is given, and operates in one of three modes:
26    
27     =over
28    
29     =item C<disable> (the default)
30    
31 sf-exg 1.2 In this mode, everything works normally and the OSC sequence is not
32 root 1.1 active.
33    
34     =item C<on>
35    
36     In this mode, events go through the window, and this can be toggled via an
37     OSC sequence.
38    
39     =item C<off>
40    
41     In this mode, events act normally, but this can be toggled via an OSC
42     sequence.
43    
44     =back
45    
46     =head2 OSC SEQUENCE
47    
48     When enabled, the OSC sequence C<< 777;clickthroughI<mode> >> can be used
49     to change the clickthrough mode. Example, switch it on, and then switch it
50     off again:
51    
52     printf '\033]777;clickthrough:on\007'
53     printf '\033]777;clickthrough:off\007'
54    
55     =head2 BUGS
56    
57     For this to work as expected, your window manager needs to support shaped
58     windows fully, but most only have partial support. The only window manager
59     known that handles this correctly is openbox 3.7 (and partially 3.6).
60    
61     A workaround is to also use C<-override-redirect>.
62    
63     In addition, input shapes don't seem to be well supported in Xorg,
64 sf-exg 1.2 which sometimes does not generate the necessary events for window
65     managers. This is currently being worked around in this extension by
66 root 1.1 re-setting the input shape after every map event.
67    
68     =cut
69    
70     sub on_start {
71     my ($self) = @_;
72    
73     my $mode = $self->x_resource ("clickthrough");
74    
75     if ($mode eq "on" or $mode eq "off") {
76     my ($major, $minor) = $self->XShapeQueryVersion;
77    
78     if ($major < 1 or ($major == 1 && $minor < 1)) {
79     warn "clickthrough cannot be enabled since the shape extension is missing or too old\n";
80     return;
81     }
82    
83     my $set_mode = sub {
84     if ($mode eq "on") {
85     my $reg = urxvt::XCreateRegion;
86     $self->XShapeCombineRegion ($self->parent, urxvt::ShapeInput, 0, 0, $reg, urxvt::ShapeSet);
87     urxvt::XDestroyRegion ($reg);
88     } elsif ($mode eq "off") {
89     $self->XShapeCombineMask ($self->parent, urxvt::ShapeInput, 0, 0, urxvt::None, urxvt::ShapeSet);
90     }
91     };
92    
93     $set_mode->();
94    
95     $self->{on_osc_seq_perl} = $self->on (osc_seq_perl => sub {
96     my ($self, $osc, $resp) = @_;
97    
98     if ($osc =~ /^clickthrough:(on|off)\z/) {
99     $mode = $1;
100     $set_mode->();
101     }
102     });
103    
104     # at least my x-server does not send a ShapeNotify event to the window manager
105     # for input shapes unless the window is mapped. Works for bounding shapes, so
106 sf-exg 1.2 # this is likely an X bug, which we work around by setting the mask on every map
107 root 1.1 #$self->{on_map_notify} = $self->on (map_notify => $set_mode);
108     }
109    
110     ()
111     }
112