]>
Dogcows Code - chaz/openbox/blob - plugins/resistance.c
1 #include "../kernel/dispatch.h"
2 #include "../kernel/client.h"
3 #include "../kernel/frame.h"
4 #include "../kernel/stacking.h"
5 #include "../kernel/screen.h"
6 #include "../kernel/config.h"
9 #define DEFAULT_RESISTANCE 10
11 void plugin_setup_config()
15 config_def_set(config_def_new("resistance", Config_Integer
,
17 "The amount of resistance to provide when "
18 "moving windows past edges."
20 config_def_set(config_def_new("resistance.windows", Config_Bool
,
21 "Edge Resistance On Windows",
22 "Whether to provide edge resistance when "
23 "moving windows past the edge of another "
26 config_set("resistance.windows", Config_Bool
, val
);
29 static void resist_move(Client
*c
, int *x
, int *y
)
33 int l
, t
, r
, b
; /* requested edges */
34 int al
, at
, ar
, ab
; /* screen area edges */
35 int cl
, ct
, cr
, cb
; /* current edges */
36 int w
, h
; /* current size */
37 Client
*snapx
= NULL
, *snapy
= NULL
;
38 ConfigValue resist
, window_resist
;
40 if (!config_get("resistance", Config_Integer
, &resist
) ||
42 resist
.integer
= DEFAULT_RESISTANCE
;
43 config_set("resistance", Config_Integer
, resist
);
45 if (!config_get("resistance.windows", Config_Bool
, &window_resist
))
46 g_assert_not_reached();
48 w
= c
->frame
->area
.width
;
49 h
= c
->frame
->area
.height
;
56 cl
= c
->frame
->area
.x
;
57 ct
= c
->frame
->area
.y
;
58 cr
= cl
+ c
->frame
->area
.width
- 1;
59 cb
= ct
+ c
->frame
->area
.height
- 1;
61 /* snap to other clients */
62 if (window_resist
.bool)
63 for (it
= stacking_list
; it
!= NULL
; it
= it
->next
) {
65 int tl
, tt
, tr
, tb
; /* 1 past the target's edges on each side */
68 /* don't snap to self or non-visibles */
69 if (!target
->frame
->visible
|| target
== c
) continue;
71 tl
= target
->frame
->area
.x
- 1;
72 tt
= target
->frame
->area
.y
- 1;
73 tr
= tl
+ target
->frame
->area
.width
+ 1;
74 tb
= tt
+ target
->frame
->area
.height
+ 1;
76 /* snapx and snapy ensure that the window snaps to the top-most
77 window edge available, without going all the way from
78 bottom-to-top in the stacking list
81 if (cl
>= tr
&& l
< tr
&& l
>= tr
- resist
.integer
)
82 *x
= tr
, snapx
= target
;
83 else if (cr
<= tl
&& r
> tl
&& r
<= tl
+ resist
.integer
)
84 *x
= tl
- w
+ 1, snapx
= target
;
86 /* try to corner snap to the window */
87 if (ct
> tt
&& t
<= tt
&& t
> tt
- resist
.integer
)
88 *y
= tt
+ 1, snapy
= target
;
89 else if (cb
< tb
&& b
>= tb
&& b
< tb
+ resist
.integer
)
90 *y
= tb
- h
, snapy
= target
;
94 if (ct
>= tb
&& t
< tb
&& t
>= tb
- resist
.integer
)
95 *y
= tb
, snapy
= target
;
96 else if (!cb
<= tt
&& b
> tt
&& b
<= tt
+ resist
.integer
)
97 *y
= tt
- h
+ 1, snapy
= target
;
99 /* try to corner snap to the window */
100 if (cl
> tl
&& l
<= tl
&& l
> tl
- resist
.integer
)
101 *x
= tl
+ 1, snapx
= target
;
102 else if (cr
< tr
&& r
>= tr
&& r
< tr
+ resist
.integer
)
103 *x
= tr
- w
, snapx
= target
;
107 if (snapx
&& snapy
) break;
110 /* get the screen boundaries */
111 area
= screen_area(c
->desktop
);
114 ar
= al
+ area
->width
- 1;
115 ab
= at
+ area
->height
- 1;
117 /* snap to screen edges */
118 if (cl
>= al
&& l
< al
&& l
>= al
- resist
.integer
)
120 else if (cr
<= ar
&& r
> ar
&& r
<= ar
+ resist
.integer
)
122 if (ct
>= at
&& t
< at
&& t
>= at
- resist
.integer
)
124 else if (cb
<= ab
&& b
> ab
&& b
< ab
+ resist
.integer
)
128 static void resist_size(Client
*c
, int *w
, int *h
, Corner corn
)
131 Client
*t
; /* target */
132 int lt
, rb
; /* my left/top and right/bottom sides */
133 int dlt
, drb
; /* my destination left/top and right/bottom sides */
134 int tlt
, trb
; /* target's left/top and right/bottom sides */
136 int al
, at
, ar
, ab
; /* screen boundaries */
137 Client
*snapx
= NULL
, *snapy
= NULL
;
138 ConfigValue resist
, window_resist
;
140 if (!config_get("resistance", Config_Integer
, &resist
) ||
141 resist
.integer
< 0) {
142 resist
.integer
= DEFAULT_RESISTANCE
;
143 config_set("resistance", Config_Integer
, resist
);
145 if (!config_get("resistance.windows", Config_Bool
, &window_resist
))
146 g_assert_not_reached();
148 /* get the screen boundaries */
149 area
= screen_area(c
->desktop
);
152 ar
= al
+ area
->width
- 1;
153 ab
= at
+ area
->height
- 1;
155 /* horizontal snapping */
157 lt
= c
->frame
->area
.x
;
158 rb
= lt
+ c
->frame
->area
.width
- 1;
160 /* snap to other windows */
161 if (window_resist
.bool) {
162 for (it
= stacking_list
; !snapx
&& it
!= NULL
; it
= it
->next
) {
165 /* don't snap to invisibles or ourself */
166 if (!t
->frame
->visible
|| t
== c
) continue;
170 case Corner_BottomLeft
:
172 drb
= rb
+ *w
- c
->frame
->area
.width
;
173 tlt
= t
->frame
->area
.x
;
174 if (rb
< tlt
&& drb
>= tlt
&& drb
< tlt
+ resist
.integer
)
175 *w
= tlt
- lt
, snapx
= t
;
177 case Corner_TopRight
:
178 case Corner_BottomRight
:
179 dlt
= lt
- *w
+ c
->frame
->area
.width
;
181 trb
= t
->frame
->area
.x
+ t
->frame
->area
.width
- 1;
182 if (lt
> trb
&& dlt
<= trb
&& dlt
> trb
- resist
.integer
)
183 *w
= rb
- trb
, snapx
= t
;
189 /* snap to screen edges */
192 case Corner_BottomLeft
:
194 drb
= rb
+ *w
- c
->frame
->area
.width
;
195 if (rb
<= ar
&& drb
> ar
&& drb
<= ar
+ resist
.integer
)
198 case Corner_TopRight
:
199 case Corner_BottomRight
:
200 dlt
= lt
- *w
+ c
->frame
->area
.width
;
202 if (lt
>= al
&& dlt
< al
&& dlt
>= al
- resist
.integer
)
207 /* vertical snapping */
209 lt
= c
->frame
->area
.y
;
210 rb
= lt
+ c
->frame
->area
.height
- 1;
212 /* snap to other windows */
213 if (window_resist
.bool) {
214 for (it
= stacking_list
; !snapy
&& it
!= NULL
; it
= it
->next
) {
217 /* don't snap to invisibles or ourself */
218 if (!t
->frame
->visible
|| t
== c
) continue;
222 case Corner_TopRight
:
224 drb
= rb
+ *h
- c
->frame
->area
.height
;
225 tlt
= t
->frame
->area
.y
;
226 if (rb
< tlt
&& drb
>= tlt
&& drb
< tlt
+ resist
.integer
)
227 *h
= tlt
- lt
, snapy
= t
;
229 case Corner_BottomLeft
:
230 case Corner_BottomRight
:
231 dlt
= lt
- *h
+ c
->frame
->area
.height
;
233 trb
= t
->frame
->area
.y
+ t
->frame
->area
.height
- 1;
234 if (lt
> trb
&& dlt
<= trb
&& dlt
> trb
- resist
.integer
)
235 *h
= rb
- trb
, snapy
= t
;
241 /* snap to screen edges */
244 case Corner_TopRight
:
246 drb
= rb
+ *h
- c
->frame
->area
.height
;
247 g_message("dlt %d drb %d rb %d ab %d", dlt
, drb
, rb
, ab
);
248 if (rb
<= ab
&& drb
> ab
&& drb
<= ab
+ resist
.integer
)
251 case Corner_BottomLeft
:
252 case Corner_BottomRight
:
253 dlt
= lt
- *h
+ c
->frame
->area
.height
;
255 if (lt
>= at
&& dlt
< at
&& dlt
>= at
- resist
.integer
)
260 /* round down for size increments */
261 *w
-= c
->frame
->area
.width
+ c
->frame
->size
.left
+ c
->frame
->size
.right
;
262 *w
= *w
/ c
->size_inc
.width
* c
->size_inc
.width
;
263 *w
+= c
->frame
->area
.width
+ c
->frame
->size
.left
+ c
->frame
->size
.right
;
265 *h
-= c
->frame
->area
.height
+ c
->frame
->size
.top
+ c
->frame
->size
.bottom
;
266 *h
= *h
/ c
->size_inc
.height
* c
->size_inc
.height
;
267 *h
+= c
->frame
->area
.height
+ c
->frame
->size
.top
+ c
->frame
->size
.bottom
;
270 static void event(ObEvent
*e
, void *foo
)
272 if (e
->type
== Event_Client_Moving
)
273 resist_move(e
->data
.c
.client
, &e
->data
.c
.num
[0], &e
->data
.c
.num
[1]);
274 else if (e
->type
== Event_Client_Resizing
)
275 resist_size(e
->data
.c
.client
, &e
->data
.c
.num
[0], &e
->data
.c
.num
[1],
279 void plugin_startup()
281 dispatch_register(Event_Client_Moving
| Event_Client_Resizing
,
282 (EventHandler
)event
, NULL
);
285 void plugin_shutdown()
287 dispatch_register(0, (EventHandler
)event
, NULL
);
This page took 0.055525 seconds and 4 git commands to generate.