Walk the window ring through one helper
d0029ccda513b5756fc8469e038d47789539709f
1 parent
5ca9d73f
swm.c
+16 -24
| 3090 | 3090 | /* Return whether two clients belong to one group. */ |
|
| 3091 | 3091 | bool clients_related(client_t *a, client_t *b) { |
|
| 3092 | 3092 | return a && b && client_main(a) == client_main(b); |
|
| 3093 | 3093 | } |
|
| 3094 | 3094 | ||
| 3095 | + | /* Return the next window in list order, wrapping past the list head. */ |
|
| 3096 | + | static client_t *client_step(client_t *c, int dir) { |
|
| 3097 | + | struct wl_list *node = dir > 0 ? c->link.next : c->link.prev; |
|
| 3098 | + | ||
| 3099 | + | if (node == &clients) |
|
| 3100 | + | node = dir > 0 ? node->next : node->prev; |
|
| 3101 | + | return wl_container_of(node, c, link); |
|
| 3102 | + | } |
|
| 3103 | + | ||
| 3095 | 3104 | /* Focus the nearest related window when the current one closes. */ |
|
| 3096 | 3105 | client_t *focus_close(client_t *c) { |
|
| 3097 | - | client_t *p; |
|
| 3098 | - | struct wl_list *node; |
|
| 3106 | + | client_t *p; |
|
| 3099 | 3107 | ||
| 3100 | 3108 | if (!c || !c->mon) |
|
| 3101 | 3109 | return nullptr; |
|
| 3102 | 3110 | ||
| 3103 | 3111 | if ((p = client_get_parent(c)) && VISIBLEON(p, c->mon) && !client_is_blocked(p)) |
|
| 3104 | 3112 | return p; |
|
| 3105 | 3113 | ||
| 3106 | - | for (node = c->link.prev; node != &c->link; node = node->prev) { |
|
| 3107 | - | if (node == &clients) |
|
| 3108 | - | continue; |
|
| 3109 | - | p = wl_container_of(node, p, link); |
|
| 3110 | - | ||
| 3114 | + | for (p = client_step(c, -1); p != c; p = client_step(p, -1)) { |
|
| 3111 | 3115 | if (VISIBLEON(p, c->mon) && !client_is_blocked(p) && !clients_related(p, c)) |
|
| 3112 | 3116 | return p; |
|
| 3113 | 3117 | } |
|
| 3114 | 3118 | return nullptr; |
|
| 3115 | 3119 | } |
| 3127 | 3131 | } |
|
| 3128 | 3132 | ||
| 3129 | 3133 | /* Move focus forward or backward through tiled windows. */ |
|
| 3130 | 3134 | void focus_stack(const arg_t *arg) { |
|
| 3131 | 3135 | /* Focus the next or previous tiled window on the selected display. */ |
|
| 3132 | - | client_t *c = nullptr, *sel = focus_top(selmon); |
|
| 3133 | - | struct wl_list *node; |
|
| 3136 | + | client_t *c, *sel = focus_top(selmon); |
|
| 3134 | 3137 | ||
| 3135 | 3138 | if (!sel) |
|
| 3136 | 3139 | return; |
|
| 3137 | 3140 | ||
| 3138 | - | for (node = arg->i > 0 ? sel->link.next : sel->link.prev; node != &sel->link; |
|
| 3139 | - | node = arg->i > 0 ? node->next : node->prev) { |
|
| 3140 | - | if (node == &clients) |
|
| 3141 | - | continue; |
|
| 3142 | - | c = wl_container_of(node, c, link); |
|
| 3143 | - | ||
| 3141 | + | for (c = client_step(sel, arg->i); c != sel; c = client_step(c, arg->i)) { |
|
| 3144 | 3142 | if (VISIBLEON(c, selmon) && !client_is_blocked(c) && !client_get_parent(c)) { |
|
| 3145 | 3143 | bool fullscreen = sel->is_fullscreen; |
|
| 3146 | 3144 | ||
| 3147 | 3145 | if (fullscreen) |
|
| 3148 | 3146 | set_fullscreen(sel, 0); |
| 6425 | 6423 | ||
| 6426 | 6424 | /* Swap the focused tiled window with its neighbor. */ |
|
| 6427 | 6425 | void swap_client(const arg_t *arg) { |
|
| 6428 | 6426 | /* swap the focused window with the next/previous window in the |
|
| 6429 | 6427 | * stacking order. */ |
|
| 6430 | - | client_t *c = nullptr, *sel = focus_top(selmon); |
|
| 6431 | - | struct wl_list *node; |
|
| 6428 | + | client_t *c, *sel = focus_top(selmon); |
|
| 6432 | 6429 | ||
| 6433 | 6430 | if (!sel || !selmon || !selmon->ws || !selmon->ws->lt->arrange || sel->is_floating || |
|
| 6434 | 6431 | sel->is_fullscreen) |
|
| 6435 | 6432 | return; |
|
| 6436 | 6433 | ||
| 6437 | - | for (node = arg->i > 0 ? sel->link.next : sel->link.prev; node != &sel->link; |
|
| 6438 | - | node = arg->i > 0 ? node->next : node->prev) { |
|
| 6439 | - | if (node == &clients) |
|
| 6440 | - | continue; |
|
| 6441 | - | c = wl_container_of(node, c, link); |
|
| 6442 | - | ||
| 6434 | + | for (c = client_step(sel, arg->i); c != sel; c = client_step(c, arg->i)) { |
|
| 6443 | 6435 | if (VISIBLEON(c, selmon) && !c->is_floating && !c->is_fullscreen) |
|
| 6444 | 6436 | break; |
|
| 6445 | 6437 | } |
|
| 6446 | - | if (node == &sel->link || !c) |
|
| 6438 | + | if (c == sel) |
|
| 6447 | 6439 | return; |
|
| 6448 | 6440 | ||
| 6449 | 6441 | /* Move the selected window next to its swap target. */ |
|
| 6450 | 6442 | wl_list_remove(&sel->link); |
|
| 6451 | 6443 |