window: Defer stack placement without a buffer

When closing a window and showing a new one, the new one may not be
granted input focus until it gets a buffer on Wayland.

If another window is chosen to receive focus and raised on top of stack,
the newly mapped window is focused but placed underneath that other
window.

Meaning that for Wayland surfaces, we need to defer adding the window to
the stack until we actually get to show it, once we have a buffer
attached.

Rather that checking the windowing backend prior to decide if a window
is stackable or not, introduce a new vfunc is_stackable() which tells
if a window should be added to the stack regardless of the underlying
windowing system.

Also add meta_window_is_in_stack() API rather than checking the stack
position directly (replacing the define WINDOW_IN_STACK only available
in stack.c) and remove a window from the stack only if it is present
in the stack, so that the test in meta_stack_remote() becomes
irrelevant.

https://bugzilla.gnome.org/show_bug.cgi?id=780820
This commit is contained in:
Olivier Fourdan
2018-01-09 13:19:40 +01:00
parent 2d090f9232
commit bd9a300801
5 changed files with 42 additions and 14 deletions

View File

@@ -1298,10 +1298,10 @@ _meta_window_shared_new (MetaDisplay *display,
* and thus constraints may try to auto-fullscreen it which also
* means restacking it.
*/
if (!window->override_redirect)
if (meta_window_is_stackable (window))
meta_stack_add (window->screen->stack,
window);
else
else if (window->override_redirect)
window->layer = META_LAYER_OVERRIDE_REDIRECT; /* otherwise set by MetaStack */
if (!window->override_redirect)
@@ -1535,7 +1535,7 @@ meta_window_unmanage (MetaWindow *window,
meta_window_main_monitor_changed (window, old);
}
if (!window->override_redirect)
if (meta_window_is_in_stack (window))
meta_stack_remove (window->screen->stack, window);
/* If an undecorated window is being withdrawn, that will change the
@@ -1698,6 +1698,10 @@ implement_showing (MetaWindow *window,
meta_verbose ("Implement showing = %d for window %s\n",
showing, window->desc);
/* Some windows are not stackable until being showed, so add those now. */
if (meta_window_is_stackable (window) && !meta_window_is_in_stack (window))
meta_stack_add (window->screen->stack, window);
if (!showing)
{
/* When we manage a new window, we normally delay placing it
@@ -6897,6 +6901,12 @@ ensure_mru_position_after (MetaWindow *window,
}
}
gboolean
meta_window_is_in_stack (MetaWindow *window)
{
return window->stack_position >= 0;
}
void
meta_window_stack_just_below (MetaWindow *window,
MetaWindow *below_this_one)
@@ -8425,3 +8435,9 @@ meta_window_shortcuts_inhibited (MetaWindow *window,
{
return META_WINDOW_GET_CLASS (window)->shortcuts_inhibited (window, source);
}
gboolean
meta_window_is_stackable (MetaWindow *window)
{
return META_WINDOW_GET_CLASS (window)->is_stackable (window);
}