~ubuntu-branches/ubuntu/trusty/shutter/trusty-proposed

« back to all changes in this revision

Viewing changes to share/shutter/resources/modules/Shutter/Screenshot/Window.pm

  • Committer: Bazaar Package Importer
  • Author(s): Ryan Niebur
  • Date: 2009-04-26 11:06:22 UTC
  • Revision ID: james.westby@ubuntu.com-20090426110622-7dvoaw207bbm5icy
Tags: upstream-0.70.2
ImportĀ upstreamĀ versionĀ 0.70.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
###################################################
 
2
#
 
3
#  Copyright (C) Mario Kemper <mario.kemper@googlemail.com> and Shutter Team
 
4
#
 
5
#  This file is part of Shutter.
 
6
#
 
7
#  Shutter is free software; you can redistribute it and/or modify
 
8
#  it under the terms of the GNU General Public License as published by
 
9
#  the Free Software Foundation; either version 3 of the License, or
 
10
#  (at your option) any later version.
 
11
#
 
12
#  Shutter is distributed in the hope that it will be useful,
 
13
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
#  GNU General Public License for more details.
 
16
#
 
17
#  You should have received a copy of the GNU General Public License
 
18
#  along with Shutter; if not, write to the Free Software
 
19
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
20
#
 
21
###################################################
 
22
 
 
23
package Shutter::Screenshot::Window;
 
24
 
 
25
#modules
 
26
#--------------------------------------
 
27
use utf8;
 
28
use strict;
 
29
use Shutter::Screenshot::Main;
 
30
use Data::Dumper;
 
31
our @ISA = qw(Shutter::Screenshot::Main);
 
32
 
 
33
#define constants
 
34
#--------------------------------------
 
35
use constant TRUE  => 1;
 
36
use constant FALSE => 0;
 
37
 
 
38
#--------------------------------------
 
39
 
 
40
sub new {
 
41
        my $class = shift;
 
42
 
 
43
        #call constructor of super class (shutter_common, include_cursor, delay)
 
44
        my $self = $class->SUPER::new( shift, shift, shift );
 
45
 
 
46
        #get params
 
47
        $self->{_x11}                           = shift;
 
48
        $self->{_include_border}        = shift;
 
49
        $self->{_xid}                           = shift;    #only used by window_by_xid, undef this when selecting a window
 
50
        $self->{_mode}                          = shift;
 
51
        $self->{_is_in_tray}            = shift;
 
52
 
 
53
        #main window
 
54
        $self->{_main_gtk_window} = $self->{_gc}->get_mainwindow;
 
55
 
 
56
        #only used by window_select
 
57
        $self->{_children} = {};
 
58
 
 
59
        bless $self, $class;
 
60
        return $self;
 
61
}
 
62
 
 
63
sub find_wm_window {
 
64
        my $self = shift;
 
65
        my $xid  = shift;
 
66
 
 
67
        do {
 
68
                my ( $qroot, $qparent, @qkids ) = $self->{_x11}->QueryTree($xid);
 
69
                return undef unless ( $qroot || $qparent );
 
70
                return $xid if ( $qroot == $qparent );
 
71
                $xid = $qparent;
 
72
        } while (TRUE);
 
73
}
 
74
 
 
75
sub query_children {
 
76
        my ( $self,  $xwindow, $xparent ) = @_;
 
77
        my ( $qroot, $qparent, @qkids )   = $self->{_x11}->QueryTree($xwindow);
 
78
        foreach (@qkids) {
 
79
 
 
80
                my $gdk_window = Gtk2::Gdk::Window->foreign_new($_);
 
81
                if ( defined $gdk_window ) {
 
82
 
 
83
                        #window needs to be viewable and visible
 
84
                        next unless $gdk_window->is_visible;
 
85
                        next unless $gdk_window->is_viewable;
 
86
 
 
87
                        #min size
 
88
                        my ( $xp, $yp, $widthp, $heightp, $depthp ) = $gdk_window->get_geometry;
 
89
                        ( $xp, $yp ) = $gdk_window->get_origin;
 
90
                        next if ( $widthp * $heightp < 4 );
 
91
 
 
92
                        #check if $gdk_window is already in hash
 
93
                        my $dub = FALSE;
 
94
                        foreach my $checkchild ( keys %{ $self->{_children}{$xparent} } ) {
 
95
                                $dub = TRUE
 
96
                                        if $self->{_children}{$xparent}{$checkchild}{'gdk_window'} == $gdk_window;
 
97
                        }
 
98
                        unless ( $dub == TRUE ) {
 
99
                                $self->{_children}{$xparent}{$_}{'gdk_window'} = $gdk_window;
 
100
                                $self->{_children}{$xparent}{$_}{'x'}          = $xp;
 
101
                                $self->{_children}{$xparent}{$_}{'y'}          = $yp;
 
102
                                $self->{_children}{$xparent}{$_}{'width'}      = $widthp;
 
103
                                $self->{_children}{$xparent}{$_}{'height'}     = $heightp;
 
104
                                $self->{_children}{$xparent}{$_}{'size'}       = $widthp * $heightp;
 
105
 
 
106
                                #check next depth
 
107
                                $self->query_children( $gdk_window->XWINDOW, $xparent );
 
108
                        }
 
109
                }
 
110
        }
 
111
        return TRUE;
 
112
}
 
113
 
 
114
sub get_shape {
 
115
        my $self = shift;
 
116
        my $xid = shift;
 
117
        my $orig = shift;
 
118
 
 
119
        print "Calculating window shape\n" if $self->{_gc}->get_debug;
 
120
 
 
121
        my ($ordering, @r) = $self->{_x11}->ShapeGetRectangles($self->find_wm_window($xid), 'Bounding');
 
122
        
 
123
        #do nothing if there are no
 
124
        #shape rectangles (or only one)
 
125
        return $orig if scalar @r <= 1;
 
126
                                                        
 
127
        #create a region from the bounding rectangles
 
128
        my $bregion = Gtk2::Gdk::Region->new;                                   
 
129
        foreach my $r (@r){
 
130
                my @rect =  @{$r};
 
131
                print "Current $rect[0],$rect[1],$rect[2],$rect[3]\n" if $self->{_gc}->get_debug;
 
132
                $bregion->union_with_rect(Gtk2::Gdk::Rectangle->new ($rect[0],$rect[1],$rect[2],$rect[3]));     
 
133
        }
 
134
 
 
135
        #create target pixbuf with dimensions if selected/current window
 
136
        my $target = Gtk2::Gdk::Pixbuf->new ($orig->get_colorspace, TRUE, 8, $orig->get_width, $orig->get_height);
 
137
        #whole pixbuf is transparent
 
138
        $target->fill('0x00000000');
 
139
        
 
140
        #copy all rectangles of bounding region to the target pixbuf
 
141
        foreach my $r($bregion->get_rectangles){
 
142
                print $r->x." ".$r->y." ".$r->width." ".$r->height."\n" if $self->{_gc}->get_debug;
 
143
 
 
144
                next if($r->x > $orig->get_width);
 
145
                next if($r->y > $orig->get_height);
 
146
 
 
147
                $r->width($orig->get_width - $r->x) if($r->x+$r->width > $orig->get_width);
 
148
                $r->height($orig->get_height - $r->y) if($r->y+$r->height > $orig->get_height); 
 
149
                
 
150
                $orig->copy_area ($r->x, $r->y, $r->width, $r->height, $target, $r->x, $r->y);          
 
151
        }
 
152
        
 
153
        return $target;
 
154
}       
 
155
 
 
156
sub get_window_size {
 
157
        my ( $self, $wnck_window, $gdk_window, $border ) = @_;
 
158
 
 
159
        my ( $xp, $yp, $widthp, $heightp ) = $wnck_window->get_geometry;
 
160
        if ($border) {
 
161
 
 
162
                #find wm_window
 
163
                my $wm_window
 
164
                        = Gtk2::Gdk::Window->foreign_new( $self->find_wm_window( $wnck_window->get_xid ) );
 
165
                $gdk_window = $wm_window if $wm_window;
 
166
 
 
167
                #get_size of it
 
168
                my ( $xp2, $yp2, $widthp2, $heightp2 ) = $gdk_window->get_geometry;
 
169
                ( $xp2, $yp2 ) = $gdk_window->get_origin;
 
170
 
 
171
                #check the correct rect
 
172
                if (   $xp2 + $widthp2 > $xp + $widthp
 
173
                        && $yp2 + $heightp2 > $yp + $heightp )
 
174
                {
 
175
                        ( $xp, $yp, $widthp, $heightp ) = ( $xp2, $yp2, $widthp2, $heightp2 );
 
176
                }
 
177
 
 
178
        } else {
 
179
                ( $widthp, $heightp ) = $gdk_window->get_size;
 
180
                ( $xp,     $yp )      = $gdk_window->get_origin;
 
181
        }
 
182
 
 
183
        return ( $xp, $yp, $widthp, $heightp );
 
184
}
 
185
 
 
186
sub window_by_xid {
 
187
        my $self = shift;
 
188
 
 
189
        my $gdk_window  = Gtk2::Gdk::Window->foreign_new( $self->{_xid} );
 
190
        my $wnck_window = Gnome2::Wnck::Window->get( $self->{_xid} );
 
191
 
 
192
        my ( $xp, $yp, $widthp, $heightp )
 
193
                = $self->get_window_size( $wnck_window, $gdk_window, $self->{_include_border} );
 
194
 
 
195
        #focus selected window (maybe it is hidden)
 
196
        $gdk_window->focus(time);
 
197
        Gtk2::Gdk->flush;
 
198
        sleep 1 if $self->{_delay} < 1;
 
199
 
 
200
        my $output = $self->get_pixbuf_from_drawable( $self->{_root}, $xp, $yp, $widthp, $heightp,
 
201
                $self->{_include_cursor},
 
202
                $self->{_delay} );
 
203
 
 
204
        #respect rounded corners of wm decorations (metacity for example - does not work with compiz currently) 
 
205
        if($self->{_x11}{ext_shape}){
 
206
                $output = $self->get_shape($self->{_xid}, $output);                             
 
207
        }
 
208
 
 
209
        return $output;
 
210
 
 
211
}
 
212
 
 
213
sub window_select {
 
214
        my $self = shift;
 
215
 
 
216
        #return value
 
217
        my $output = 5;
 
218
 
 
219
        #get all the windows
 
220
        my @wnck_windows = $self->{_wnck_screen}->get_windows;
 
221
 
 
222
        #...and window "pick" cursor
 
223
        my $hand_cursor2 = Gtk2::Gdk::Cursor->new('GDK_HAND2');
 
224
 
 
225
        #define graphics context
 
226
        my $cr = undef;
 
227
        my $white = Gtk2::Gdk::Color->new( 65535, 65535, 65535 );
 
228
        my $black = Gtk2::Gdk::Color->new( 0,     0,     0 );
 
229
        my $gc = Gtk2::Gdk::GC->new( $self->{_root}, undef );
 
230
        $gc->set_line_attributes( 5, 'solid', 'round', 'round' );
 
231
        $gc->set_rgb_bg_color($black);
 
232
        $gc->set_rgb_fg_color($white);
 
233
        $gc->set_subwindow('include-inferiors');
 
234
        $gc->set_function('xor');
 
235
 
 
236
        my $grab_counter = 0;
 
237
        while ( !Gtk2::Gdk->pointer_is_grabbed && $grab_counter < 100 ) {
 
238
                Gtk2::Gdk->pointer_grab(
 
239
                        $self->{_root},
 
240
                        0,
 
241
                        [   qw/
 
242
                                        pointer-motion-mask
 
243
                                        button-release-mask/
 
244
                        ],
 
245
                        undef,
 
246
                        $hand_cursor2,
 
247
                        Gtk2->get_current_event_time
 
248
                );
 
249
                Gtk2::Gdk->keyboard_grab( $self->{_root}, 0, Gtk2->get_current_event_time );
 
250
                $grab_counter++;
 
251
        }
 
252
 
 
253
        if ( Gtk2::Gdk->pointer_is_grabbed ) {
 
254
 
 
255
                $self->{_children} = ();
 
256
                my $drawable        = undef;
 
257
                my $window_selected = FALSE;
 
258
                $self->{_children}{'last_win'}{'gdk_window'} = 0;
 
259
                my $active_workspace = $self->{_wnck_screen}->get_active_workspace;
 
260
 
 
261
                #something went wrong here, no active workspace detected
 
262
                unless ( $active_workspace ) {
 
263
                        $self->ungrab_pointer_and_keyboard( FALSE, FALSE, FALSE );
 
264
                        $output = 0;
 
265
                        return $output;
 
266
                }
 
267
 
 
268
                Gtk2::Gdk::Event->handler_set(
 
269
                        sub {
 
270
                                my ( $event, $data ) = @_;
 
271
                                return FALSE unless defined $event;
 
272
 
 
273
                                #handle key events here
 
274
                                if ( $event->type eq 'key-press' ) {
 
275
                                        next unless defined $event->keyval;
 
276
                                        if ( $event->keyval == $Gtk2::Gdk::Keysyms{Escape} ) {
 
277
 
 
278
                                                #clear the last rectangle
 
279
                                                if ( defined $self->{_children}{'last_win'} ) {
 
280
                                                        $self->{_root}->draw_rectangle(
 
281
                                                                $gc,
 
282
                                                                0,
 
283
                                                                $self->{_children}{'last_win'}{'x'},
 
284
                                                                $self->{_children}{'last_win'}{'y'},
 
285
                                                                $self->{_children}{'last_win'}{'width'},
 
286
                                                                $self->{_children}{'last_win'}{'height'}
 
287
                                                        );
 
288
                                                        
 
289
                                                }
 
290
 
 
291
                                                $self->ungrab_pointer_and_keyboard( FALSE, TRUE, TRUE );
 
292
 
 
293
                                                $output = 5;
 
294
                                        }
 
295
                                } elsif ( $event->type eq 'button-release' ) {
 
296
                                        print "Type: " . $event->type . "\n"
 
297
                                                if ( defined $event && $self->{_gc}->get_debug );
 
298
 
 
299
                                        #looking for a section of a window?
 
300
                                        #keep current window in mind and search for children
 
301
                                        if ( ( $self->{_mode} eq "section" || $self->{_mode} eq "tray_section" )
 
302
                                                && !$window_selected )
 
303
                                        {
 
304
 
 
305
                                                #something went wrong here, no window on screen detected
 
306
                                                unless ( $self->{_children}{'last_win'}{'gdk_window'} ) {
 
307
                                                        $self->ungrab_pointer_and_keyboard( FALSE, TRUE, TRUE );
 
308
                                                        $output = "";
 
309
                                                        return $output;
 
310
                                                }
 
311
 
 
312
                                                $self->query_children(
 
313
                                                        $self->{_children}{'last_win'}{'gdk_window'}->XWINDOW,
 
314
                                                        $self->{_children}{'last_win'}{'gdk_window'}->XWINDOW
 
315
                                                );
 
316
 
 
317
                                                #focus selected window (maybe it is hidden)
 
318
                                                $self->{_children}{'last_win'}{'gdk_window'}->focus(time);
 
319
                                                Gtk2::Gdk->flush;
 
320
                                                $window_selected
 
321
                                                        = $self->{_children}{'curr_win'}{'gdk_window'};
 
322
 
 
323
                                                return TRUE;
 
324
                                        }
 
325
 
 
326
                                        $self->ungrab_pointer_and_keyboard( FALSE, TRUE, TRUE );
 
327
 
 
328
                                        #clear the last rectangle
 
329
                                        if ( defined $self->{_children}{'last_win'}
 
330
                                                && $self->{_children}{'last_win'}{'gdk_window'} )
 
331
                                        {
 
332
                                                $self->{_root}->draw_rectangle(
 
333
                                                        $gc,
 
334
                                                        0,
 
335
                                                        $self->{_children}{'last_win'}{'x'},
 
336
                                                        $self->{_children}{'last_win'}{'y'},
 
337
                                                        $self->{_children}{'last_win'}{'width'},
 
338
                                                        $self->{_children}{'last_win'}{'height'}
 
339
                                                );
 
340
 
 
341
                                                #focus selected window (maybe it is hidden)
 
342
                                                $self->{_children}{'last_win'}{'gdk_window'}->focus(time);
 
343
                                                Gtk2::Gdk->flush;
 
344
                                                sleep 1 if $self->{_delay} < 1;
 
345
                                                
 
346
                                                $output = $self->get_pixbuf_from_drawable(
 
347
                                                        $self->{_root},
 
348
                                                        $self->{_children}{'curr_win'}{'x'},
 
349
                                                        $self->{_children}{'curr_win'}{'y'},
 
350
                                                        $self->{_children}{'curr_win'}{'width'},
 
351
                                                        $self->{_children}{'curr_win'}{'height'},
 
352
                                                        $self->{_include_cursor},
 
353
                                                        $self->{_delay}
 
354
                                                );                                               
 
355
                                                
 
356
                                                #respect rounded corners of wm decorations (metacity for example - does not work with compiz currently) 
 
357
                                                if($self->{_x11}{ext_shape}){
 
358
                                                        my $xid = $self->{_children}{ 'curr_win' }{ 'gdk_window' }->get_xid;
 
359
                                                        #do not try this for child windows
 
360
                                                        foreach my $win ($self->{_wnck_screen}->get_windows){
 
361
                                                                if($win->get_xid == $xid){
 
362
                                                                        $output = $self->get_shape($xid, $output);                              
 
363
                                                                }
 
364
                                                        }
 
365
                                                }
 
366
 
 
367
                                        } else {
 
368
                                                $output = 0;
 
369
                                        }
 
370
                                } elsif ( $event->type eq 'motion-notify' ) {
 
371
                                        print "Type: " . $event->type . "\n"
 
372
                                                if ( defined $event && $self->{_gc}->get_debug );
 
373
 
 
374
                                        my $min_x = $self->{_root}->{w};
 
375
                                        my $min_y = $self->{_root}->{h};
 
376
 
 
377
                                        #if there is no window already selected
 
378
                                        unless ($window_selected) {
 
379
                                                print "Searching for window...\n"
 
380
                                                        if $self->{_gc}->get_debug;
 
381
                                                foreach my $curr_window (@wnck_windows) {
 
382
                                                        $drawable = Gtk2::Gdk::Window->foreign_new( $curr_window->get_xid );
 
383
                                                        next unless defined $drawable;
 
384
 
 
385
                                                        print "Do not detect gscrot main window...\n"
 
386
                                                                if $self->{_gc}->get_debug;
 
387
 
 
388
                                                        #do not detect gscrot window when it is hidden
 
389
                                                        if (   $self->{_main_gtk_window}->window
 
390
                                                                && $self->{_is_in_tray} )
 
391
                                                        {
 
392
                                                                next
 
393
                                                                        if ( $curr_window->get_xid
 
394
                                                                        == $self->{_main_gtk_window}->window->get_xid );
 
395
                                                        }
 
396
 
 
397
                                                        my ( $xp, $yp, $widthp, $heightp )
 
398
                                                                = $self->get_window_size( $curr_window, $drawable,
 
399
                                                                $self->{_include_border} );
 
400
 
 
401
                                                        print "Create region of window...\n"
 
402
                                                                if $self->{_gc}->get_debug;
 
403
                                                        my $window_region = Gtk2::Gdk::Region->rectangle(
 
404
                                                                Gtk2::Gdk::Rectangle->new( $xp, $yp, $widthp, $heightp ) );
 
405
 
 
406
                                                        print "determine if window fits on screen...\n"
 
407
                                                                if $self->{_gc}->get_debug;
 
408
                                                        if ($curr_window->is_visible_on_workspace(
 
409
                                                                        $active_workspace
 
410
                                                                )
 
411
                                                                && $window_region->point_in( $event->x, $event->y )
 
412
                                                                )
 
413
                                                        {
 
414
                                                                print "Parent X: $xp, Y: $yp, Width: $widthp, Height: $heightp\n"
 
415
                                                                        if $self->{_gc}->get_debug;
 
416
                                                                $self->{_children}{'curr_win'}{'window'}     = $curr_window;
 
417
                                                                $self->{_children}{'curr_win'}{'gdk_window'} = $drawable;
 
418
                                                                $self->{_children}{'curr_win'}{'x'}          = $xp;
 
419
                                                                $self->{_children}{'curr_win'}{'y'}          = $yp;
 
420
                                                                $self->{_children}{'curr_win'}{'width'}      = $widthp;
 
421
                                                                $self->{_children}{'curr_win'}{'height'}     = $heightp;
 
422
                                                                $min_x                                       = $xp + $widthp;
 
423
                                                                $min_y                                       = $yp + $heightp;
 
424
 
 
425
                                                        }
 
426
 
 
427
                                                }    #end if toplevel window loop
 
428
 
 
429
                                                #something went wrong here, no window on screen detected
 
430
                                                unless ( $self->{_children}{'curr_win'}{'window'} ) {
 
431
                                                        $self->ungrab_pointer_and_keyboard( FALSE, TRUE, TRUE );
 
432
                                                        $output = "";
 
433
                                                        return $output;
 
434
                                                }
 
435
 
 
436
                                                #window selected, search for children now
 
437
                                        } elsif ( ( $self->{_mode} eq "section" || $self->{_mode} eq "tray_section" )
 
438
                                                && $window_selected )
 
439
                                        {
 
440
                                                print "Searching for children now...\n"
 
441
                                                        if $self->{_gc}->get_debug;
 
442
 
 
443
                                                #selected window is parent
 
444
                                                my $curr_parent = $window_selected->XWINDOW;
 
445
                                                foreach my $curr_child ( keys %{ $self->{_children}{$curr_parent} } ) {
 
446
                                                        next unless defined $curr_child;
 
447
                                                        print "Child Current Event x: " . $event->x . ", y: " . $event->y . "\n"
 
448
                                                                if $self->{_gc}->get_debug;
 
449
 
 
450
                                                        my $section_region = Gtk2::Gdk::Region->rectangle(
 
451
                                                                Gtk2::Gdk::Rectangle->new(
 
452
                                                                        $self->{_children}{$curr_parent}{$curr_child}{'x'},
 
453
                                                                        $self->{_children}{$curr_parent}{$curr_child}{'y'},
 
454
                                                                        $self->{_children}{$curr_parent}{$curr_child}{'width'},
 
455
                                                                        $self->{_children}{$curr_parent}{$curr_child}{'height'}
 
456
                                                                )
 
457
                                                        );
 
458
 
 
459
                                                        if ($section_region->point_in( $event->x, $event->y )
 
460
                                                                &&
 
461
 
 
462
                                                                (   (     $self->{_children}{$curr_parent}{$curr_child}{'x'}
 
463
                                                                                + $self->{_children}{$curr_parent}{$curr_child}{'width'}
 
464
                                                                        ) * (
 
465
                                                                                $self->{_children}{$curr_parent}{$curr_child}{'y'}
 
466
                                                                                        + $self->{_children}{$curr_parent}{$curr_child}
 
467
                                                                                        {'height'}
 
468
                                                                        ) <= $min_x * $min_y
 
469
                                                                )
 
470
 
 
471
                                                                )
 
472
                                                        {
 
473
                                                                $self->{_children}{'curr_win'}{'gdk_window'}
 
474
                                                                        = $self->{_children}{$curr_parent}{$curr_child}{'gdk_window'};
 
475
                                                                $self->{_children}{'curr_win'}{'x'}
 
476
                                                                        = $self->{_children}{$curr_parent}{$curr_child}{'x'};
 
477
                                                                $self->{_children}{'curr_win'}{'y'}
 
478
                                                                        = $self->{_children}{$curr_parent}{$curr_child}{'y'};
 
479
                                                                $self->{_children}{'curr_win'}{'width'}
 
480
                                                                        = $self->{_children}{$curr_parent}{$curr_child}{'width'};
 
481
                                                                $self->{_children}{'curr_win'}{'height'}
 
482
                                                                        = $self->{_children}{$curr_parent}{$curr_child}{'height'};
 
483
                                                                $min_x = $self->{_children}{$curr_parent}{$curr_child}{'x'}
 
484
                                                                        + $self->{_children}{$curr_parent}{$curr_child}{'width'};
 
485
                                                                $min_y = $self->{_children}{$curr_parent}{$curr_child}{'y'}
 
486
                                                                        + $self->{_children}{$curr_parent}{$curr_child}{'height'};
 
487
                                                        }
 
488
                                                }
 
489
                                        }    #endif search for children
 
490
 
 
491
                                        #draw rect if needed
 
492
                                        if ( $self->{_children}{'last_win'}{'gdk_window'} ne
 
493
                                                $self->{_children}{'curr_win'}{'gdk_window'} )
 
494
                                        {
 
495
 
 
496
                                                #clear last rectangle
 
497
                                                if ( $self->{_children}{'last_win'}{'gdk_window'} ) {
 
498
                                                        $self->{_root}->draw_rectangle(
 
499
                                                                $gc,
 
500
                                                                0,
 
501
                                                                $self->{_children}{'last_win'}{'x'},
 
502
                                                                $self->{_children}{'last_win'}{'y'},
 
503
                                                                $self->{_children}{'last_win'}{'width'},
 
504
                                                                $self->{_children}{'last_win'}{'height'}
 
505
                                                        );
 
506
                                                        Gtk2::Gdk->flush;
 
507
                                                }
 
508
 
 
509
                                                #draw new rectangle for current window
 
510
                                                if ( $self->{_children}{'curr_win'}{'gdk_window'} ) {
 
511
                                                        $self->{_root}->draw_rectangle(
 
512
                                                                $gc,
 
513
                                                                0,
 
514
                                                                $self->{_children}{'curr_win'}{'x'} - 3,
 
515
                                                                $self->{_children}{'curr_win'}{'y'} - 3,
 
516
                                                                $self->{_children}{'curr_win'}{'width'} + 5,
 
517
                                                                $self->{_children}{'curr_win'}{'height'} + 5
 
518
                                                        );
 
519
                                                }
 
520
 
 
521
                                                $self->{_children}{'last_win'}{'window'}
 
522
                                                        = $self->{_children}{'curr_win'}{'window'};
 
523
                                                $self->{_children}{'last_win'}{'gdk_window'}
 
524
                                                        = $self->{_children}{'curr_win'}{'gdk_window'};
 
525
                                                $self->{_children}{'last_win'}{'x'}
 
526
                                                        = $self->{_children}{'curr_win'}{'x'} - 3;
 
527
                                                $self->{_children}{'last_win'}{'y'}
 
528
                                                        = $self->{_children}{'curr_win'}{'y'} - 3;
 
529
                                                $self->{_children}{'last_win'}{'width'}
 
530
                                                        = $self->{_children}{'curr_win'}{'width'} + 5;
 
531
                                                $self->{_children}{'last_win'}{'height'}
 
532
                                                        = $self->{_children}{'curr_win'}{'height'} + 5;
 
533
 
 
534
                                        }
 
535
                                } else {
 
536
                                        Gtk2->main_do_event($event);
 
537
                                }
 
538
                        },
 
539
                        'window'
 
540
                );
 
541
                Gtk2->main;
 
542
        } else {    #pointer not grabbed
 
543
 
 
544
                $self->ungrab_pointer_and_keyboard( FALSE, FALSE, FALSE );
 
545
                $output = 0;
 
546
        }
 
547
        return $output;
 
548
}
 
549
 
 
550
1;