core: Move Stack to StackTracker synchronization back to stack.c
We indirectly were relying on the MetaX11Stack for this. We strictly need the _NET_CLIENT_LIST* property updates there, so move our own internal synchronization to common code. Fixes stacking changes of windows while there's no MetaX11Display. https://gitlab.gnome.org/GNOME/mutter/merge_requests/730
This commit is contained in:
parent
9b7d918537
commit
433e1b388d
2 changed files with 86 additions and 60 deletions
|
@ -36,6 +36,7 @@
|
||||||
#include "meta/group.h"
|
#include "meta/group.h"
|
||||||
#include "meta/prefs.h"
|
#include "meta/prefs.h"
|
||||||
#include "meta/workspace.h"
|
#include "meta/workspace.h"
|
||||||
|
#include "x11/meta-x11-display-private.h"
|
||||||
|
|
||||||
#define WINDOW_HAS_TRANSIENT_TYPE(w) \
|
#define WINDOW_HAS_TRANSIENT_TYPE(w) \
|
||||||
(w->type == META_WINDOW_DIALOG || \
|
(w->type == META_WINDOW_DIALOG || \
|
||||||
|
@ -73,9 +74,94 @@ static guint signals[N_SIGNALS] = { 0 };
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaStack, meta_stack, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (MetaStack, meta_stack, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_stack_changed (MetaStack *stack)
|
||||||
|
{
|
||||||
|
MetaDisplay *display = stack->display;
|
||||||
|
GArray *all_root_children_stacked;
|
||||||
|
GList *l;
|
||||||
|
GArray *hidden_stack_ids;
|
||||||
|
GList *sorted;
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_STACK, "Syncing window stack to server\n");
|
||||||
|
|
||||||
|
all_root_children_stacked = g_array_new (FALSE, FALSE, sizeof (uint64_t));
|
||||||
|
hidden_stack_ids = g_array_new (FALSE, FALSE, sizeof (uint64_t));
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_STACK, "Bottom to top: ");
|
||||||
|
meta_push_no_msg_prefix ();
|
||||||
|
|
||||||
|
sorted = meta_stack_list_windows (stack, NULL);
|
||||||
|
|
||||||
|
for (l = sorted; l; l = l->next)
|
||||||
|
{
|
||||||
|
MetaWindow *w = l->data;
|
||||||
|
uint64_t top_level_window;
|
||||||
|
uint64_t stack_id;
|
||||||
|
|
||||||
|
if (w->unmanaging)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_STACK, "%u:%d - %s ",
|
||||||
|
w->layer, w->stack_position, w->desc);
|
||||||
|
|
||||||
|
if (w->frame)
|
||||||
|
top_level_window = w->frame->xwindow;
|
||||||
|
else
|
||||||
|
top_level_window = w->xwindow;
|
||||||
|
|
||||||
|
if (w->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||||
|
stack_id = top_level_window;
|
||||||
|
else
|
||||||
|
stack_id = w->stamp;
|
||||||
|
|
||||||
|
/* We don't restack hidden windows along with the rest, though they are
|
||||||
|
* reflected in the _NET hints. Hidden windows all get pushed below
|
||||||
|
* the screens fullscreen guard_window. */
|
||||||
|
if (w->hidden)
|
||||||
|
{
|
||||||
|
g_array_append_val (hidden_stack_ids, stack_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_array_append_val (all_root_children_stacked, stack_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_STACK, "\n");
|
||||||
|
meta_pop_no_msg_prefix ();
|
||||||
|
|
||||||
|
if (display->x11_display)
|
||||||
|
{
|
||||||
|
uint64_t guard_window_id;
|
||||||
|
|
||||||
|
/* The screen guard window sits above all hidden windows and acts as
|
||||||
|
* a barrier to input reaching these windows. */
|
||||||
|
guard_window_id = display->x11_display->guard_window;
|
||||||
|
g_array_append_val (hidden_stack_ids, guard_window_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sync to server */
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_STACK, "Restacking %u windows\n",
|
||||||
|
all_root_children_stacked->len);
|
||||||
|
|
||||||
|
meta_stack_tracker_restack_managed (display->stack_tracker,
|
||||||
|
(uint64_t *)all_root_children_stacked->data,
|
||||||
|
all_root_children_stacked->len);
|
||||||
|
meta_stack_tracker_restack_at_bottom (display->stack_tracker,
|
||||||
|
(uint64_t *)hidden_stack_ids->data,
|
||||||
|
hidden_stack_ids->len);
|
||||||
|
|
||||||
|
g_array_free (hidden_stack_ids, TRUE);
|
||||||
|
g_array_free (all_root_children_stacked, TRUE);
|
||||||
|
g_list_free (sorted);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_stack_init (MetaStack *stack)
|
meta_stack_init (MetaStack *stack)
|
||||||
{
|
{
|
||||||
|
g_signal_connect (stack, "changed",
|
||||||
|
G_CALLBACK (on_stack_changed), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -232,10 +232,7 @@ x11_stack_sync_to_xserver (MetaX11Stack *x11_stack)
|
||||||
MetaX11Display *x11_display = x11_stack->x11_display;
|
MetaX11Display *x11_display = x11_stack->x11_display;
|
||||||
MetaStack *stack = x11_display->display->stack;
|
MetaStack *stack = x11_display->display->stack;
|
||||||
GArray *x11_stacked;
|
GArray *x11_stacked;
|
||||||
GArray *all_root_children_stacked; /* wayland OR x11 */
|
|
||||||
GList *tmp;
|
GList *tmp;
|
||||||
GArray *hidden_stack_ids;
|
|
||||||
uint64_t guard_window_id;
|
|
||||||
GList *sorted;
|
GList *sorted;
|
||||||
|
|
||||||
meta_topic (META_DEBUG_STACK, "Syncing window stack to server\n");
|
meta_topic (META_DEBUG_STACK, "Syncing window stack to server\n");
|
||||||
|
@ -244,71 +241,16 @@ x11_stack_sync_to_xserver (MetaX11Stack *x11_stack)
|
||||||
*/
|
*/
|
||||||
x11_stacked = g_array_new (FALSE, FALSE, sizeof (Window));
|
x11_stacked = g_array_new (FALSE, FALSE, sizeof (Window));
|
||||||
|
|
||||||
all_root_children_stacked = g_array_new (FALSE, FALSE, sizeof (guint64));
|
|
||||||
hidden_stack_ids = g_array_new (FALSE, FALSE, sizeof (guint64));
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_STACK, "Bottom to top: ");
|
|
||||||
meta_push_no_msg_prefix ();
|
|
||||||
|
|
||||||
sorted = meta_stack_list_windows (stack, NULL);
|
sorted = meta_stack_list_windows (stack, NULL);
|
||||||
|
|
||||||
for (tmp = sorted; tmp; tmp = tmp->next)
|
for (tmp = sorted; tmp; tmp = tmp->next)
|
||||||
{
|
{
|
||||||
MetaWindow *w = tmp->data;
|
MetaWindow *w = tmp->data;
|
||||||
guint64 top_level_window;
|
|
||||||
guint64 stack_id;
|
|
||||||
|
|
||||||
if (w->unmanaging)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_STACK, "%u:%d - %s ",
|
|
||||||
w->layer, w->stack_position, w->desc);
|
|
||||||
|
|
||||||
if (w->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
if (w->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||||
g_array_append_val (x11_stacked, w->xwindow);
|
g_array_append_val (x11_stacked, w->xwindow);
|
||||||
|
|
||||||
if (w->frame)
|
|
||||||
top_level_window = w->frame->xwindow;
|
|
||||||
else
|
|
||||||
top_level_window = w->xwindow;
|
|
||||||
|
|
||||||
if (w->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
|
||||||
stack_id = top_level_window;
|
|
||||||
else
|
|
||||||
stack_id = w->stamp;
|
|
||||||
|
|
||||||
/* We don't restack hidden windows along with the rest, though they are
|
|
||||||
* reflected in the _NET hints. Hidden windows all get pushed below
|
|
||||||
* the screens fullscreen guard_window. */
|
|
||||||
if (w->hidden)
|
|
||||||
{
|
|
||||||
g_array_append_val (hidden_stack_ids, stack_id);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_array_append_val (all_root_children_stacked, stack_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_topic (META_DEBUG_STACK, "\n");
|
|
||||||
meta_pop_no_msg_prefix ();
|
|
||||||
|
|
||||||
/* The screen guard window sits above all hidden windows and acts as
|
|
||||||
* a barrier to input reaching these windows. */
|
|
||||||
guard_window_id = x11_stack->x11_display->guard_window;
|
|
||||||
g_array_append_val (hidden_stack_ids, guard_window_id);
|
|
||||||
|
|
||||||
/* Sync to server */
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_STACK, "Restacking %u windows\n",
|
|
||||||
all_root_children_stacked->len);
|
|
||||||
|
|
||||||
meta_stack_tracker_restack_managed (x11_display->display->stack_tracker,
|
|
||||||
(guint64 *)all_root_children_stacked->data,
|
|
||||||
all_root_children_stacked->len);
|
|
||||||
meta_stack_tracker_restack_at_bottom (x11_display->display->stack_tracker,
|
|
||||||
(guint64 *)hidden_stack_ids->data,
|
|
||||||
hidden_stack_ids->len);
|
|
||||||
|
|
||||||
/* Sync _NET_CLIENT_LIST and _NET_CLIENT_LIST_STACKING */
|
/* Sync _NET_CLIENT_LIST and _NET_CLIENT_LIST_STACKING */
|
||||||
|
|
||||||
XChangeProperty (x11_stack->x11_display->xdisplay,
|
XChangeProperty (x11_stack->x11_display->xdisplay,
|
||||||
|
@ -327,8 +269,6 @@ x11_stack_sync_to_xserver (MetaX11Stack *x11_stack)
|
||||||
x11_stacked->len);
|
x11_stacked->len);
|
||||||
|
|
||||||
g_array_free (x11_stacked, TRUE);
|
g_array_free (x11_stacked, TRUE);
|
||||||
g_array_free (hidden_stack_ids, TRUE);
|
|
||||||
g_array_free (all_root_children_stacked, TRUE);
|
|
||||||
g_list_free (sorted);
|
g_list_free (sorted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue