diff --git a/src/core/stack.c b/src/core/stack.c index d36e1e045..ff706119d 100644 --- a/src/core/stack.c +++ b/src/core/stack.c @@ -36,6 +36,7 @@ #include "meta/group.h" #include "meta/prefs.h" #include "meta/workspace.h" +#include "x11/meta-x11-display-private.h" #define WINDOW_HAS_TRANSIENT_TYPE(w) \ (w->type == META_WINDOW_DIALOG || \ @@ -73,9 +74,94 @@ static guint signals[N_SIGNALS] = { 0 }; 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 meta_stack_init (MetaStack *stack) { + g_signal_connect (stack, "changed", + G_CALLBACK (on_stack_changed), NULL); } static void diff --git a/src/x11/meta-x11-stack.c b/src/x11/meta-x11-stack.c index fa08fc4c5..a8fb6733e 100644 --- a/src/x11/meta-x11-stack.c +++ b/src/x11/meta-x11-stack.c @@ -232,10 +232,7 @@ x11_stack_sync_to_xserver (MetaX11Stack *x11_stack) MetaX11Display *x11_display = x11_stack->x11_display; MetaStack *stack = x11_display->display->stack; GArray *x11_stacked; - GArray *all_root_children_stacked; /* wayland OR x11 */ GList *tmp; - GArray *hidden_stack_ids; - uint64_t guard_window_id; GList *sorted; 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)); - 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); for (tmp = sorted; tmp; tmp = tmp->next) { 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) 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 */ XChangeProperty (x11_stack->x11_display->xdisplay, @@ -327,8 +269,6 @@ x11_stack_sync_to_xserver (MetaX11Stack *x11_stack) x11_stacked->len); 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); }