mirror of
https://github.com/brl/mutter.git
synced 2024-11-28 19:10:43 -05:00
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:
parent
2d090f9232
commit
bd9a300801
@ -49,8 +49,6 @@
|
|||||||
#define WINDOW_TRANSIENT_FOR_WHOLE_GROUP(w) \
|
#define WINDOW_TRANSIENT_FOR_WHOLE_GROUP(w) \
|
||||||
(WINDOW_HAS_TRANSIENT_TYPE (w) && w->transient_for == NULL)
|
(WINDOW_HAS_TRANSIENT_TYPE (w) && w->transient_for == NULL)
|
||||||
|
|
||||||
#define WINDOW_IN_STACK(w) (w->stack_position >= 0)
|
|
||||||
|
|
||||||
static void stack_sync_to_xserver (MetaStack *stack);
|
static void stack_sync_to_xserver (MetaStack *stack);
|
||||||
static void meta_window_set_stack_position_no_sync (MetaWindow *window,
|
static void meta_window_set_stack_position_no_sync (MetaWindow *window,
|
||||||
int position);
|
int position);
|
||||||
@ -102,11 +100,11 @@ void
|
|||||||
meta_stack_add (MetaStack *stack,
|
meta_stack_add (MetaStack *stack,
|
||||||
MetaWindow *window)
|
MetaWindow *window)
|
||||||
{
|
{
|
||||||
g_return_if_fail (!window->override_redirect);
|
g_return_if_fail (meta_window_is_stackable (window));
|
||||||
|
|
||||||
meta_topic (META_DEBUG_STACK, "Adding window %s to the stack\n", window->desc);
|
meta_topic (META_DEBUG_STACK, "Adding window %s to the stack\n", window->desc);
|
||||||
|
|
||||||
if (window->stack_position >= 0)
|
if (meta_window_is_in_stack (window))
|
||||||
meta_bug ("Window %s had stack position already\n", window->desc);
|
meta_bug ("Window %s had stack position already\n", window->desc);
|
||||||
|
|
||||||
stack->added = g_list_prepend (stack->added, window);
|
stack->added = g_list_prepend (stack->added, window);
|
||||||
@ -127,10 +125,6 @@ meta_stack_remove (MetaStack *stack,
|
|||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_STACK, "Removing window %s from the stack\n", window->desc);
|
meta_topic (META_DEBUG_STACK, "Removing window %s from the stack\n", window->desc);
|
||||||
|
|
||||||
if (window->stack_position < 0)
|
|
||||||
meta_bug ("Window %s removed from stack but had no stack position\n",
|
|
||||||
window->desc);
|
|
||||||
|
|
||||||
/* Set window to top position, so removing it will not leave gaps
|
/* Set window to top position, so removing it will not leave gaps
|
||||||
* in the set of positions
|
* in the set of positions
|
||||||
*/
|
*/
|
||||||
@ -530,7 +524,7 @@ create_constraints (Constraint **constraints,
|
|||||||
{
|
{
|
||||||
MetaWindow *w = tmp->data;
|
MetaWindow *w = tmp->data;
|
||||||
|
|
||||||
if (!WINDOW_IN_STACK (w))
|
if (!meta_window_is_in_stack (w))
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_STACK, "Window %s not in the stack, not constraining it\n",
|
meta_topic (META_DEBUG_STACK, "Window %s not in the stack, not constraining it\n",
|
||||||
w->desc);
|
w->desc);
|
||||||
@ -557,7 +551,7 @@ create_constraints (Constraint **constraints,
|
|||||||
{
|
{
|
||||||
MetaWindow *group_window = tmp2->data;
|
MetaWindow *group_window = tmp2->data;
|
||||||
|
|
||||||
if (!WINDOW_IN_STACK (group_window) ||
|
if (!meta_window_is_in_stack (group_window) ||
|
||||||
w->screen != group_window->screen ||
|
w->screen != group_window->screen ||
|
||||||
group_window->override_redirect)
|
group_window->override_redirect)
|
||||||
{
|
{
|
||||||
@ -592,7 +586,7 @@ create_constraints (Constraint **constraints,
|
|||||||
|
|
||||||
parent = w->transient_for;
|
parent = w->transient_for;
|
||||||
|
|
||||||
if (parent && WINDOW_IN_STACK (parent))
|
if (parent && meta_window_is_in_stack (parent))
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_STACK, "Constraining %s above %s due to transiency\n",
|
meta_topic (META_DEBUG_STACK, "Constraining %s above %s due to transiency\n",
|
||||||
w->desc, parent->desc);
|
w->desc, parent->desc);
|
||||||
|
@ -553,6 +553,7 @@ struct _MetaWindowClass
|
|||||||
ClutterInputDevice *source);
|
ClutterInputDevice *source);
|
||||||
gboolean (*shortcuts_inhibited) (MetaWindow *window,
|
gboolean (*shortcuts_inhibited) (MetaWindow *window,
|
||||||
ClutterInputDevice *source);
|
ClutterInputDevice *source);
|
||||||
|
gboolean (*is_stackable) (MetaWindow *window);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* These differ from window->has_foo_func in that they consider
|
/* These differ from window->has_foo_func in that they consider
|
||||||
@ -699,6 +700,8 @@ void meta_window_set_type (MetaWindow *window,
|
|||||||
|
|
||||||
void meta_window_frame_size_changed (MetaWindow *window);
|
void meta_window_frame_size_changed (MetaWindow *window);
|
||||||
|
|
||||||
|
gboolean meta_window_is_in_stack (MetaWindow *window);
|
||||||
|
|
||||||
void meta_window_stack_just_below (MetaWindow *window,
|
void meta_window_stack_just_below (MetaWindow *window,
|
||||||
MetaWindow *below_this_one);
|
MetaWindow *below_this_one);
|
||||||
|
|
||||||
@ -795,4 +798,5 @@ void meta_window_force_restore_shortcuts (MetaWindow *window,
|
|||||||
|
|
||||||
gboolean meta_window_shortcuts_inhibited (MetaWindow *window,
|
gboolean meta_window_shortcuts_inhibited (MetaWindow *window,
|
||||||
ClutterInputDevice *source);
|
ClutterInputDevice *source);
|
||||||
|
gboolean meta_window_is_stackable (MetaWindow *window);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1298,10 +1298,10 @@ _meta_window_shared_new (MetaDisplay *display,
|
|||||||
* and thus constraints may try to auto-fullscreen it which also
|
* and thus constraints may try to auto-fullscreen it which also
|
||||||
* means restacking it.
|
* means restacking it.
|
||||||
*/
|
*/
|
||||||
if (!window->override_redirect)
|
if (meta_window_is_stackable (window))
|
||||||
meta_stack_add (window->screen->stack,
|
meta_stack_add (window->screen->stack,
|
||||||
window);
|
window);
|
||||||
else
|
else if (window->override_redirect)
|
||||||
window->layer = META_LAYER_OVERRIDE_REDIRECT; /* otherwise set by MetaStack */
|
window->layer = META_LAYER_OVERRIDE_REDIRECT; /* otherwise set by MetaStack */
|
||||||
|
|
||||||
if (!window->override_redirect)
|
if (!window->override_redirect)
|
||||||
@ -1535,7 +1535,7 @@ meta_window_unmanage (MetaWindow *window,
|
|||||||
meta_window_main_monitor_changed (window, old);
|
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);
|
meta_stack_remove (window->screen->stack, window);
|
||||||
|
|
||||||
/* If an undecorated window is being withdrawn, that will change the
|
/* 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",
|
meta_verbose ("Implement showing = %d for window %s\n",
|
||||||
showing, window->desc);
|
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)
|
if (!showing)
|
||||||
{
|
{
|
||||||
/* When we manage a new window, we normally delay placing it
|
/* 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
|
void
|
||||||
meta_window_stack_just_below (MetaWindow *window,
|
meta_window_stack_just_below (MetaWindow *window,
|
||||||
MetaWindow *below_this_one)
|
MetaWindow *below_this_one)
|
||||||
@ -8425,3 +8435,9 @@ meta_window_shortcuts_inhibited (MetaWindow *window,
|
|||||||
{
|
{
|
||||||
return META_WINDOW_GET_CLASS (window)->shortcuts_inhibited (window, source);
|
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);
|
||||||
|
}
|
||||||
|
@ -543,6 +543,12 @@ meta_window_wayland_shortcuts_inhibited (MetaWindow *window,
|
|||||||
return meta_wayland_compositor_is_shortcuts_inhibited (compositor, source);
|
return meta_wayland_compositor_is_shortcuts_inhibited (compositor, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_window_wayland_is_stackable (MetaWindow *window)
|
||||||
|
{
|
||||||
|
return meta_wayland_surface_get_buffer (window->surface) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_window_wayland_class_init (MetaWindowWaylandClass *klass)
|
meta_window_wayland_class_init (MetaWindowWaylandClass *klass)
|
||||||
{
|
{
|
||||||
@ -562,6 +568,7 @@ meta_window_wayland_class_init (MetaWindowWaylandClass *klass)
|
|||||||
window_class->get_client_pid = meta_window_wayland_get_client_pid;
|
window_class->get_client_pid = meta_window_wayland_get_client_pid;
|
||||||
window_class->force_restore_shortcuts = meta_window_wayland_force_restore_shortcuts;
|
window_class->force_restore_shortcuts = meta_window_wayland_force_restore_shortcuts;
|
||||||
window_class->shortcuts_inhibited = meta_window_wayland_shortcuts_inhibited;
|
window_class->shortcuts_inhibited = meta_window_wayland_shortcuts_inhibited;
|
||||||
|
window_class->is_stackable = meta_window_wayland_is_stackable;
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaWindow *
|
MetaWindow *
|
||||||
|
@ -1549,6 +1549,12 @@ meta_window_x11_shortcuts_inhibited (MetaWindow *window,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_window_x11_is_stackable (MetaWindow *window)
|
||||||
|
{
|
||||||
|
return !window->override_redirect;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_window_x11_class_init (MetaWindowX11Class *klass)
|
meta_window_x11_class_init (MetaWindowX11Class *klass)
|
||||||
{
|
{
|
||||||
@ -1572,6 +1578,7 @@ meta_window_x11_class_init (MetaWindowX11Class *klass)
|
|||||||
window_class->get_client_pid = meta_window_x11_get_client_pid;
|
window_class->get_client_pid = meta_window_x11_get_client_pid;
|
||||||
window_class->force_restore_shortcuts = meta_window_x11_force_restore_shortcuts;
|
window_class->force_restore_shortcuts = meta_window_x11_force_restore_shortcuts;
|
||||||
window_class->shortcuts_inhibited = meta_window_x11_shortcuts_inhibited;
|
window_class->shortcuts_inhibited = meta_window_x11_shortcuts_inhibited;
|
||||||
|
window_class->is_stackable = meta_window_x11_is_stackable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user