From 6944839ab68845cfd41d9d1ef6aad0faf40464c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 29 Oct 2019 19:08:01 +0100 Subject: [PATCH] window-props: Read WM_TRANSIENT_FOR for override-redirect windows As per the Extended Window Manager Hints standard version 1.3 [1] an override-redirect window can set a transient-for window per compositing and app-matching purposes. So just read the WM_TRASIENT_FOR property also for such windows, adapting the error in case they are transient for another O-R window and adding a test to check such case. [1] https://standards.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472512128 https://gitlab.gnome.org/GNOME/mutter/merge_requests/920 --- .../set-override-redirect-parent.metatest | 13 +++++++ src/x11/window-props.c | 37 +++++++++++++++---- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/tests/stacking/set-override-redirect-parent.metatest b/src/tests/stacking/set-override-redirect-parent.metatest index fc99e4818..4c98bee22 100644 --- a/src/tests/stacking/set-override-redirect-parent.metatest +++ b/src/tests/stacking/set-override-redirect-parent.metatest @@ -22,3 +22,16 @@ show 2/2 create 2/3 set_parent 2/3 2 show 2/3 + + +new_client 3 x11 +create 3/1 override +show 3/1 + +create 3/2 override +set_parent 3/2 1 +show 3/2 + +create 3/3 override +set_parent 3/3 2 +show 3/3 diff --git a/src/x11/window-props.c b/src/x11/window-props.c index e1e96e0e3..45a16c4b8 100644 --- a/src/x11/window-props.c +++ b/src/x11/window-props.c @@ -1663,12 +1663,35 @@ reload_transient_for (MetaWindow *window, } else if (parent->override_redirect) { - meta_warning ("WM_TRANSIENT_FOR window %s for top-level %s is an " - "override-redirect window and this is not correct " - "according to the standard, so we'll fallback to " - "the root window.\n", parent->desc, window->desc); - transient_for = parent->display->x11_display->xroot; - parent = NULL; + const gchar *window_kind = window->override_redirect ? + "override-redirect" : "top-level"; + + if (parent->xtransient_for != None) + { + /* We don't have to go through the parents, as per this code it is + * not possible that a window has the WM_TRANSIENT_FOR set to an + * override-redirect window anyways */ + meta_warning ("WM_TRANSIENT_FOR window %s for %s window %s is an " + "override-redirect window and this is not correct " + "according to the standard, so we'll fallback to " + "the first non-override-redirect window 0x%lx.\n", + parent->desc, window->desc, window_kind, + parent->xtransient_for); + transient_for = parent->xtransient_for; + parent = + meta_x11_display_lookup_x_window (parent->display->x11_display, + transient_for); + } + else + { + meta_warning ("WM_TRANSIENT_FOR window %s for %s window %s is an " + "override-redirect window and this is not correct " + "according to the standard, so we'll fallback to " + "the root window.\n", parent->desc, window_kind, + window->desc); + transient_for = parent->display->x11_display->xroot; + parent = NULL; + } } /* Make sure there is not a loop */ @@ -1840,7 +1863,7 @@ meta_x11_display_init_window_prop_hooks (MetaX11Display *x11_display) { x11_display->atom__NET_WM_USER_TIME, META_PROP_VALUE_CARDINAL, reload_net_wm_user_time, LOAD_INIT }, { x11_display->atom__NET_WM_STATE, META_PROP_VALUE_ATOM_LIST, reload_net_wm_state, LOAD_INIT | INIT_ONLY }, { x11_display->atom__MOTIF_WM_HINTS, META_PROP_VALUE_MOTIF_HINTS, reload_mwm_hints, LOAD_INIT }, - { XA_WM_TRANSIENT_FOR, META_PROP_VALUE_WINDOW, reload_transient_for, LOAD_INIT }, + { XA_WM_TRANSIENT_FOR, META_PROP_VALUE_WINDOW, reload_transient_for, LOAD_INIT | INCLUDE_OR }, { x11_display->atom__GTK_THEME_VARIANT, META_PROP_VALUE_UTF8, reload_gtk_theme_variant, LOAD_INIT }, { x11_display->atom__GTK_APPLICATION_ID, META_PROP_VALUE_UTF8, reload_gtk_application_id, LOAD_INIT }, { x11_display->atom__GTK_UNIQUE_BUS_NAME, META_PROP_VALUE_UTF8, reload_gtk_unique_bus_name, LOAD_INIT },