win: handle restack to bottom correctly
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
166ec55778
commit
b9f894c4fc
|
@ -394,6 +394,9 @@ typedef struct session {
|
||||||
win *windows;
|
win *windows;
|
||||||
/// Windows in their stacking order
|
/// Windows in their stacking order
|
||||||
win *window_stack;
|
win *window_stack;
|
||||||
|
/// Pointer to the `next` field of the bottom most window,
|
||||||
|
/// or a pointer to `window_stack` when there is no window
|
||||||
|
win **window_stack_bottom;
|
||||||
/// Pointer to <code>win</code> of current active window. Used by
|
/// Pointer to <code>win</code> of current active window. Used by
|
||||||
/// EWMH <code>_NET_ACTIVE_WINDOW</code> focus detection. In theory,
|
/// EWMH <code>_NET_ACTIVE_WINDOW</code> focus detection. In theory,
|
||||||
/// it's more reliable to store the window ID directly here, just in
|
/// it's more reliable to store the window ID directly here, just in
|
||||||
|
|
|
@ -652,8 +652,10 @@ static void restack_win(session_t *ps, win *w, xcb_window_t new_above) {
|
||||||
|
|
||||||
if (w->next) {
|
if (w->next) {
|
||||||
old_above = w->next->id;
|
old_above = w->next->id;
|
||||||
|
assert(&w->next != ps->window_stack_bottom);
|
||||||
} else {
|
} else {
|
||||||
old_above = XCB_NONE;
|
old_above = XCB_NONE;
|
||||||
|
assert(&w->next == ps->window_stack_bottom);
|
||||||
}
|
}
|
||||||
log_debug("Restack %#010x (%s), old_above: %#010x, new_above: %#010x", w->id,
|
log_debug("Restack %#010x (%s), old_above: %#010x, new_above: %#010x", w->id,
|
||||||
w->name, old_above, new_above);
|
w->name, old_above, new_above);
|
||||||
|
@ -674,19 +676,31 @@ static void restack_win(session_t *ps, win *w, xcb_window_t new_above) {
|
||||||
w->id, new_above);
|
w->id, new_above);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
prev = tmp_w->prev;
|
|
||||||
// Unlink from old position
|
// Unlink from old position
|
||||||
*w->prev = w->next;
|
*w->prev = w->next;
|
||||||
if (w->next) {
|
if (w->next) {
|
||||||
w->next->prev = w->prev;
|
w->next->prev = w->prev;
|
||||||
}
|
}
|
||||||
// Link to new position
|
if (ps->window_stack_bottom == &w->next) {
|
||||||
w->next = *prev;
|
ps->window_stack_bottom = w->prev;
|
||||||
if (w->next) {
|
}
|
||||||
w->next->prev = &w->next;
|
|
||||||
|
if (!new_above) {
|
||||||
|
*ps->window_stack_bottom = w;
|
||||||
|
w->prev = ps->window_stack_bottom;
|
||||||
|
ps->window_stack_bottom = &w->next;
|
||||||
|
w->next = NULL;
|
||||||
|
} else {
|
||||||
|
prev = tmp_w->prev;
|
||||||
|
// Link to new position
|
||||||
|
w->next = *prev;
|
||||||
|
if (w->next) {
|
||||||
|
w->next->prev = &w->next;
|
||||||
|
}
|
||||||
|
w->prev = prev;
|
||||||
|
*w->prev = w;
|
||||||
}
|
}
|
||||||
w->prev = prev;
|
|
||||||
*w->prev = w;
|
|
||||||
|
|
||||||
// add damage for this window
|
// add damage for this window
|
||||||
add_damage_from_win(ps, w);
|
add_damage_from_win(ps, w);
|
||||||
|
@ -1738,6 +1752,7 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
|
||||||
#ifdef CONFIG_DBUS
|
#ifdef CONFIG_DBUS
|
||||||
.dbus_data = NULL,
|
.dbus_data = NULL,
|
||||||
#endif
|
#endif
|
||||||
|
.window_stack = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
auto stderr_logger = stderr_logger_new();
|
auto stderr_logger = stderr_logger_new();
|
||||||
|
@ -1750,6 +1765,7 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
|
||||||
// Allocate a session and copy default values into it
|
// Allocate a session and copy default values into it
|
||||||
session_t *ps = cmalloc(session_t);
|
session_t *ps = cmalloc(session_t);
|
||||||
*ps = s_def;
|
*ps = s_def;
|
||||||
|
ps->window_stack_bottom = &ps->window_stack;
|
||||||
ps->loop = EV_DEFAULT;
|
ps->loop = EV_DEFAULT;
|
||||||
pixman_region32_init(&ps->screen_reg);
|
pixman_region32_init(&ps->screen_reg);
|
||||||
|
|
||||||
|
@ -2189,6 +2205,7 @@ static void session_destroy(session_t *ps) {
|
||||||
free(w);
|
free(w);
|
||||||
}
|
}
|
||||||
ps->window_stack = NULL;
|
ps->window_stack = NULL;
|
||||||
|
ps->window_stack_bottom = &ps->window_stack;
|
||||||
|
|
||||||
// Free blacklists
|
// Free blacklists
|
||||||
free_wincondlst(&ps->o.shadow_blacklist);
|
free_wincondlst(&ps->o.shadow_blacklist);
|
||||||
|
|
|
@ -1040,6 +1040,9 @@ void add_win(session_t *ps, xcb_window_t id, xcb_window_t prev) {
|
||||||
}
|
}
|
||||||
new->prev = p;
|
new->prev = p;
|
||||||
*p = new;
|
*p = new;
|
||||||
|
if (p == ps->window_stack_bottom) {
|
||||||
|
ps->window_stack_bottom = &new->next;
|
||||||
|
}
|
||||||
HASH_ADD_INT(ps->windows, id, new);
|
HASH_ADD_INT(ps->windows, id, new);
|
||||||
|
|
||||||
#ifdef CONFIG_DBUS
|
#ifdef CONFIG_DBUS
|
||||||
|
@ -1494,6 +1497,9 @@ static void finish_destroy_win(session_t *ps, win **_w) {
|
||||||
if (w->next) {
|
if (w->next) {
|
||||||
w->next->prev = w->prev;
|
w->next->prev = w->prev;
|
||||||
}
|
}
|
||||||
|
if (&w->next == ps->window_stack_bottom) {
|
||||||
|
ps->window_stack_bottom = w->prev;
|
||||||
|
}
|
||||||
|
|
||||||
if (w == ps->active_win) {
|
if (w == ps->active_win) {
|
||||||
ps->active_win = NULL;
|
ps->active_win = NULL;
|
||||||
|
|
Loading…
Reference in New Issue