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
This commit is contained in:
Marco Trevisan (Treviño) 2019-10-29 04:22:19 +01:00 committed by Marco Trevisan
parent c85fb107c0
commit bacbbbd628
3 changed files with 34 additions and 0 deletions

View File

@ -131,6 +131,7 @@ stacking_tests = [
'mixed-windows',
'set-parent',
'override-redirect',
'set-override-redirect-parent',
'set-parent-exported',
]

View File

@ -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

View File

@ -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))