From 52f7ff3dfddef6813f0558797286b74c8fc930e6 Mon Sep 17 00:00:00 2001 From: Bastien Dejean Date: Thu, 5 Nov 2015 22:05:07 +0100 Subject: [PATCH] Handle stacking of unfocused windows Put focused (resp. unfocused) window at the top (resp. bottom) of the group of windows having the same stacking level. --- pointer.c | 2 +- stack.c | 55 +++++++++++++++++++++++++++++++++++++++---------------- stack.h | 4 +++- tree.c | 34 +++++++++++++++++++++------------- window.c | 8 ++++---- 5 files changed, 68 insertions(+), 35 deletions(-) diff --git a/pointer.c b/pointer.c index 6e34615..b3744d1 100644 --- a/pointer.c +++ b/pointer.c @@ -62,7 +62,7 @@ void grab_pointer(pointer_action_t pac) focus_node(loc.monitor, loc.desktop, loc.node); pointer_follows_monitor = backup; } else if (focus_follows_pointer) { - stack(loc.node); + stack(loc.node, true); } frozen_pointer->action = ACTION_NONE; break; diff --git a/stack.c b/stack.c index eabcf46..bdff79a 100644 --- a/stack.c +++ b/stack.c @@ -114,30 +114,53 @@ int stack_cmp(client_t *c1, client_t *c2) return stack_level(c1) - stack_level(c2); } -void stack(node_t *n) +stacking_list_t *limit_above(node_t *n) { + stacking_list_t *s = stack_head; + while (s != NULL && stack_cmp(n->client, s->node->client) >= 0) { + s = s->next; + } + if (s == NULL) { + s = stack_tail; + } + if (s->node == n) { + s = s->prev; + } + return s; +} + +stacking_list_t *limit_below(node_t *n) +{ + stacking_list_t *s = stack_tail; + while (s != NULL && stack_cmp(n->client, s->node->client) <= 0) { + s = s->prev; + } + if (s == NULL) { + s = stack_head; + } + if (s->node == n) { + s = s->next; + } + return s; +} + +void stack(node_t *n, bool focused) +{ + if (IS_FLOATING(n->client) && !auto_raise) { + return; + } + PRINTF("stack %X\n", n->client->window); if (stack_head == NULL) { stack_insert_after(NULL, n); } else { - if (IS_FLOATING(n->client) && !auto_raise) { - return; - } - stacking_list_t *s = stack_head; - while (s != NULL && stack_cmp(n->client, s->node->client) >= 0) { - s = s->next; - } + stacking_list_t *s = (focused ? limit_above(n) : limit_below(n)); if (s == NULL) { - s = stack_tail; - } - if (s->node == n) { - s = s->prev; - if (s == NULL) { - return; - } + return; } - if (stack_cmp(n->client, s->node->client) < 0) { + int i = stack_cmp(n->client, s->node->client); + if (i < 0 || (i == 0 && !focused)) { stack_insert_before(s, n); window_below(n->client->window, s->node->client->window); } else { diff --git a/stack.h b/stack.h index 069fc38..3929cf2 100644 --- a/stack.h +++ b/stack.h @@ -32,6 +32,8 @@ void remove_stack(stacking_list_t *s); void remove_stack_node(node_t *n); int stack_level(client_t *c); int stack_cmp(client_t *c1, client_t *c2); -void stack(node_t *n); +stacking_list_t *limit_above(node_t *n); +stacking_list_t *limit_below(node_t *n); +void stack(node_t *n, bool focused); #endif diff --git a/tree.c b/tree.c index 043122e..f591d6c 100644 --- a/tree.c +++ b/tree.c @@ -296,7 +296,7 @@ void insert_node(monitor_t *m, desktop_t *d, node_t *n, node_t *f) void pseudo_focus(monitor_t *m, desktop_t *d, node_t *n) { if (n != NULL) { - stack(n); + stack(n, true); if (d->focus != n) { window_draw_border(d->focus, false, m == mon); window_draw_border(n, true, m == mon); @@ -362,7 +362,7 @@ void focus_node(monitor_t *m, desktop_t *d, node_t *n) ewmh_update_active_window(); return; } else { - stack(n); + stack(n, true); } PRINTF("focus node %X\n", n->client->window); @@ -1060,8 +1060,9 @@ bool swap_nodes(monitor_t *m1, desktop_t *d1, node_t *n1, monitor_t *m2, desktop bool transfer_node(monitor_t *ms, desktop_t *ds, node_t *ns, monitor_t *md, desktop_t *dd, node_t *nd) { - if (ns == NULL || ns == nd || (sticky_still && ns->client->sticky)) + if (ns == NULL || ns == nd || (sticky_still && ns->client->sticky)) { return false; + } PRINTF("transfer node %X\n", ns->client->window); put_status(SBSC_MASK_WINDOW_TRANSFER, "window_transfer %s %s 0x%X %s %s 0x%X\n", ms->name, ds->name, ns->client->window, md->name, dd->name, nd!=NULL?nd->client->window:0); @@ -1069,43 +1070,50 @@ bool transfer_node(monitor_t *ms, desktop_t *ds, node_t *ns, monitor_t *md, desk bool focused = (ns == mon->desk->focus); bool active = (ns == ds->focus); - if (focused) + if (focused) { clear_input_focus(); + } unlink_node(ms, ds, ns); insert_node(md, dd, ns, nd); - if (md != ms) + if (md != ms) { translate_client(ms, md, ns->client); + } if (ds != dd) { ewmh_set_wm_desktop(ns, dd); if (!ns->client->sticky) { - if (ds == ms->desk && dd != md->desk) + if (ds == ms->desk && dd != md->desk) { window_hide(ns->client->window); - else if (ds != ms->desk && dd == md->desk) + } else if (ds != ms->desk && dd == md->desk) { window_show(ns->client->window); + } } } history_transfer_node(md, dd, ns); - stack(ns); + stack(ns, false); if (ds == dd) { - if (focused) + if (focused) { focus_node(md, dd, ns); - else if (active) + } else if (active) { pseudo_focus(md, dd, ns); + } } else { - if (focused) + if (focused) { update_current(); - else if (ns == mon->desk->focus) + } else if (ns == mon->desk->focus) { update_input_focus(); + } } arrange(ms, ds); - if (ds != dd) + + if (ds != dd) { arrange(md, dd); + } return true; } diff --git a/window.c b/window.c index 5d0560d..abd0b26 100644 --- a/window.c +++ b/window.c @@ -173,7 +173,7 @@ void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd) } else if (csq->focus) { pseudo_focus(m, d, n); } else { - stack(n); + stack(n, false); } uint32_t values[] = {CLIENT_EVENT_MASK | (focus_follows_pointer ? XCB_EVENT_MASK_ENTER_WINDOW : 0)}; @@ -411,7 +411,7 @@ void set_layer(monitor_t *m, desktop_t *d, node_t *n, stack_layer_t l) neutralize_obscuring_windows(m, d, n); } - stack(n); + stack(n, (d->focus == n)); } void set_state(monitor_t *m, desktop_t *d, node_t *n, client_state_t s) @@ -477,7 +477,7 @@ void set_floating(monitor_t *m, desktop_t *d, node_t *n, bool value) } } - stack(n); + stack(n, (d->focus == n)); } void set_fullscreen(monitor_t *m, desktop_t *d, node_t *n, bool value) @@ -504,7 +504,7 @@ void set_fullscreen(monitor_t *m, desktop_t *d, node_t *n, bool value) } } - stack(n); + stack(n, (d->focus == n)); } void neutralize_obscuring_windows(monitor_t *m, desktop_t *d, node_t *n) -- 2.44.0