]> Dogcows Code - chaz/openbox/blob - openbox/action.c
check for no client
[chaz/openbox] / openbox / action.c
1 #include "client.h"
2 #include "stacking.h"
3 #include "frame.h"
4 #include "screen.h"
5 #include "action.h"
6 #include "dispatch.h"
7 #include "openbox.h"
8
9 #include <glib.h>
10
11 Action *action_new(void (*func)(union ActionData *data))
12 {
13 Action *a = g_new(Action, 1);
14 a->func = func;
15
16 /* deal with pointers */
17 if (func == action_execute)
18 a->data.execute.path = NULL;
19
20 return a;
21 }
22
23 void action_free(Action *a)
24 {
25 /* deal with pointers */
26 if (a->func == action_execute || a->func == action_restart)
27 g_free(a->data.execute.path);
28
29 g_free(a);
30 }
31
32 void action_execute(union ActionData *data)
33 {
34 GError *e = NULL;
35 if (!g_spawn_command_line_async(data->execute.path, &e)) {
36 g_warning("failed to execute '%s': %s",
37 data->execute.path, e->message);
38 }
39 }
40
41 void action_focus(union ActionData *data)
42 {
43 if (data->client.c)
44 client_focus(data->client.c);
45 }
46
47 void action_unfocus (union ActionData *data)
48 {
49 if (data->client.c)
50 client_unfocus(data->client.c);
51 }
52
53 void action_iconify(union ActionData *data)
54 {
55 if (data->client.c)
56 client_iconify(data->client.c, TRUE, TRUE);
57 }
58
59 void action_focusraise(union ActionData *data)
60 {
61 if (data->client.c) {
62 client_focus(data->client.c);
63 stacking_raise(data->client.c);
64 }
65 }
66
67 void action_raise(union ActionData *data)
68 {
69 if (data->client.c)
70 stacking_raise(data->client.c);
71 }
72
73 void action_lower(union ActionData *data)
74 {
75 if (data->client.c)
76 stacking_lower(data->client.c);
77 }
78
79 void action_close(union ActionData *data)
80 {
81 if (data->client.c)
82 client_close(data->client.c);
83 }
84
85 void action_kill(union ActionData *data)
86 {
87 if (data->client.c)
88 client_kill(data->client.c);
89 }
90
91 void action_shade(union ActionData *data)
92 {
93 if (data->client.c)
94 client_shade(data->client.c, TRUE);
95 }
96
97 void action_unshade(union ActionData *data)
98 {
99 if (data->client.c)
100 client_shade(data->client.c, FALSE);
101 }
102
103 void action_toggle_shade(union ActionData *data)
104 {
105 if (data->client.c)
106 client_shade(data->client.c, !data->client.c->shaded);
107 }
108
109 void action_toggle_omnipresent(union ActionData *data)
110 {
111 if (data->client.c)
112 client_set_desktop(data->client.c,
113 data->client.c->desktop == DESKTOP_ALL ?
114 screen_desktop : DESKTOP_ALL);
115 }
116
117 void action_move_relative(union ActionData *data)
118 {
119 Client *c = data->relative.c;
120 if (c)
121 client_configure(c, Corner_TopLeft,
122 c->area.x + data->relative.dx,
123 c->area.y + data->relative.dy,
124 c->area.width, c->area.height, TRUE, TRUE);
125 }
126
127 void action_resize_relative(union ActionData *data)
128 {
129 Client *c = data->relative.c;
130 if (c)
131 client_configure(c, Corner_TopLeft, c->area.x, c->area.y,
132 c->area.width + data->relative.dx,
133 c->area.height + data->relative.dy, TRUE, TRUE);
134 }
135
136 void action_maximize_full(union ActionData *data)
137 {
138 if (data->client.c)
139 client_maximize(data->client.c, TRUE, 0, TRUE);
140 }
141
142 void action_unmaximize_full(union ActionData *data)
143 {
144 if (data->client.c)
145 client_maximize(data->client.c, FALSE, 0, TRUE);
146 }
147
148 void action_toggle_maximize_full(union ActionData *data)
149 {
150 if (data->client.c)
151 client_maximize(data->client.c,
152 !(data->client.c->max_horz ||
153 data->client.c->max_vert),
154 0, TRUE);
155 }
156
157 void action_maximize_horz(union ActionData *data)
158 {
159 if (data->client.c)
160 client_maximize(data->client.c, TRUE, 1, TRUE);
161 }
162
163 void action_unmaximize_horz(union ActionData *data)
164 {
165 if (data->client.c)
166 client_maximize(data->client.c, FALSE, 1, TRUE);
167 }
168
169 void action_toggle_maximize_horz(union ActionData *data)
170 {
171 if (data->client.c)
172 client_maximize(data->client.c, !data->client.c->max_horz, 1, TRUE);
173 }
174
175 void action_maximize_vert(union ActionData *data)
176 {
177 if (data->client.c)
178 client_maximize(data->client.c, TRUE, 2, TRUE);
179 }
180
181 void action_unmaximize_vert(union ActionData *data)
182 {
183 if (data->client.c)
184 client_maximize(data->client.c, FALSE, 2, TRUE);
185 }
186
187 void action_toggle_maximize_vert(union ActionData *data)
188 {
189 if (data->client.c)
190 client_maximize(data->client.c, !data->client.c->max_vert, 2, TRUE);
191 }
192
193 void action_send_to_desktop(union ActionData *data)
194 {
195 if (data->sendto.c)
196 if (data->sendto.desktop < screen_num_desktops ||
197 data->sendto.desktop == DESKTOP_ALL)
198 client_set_desktop(data->sendto.c, data->sendto.desktop);
199 }
200
201 void action_send_to_next_desktop(union ActionData *data)
202 {
203 guint d;
204
205 if (!data->sendto.c) return;
206
207 d = screen_desktop + 1;
208 if (d >= screen_num_desktops) {
209 if (!data->sendtonextprev.wrap) return;
210 d = 0;
211 }
212 client_set_desktop(data->sendtonextprev.c, d);
213 if (data->sendtonextprev.follow) screen_set_desktop(d);
214 }
215
216 void action_send_to_previous_desktop(union ActionData *data)
217 {
218 guint d;
219
220 if (!data->sendto.c) return;
221
222 d = screen_desktop - 1;
223 if (d >= screen_num_desktops) {
224 if (!data->sendtonextprev.wrap) return;
225 d = screen_num_desktops - 1;
226 }
227 client_set_desktop(data->sendtonextprev.c, d);
228 if (data->sendtonextprev.follow) screen_set_desktop(d);
229 }
230
231 void action_desktop(union ActionData *data)
232 {
233 if (data->desktop.desk < screen_num_desktops ||
234 data->desktop.desk == DESKTOP_ALL)
235 screen_set_desktop(data->desktop.desk);
236 }
237
238 void action_next_desktop(union ActionData *data)
239 {
240 guint d;
241
242 d = screen_desktop + 1;
243 if (d >= screen_num_desktops) {
244 if (!data->nextprevdesktop.wrap) return;
245 d = 0;
246 }
247 screen_set_desktop(d);
248 }
249
250 void action_previous_desktop(union ActionData *data)
251 {
252 guint d;
253
254 d = screen_desktop - 1;
255 if (d >= screen_num_desktops) {
256 if (!data->nextprevdesktop.wrap) return;
257 d = screen_num_desktops - 1;
258 }
259 screen_set_desktop(d);
260 }
261
262 static void cur_row_col(guint *r, guint *c)
263 {
264 switch (screen_desktop_layout.orientation) {
265 case Orientation_Horz:
266 switch (screen_desktop_layout.start_corner) {
267 case Corner_TopLeft:
268 *r = screen_desktop / screen_desktop_layout.columns;
269 *c = screen_desktop % screen_desktop_layout.columns;
270 break;
271 case Corner_BottomLeft:
272 *r = screen_desktop_layout.rows - 1 -
273 screen_desktop / screen_desktop_layout.columns;
274 *c = screen_desktop % screen_desktop_layout.columns;
275 break;
276 break;
277 case Corner_TopRight:
278 *r = screen_desktop / screen_desktop_layout.columns;
279 *c = screen_desktop_layout.columns - 1 -
280 screen_desktop % screen_desktop_layout.columns;
281 break;
282 case Corner_BottomRight:
283 *r = screen_desktop_layout.rows - 1 -
284 screen_desktop / screen_desktop_layout.columns;
285 *c = screen_desktop_layout.columns - 1 -
286 screen_desktop % screen_desktop_layout.columns;
287 break;
288 break;
289 }
290 case Orientation_Vert:
291 switch (screen_desktop_layout.start_corner) {
292 case Corner_TopLeft:
293 *r = screen_desktop % screen_desktop_layout.rows;
294 *c = screen_desktop / screen_desktop_layout.rows;
295 break;
296 case Corner_BottomLeft:
297 *r = screen_desktop_layout.rows - 1 -
298 screen_desktop % screen_desktop_layout.rows;
299 *c = screen_desktop / screen_desktop_layout.rows;
300 break;
301 break;
302 case Corner_TopRight:
303 *r = screen_desktop % screen_desktop_layout.rows;
304 *c = screen_desktop_layout.columns - 1 -
305 screen_desktop / screen_desktop_layout.rows;
306 break;
307 case Corner_BottomRight:
308 *r = screen_desktop_layout.rows - 1 -
309 screen_desktop % screen_desktop_layout.rows;
310 *c = screen_desktop_layout.columns - 1 -
311 screen_desktop / screen_desktop_layout.rows;
312 break;
313 break;
314 }
315 break;
316 }
317 }
318
319 static guint translate_row_col(guint r, guint c)
320 {
321 switch (screen_desktop_layout.orientation) {
322 case Orientation_Horz:
323 switch (screen_desktop_layout.start_corner) {
324 case Corner_TopLeft:
325 return r * screen_desktop_layout.columns + c;
326 case Corner_BottomLeft:
327 return (screen_desktop_layout.rows - 1 - r) *
328 screen_desktop_layout.columns + c;
329 case Corner_TopRight:
330 return r * screen_desktop_layout.columns +
331 (screen_desktop_layout.columns - 1 - c);
332 case Corner_BottomRight:
333 return (screen_desktop_layout.rows - 1 - r) *
334 screen_desktop_layout.columns +
335 (screen_desktop_layout.columns - 1 - c);
336 }
337 case Orientation_Vert:
338 switch (screen_desktop_layout.start_corner) {
339 case Corner_TopLeft:
340 return c * screen_desktop_layout.rows + r;
341 case Corner_BottomLeft:
342 return c * screen_desktop_layout.rows +
343 (screen_desktop_layout.rows - 1 - r);
344 case Corner_TopRight:
345 return (screen_desktop_layout.columns - 1 - c) *
346 screen_desktop_layout.rows + r;
347 case Corner_BottomRight:
348 return (screen_desktop_layout.columns - 1 - c) *
349 screen_desktop_layout.rows +
350 (screen_desktop_layout.rows - 1 - r);
351 }
352 }
353 g_assert_not_reached();
354 return 0;
355 }
356
357 void action_next_desktop_column(union ActionData *data)
358 {
359 guint r, c, d;
360
361 cur_row_col(&r, &c);
362 ++c;
363 d = translate_row_col(r, c);
364 if (d >= screen_num_desktops) {
365 if (!data->nextprevdesktop.wrap) return;
366 c = 0;
367 }
368 if (d >= screen_num_desktops)
369 ++c;
370 d = translate_row_col(r, c);
371 if (d < screen_num_desktops)
372 screen_set_desktop(d);
373 }
374
375 void action_previous_desktop_column(union ActionData *data)
376 {
377 guint r, c, d;
378
379 cur_row_col(&r, &c);
380 --c;
381 d = translate_row_col(r, c);
382 if (d >= screen_num_desktops) {
383 if (!data->nextprevdesktop.wrap) return;
384 c = screen_desktop_layout.columns - 1;
385 }
386 if (d >= screen_num_desktops)
387 --c;
388 d = translate_row_col(r, c);
389 if (d < screen_num_desktops)
390 screen_set_desktop(d);
391 }
392
393 void action_next_desktop_row(union ActionData *data)
394 {
395 guint r, c, d;
396
397 cur_row_col(&r, &c);
398 ++r;
399 d = translate_row_col(r, c);
400 if (d >= screen_num_desktops) {
401 if (!data->nextprevdesktop.wrap) return;
402 r = 0;
403 }
404 if (d >= screen_num_desktops)
405 ++r;
406 d = translate_row_col(r, c);
407 if (d < screen_num_desktops)
408 screen_set_desktop(d);
409 }
410
411 void action_previous_desktop_row(union ActionData *data)
412 {
413 guint r, c, d;
414
415 cur_row_col(&r, &c);
416 --r;
417 d = translate_row_col(r, c);
418 if (d >= screen_num_desktops) {
419 if (!data->nextprevdesktop.wrap) return;
420 c = screen_desktop_layout.rows - 1;
421 }
422 if (d >= screen_num_desktops)
423 --r;
424 d = translate_row_col(r, c);
425 if (d < screen_num_desktops)
426 screen_set_desktop(d);
427 }
428
429 void action_toggle_decorations(union ActionData *data)
430 {
431 Client *c = data->client.c;
432 c->disabled_decorations = c->disabled_decorations ? 0 : ~0;
433 client_setup_decor_and_functions(c);
434 }
435
436 void action_move(union ActionData *data)
437 {
438 Client *c = data->move.c;
439 int x = data->move.x;
440 int y = data->move.y;
441
442 if (!c || !client_normal(c)) return;
443
444 dispatch_move(c, &x, &y);
445
446 frame_frame_gravity(c->frame, &x, &y); /* get where the client should be */
447 client_configure(c, Corner_TopLeft, x, y, c->area.width, c->area.height,
448 TRUE, data->move.final);
449 }
450
451 void action_resize(union ActionData *data)
452 {
453 Client *c = data->resize.c;
454 int w = data->resize.x - c->frame->size.left - c->frame->size.right;
455 int h = data->resize.y - c->frame->size.top - c->frame->size.bottom;
456
457 if (!c || !client_normal(c)) return;
458
459 /* XXX window snapping/struts */
460
461 client_configure(c, data->resize.corner, c->area.x, c->area.y, w, h,
462 TRUE, data->resize.final);
463 }
464
465 void action_restart(union ActionData *data)
466 {
467 ob_restart_path = data->execute.path;
468 ob_shutdown = ob_restart = TRUE;
469 }
470
471 void action_exit(union ActionData *data)
472 {
473 ob_shutdown = TRUE;
474 }
This page took 0.052845 seconds and 4 git commands to generate.