]>
Dogcows Code - chaz/openbox/blob - openbox/resist.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 resist.c for the Openbox window manager
4 Copyright (c) 2003 Ben Jansens
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 See the COPYING file for a copy of the GNU General Public License.
24 #include "parser/parse.h"
28 void resist_move_windows(ObClient
*c
, gint
*x
, gint
*y
)
31 gint l
, t
, r
, b
; /* requested edges */
32 gint cl
, ct
, cr
, cb
; /* current edges */
33 gint w
, h
; /* current size */
34 ObClient
*snapx
= NULL
, *snapy
= NULL
;
36 w
= c
->frame
->area
.width
;
37 h
= c
->frame
->area
.height
;
44 cl
= RECT_LEFT(c
->frame
->area
);
45 ct
= RECT_TOP(c
->frame
->area
);
46 cr
= RECT_RIGHT(c
->frame
->area
);
47 cb
= RECT_BOTTOM(c
->frame
->area
);
49 if (config_resist_win
)
50 for (it
= stacking_list
; it
!= NULL
; it
= it
->next
) {
52 int tl
, tt
, tr
, tb
; /* 1 past the target's edges on each side */
54 if (!WINDOW_IS_CLIENT(it
->data
))
57 /* don't snap to self or non-visibles */
58 if (!target
->frame
->visible
|| target
== c
) continue;
60 tl
= RECT_LEFT(target
->frame
->area
) - 1;
61 tt
= RECT_TOP(target
->frame
->area
) - 1;
62 tr
= RECT_RIGHT(target
->frame
->area
) + 1;
63 tb
= RECT_BOTTOM(target
->frame
->area
) + 1;
65 /* snapx and snapy ensure that the window snaps to the top-most
66 window edge available, without going all the way from
67 bottom-to-top in the stacking list
70 if (ct
< tb
&& cb
> tt
) {
71 if (cl
>= tr
&& l
< tr
&& l
>= tr
- config_resist_win
)
72 *x
= tr
, snapx
= target
;
73 else if (cr
<= tl
&& r
> tl
&&
74 r
<= tl
+ config_resist_win
)
75 *x
= tl
- w
+ 1, snapx
= target
;
77 /* try to corner snap to the window */
78 if (ct
> tt
&& t
<= tt
&&
79 t
> tt
- config_resist_win
)
80 *y
= tt
+ 1, snapy
= target
;
81 else if (cb
< tb
&& b
>= tb
&&
82 b
< tb
+ config_resist_win
)
83 *y
= tb
- h
, snapy
= target
;
88 if (cl
< tr
&& cr
> tl
) {
89 if (ct
>= tb
&& t
< tb
&& t
>= tb
- config_resist_win
)
90 *y
= tb
, snapy
= target
;
91 else if (cb
<= tt
&& b
> tt
&&
92 b
<= tt
+ config_resist_win
)
93 *y
= tt
- h
+ 1, snapy
= target
;
95 /* try to corner snap to the window */
96 if (cl
> tl
&& l
<= tl
&&
97 l
> tl
- config_resist_win
)
98 *x
= tl
+ 1, snapx
= target
;
99 else if (cr
< tr
&& r
>= tr
&&
100 r
< tr
+ config_resist_win
)
101 *x
= tr
- w
, snapx
= target
;
106 if (snapx
&& snapy
) break;
110 void resist_move_monitors(ObClient
*c
, gint
*x
, gint
*y
)
114 gint l
, t
, r
, b
; /* requested edges */
115 gint al
, at
, ar
, ab
; /* screen area edges */
116 gint pl
, pt
, pr
, pb
; /* physical screen area edges */
117 gint cl
, ct
, cr
, cb
; /* current edges */
118 gint w
, h
; /* current size */
120 w
= c
->frame
->area
.width
;
121 h
= c
->frame
->area
.height
;
128 cl
= RECT_LEFT(c
->frame
->area
);
129 ct
= RECT_TOP(c
->frame
->area
);
130 cr
= RECT_RIGHT(c
->frame
->area
);
131 cb
= RECT_BOTTOM(c
->frame
->area
);
133 if (config_resist_edge
) {
134 for (i
= 0; i
< screen_num_monitors
; ++i
) {
135 area
= screen_area_monitor(c
->desktop
, i
);
136 parea
= screen_physical_area_monitor(i
);
138 if (!RECT_INTERSECTS_RECT(*parea
, c
->frame
->area
))
141 al
= RECT_LEFT(*area
);
142 at
= RECT_TOP(*area
);
143 ar
= RECT_RIGHT(*area
);
144 ab
= RECT_BOTTOM(*area
);
145 pl
= RECT_LEFT(*parea
);
146 pt
= RECT_TOP(*parea
);
147 pr
= RECT_RIGHT(*parea
);
148 pb
= RECT_BOTTOM(*parea
);
150 if (cl
>= al
&& l
< al
&& l
>= al
- config_resist_edge
)
152 else if (cr
<= ar
&& r
> ar
&& r
<= ar
+ config_resist_edge
)
154 else if (cl
>= pl
&& l
< pl
&& l
>= pl
- config_resist_edge
)
156 else if (cr
<= pr
&& r
> pr
&& r
<= pr
+ config_resist_edge
)
159 if (ct
>= at
&& t
< at
&& t
>= at
- config_resist_edge
)
161 else if (cb
<= ab
&& b
> ab
&& b
< ab
+ config_resist_edge
)
163 else if (ct
>= pt
&& t
< pt
&& t
>= pt
- config_resist_edge
)
165 else if (cb
<= pb
&& b
> pb
&& b
< pb
+ config_resist_edge
)
171 void resist_size_windows(ObClient
*c
, gint
*w
, gint
*h
, ObCorner corn
)
174 ObClient
*target
; /* target */
175 gint l
, t
, r
, b
; /* my left, top, right and bottom sides */
176 gint dlt
, drb
; /* my destination left/top and right/bottom sides */
177 gint tl
, tt
, tr
, tb
; /* target's left, top, right and bottom bottom sides*/
179 ObClient
*snapx
= NULL
, *snapy
= NULL
;
181 incw
= c
->size_inc
.width
;
182 inch
= c
->size_inc
.height
;
184 l
= RECT_LEFT(c
->frame
->area
);
185 r
= RECT_RIGHT(c
->frame
->area
);
186 t
= RECT_TOP(c
->frame
->area
);
187 b
= RECT_BOTTOM(c
->frame
->area
);
189 if (config_resist_win
) {
190 for (it
= stacking_list
; it
!= NULL
; it
= it
->next
) {
191 if (!WINDOW_IS_CLIENT(it
->data
))
195 /* don't snap to invisibles or ourself */
196 if (!target
->frame
->visible
|| target
== c
) continue;
198 tl
= RECT_LEFT(target
->frame
->area
);
199 tr
= RECT_RIGHT(target
->frame
->area
);
200 tt
= RECT_TOP(target
->frame
->area
);
201 tb
= RECT_BOTTOM(target
->frame
->area
);
204 /* horizontal snapping */
205 if (t
< tb
&& b
> tt
) {
207 case OB_CORNER_TOPLEFT
:
208 case OB_CORNER_BOTTOMLEFT
:
210 drb
= r
+ *w
- c
->frame
->area
.width
;
211 if (r
< tl
&& drb
>= tl
&&
212 drb
< tl
+ config_resist_win
)
213 *w
= tl
- l
, snapx
= target
;
215 case OB_CORNER_TOPRIGHT
:
216 case OB_CORNER_BOTTOMRIGHT
:
217 dlt
= l
- *w
+ c
->frame
->area
.width
;
219 if (l
> tr
&& dlt
<= tr
&&
220 dlt
> tr
- config_resist_win
)
221 *w
= r
- tr
, snapx
= target
;
228 /* vertical snapping */
229 if (l
< tr
&& r
> tl
) {
231 case OB_CORNER_TOPLEFT
:
232 case OB_CORNER_TOPRIGHT
:
234 drb
= b
+ *h
- c
->frame
->area
.height
;
235 if (b
< tt
&& drb
>= tt
&&
236 drb
< tt
+ config_resist_win
)
237 *h
= tt
- t
, snapy
= target
;
239 case OB_CORNER_BOTTOMLEFT
:
240 case OB_CORNER_BOTTOMRIGHT
:
241 dlt
= t
- *h
+ c
->frame
->area
.height
;
243 if (t
> tb
&& dlt
<= tb
&&
244 dlt
> tb
- config_resist_win
)
245 *h
= b
- tb
, snapy
= target
;
251 /* snapped both ways */
252 if (snapx
&& snapy
) break;
257 void resist_size_monitors(ObClient
*c
, gint
*w
, gint
*h
, ObCorner corn
)
259 gint l
, t
, r
, b
; /* my left, top, right and bottom sides */
260 gint dlt
, drb
; /* my destination left/top and right/bottom sides */
262 gint al
, at
, ar
, ab
; /* screen boundaries */
263 gint pl
, pt
, pr
, pb
; /* physical screen boundaries */
267 l
= RECT_LEFT(c
->frame
->area
);
268 r
= RECT_RIGHT(c
->frame
->area
);
269 t
= RECT_TOP(c
->frame
->area
);
270 b
= RECT_BOTTOM(c
->frame
->area
);
272 incw
= c
->size_inc
.width
;
273 inch
= c
->size_inc
.height
;
275 for (i
= 0; i
< screen_num_monitors
; ++i
) {
276 area
= screen_area_monitor(c
->desktop
, i
);
277 parea
= screen_physical_area_monitor(i
);
279 if (!RECT_INTERSECTS_RECT(*parea
, c
->frame
->area
))
282 /* get the screen boundaries */
283 al
= RECT_LEFT(*area
);
284 at
= RECT_TOP(*area
);
285 ar
= RECT_RIGHT(*area
);
286 ab
= RECT_BOTTOM(*area
);
287 pl
= RECT_LEFT(*parea
);
288 pt
= RECT_TOP(*parea
);
289 pr
= RECT_RIGHT(*parea
);
290 pb
= RECT_BOTTOM(*parea
);
292 if (config_resist_edge
) {
293 /* horizontal snapping */
295 case OB_CORNER_TOPLEFT
:
296 case OB_CORNER_BOTTOMLEFT
:
298 drb
= r
+ *w
- c
->frame
->area
.width
;
299 if (r
<= ar
&& drb
> ar
&& drb
<= ar
+ config_resist_edge
)
301 else if (r
<= pr
&& drb
> pr
&& drb
<= pr
+ config_resist_edge
)
304 case OB_CORNER_TOPRIGHT
:
305 case OB_CORNER_BOTTOMRIGHT
:
306 dlt
= l
- *w
+ c
->frame
->area
.width
;
308 if (l
>= al
&& dlt
< al
&& dlt
>= al
- config_resist_edge
)
310 else if (l
>= pl
&& dlt
< pl
&& dlt
>= pl
- config_resist_edge
)
315 /* vertical snapping */
317 case OB_CORNER_TOPLEFT
:
318 case OB_CORNER_TOPRIGHT
:
320 drb
= b
+ *h
- c
->frame
->area
.height
;
321 if (b
<= ab
&& drb
> ab
&& drb
<= ab
+ config_resist_edge
)
323 else if (b
<= pb
&& drb
> pb
&& drb
<= pb
+ config_resist_edge
)
326 case OB_CORNER_BOTTOMLEFT
:
327 case OB_CORNER_BOTTOMRIGHT
:
328 dlt
= t
- *h
+ c
->frame
->area
.height
;
330 if (t
>= at
&& dlt
< at
&& dlt
>= at
- config_resist_edge
)
332 else if (t
>= pt
&& dlt
< pt
&& dlt
>= pt
- config_resist_edge
)
This page took 0.054237 seconds and 4 git commands to generate.