cvsimport
[fvwm.git] / modules / FvwmCommand / scripts / push-away.pl
blob684c9b5448c2cb136242e6df4036622ac5aded5f
1 #! xPERLx
2 # FvwmCommand script
3 # Written by Toshi Isogai
5 # push-away
6 # push other windows back when they overlap
7 # usage: push-away <direction> <window name>
8 # direction - direction (down,up,left,right) to push away
9 # window name - windows to be protected, name can be regular expression
10 # icons are ignored
12 # This program is free software; you can redistribute it and/or modify
13 # it under the terms of the GNU General Public License as published by
14 # the Free Software Foundation; either version 2 of the License, or
15 # (at your option) any later version.
17 # This program is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # GNU General Public License for more details.
22 # You should have received a copy of the GNU General Public License
23 # along with this program; if not, write to the Free Software
24 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 $Dir = shift;
28 $Wn = shift;
30 if( $Dir =~ /down/i ) {
31 $Dir = 1;
32 }elsif( $Dir =~ /up/i ) {
33 $Dir = 2;
34 }elsif( $Dir =~ /left/i ) {
35 $Dir = 3;
36 }elsif( $Dir =~ /right/i ) {
37 $Dir = 4;
40 if( $Dir == 0 || $Wn eq '' ) {
41 print STDERR "push other windows back when they overlap\n";
42 print STDERR "usage: push-away <direction> <window name>\n";
43 print STDERR " direction - direction (down,up,left,right) to push away\n";
44 print STDERR " window name - windows to be protected\n";
45 print STDERR " name can be regular expression\n";
46 exit(1);
50 # start a dedicated server
51 $fifo = "$ENV{'HOME'}/.FCMpb";
52 system( "FvwmCommand 'FvwmCommandS $fifo'");
54 # larger number for slow machine
55 select(undef,undef,undef,0.5);
57 # we need this to run this script in background job
58 $SIG{'TTIN'} = "IGNORE";
60 # start monitoring (-m option ) all fvwm transaction (-i3 option )
61 open( FCM, "FvwmCommand -f $fifo -m -i3 |" ) || die "FCM $fifo";
63 # send command through the new fifo which is "$fifo" + "C"
64 open( FCC, ">${fifo}C" ) || die "FCC $fifo" ;
66 # non blocking outputs
67 select( FCC ); $| = 1;
68 select( STDOUT ); $| = 1;
71 # some delay for slow one
72 select(undef,undef,undef,0.1);
73 print FCC "send_windowlist\n";
74 # yet some more delay for slow one
75 select(undef,undef,undef,0.1);
77 $endlist = 0;
78 while( <FCM> ) {
80 if( /^(0x\S+) frame\s+x (-?\d+), y (-?\d+), width (\d+), height (\d+)/ ) {
81 $id = $1;
82 $Config{$id}{'x'} = $2;
83 $Config{$id}{'y'} = $3;
84 $Config{$id}{'w'} = $4;
85 $Config{$id}{'h'} = $5;
87 next if ! $endlist ;
89 # move other windows if necessary
90 if( $Config{$id}{'protect'} ) {
91 foreach $w (keys %Config) {
92 if( $id ne $w ) {
93 move_if_overlap( $w, $id );
96 }else{
97 foreach $w (keys %Config) {
98 if( $Config{$w}{'protect'} ) {
99 move_if_overlap( $id, $w );
104 }elsif( /^(0x\S+) desktop +(-?\d+)/ ) {
105 $Config{$1}{'desk'} = $2;
107 }elsif( /^(0x\S+) Iconified +(yes|no)/ ) {
108 $Config{$1}{'Iconified'} = $2;
110 }elsif( /^(0x\S+) window +(.*)/ ) {
111 $id = $1;
112 $window = $2;
114 if( $window =~ /$Wn/ ) {
115 $Config{$id}{'protect'} = 1;
118 }elsif( /end windowlist/ ) {
119 $endlist = 1;
120 foreach $id (keys %Config) {
121 if( $Config{$id}{'protect'} ) {
122 foreach $w (keys %Config) {
123 if( $id ne $w ) {
124 move_if_overlap( $w, $id );
130 }elsif( /^(0x\S+) destroy/ ) {
131 delete $Config{$1};
137 sub move_if_overlap {
138 my($id1, $id2) = @_;
139 my($ov);
140 my($c1xl,$c1xh,$c1yl,$c1yh);
141 my($c2xl,$c2xh,$c2yl,$c2yh);
145 if( $Config{$id1}{'desk'} != $Config{$id2}{'desk'}
146 || $Config{$id1}{'Iconified'} eq 'yes'
147 || $Config{$id2}{'Iconified'} eq 'yes' ) {
148 return;
152 $ov = 0;
154 $c1xl = $Config{$id1}{'x'};
155 $c1yl = $Config{$id1}{'y'};
156 $c1xh = $Config{$id1}{'x'}+$Config{$id1}{'w'};
157 $c1yh = $Config{$id1}{'y'}+$Config{$id1}{'h'};
159 $c2xl = $Config{$id2}{'x'};
160 $c2yl = $Config{$id2}{'y'};
161 $c2xh = $Config{$id2}{'x'}+$Config{$id2}{'w'};
162 $c2yh = $Config{$id2}{'y'}+$Config{$id2}{'h'};
165 if( $c2xl >= $c1xl && $c2xl <= $c1xh
166 || $c2xh >= $c1xl && $c2xh <= $c1xh ) {
167 if($c2yl >= $c1yl && $c2yl <= $c1yh
168 || $c2yh >= $c1yl && $c2yh <= $c1yh ) {
169 $ov = 1;
171 }elsif( $c1xl >= $c2xl && $c1xl <= $c2xh
172 || $c1xh >= $c2xl && $c1xh <= $c2xh ) {
173 if($c1yl >= $c2yl && $c1yl <= $c2yh
174 || $c1yh >= $c2yl && $c1yh <= $c2yh ) {
175 $ov = 1;
179 if( $ov ) {
180 $x = $c1xl;
181 $y = $c1yl;
182 if( $Dir==1 ) {
183 $y = $c2yh+1;
184 }elsif( $Dir==2 ) {
185 $y = $c2yl-($c1yh-$c1yl)-1;
186 }elsif( $Dir==3 ) {
187 $x = $c2xl-($c1xh-$c1xl)-1;
188 }elsif( $Dir==4 ) {
189 $x = $c2xh+1;
193 print FCC "windowid $id1 move ${x}p ${y}p\n";
195 # ignore - pixel info is the last info for move
196 while(<FCM>) {
197 last if /^0x\S+ pixel/;
200 select(undef,undef,undef,0.1);