From bacbbbd628fd68618f14bdf07ba3f9e6ccd1c038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 29 Oct 2019 04:22:19 +0100 Subject: [PATCH] window-props: Don't set override redirect windows as top-level parent Java applications might use override-redirect windows as parent windows for top-level windows, although this is not following the standard [1]. In such case, the first non-override-redirect child window that is created was marked as being on_all_workspaces since the call to should_be_on_all_workspaces() returns TRUE for its parent, and this even though the on_all_workspaces_requested bit is unset. When a further child of this window was added, it was set as not having a workspace and not being on_all_workspaces, since the call to should_be_on_all_workspaces() for its parent would return FALSE (unless if it is in a different monitor, and the multiple-monitors workspaces are disabled). Since per commit 09bab98b we don't recompute the workspace if the on_all_workspaces bit is unset, we could end up in a case where a window can be nor in all the workspaces or in a specific workspace. So let's just ignore the transient_for bit for a window if that points to an override-redirect, using the x11 root window instead. Add a stacking test to verify this scenario (was failing before of this commit). Fixes https://gitlab.gnome.org/GNOME/mutter/issues/885 https://gitlab.gnome.org/GNOME/mutter/merge_requests/895 [1] https://standards.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472512128 --- src/tests/meson.build | 1 + .../set-override-redirect-parent.metatest | 24 +++++++++++++++++++ src/x11/window-props.c | 9 +++++++ 3 files changed, 34 insertions(+) create mode 100644 src/tests/stacking/set-override-redirect-parent.metatest diff --git a/src/tests/meson.build b/src/tests/meson.build index dafe67ff8..f5a132f6b 100644 --- a/src/tests/meson.build +++ b/src/tests/meson.build @@ -131,6 +131,7 @@ stacking_tests = [ 'mixed-windows', 'set-parent', 'override-redirect', + 'set-override-redirect-parent', 'set-parent-exported', ] diff --git a/src/tests/stacking/set-override-redirect-parent.metatest b/src/tests/stacking/set-override-redirect-parent.metatest new file mode 100644 index 000000000..fc99e4818 --- /dev/null +++ b/src/tests/stacking/set-override-redirect-parent.metatest @@ -0,0 +1,24 @@ +new_client 1 x11 +create 1/1 override +show 1/1 + +create 1/2 +set_parent 1/2 1 +show 1/2 + +create 1/3 +set_parent 1/3 2 +show 1/3 + + +new_client 2 x11 +create 2/1 +show 2/1 + +create 2/2 override +set_parent 2/2 1 +show 2/2 + +create 2/3 +set_parent 2/3 2 +show 2/3 diff --git a/src/x11/window-props.c b/src/x11/window-props.c index 2564909a9..e1e96e0e3 100644 --- a/src/x11/window-props.c +++ b/src/x11/window-props.c @@ -1661,6 +1661,15 @@ reload_transient_for (MetaWindow *window, transient_for, window->desc); transient_for = None; } + 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; + } /* Make sure there is not a loop */ if (check_xtransient_for_loop (window, parent))