Walk the window ring through one helper

d0029ccda513b5756fc8469e038d47789539709f
Alexis Sellier committed ago 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