From 0659a0d98ca98fcd134c277c6a61ca3c9a04544e Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 7 Apr 2013 15:38:00 +0200 Subject: [PATCH] raise fullscreen windows on top of all other X11 windows MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Note that this is ineffective for dunst’s notifications because dunst re-raises them as soon as they get obscured. It does work for dzen2 however, which was the original use-case. fixes #569 --- include/x.h | 6 +++++- src/render.c | 14 +++++++------- src/x.c | 13 ++++++++++++- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/include/x.h b/include/x.h index c3d4ffc7..b712c786 100644 --- a/include/x.h +++ b/include/x.h @@ -93,8 +93,12 @@ void x_push_changes(Con *con); * Raises the specified container in the internal stack of X windows. The * next call to x_push_changes() will make the change visible in X11. * + * If above_all is true, the X11 window will be raised to the top + * of the stack. This should only be used for precisely one fullscreen + * window per output. + * */ -void x_raise_con(Con *con); +void x_raise_con(Con *con, bool above_all); /** * Sets the WM_NAME property (so, no UTF8, but used only for debugging anyways) diff --git a/src/render.c b/src/render.c index 6061838a..68cbbdf4 100644 --- a/src/render.c +++ b/src/render.c @@ -70,7 +70,7 @@ static void render_l_output(Con *con) { Con *fullscreen = con_get_fullscreen_con(ws, CF_OUTPUT); if (fullscreen) { fullscreen->rect = con->rect; - x_raise_con(fullscreen); + x_raise_con(fullscreen, true); render_con(fullscreen, true); return; } @@ -110,7 +110,7 @@ static void render_l_output(Con *con) { DLOG("child at (%d, %d) with (%d x %d)\n", child->rect.x, child->rect.y, child->rect.width, child->rect.height); - x_raise_con(child); + x_raise_con(child, false); render_con(child, false); } } @@ -207,7 +207,7 @@ void render_con(Con *con, bool render_fullscreen) { } if (fullscreen) { fullscreen->rect = rect; - x_raise_con(fullscreen); + x_raise_con(fullscreen, false); render_con(fullscreen, true); return; } @@ -298,7 +298,7 @@ void render_con(Con *con, bool render_fullscreen) { } DLOG("floating child at (%d,%d) with %d x %d\n", child->rect.x, child->rect.y, child->rect.width, child->rect.height); - x_raise_con(child); + x_raise_con(child, false); render_con(child, false); } } @@ -407,7 +407,7 @@ void render_con(Con *con, bool render_fullscreen) { DLOG("child at (%d, %d) with (%d x %d)\n", child->rect.x, child->rect.y, child->rect.width, child->rect.height); - x_raise_con(child); + x_raise_con(child, false); render_con(child, false); i++; } @@ -415,7 +415,7 @@ void render_con(Con *con, bool render_fullscreen) { /* in a stacking or tabbed container, we ensure the focused client is raised */ if (con->layout == L_STACKED || con->layout == L_TABBED) { TAILQ_FOREACH_REVERSE(child, &(con->focus_head), focus_head, focused) - x_raise_con(child); + x_raise_con(child, false); if ((child = TAILQ_FIRST(&(con->focus_head)))) { /* By rendering the stacked container again, we handle the case * that we have a non-leaf-container inside the stack. In that @@ -429,7 +429,7 @@ void render_con(Con *con, bool render_fullscreen) { * top of every stack window. That way, when a new window is opened in * the stack, the old window will not obscure part of the decoration * (it’s unmapped afterwards). */ - x_raise_con(con); + x_raise_con(con, false); } } } diff --git a/src/x.c b/src/x.c index fcb63c35..ae6e8a60 100644 --- a/src/x.c +++ b/src/x.c @@ -36,6 +36,7 @@ typedef struct con_state { bool mapped; bool unmap_now; bool child_mapped; + bool above_all; /** The con for which this state is. */ Con *con; @@ -899,6 +900,10 @@ void x_push_changes(Con *con) { xcb_configure_window(conn, prev->id, mask, values); } + if (state->above_all) { + DLOG("above all: 0x%08x\n", state->id); + xcb_configure_window(conn, state->id, XCB_CONFIG_WINDOW_STACK_MODE, (uint32_t[]){ XCB_STACK_MODE_ABOVE }); + } state->initial = false; } @@ -1024,12 +1029,18 @@ void x_push_changes(Con *con) { * Raises the specified container in the internal stack of X windows. The * next call to x_push_changes() will make the change visible in X11. * + * If above_all is true, the X11 window will be raised to the top + * of the stack. This should only be used for precisely one fullscreen + * window per output. + * */ -void x_raise_con(Con *con) { +void x_raise_con(Con *con, bool above_all) { con_state *state; state = state_for_frame(con->frame); //DLOG("raising in new stack: %p / %s / %s / xid %08x\n", con, con->name, con->window ? con->window->name_json : "", state->id); + state->above_all = above_all; + CIRCLEQ_REMOVE(&state_head, state, state); CIRCLEQ_INSERT_HEAD(&state_head, state, state); } -- 2.39.2