1package X11::Xlib::Window;
2use strict;
3use warnings;
4use parent 'X11::Xlib::XID';
5
6# All modules in dist share a version
7BEGIN { our $VERSION= $X11::Xlib::VERSION; }
8
9sub clear_all {
10    delete @{$_[0]}{qw( attributes )};
11}
12
13sub attributes {
14    my $self= shift;
15    unless (defined $self->{attributes}) {
16        $self->display->XGetWindowAttributes($self, my $struct);
17        $self->{attributes}= $struct;
18    }
19    $self->{attributes}
20}
21
22sub get_property_list {
23    my $self= shift;
24    $self->display->XListProperties($self);
25}
26
27sub get_property {
28    my ($self, $prop, $type, $offset, $max_length)= @_;
29    $type ||= X11::Xlib::AnyPropertyType();
30    $offset ||= 0;
31    $max_length ||= 1024;
32    if (0 == $self->display->XGetWindowProperty($self, $prop, 0, int($max_length/4), 0, $type,
33        my $actual_type, my $actual_format, my $n, my $remaining, my $data)
34    ) {
35        return {
36            type => $actual_type,
37            format => $actual_format,
38            count => $n,
39            remaining => $remaining,
40            data => $data
41        };
42    }
43    return undef;
44}
45
46sub set_property {
47    my ($self, $prop, $type, $value, $item_size, $count)= @_;
48    if (!defined $type || !defined $value) {
49        $self->display->XDeleteProperty($self, $prop);
50    } else {
51        $item_size ||= 8;
52        $count ||= int(length($value)/int($item_size/8));
53        $self->display->XChangeProperty($self, $prop, $type, $item_size,
54            X11::Xlib::PropModeReplace, $value, $count);
55    }
56}
57
58sub get_w_h {
59    my $self= shift;
60    my ($x, $y);
61    (undef, undef, undef, $x, $y)
62        = $self->display->XGetGeometry($self->xid);
63    return ($x, $y);
64}
65
66sub show {
67    my ($self, $visible)= @_;
68    if ($visible || !defined $visible) {
69        $self->display->XMapWindow($self->xid);
70    } else {
71        $self->display->XUnmapWindow($self->xid);
72    }
73}
74
75sub hide { shift->show(0) }
76
77sub event_mask {
78    my $self= shift;
79    if (@_) {
80        my $mask= 0;
81        $mask |= $_ for @_;
82        $self->display->XSelectInput($self->xid, $mask);
83        $self->{attributes}->your_event_mask($mask)
84            if defined $self->{attributes};
85    } else {
86        $self->attributes->your_event_mask;
87    }
88}
89
90sub event_mask_include {
91    my $self= shift;
92    my $mask= 0;
93    $mask |= $_ for @_;
94    return unless $mask;
95    my $old= $self->event_mask;
96    return unless ~$old & $mask;
97    $self->event_mask($old | $mask);
98}
99
100sub event_mask_exclude {
101    my $self= shift;
102    my $mask= 0;
103    $mask |= $_ for @_;
104    return unless $mask;
105    my $old= $self->event_mask;
106    return unless $old & $mask;
107    $self->event_mask($old & ~$mask);
108}
109
110sub set_bounding_region {
111    my ($self, $region, $ofs_x, $ofs_y)= @_;
112    $self->display->XFixesSetWindowShapeRegion(
113        $self, &X11::Xlib::ShapeBounding, $ofs_x||0, $ofs_y||0, $region||0
114    );
115}
116
117sub set_input_region {
118    my ($self, $region, $ofs_x, $ofs_y)= @_;
119    $self->display->XFixesSetWindowShapeRegion(
120        $self, &X11::Xlib::ShapeInput, $ofs_x||0, $ofs_y||0, $region||0
121    );
122}
123
124sub DESTROY {
125    my $self= shift;
126    $self->display->XDestroyWindow($self->xid)
127        if $self->autofree;
128}
129
1301;
131
132__END__
133
134=head1 NAME
135
136X11::Xlib::Window - XID wrapper for Window
137
138=head1 SYNOPSIS
139
140  use X11::Xlib;
141  my $display = X11::Xlib->new();
142  my $window = $display->RootWindow();
143  ...
144
145=head1 METHODS
146
147(see L<X11::Xlib::XID> for inherited methods/attributes)
148
149=head2 attributes
150
151Calls L<X11::Xlib/XGetWindowAttributes>, caches the result, and returns
152the instance of L<X11::Xlib::XWindowAttributes>.
153
154=head2 clear_all
155
156Clear any cached value of the window so that the next access loads it fresh
157from the server.
158
159=head2 event_mask
160
161  my $current_mask= $window->event_mask;
162  $window->event_mask( $current_mask | SubstructureRedirectMask );
163
164Get or set the event mask.  Reading this value may return cached data, or else
165cause a call to L<XGetWindowAttibutes|X11::Xlib/XGetWindowAttibutes>.
166Setting the event mask uses L<XSelectInput|X11::Xlib/XSelectInput>, and
167updates the cache.
168
169=head2 event_mask_include
170
171  $window->event_mask_include( @event_masks );
172
173Read the current event mask (unless cached already), then bitwise OR it with
174each parameter, then set the mask on the window if anything changed.
175
176=head2 event_mask_exclude
177
178  $window->event_mask_exclude( @event_masks );
179
180Read the current event mask (unless cached already), then bitwise AND NOT with
181each parameter, then set the mask on the window if anything changed.
182
183=head2 get_w_h
184
185  my ($w, $h)= $window->get_w_h
186
187Return width and height of the window by calling L<XGetGeometry|X11::Xlib/XGetGeometry>.
188This never uses a cache and always returns the current size of the window,
189since often it has been altered by window managers etc.
190
191For a cached value, just use C<< $window->attributes->width >> etc.
192
193=head2 show
194
195  $win->show;
196  $win->show(1);
197  $win->show(0);  # equivalent to 'hide'
198
199Calls L<XMapWindow|X11::Xlib/XMapWindow> to request that the X server display the window.
200
201You can pass a boolean argument to conditionally call L</hide> instead.
202
203=head2 hide
204
205Calls L<XUnmapWindow|X11::Xlib/XUnmapWindow> to request the window be hidden.
206
207=head2 set_bounding_region
208
209  $window->set_bounding_region($region);
210  $window->set_bounding_region($region, $x_ofs, $y_ofs);
211
212Set the L<region|X11::Xlib::XserverRegion> for the boundary of the window, optionally
213offset by an (x,y) coordinate.  C<$region> may be undef or 0 to un-set the region.
214
215=head2 set_input_region
216
217  $window->set_input_region($region);
218  $window->set_input_region($region, $x_ofs, $y_ofs);
219
220Set the input "hit" L<region|X11::Xlib::XserverRegion> of the window, optionally
221offset by an (x,y) coordinate. C<$region> may be undef or 0 to un-set the region.
222
223=head1 SEE ALSO
224
225L<X11::Xlib>
226
227=head1 AUTHOR
228
229Olivier Thauvin, E<lt>nanardon@nanardon.zarb.orgE<gt>
230
231Michael Conrad, E<lt>mike@nrdvana.netE<gt>
232
233=head1 COPYRIGHT AND LICENSE
234
235Copyright (C) 2009-2010 by Olivier Thauvin
236
237Copyright (C) 2017 by Michael Conrad
238
239This library is free software; you can redistribute it and/or modify
240it under the same terms as Perl itself, either Perl version 5.10.0 or,
241at your option, any later version of Perl 5 you may have available.
242
243=cut
244