]>
Dogcows Code - chaz/openbox/blob - resist.c
dc4e2d7051dea248fa92d243405b2b7c3d2ddfe8
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 resist.c for the Openbox window manager
4 Copyright (c) 2006 Mikael Magnusson
5 Copyright (c) 2003-2007 Dana Jansens
7 This program 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 2 of the License, or
10 (at your option) any later version.
12 This program 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.
17 See the COPYING file for a copy of the GNU General Public License.
30 static gboolean
resist_move_window(Rect window
,
31 Rect target
, gint resist
,
34 gint l
, t
, r
, b
; /* requested edges */
35 gint cl
, ct
, cr
, cb
; /* current edges */
36 gint w
, h
; /* current size */
37 gint tl
, tt
, tr
, tb
; /* 1 past the target's edges on each side */
38 gboolean snapx
= 0, snapy
= 0;
48 cl
= RECT_LEFT(window
);
49 ct
= RECT_TOP(window
);
50 cr
= RECT_RIGHT(window
);
51 cb
= RECT_BOTTOM(window
);
53 tl
= RECT_LEFT(target
) - 1;
54 tt
= RECT_TOP(target
) - 1;
55 tr
= RECT_RIGHT(target
) + 1;
56 tb
= RECT_BOTTOM(target
) + 1;
58 /* snapx and snapy ensure that the window snaps to the top-most
59 window edge available, without going all the way from
60 bottom-to-top in the stacking list
63 if (ct
< tb
&& cb
> tt
) {
64 if (cl
>= tr
&& l
< tr
&& l
>= tr
- resist
)
65 *x
= tr
, snapx
= TRUE
;
66 else if (cr
<= tl
&& r
> tl
&&
68 *x
= tl
- w
+ 1, snapx
= TRUE
;
70 /* try to corner snap to the window */
71 if (ct
> tt
&& t
<= tt
&&
73 *y
= tt
+ 1, snapy
= TRUE
;
74 else if (cb
< tb
&& b
>= tb
&&
76 *y
= tb
- h
, snapy
= TRUE
;
81 if (cl
< tr
&& cr
> tl
) {
82 if (ct
>= tb
&& t
< tb
&& t
>= tb
- resist
)
83 *y
= tb
, snapy
= TRUE
;
84 else if (cb
<= tt
&& b
> tt
&&
86 *y
= tt
- h
+ 1, snapy
= TRUE
;
88 /* try to corner snap to the window */
89 if (cl
> tl
&& l
<= tl
&&
91 *x
= tl
+ 1, snapx
= TRUE
;
92 else if (cr
< tr
&& r
>= tr
&&
94 *x
= tr
- w
, snapx
= TRUE
;
99 return snapx
&& snapy
;
102 void resist_move_windows(ObClient
*c
, gint resist
, gint
*x
, gint
*y
)
109 frame_client_gravity(c
->frame
, x
, y
);
112 for (it
= stacking_list
; it
; it
= g_list_next(it
)) {
115 if (!WINDOW_IS_CLIENT(it
->data
))
119 /* don't snap to self or non-visibles */
120 if (!target
->frame
->visible
|| target
== c
)
122 /* don't snap to windows set to below and skip_taskbar (desklets) */
123 if (target
->below
&& !c
->below
&& target
->skip_taskbar
)
126 if (resist_move_window(c
->frame
->area
, target
->frame
->area
,
130 dock_get_area(&dock_area
);
131 resist_move_window(c
->frame
->area
, dock_area
, resist
, x
, y
);
133 frame_frame_gravity(c
->frame
, x
, y
);
136 void resist_move_monitors(ObClient
*c
, gint resist
, gint
*x
, gint
*y
)
140 gint l
, t
, r
, b
; /* requested edges */
141 gint al
, at
, ar
, ab
; /* screen area edges */
142 gint pl
, pt
, pr
, pb
; /* physical screen area edges */
143 gint cl
, ct
, cr
, cb
; /* current edges */
144 gint w
, h
; /* current size */
149 frame_client_gravity(c
->frame
, x
, y
);
151 w
= c
->frame
->area
.width
;
152 h
= c
->frame
->area
.height
;
159 cl
= RECT_LEFT(c
->frame
->area
);
160 ct
= RECT_TOP(c
->frame
->area
);
161 cr
= RECT_RIGHT(c
->frame
->area
);
162 cb
= RECT_BOTTOM(c
->frame
->area
);
164 RECT_SET(desired_area
, c
->frame
->area
.x
, c
->frame
->area
.y
,
165 c
->frame
->area
.width
, c
->frame
->area
.height
);
167 for (i
= 0; i
< screen_num_monitors
; ++i
) {
168 parea
= screen_physical_area_monitor(i
);
170 if (!RECT_INTERSECTS_RECT(*parea
, c
->frame
->area
)) {
175 area
= screen_area(c
->desktop
, SCREEN_AREA_ALL_MONITORS
,
178 al
= RECT_LEFT(*area
);
179 at
= RECT_TOP(*area
);
180 ar
= RECT_RIGHT(*area
);
181 ab
= RECT_BOTTOM(*area
);
182 pl
= RECT_LEFT(*parea
);
183 pt
= RECT_TOP(*parea
);
184 pr
= RECT_RIGHT(*parea
);
185 pb
= RECT_BOTTOM(*parea
);
187 if (cl
>= al
&& l
< al
&& l
>= al
- resist
)
189 else if (cr
<= ar
&& r
> ar
&& r
<= ar
+ resist
)
191 else if (cl
>= pl
&& l
< pl
&& l
>= pl
- resist
)
193 else if (cr
<= pr
&& r
> pr
&& r
<= pr
+ resist
)
196 if (ct
>= at
&& t
< at
&& t
>= at
- resist
)
198 else if (cb
<= ab
&& b
> ab
&& b
< ab
+ resist
)
200 else if (ct
>= pt
&& t
< pt
&& t
>= pt
- resist
)
202 else if (cb
<= pb
&& b
> pb
&& b
< pb
+ resist
)
209 frame_frame_gravity(c
->frame
, x
, y
);
212 static gboolean
resist_size_window(Rect window
, Rect target
, gint resist
,
213 gint
*w
, gint
*h
, ObDirection dir
)
215 gint l
, t
, r
, b
; /* my left, top, right and bottom sides */
216 gint tl
, tt
, tr
, tb
; /* target's left, top, right and bottom bottom sides*/
217 gint dlt
, drb
; /* my destination left/top and right/bottom sides */
218 gboolean snapx
= 0, snapy
= 0;
221 l
= RECT_LEFT(window
);
222 t
= RECT_TOP(window
);
223 r
= RECT_RIGHT(window
);
224 b
= RECT_BOTTOM(window
);
227 orgh
= window
.height
;
229 tl
= RECT_LEFT(target
);
230 tt
= RECT_TOP(target
);
231 tr
= RECT_RIGHT(target
);
232 tb
= RECT_BOTTOM(target
);
235 /* horizontal snapping */
236 if (t
< tb
&& b
> tt
) {
238 case OB_DIRECTION_EAST
:
239 case OB_DIRECTION_NORTHEAST
:
240 case OB_DIRECTION_SOUTHEAST
:
241 case OB_DIRECTION_NORTH
:
242 case OB_DIRECTION_SOUTH
:
245 if (r
< tl
&& drb
>= tl
&&
247 *w
= tl
- l
, snapx
= TRUE
;
249 case OB_DIRECTION_WEST
:
250 case OB_DIRECTION_NORTHWEST
:
251 case OB_DIRECTION_SOUTHWEST
:
254 if (l
> tr
&& dlt
<= tr
&&
256 *w
= r
- tr
, snapx
= TRUE
;
263 /* vertical snapping */
264 if (l
< tr
&& r
> tl
) {
266 case OB_DIRECTION_SOUTH
:
267 case OB_DIRECTION_SOUTHWEST
:
268 case OB_DIRECTION_SOUTHEAST
:
269 case OB_DIRECTION_EAST
:
270 case OB_DIRECTION_WEST
:
273 if (b
< tt
&& drb
>= tt
&&
275 *h
= tt
- t
, snapy
= TRUE
;
277 case OB_DIRECTION_NORTH
:
278 case OB_DIRECTION_NORTHWEST
:
279 case OB_DIRECTION_NORTHEAST
:
282 if (t
> tb
&& dlt
<= tb
&&
284 *h
= b
- tb
, snapy
= TRUE
;
290 /* snapped both ways */
291 return snapx
&& snapy
;
294 void resist_size_windows(ObClient
*c
, gint resist
, gint
*w
, gint
*h
,
298 ObClient
*target
; /* target */
303 for (it
= stacking_list
; it
; it
= g_list_next(it
)) {
304 if (!WINDOW_IS_CLIENT(it
->data
))
308 /* don't snap to invisibles or ourself */
309 if (!target
->frame
->visible
|| target
== c
)
311 /* don't snap to windows set to below and skip_taskbar (desklets) */
312 if (target
->below
&& !c
->below
&& target
->skip_taskbar
)
315 if (resist_size_window(c
->frame
->area
, target
->frame
->area
,
319 dock_get_area(&dock_area
);
320 resist_size_window(c
->frame
->area
, dock_area
,
324 void resist_size_monitors(ObClient
*c
, gint resist
, gint
*w
, gint
*h
,
327 gint l
, t
, r
, b
; /* my left, top, right and bottom sides */
328 gint dlt
, drb
; /* my destination left/top and right/bottom sides */
330 gint al
, at
, ar
, ab
; /* screen boundaries */
331 gint pl
, pt
, pr
, pb
; /* physical screen boundaries */
337 l
= RECT_LEFT(c
->frame
->area
);
338 r
= RECT_RIGHT(c
->frame
->area
);
339 t
= RECT_TOP(c
->frame
->area
);
340 b
= RECT_BOTTOM(c
->frame
->area
);
342 RECT_SET(desired_area
, c
->area
.x
, c
->area
.y
, *w
, *h
);
344 for (i
= 0; i
< screen_num_monitors
; ++i
) {
345 parea
= screen_physical_area_monitor(i
);
347 if (!RECT_INTERSECTS_RECT(*parea
, c
->frame
->area
)) {
352 area
= screen_area(c
->desktop
, SCREEN_AREA_ALL_MONITORS
,
355 /* get the screen boundaries */
356 al
= RECT_LEFT(*area
);
357 at
= RECT_TOP(*area
);
358 ar
= RECT_RIGHT(*area
);
359 ab
= RECT_BOTTOM(*area
);
360 pl
= RECT_LEFT(*parea
);
361 pt
= RECT_TOP(*parea
);
362 pr
= RECT_RIGHT(*parea
);
363 pb
= RECT_BOTTOM(*parea
);
365 /* horizontal snapping */
367 case OB_DIRECTION_EAST
:
368 case OB_DIRECTION_NORTHEAST
:
369 case OB_DIRECTION_SOUTHEAST
:
370 case OB_DIRECTION_NORTH
:
371 case OB_DIRECTION_SOUTH
:
373 drb
= r
+ *w
- c
->frame
->area
.width
;
374 if (r
<= ar
&& drb
> ar
&& drb
<= ar
+ resist
)
376 else if (r
<= pr
&& drb
> pr
&& drb
<= pr
+ resist
)
379 case OB_DIRECTION_WEST
:
380 case OB_DIRECTION_NORTHWEST
:
381 case OB_DIRECTION_SOUTHWEST
:
382 dlt
= l
- *w
+ c
->frame
->area
.width
;
384 if (l
>= al
&& dlt
< al
&& dlt
>= al
- resist
)
386 else if (l
>= pl
&& dlt
< pl
&& dlt
>= pl
- resist
)
391 /* vertical snapping */
393 case OB_DIRECTION_SOUTH
:
394 case OB_DIRECTION_SOUTHWEST
:
395 case OB_DIRECTION_SOUTHEAST
:
396 case OB_DIRECTION_WEST
:
397 case OB_DIRECTION_EAST
:
399 drb
= b
+ *h
- c
->frame
->area
.height
;
400 if (b
<= ab
&& drb
> ab
&& drb
<= ab
+ resist
)
402 else if (b
<= pb
&& drb
> pb
&& drb
<= pb
+ resist
)
405 case OB_DIRECTION_NORTH
:
406 case OB_DIRECTION_NORTHWEST
:
407 case OB_DIRECTION_NORTHEAST
:
408 dlt
= t
- *h
+ c
->frame
->area
.height
;
410 if (t
>= at
&& dlt
< at
&& dlt
>= at
- resist
)
412 else if (t
>= pt
&& dlt
< pt
&& dlt
>= pt
- resist
)
This page took 0.049631 seconds and 3 git commands to generate.