From: Mats Date: Wed, 20 Feb 2013 15:56:03 +0000 (+0100) Subject: Bugfix: Handle nested transient popups properly X-Git-Tag: 4.5~8 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=a38749e7e451558d35e507fd4317e04cef8bdf2b;p=i3%2Fi3 Bugfix: Handle nested transient popups properly During smart popup fullscreen handling, display all transient popups that belong to the respective fullscreen application. A popup window belongs to another window if the latter is reachable via the path induced by the WM_TRANSIENT_FOR hints. fixes #881 --- diff --git a/src/manage.c b/src/manage.c index a2319912..ae3cef0f 100644 --- a/src/manage.c +++ b/src/manage.c @@ -385,10 +385,20 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki con_toggle_fullscreen(fs, CF_OUTPUT); } else if (config.popup_during_fullscreen == PDF_SMART && fs != NULL && - fs->window != NULL && - fs->window->id == cwindow->transient_for) { - LOG("This floating window belongs to the fullscreen window (popup_during_fullscreen == smart)\n"); - con_focus(nc); + fs->window != NULL) { + i3Window *transient_win = cwindow; + while (transient_win != NULL && + transient_win->transient_for != XCB_NONE) { + if (transient_win->transient_for == fs->window->id) { + LOG("This floating window belongs to the fullscreen window (popup_during_fullscreen == smart)\n"); + con_focus(nc); + break; + } + Con *next_transient = con_by_window_id(transient_win->transient_for); + if (next_transient == NULL) + break; + transient_win = next_transient->window; + } } } diff --git a/src/render.c b/src/render.c index 5027cd21..16bfc55b 100644 --- a/src/render.c +++ b/src/render.c @@ -271,18 +271,28 @@ void render_con(Con *con, bool render_fullscreen) { /* Don’t render floating windows when there is a fullscreen window * on that workspace. Necessary to make floating fullscreen work * correctly (ticket #564). */ - if (fullscreen != NULL) { + if (fullscreen != NULL && fullscreen->window != NULL) { Con *floating_child = con_descend_focused(child); + Con *transient_con = floating_child; + bool is_transient_for = false; /* Exception to the above rule: smart * popup_during_fullscreen handling (popups belonging to * the fullscreen app will be rendered). */ - if (floating_child->window == NULL || - fullscreen->window == NULL || - floating_child->window->transient_for != fullscreen->window->id) + while (transient_con != NULL && + transient_con->window != NULL && + transient_con->window->transient_for != XCB_NONE) { + if (transient_con->window->transient_for == fullscreen->window->id) { + is_transient_for = true; + break; + } + transient_con = con_by_window_id(transient_con->window->transient_for); + } + + if (!is_transient_for) continue; else { DLOG("Rendering floating child even though in fullscreen mode: " - "floating->transient_for (0x%08x) == fullscreen->id (0x%08x)\n", + "floating->transient_for (0x%08x) --> fullscreen->id (0x%08x)\n", floating_child->window->transient_for, fullscreen->window->id); } }