From 2fecf57699f57e9b2ed85cc85ec0369a741c765a Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Tue, 26 Aug 2014 10:00:14 +0200 Subject: [PATCH] Properly handle windows unsetting WM_TRANSIENT_FOR (Thanks Janus) fixes #1351 --- src/ipc.c | 5 +++++ src/render.c | 2 ++ src/window.c | 8 +++++--- testcases/t/114-client-leader.t | 21 +++++++++++++++++++++ 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/ipc.c b/src/ipc.c index 59f0938d..03b3d5ad 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -339,6 +339,11 @@ void dump_node(yajl_gen gen, struct Con *con, bool inplace_restart) { ystr(i3string_as_utf8(con->window->name)); } + ystr("transient_for"); + if (con->window->transient_for == XCB_NONE) + y(null); + else y(integer, con->window->transient_for); + y(map_close); } diff --git a/src/render.c b/src/render.c index ed35eb0c..3cc50063 100644 --- a/src/render.c +++ b/src/render.c @@ -288,6 +288,8 @@ void render_con(Con *con, bool render_fullscreen) { while (transient_con != NULL && transient_con->window != NULL && transient_con->window->transient_for != XCB_NONE) { + DLOG("transient_con = 0x%08x, transient_con->window->transient_for = 0x%08x, fullscreen_id = 0x%08x\n", + transient_con->window->id, transient_con->window->transient_for, fullscreen->window->id); if (transient_con->window->transient_for == fullscreen->window->id) { is_transient_for = true; break; diff --git a/src/window.c b/src/window.c index 538f4629..e406752a 100644 --- a/src/window.c +++ b/src/window.c @@ -125,7 +125,8 @@ void window_update_name_legacy(i3Window *win, xcb_get_property_reply_t *prop, bo */ void window_update_leader(i3Window *win, xcb_get_property_reply_t *prop) { if (prop == NULL || xcb_get_property_value_length(prop) == 0) { - DLOG("CLIENT_LEADER not set.\n"); + DLOG("CLIENT_LEADER not set on window 0x%08x.\n", win->id); + win->leader = XCB_NONE; FREE(prop); return; } @@ -149,7 +150,8 @@ void window_update_leader(i3Window *win, xcb_get_property_reply_t *prop) { */ void window_update_transient_for(i3Window *win, xcb_get_property_reply_t *prop) { if (prop == NULL || xcb_get_property_value_length(prop) == 0) { - DLOG("TRANSIENT_FOR not set.\n"); + DLOG("TRANSIENT_FOR not set on window 0x%08x.\n", win->id); + win->transient_for = XCB_NONE; FREE(prop); return; } @@ -160,7 +162,7 @@ void window_update_transient_for(i3Window *win, xcb_get_property_reply_t *prop) return; } - DLOG("Transient for changed to %08x\n", transient_for); + DLOG("Transient for changed to 0x%08x (window 0x%08x)\n", transient_for, win->id); win->transient_for = transient_for; diff --git a/testcases/t/114-client-leader.t b/testcases/t/114-client-leader.t index 63e92c3c..1efe34bf 100644 --- a/testcases/t/114-client-leader.t +++ b/testcases/t/114-client-leader.t @@ -99,4 +99,25 @@ is($x->input_focus, $child->id, "Child window focused"); } +################################################################################ +# Verify that transient_for can be set and unset. +################################################################################ + +$tmp = fresh_workspace; + +$fwindow = open_window({ dont_map => 1 }); +$fwindow->transient_for($right); +$fwindow->map; + +my $floating_con = get_ws($tmp)->{floating_nodes}[0]->{nodes}[0]; +is($floating_con->{window_properties}->{transient_for}, $right->id, 'WM_TRANSIENT_FOR properly parsed'); + +$x->delete_property($fwindow->id, $x->atom(name => 'WM_TRANSIENT_FOR')->id); +$x->flush; + +sync_with_i3; + +$floating_con = get_ws($tmp)->{floating_nodes}[0]->{nodes}[0]; +is($floating_con->{window_properties}->{transient_for}, undef, 'WM_TRANSIENT_FOR properly removed'); + done_testing; -- 2.39.2