]> Dogcows Code - chaz/openbox/blob - openbox/action.c
allow specifying that some focus events should be ignored for the focus order list
[chaz/openbox] / openbox / action.c
1 #include "client.h"
2 #include "focus.h"
3 #include "stacking.h"
4 #include "frame.h"
5 #include "screen.h"
6 #include "action.h"
7 #include "dispatch.h"
8 #include "openbox.h"
9
10 #include <glib.h>
11
12 Action *action_new(void (*func)(union ActionData *data))
13 {
14 Action *a = g_new0(Action, 1);
15 a->func = func;
16
17 /* deal with pointers */
18 if (func == action_execute)
19 a->data.execute.path = NULL;
20
21 return a;
22 }
23
24 void action_free(Action *a)
25 {
26 if (a == NULL) return;
27
28 /* deal with pointers */
29 if (a->func == action_execute || a->func == action_restart)
30 g_free(a->data.execute.path);
31
32 g_free(a);
33 }
34
35 Action *action_from_string(char *name)
36 {
37 Action *a = NULL;
38 if (!g_ascii_strcasecmp(name, "execute")) {
39 a = action_new(action_execute);
40 } else if (!g_ascii_strcasecmp(name, "focus")) {
41 a = action_new(action_focus);
42 } else if (!g_ascii_strcasecmp(name, "unfocus")) {
43 a = action_new(action_unfocus);
44 } else if (!g_ascii_strcasecmp(name, "iconify")) {
45 a = action_new(action_iconify);
46 } else if (!g_ascii_strcasecmp(name, "raise")) {
47 a = action_new(action_raise);
48 } else if (!g_ascii_strcasecmp(name, "lower")) {
49 a = action_new(action_lower);
50 } else if (!g_ascii_strcasecmp(name, "focusraise")) {
51 a = action_new(action_focusraise);
52 } else if (!g_ascii_strcasecmp(name, "close")) {
53 a = action_new(action_close);
54 } else if (!g_ascii_strcasecmp(name, "kill")) {
55 a = action_new(action_kill);
56 } else if (!g_ascii_strcasecmp(name, "shadelower")) {
57 a = action_new(action_shadelower);
58 } else if (!g_ascii_strcasecmp(name, "unshaderaise")) {
59 a = action_new(action_unshaderaise);
60 } else if (!g_ascii_strcasecmp(name, "shade")) {
61 a = action_new(action_shade);
62 } else if (!g_ascii_strcasecmp(name, "unshade")) {
63 a = action_new(action_unshade);
64 } else if (!g_ascii_strcasecmp(name, "toggleshade")) {
65 a = action_new(action_toggle_shade);
66 } else if (!g_ascii_strcasecmp(name, "toggleomnipresent")) {
67 a = action_new(action_toggle_omnipresent);
68 } else if (!g_ascii_strcasecmp(name, "moverelativehorz")) {
69 a = action_new(action_move_relative_horz);
70 } else if (!g_ascii_strcasecmp(name, "moverelativevert")) {
71 a = action_new(action_move_relative_vert);
72 } else if (!g_ascii_strcasecmp(name, "resizerelativehorz")) {
73 a = action_new(action_resize_relative_horz);
74 } else if (!g_ascii_strcasecmp(name, "resizerelativevert")) {
75 a = action_new(action_resize_relative_vert);
76 } else if (!g_ascii_strcasecmp(name, "maximizefull")) {
77 a = action_new(action_maximize_full);
78 } else if (!g_ascii_strcasecmp(name, "unmaximizefull")) {
79 a = action_new(action_unmaximize_full);
80 } else if (!g_ascii_strcasecmp(name, "togglemaximizefull")) {
81 a = action_new(action_toggle_maximize_full);
82 } else if (!g_ascii_strcasecmp(name, "maximizehorz")) {
83 a = action_new(action_maximize_horz);
84 } else if (!g_ascii_strcasecmp(name, "unmaximizehorz")) {
85 a = action_new(action_unmaximize_horz);
86 } else if (!g_ascii_strcasecmp(name, "togglemaximizehorz")) {
87 a = action_new(action_toggle_maximize_horz);
88 } else if (!g_ascii_strcasecmp(name, "maximizevert")) {
89 a = action_new(action_maximize_vert);
90 } else if (!g_ascii_strcasecmp(name, "unmaximizevert")) {
91 a = action_new(action_unmaximize_vert);
92 } else if (!g_ascii_strcasecmp(name, "togglemaximizevert")) {
93 a = action_new(action_toggle_maximize_vert);
94 } else if (!g_ascii_strcasecmp(name, "sendtodesktop")) {
95 a = action_new(action_send_to_desktop);
96 a->data.sendto.follow = TRUE;
97 } else if (!g_ascii_strcasecmp(name, "sendtonextdesktop")) {
98 a = action_new(action_send_to_next_desktop);
99 a->data.sendtonextprev.wrap = FALSE;
100 a->data.sendtonextprev.follow = TRUE;
101 } else if (!g_ascii_strcasecmp(name, "sendtonextdesktopwrap")) {
102 a = action_new(action_send_to_next_desktop);
103 a->data.sendtonextprev.wrap = TRUE;
104 a->data.sendtonextprev.follow = TRUE;
105 } else if (!g_ascii_strcasecmp(name, "sendtopreviousdesktop")) {
106 a = action_new(action_send_to_previous_desktop);
107 a->data.sendtonextprev.wrap = FALSE;
108 a->data.sendtonextprev.follow = TRUE;
109 } else if (!g_ascii_strcasecmp(name, "sendtopreviousdesktopwrap")) {
110 a = action_new(action_send_to_previous_desktop);
111 a->data.sendtonextprev.wrap = TRUE;
112 a->data.sendtonextprev.follow = TRUE;
113 } else if (!g_ascii_strcasecmp(name, "desktop")) {
114 a = action_new(action_desktop);
115 } else if (!g_ascii_strcasecmp(name, "nextdesktop")) {
116 a = action_new(action_next_desktop);
117 a->data.nextprevdesktop.wrap = FALSE;
118 } else if (!g_ascii_strcasecmp(name, "nextdesktopwrap")) {
119 a = action_new(action_next_desktop);
120 a->data.nextprevdesktop.wrap = TRUE;
121 } else if (!g_ascii_strcasecmp(name, "previousdesktop")) {
122 a = action_new(action_previous_desktop);
123 a->data.nextprevdesktop.wrap = FALSE;
124 } else if (!g_ascii_strcasecmp(name, "previousdesktopwrap")) {
125 a = action_new(action_previous_desktop);
126 a->data.nextprevdesktop.wrap = TRUE;
127 } else if (!g_ascii_strcasecmp(name, "nextdesktopcolumn")) {
128 a = action_new(action_next_desktop_column);
129 a->data.nextprevdesktop.wrap = FALSE;
130 } else if (!g_ascii_strcasecmp(name, "nextdesktopcolumnwrap")) {
131 a = action_new(action_next_desktop_column);
132 a->data.nextprevdesktop.wrap = TRUE;
133 } else if (!g_ascii_strcasecmp(name, "previousdesktopcolumn")) {
134 a = action_new(action_previous_desktop_column);
135 a->data.nextprevdesktop.wrap = FALSE;
136 } else if (!g_ascii_strcasecmp(name, "previousdesktopcolumnwrap")) {
137 a = action_new(action_previous_desktop_column);
138 a->data.nextprevdesktop.wrap = TRUE;
139 } else if (!g_ascii_strcasecmp(name, "nextdesktoprow")) {
140 a = action_new(action_next_desktop_row);
141 a->data.nextprevdesktop.wrap = FALSE;
142 } else if (!g_ascii_strcasecmp(name, "nextdesktoprowwrap")) {
143 a = action_new(action_next_desktop_row);
144 a->data.nextprevdesktop.wrap = TRUE;
145 } else if (!g_ascii_strcasecmp(name, "previousdesktoprow")) {
146 a = action_new(action_previous_desktop_row);
147 a->data.nextprevdesktop.wrap = FALSE;
148 } else if (!g_ascii_strcasecmp(name, "previousdesktoprowwrap")) {
149 a = action_new(action_previous_desktop_row);
150 a->data.nextprevdesktop.wrap = TRUE;
151 } else if (!g_ascii_strcasecmp(name, "toggledecorations")) {
152 a = action_new(action_toggle_decorations);
153 } else if (!g_ascii_strcasecmp(name, "move")) {
154 a = action_new(action_move);
155 } else if (!g_ascii_strcasecmp(name, "resize")) {
156 a = action_new(action_resize);
157 } else if (!g_ascii_strcasecmp(name, "restart")) {
158 a = action_new(action_restart);
159 } else if (!g_ascii_strcasecmp(name, "exit")) {
160 a = action_new(action_exit);
161 } else if (!g_ascii_strcasecmp(name, "showmenu")) {
162 a = action_new(action_showmenu);
163 } else if (!g_ascii_strcasecmp(name, "nextwindowlinear")) {
164 a = action_new(action_cycle_windows);
165 a->data.cycle.linear = TRUE;
166 a->data.cycle.forward = TRUE;
167 } else if (!g_ascii_strcasecmp(name, "previouswindowlinear")) {
168 a = action_new(action_cycle_windows);
169 a->data.cycle.linear = TRUE;
170 a->data.cycle.forward = FALSE;
171 } else if (!g_ascii_strcasecmp(name, "nextwindow")) {
172 a = action_new(action_cycle_windows);
173 a->data.cycle.linear = FALSE;
174 a->data.cycle.forward = TRUE;
175 } else if (!g_ascii_strcasecmp(name, "previouswindow")) {
176 a = action_new(action_cycle_windows);
177 a->data.cycle.linear = FALSE;
178 a->data.cycle.forward = FALSE;
179 }
180
181 return a;
182 }
183
184 void action_execute(union ActionData *data)
185 {
186 GError *e = NULL;
187 if (data->execute.path)
188 if (!g_spawn_command_line_async(data->execute.path, &e)) {
189 g_warning("failed to execute '%s': %s",
190 data->execute.path, e->message);
191 }
192 }
193
194 void action_focus(union ActionData *data)
195 {
196 if (data->client.c)
197 client_focus(data->client.c);
198 }
199
200 void action_unfocus (union ActionData *data)
201 {
202 if (data->client.c)
203 client_unfocus(data->client.c);
204 }
205
206 void action_iconify(union ActionData *data)
207 {
208 if (data->client.c)
209 client_iconify(data->client.c, TRUE, TRUE);
210 }
211
212 void action_focusraise(union ActionData *data)
213 {
214 if (data->client.c) {
215 client_focus(data->client.c);
216 stacking_raise(data->client.c);
217 }
218 }
219
220 void action_raise(union ActionData *data)
221 {
222 if (data->client.c)
223 stacking_raise(data->client.c);
224 }
225
226 void action_unshaderaise(union ActionData *data)
227 {
228 if (data->client.c) {
229 if (data->client.c->shaded)
230 client_shade(data->client.c, FALSE);
231 else
232 stacking_raise(data->client.c);
233 }
234 }
235
236 void action_shadelower(union ActionData *data)
237 {
238 if (data->client.c) {
239 if (data->client.c->shaded)
240 stacking_lower(data->client.c);
241 else
242 client_shade(data->client.c, TRUE);
243 }
244 }
245
246 void action_lower(union ActionData *data)
247 {
248 if (data->client.c)
249 stacking_lower(data->client.c);
250 }
251
252 void action_close(union ActionData *data)
253 {
254 if (data->client.c)
255 client_close(data->client.c);
256 }
257
258 void action_kill(union ActionData *data)
259 {
260 if (data->client.c)
261 client_kill(data->client.c);
262 }
263
264 void action_shade(union ActionData *data)
265 {
266 if (data->client.c)
267 client_shade(data->client.c, TRUE);
268 }
269
270 void action_unshade(union ActionData *data)
271 {
272 if (data->client.c)
273 client_shade(data->client.c, FALSE);
274 }
275
276 void action_toggle_shade(union ActionData *data)
277 {
278 if (data->client.c)
279 client_shade(data->client.c, !data->client.c->shaded);
280 }
281
282 void action_toggle_omnipresent(union ActionData *data)
283 {
284 if (data->client.c)
285 client_set_desktop(data->client.c,
286 data->client.c->desktop == DESKTOP_ALL ?
287 screen_desktop : DESKTOP_ALL, FALSE);
288 }
289
290 void action_move_relative_horz(union ActionData *data)
291 {
292 Client *c = data->relative.c;
293 if (c)
294 client_configure(c, Corner_TopLeft,
295 c->area.x + data->relative.delta, c->area.y,
296 c->area.width, c->area.height, TRUE, TRUE);
297 }
298
299 void action_move_relative_vert(union ActionData *data)
300 {
301 Client *c = data->relative.c;
302 if (c)
303 client_configure(c, Corner_TopLeft,
304 c->area.x, c->area.y + data->relative.delta,
305 c->area.width, c->area.height, TRUE, TRUE);
306 }
307
308 void action_resize_relative_horz(union ActionData *data)
309 {
310 Client *c = data->relative.c;
311 if (c)
312 client_configure(c, Corner_TopLeft, c->area.x, c->area.y,
313 c->area.width + data->relative.delta,
314 c->area.height, TRUE, TRUE);
315 }
316
317 void action_resize_relative_vert(union ActionData *data)
318 {
319 Client *c = data->relative.c;
320 if (c && !c->shaded)
321 client_configure(c, Corner_TopLeft, c->area.x, c->area.y,
322 c->area.width, c->area.height + data->relative.delta,
323 TRUE, TRUE);
324 }
325
326 void action_maximize_full(union ActionData *data)
327 {
328 if (data->client.c)
329 client_maximize(data->client.c, TRUE, 0, TRUE);
330 }
331
332 void action_unmaximize_full(union ActionData *data)
333 {
334 if (data->client.c)
335 client_maximize(data->client.c, FALSE, 0, TRUE);
336 }
337
338 void action_toggle_maximize_full(union ActionData *data)
339 {
340 if (data->client.c)
341 client_maximize(data->client.c,
342 !(data->client.c->max_horz ||
343 data->client.c->max_vert),
344 0, TRUE);
345 }
346
347 void action_maximize_horz(union ActionData *data)
348 {
349 if (data->client.c)
350 client_maximize(data->client.c, TRUE, 1, TRUE);
351 }
352
353 void action_unmaximize_horz(union ActionData *data)
354 {
355 if (data->client.c)
356 client_maximize(data->client.c, FALSE, 1, TRUE);
357 }
358
359 void action_toggle_maximize_horz(union ActionData *data)
360 {
361 if (data->client.c)
362 client_maximize(data->client.c, !data->client.c->max_horz, 1, TRUE);
363 }
364
365 void action_maximize_vert(union ActionData *data)
366 {
367 if (data->client.c)
368 client_maximize(data->client.c, TRUE, 2, TRUE);
369 }
370
371 void action_unmaximize_vert(union ActionData *data)
372 {
373 if (data->client.c)
374 client_maximize(data->client.c, FALSE, 2, TRUE);
375 }
376
377 void action_toggle_maximize_vert(union ActionData *data)
378 {
379 if (data->client.c)
380 client_maximize(data->client.c, !data->client.c->max_vert, 2, TRUE);
381 }
382
383 void action_send_to_desktop(union ActionData *data)
384 {
385 if (data->sendto.c) {
386 if (data->sendto.desk < screen_num_desktops ||
387 data->sendto.desk == DESKTOP_ALL) {
388 client_set_desktop(data->desktop.c,
389 data->sendto.desk, data->sendto.follow);
390 if (data->sendto.follow) screen_set_desktop(data->sendto.desk);
391 }
392 }
393 }
394
395 void action_send_to_next_desktop(union ActionData *data)
396 {
397 guint d;
398
399 if (!data->sendtonextprev.c) return;
400
401 d = screen_desktop + 1;
402 if (d >= screen_num_desktops) {
403 if (!data->sendtonextprev.wrap) return;
404 d = 0;
405 }
406 client_set_desktop(data->sendtonextprev.c, d, data->sendtonextprev.follow);
407 if (data->sendtonextprev.follow) screen_set_desktop(d);
408 }
409
410 void action_send_to_previous_desktop(union ActionData *data)
411 {
412 guint d;
413
414 if (!data->sendtonextprev.c) return;
415
416 d = screen_desktop - 1;
417 if (d >= screen_num_desktops) {
418 if (!data->sendtonextprev.wrap) return;
419 d = screen_num_desktops - 1;
420 }
421 client_set_desktop(data->sendtonextprev.c, d, data->sendtonextprev.follow);
422 if (data->sendtonextprev.follow) screen_set_desktop(d);
423 }
424
425 void action_desktop(union ActionData *data)
426 {
427 if (data->desktop.desk < screen_num_desktops ||
428 data->desktop.desk == DESKTOP_ALL)
429 screen_set_desktop(data->desktop.desk);
430 }
431
432 void action_next_desktop(union ActionData *data)
433 {
434 guint d;
435
436 d = screen_desktop + 1;
437 if (d >= screen_num_desktops) {
438 if (!data->nextprevdesktop.wrap) return;
439 d = 0;
440 }
441 screen_set_desktop(d);
442 }
443
444 void action_previous_desktop(union ActionData *data)
445 {
446 guint d;
447
448 d = screen_desktop - 1;
449 if (d >= screen_num_desktops) {
450 if (!data->nextprevdesktop.wrap) return;
451 d = screen_num_desktops - 1;
452 }
453 screen_set_desktop(d);
454 }
455
456 static void cur_row_col(guint *r, guint *c)
457 {
458 switch (screen_desktop_layout.orientation) {
459 case Orientation_Horz:
460 switch (screen_desktop_layout.start_corner) {
461 case Corner_TopLeft:
462 *r = screen_desktop / screen_desktop_layout.columns;
463 *c = screen_desktop % screen_desktop_layout.columns;
464 break;
465 case Corner_BottomLeft:
466 *r = screen_desktop_layout.rows - 1 -
467 screen_desktop / screen_desktop_layout.columns;
468 *c = screen_desktop % screen_desktop_layout.columns;
469 break;
470 case Corner_TopRight:
471 *r = screen_desktop / screen_desktop_layout.columns;
472 *c = screen_desktop_layout.columns - 1 -
473 screen_desktop % screen_desktop_layout.columns;
474 break;
475 case Corner_BottomRight:
476 *r = screen_desktop_layout.rows - 1 -
477 screen_desktop / screen_desktop_layout.columns;
478 *c = screen_desktop_layout.columns - 1 -
479 screen_desktop % screen_desktop_layout.columns;
480 break;
481 }
482 break;
483 case Orientation_Vert:
484 switch (screen_desktop_layout.start_corner) {
485 case Corner_TopLeft:
486 *r = screen_desktop % screen_desktop_layout.rows;
487 *c = screen_desktop / screen_desktop_layout.rows;
488 break;
489 case Corner_BottomLeft:
490 *r = screen_desktop_layout.rows - 1 -
491 screen_desktop % screen_desktop_layout.rows;
492 *c = screen_desktop / screen_desktop_layout.rows;
493 break;
494 case Corner_TopRight:
495 *r = screen_desktop % screen_desktop_layout.rows;
496 *c = screen_desktop_layout.columns - 1 -
497 screen_desktop / screen_desktop_layout.rows;
498 break;
499 case Corner_BottomRight:
500 *r = screen_desktop_layout.rows - 1 -
501 screen_desktop % screen_desktop_layout.rows;
502 *c = screen_desktop_layout.columns - 1 -
503 screen_desktop / screen_desktop_layout.rows;
504 break;
505 }
506 break;
507 }
508 }
509
510 static guint translate_row_col(guint r, guint c)
511 {
512 switch (screen_desktop_layout.orientation) {
513 case Orientation_Horz:
514 switch (screen_desktop_layout.start_corner) {
515 case Corner_TopLeft:
516 return r * screen_desktop_layout.columns + c;
517 case Corner_BottomLeft:
518 return (screen_desktop_layout.rows - 1 - r) *
519 screen_desktop_layout.columns + c;
520 case Corner_TopRight:
521 return r * screen_desktop_layout.columns +
522 (screen_desktop_layout.columns - 1 - c);
523 case Corner_BottomRight:
524 return (screen_desktop_layout.rows - 1 - r) *
525 screen_desktop_layout.columns +
526 (screen_desktop_layout.columns - 1 - c);
527 }
528 case Orientation_Vert:
529 switch (screen_desktop_layout.start_corner) {
530 case Corner_TopLeft:
531 return c * screen_desktop_layout.rows + r;
532 case Corner_BottomLeft:
533 return c * screen_desktop_layout.rows +
534 (screen_desktop_layout.rows - 1 - r);
535 case Corner_TopRight:
536 return (screen_desktop_layout.columns - 1 - c) *
537 screen_desktop_layout.rows + r;
538 case Corner_BottomRight:
539 return (screen_desktop_layout.columns - 1 - c) *
540 screen_desktop_layout.rows +
541 (screen_desktop_layout.rows - 1 - r);
542 }
543 }
544 g_assert_not_reached();
545 return 0;
546 }
547
548 void action_next_desktop_column(union ActionData *data)
549 {
550 guint r, c, d;
551
552 cur_row_col(&r, &c);
553 ++c;
554 d = translate_row_col(r, c);
555 if (d >= screen_num_desktops) {
556 if (!data->nextprevdesktop.wrap) return;
557 c = 0;
558 }
559 if (d >= screen_num_desktops)
560 ++c;
561 d = translate_row_col(r, c);
562 if (d < screen_num_desktops)
563 screen_set_desktop(d);
564 }
565
566 void action_previous_desktop_column(union ActionData *data)
567 {
568 guint r, c, d;
569
570 cur_row_col(&r, &c);
571 --c;
572 d = translate_row_col(r, c);
573 if (d >= screen_num_desktops) {
574 if (!data->nextprevdesktop.wrap) return;
575 c = screen_desktop_layout.columns - 1;
576 }
577 if (d >= screen_num_desktops)
578 --c;
579 d = translate_row_col(r, c);
580 if (d < screen_num_desktops)
581 screen_set_desktop(d);
582 }
583
584 void action_next_desktop_row(union ActionData *data)
585 {
586 guint r, c, d;
587
588 cur_row_col(&r, &c);
589 ++r;
590 d = translate_row_col(r, c);
591 if (d >= screen_num_desktops) {
592 if (!data->nextprevdesktop.wrap) return;
593 r = 0;
594 }
595 if (d >= screen_num_desktops)
596 ++r;
597 d = translate_row_col(r, c);
598 if (d < screen_num_desktops)
599 screen_set_desktop(d);
600 }
601
602 void action_previous_desktop_row(union ActionData *data)
603 {
604 guint r, c, d;
605
606 cur_row_col(&r, &c);
607 --r;
608 d = translate_row_col(r, c);
609 if (d >= screen_num_desktops) {
610 if (!data->nextprevdesktop.wrap) return;
611 c = screen_desktop_layout.rows - 1;
612 }
613 if (d >= screen_num_desktops)
614 --r;
615 d = translate_row_col(r, c);
616 if (d < screen_num_desktops)
617 screen_set_desktop(d);
618 }
619
620 void action_toggle_decorations(union ActionData *data)
621 {
622 Client *c = data->client.c;
623 c->disabled_decorations = c->disabled_decorations ? 0 : ~0;
624 client_setup_decor_and_functions(c);
625 }
626
627 void action_move(union ActionData *data)
628 {
629 Client *c = data->move.c;
630 int x = data->move.x;
631 int y = data->move.y;
632
633 if (!c || !client_normal(c)) return;
634
635 dispatch_move(c, &x, &y);
636
637 frame_frame_gravity(c->frame, &x, &y); /* get where the client should be */
638 client_configure(c, Corner_TopLeft, x, y, c->area.width, c->area.height,
639 TRUE, data->move.final);
640 }
641
642 void action_resize(union ActionData *data)
643 {
644 Client *c = data->resize.c;
645 int w = data->resize.x;
646 int h = data->resize.y;
647
648 if (!c || c->shaded || !client_normal(c)) return;
649
650 dispatch_resize(c, &w, &h, data->resize.corner);
651
652 w -= c->frame->size.left + c->frame->size.right;
653 h -= c->frame->size.top + c->frame->size.bottom;
654
655 client_configure(c, data->resize.corner, c->area.x, c->area.y, w, h,
656 TRUE, data->resize.final);
657 }
658
659 void action_restart(union ActionData *data)
660 {
661 ob_restart_path = data->execute.path;
662 ob_shutdown = ob_restart = TRUE;
663 }
664
665 void action_exit(union ActionData *data)
666 {
667 ob_shutdown = TRUE;
668 }
669
670 void action_showmenu(union ActionData *data)
671 {
672 g_message(__FUNCTION__);
673 }
674
675 void action_cycle_windows(union ActionData *data)
676 {
677 static Client *first = NULL;
678 static Client *t = NULL;
679 static GList *order = NULL;
680 GList *it, *start, *list;
681
682 if (data->cycle.cancel) {
683 if (first) client_focus(first);
684 goto done_cycle;
685 }
686 if (!first) first = focus_client;
687
688 if (data->cycle.linear)
689 list = client_list;
690 else {
691 if (!order) order = g_list_copy(focus_order[screen_desktop]);
692 list = order;
693 }
694 start = it = g_list_find(list, data->cycle.c);
695 if (!start) goto done_cycle;
696
697 if (!data->cycle.final) {
698 t = NULL;
699 if (!start) /* switched desktops or something? */
700 goto done_cycle;
701
702 do {
703 if (data->cycle.forward) {
704 it = it->next;
705 if (it == NULL) it = list;
706 } else {
707 it = it->prev;
708 if (it == NULL) it = g_list_last(list);
709 }
710 if (client_focus(it->data)) {
711 t = it->data;
712 focus_ignore_in++;
713 break;
714 }
715 } while (it != start);
716 } else {
717 if (t) stacking_raise(t);
718 goto done_cycle;
719 }
720 return;
721
722 done_cycle:
723 first = NULL;
724 g_list_free(order);
725 order = NULL;
726 }
727
This page took 0.072701 seconds and 4 git commands to generate.