Replace MetaStackWindow with a 64-bit "stack ID"
Putting X windows and pointers to MetaWindows into a union had a number of problems: - It caused awkward initialization and conditionalization - There was no way to refer to Wayland windows (represented by MetaWindow *) in the past, which is necessary for the MetaStackTracker algorithms - We never even cleaned up old MetaStackWindow so there could be records in MetaStackWindow pointing to freed MetaWindow. Replace MetaStackWindow with a 64-bit "stack ID" which is: - The XID for X Windows - a "window stamp" for Wayland windows - window stamps are assigned for all MetaWindow and are unique across the life of the process. https://bugzilla.gnome.org/show_bug.cgi?id=736559
This commit is contained in:
parent
b49a4ae0bc
commit
73573a85de
@ -166,6 +166,7 @@ struct _MetaDisplay
|
|||||||
/*< private-ish >*/
|
/*< private-ish >*/
|
||||||
MetaScreen *screen;
|
MetaScreen *screen;
|
||||||
GHashTable *xids;
|
GHashTable *xids;
|
||||||
|
GHashTable *stamps;
|
||||||
GHashTable *wayland_windows;
|
GHashTable *wayland_windows;
|
||||||
|
|
||||||
/* serials of leave/unmap events that may
|
/* serials of leave/unmap events that may
|
||||||
@ -341,6 +342,29 @@ void meta_display_register_x_window (MetaDisplay *display,
|
|||||||
void meta_display_unregister_x_window (MetaDisplay *display,
|
void meta_display_unregister_x_window (MetaDisplay *display,
|
||||||
Window xwindow);
|
Window xwindow);
|
||||||
|
|
||||||
|
/* Each MetaWindow is uniquely identified by a 64-bit "stamp"; unlike a
|
||||||
|
* a MetaWindow *, a stamp will never be recycled
|
||||||
|
*/
|
||||||
|
MetaWindow* meta_display_lookup_stamp (MetaDisplay *display,
|
||||||
|
guint64 stamp);
|
||||||
|
void meta_display_register_stamp (MetaDisplay *display,
|
||||||
|
guint64 *stampp,
|
||||||
|
MetaWindow *window);
|
||||||
|
void meta_display_unregister_stamp (MetaDisplay *display,
|
||||||
|
guint64 stamp);
|
||||||
|
|
||||||
|
/* A "stack id" is a XID or a stamp */
|
||||||
|
|
||||||
|
#define META_STACK_ID_IS_X11(id) ((id) < G_GUINT64_CONSTANT(0x100000000))
|
||||||
|
MetaWindow* meta_display_lookup_stack_id (MetaDisplay *display,
|
||||||
|
guint64 stack_id);
|
||||||
|
|
||||||
|
/* for debug logging only; returns a human-description of the stack
|
||||||
|
* ID - a small number of buffers are recycled, so the result must
|
||||||
|
* be used immediately or copied */
|
||||||
|
const char *meta_display_describe_stack_id (MetaDisplay *display,
|
||||||
|
guint64 stack_id);
|
||||||
|
|
||||||
void meta_display_register_wayland_window (MetaDisplay *display,
|
void meta_display_register_wayland_window (MetaDisplay *display,
|
||||||
MetaWindow *window);
|
MetaWindow *window);
|
||||||
void meta_display_unregister_wayland_window (MetaDisplay *display,
|
void meta_display_unregister_wayland_window (MetaDisplay *display,
|
||||||
|
@ -627,6 +627,8 @@ meta_display_open (void)
|
|||||||
|
|
||||||
display->xids = g_hash_table_new (meta_unsigned_long_hash,
|
display->xids = g_hash_table_new (meta_unsigned_long_hash,
|
||||||
meta_unsigned_long_equal);
|
meta_unsigned_long_equal);
|
||||||
|
display->stamps = g_hash_table_new (g_int64_hash,
|
||||||
|
g_int64_equal);
|
||||||
display->wayland_windows = g_hash_table_new (NULL, NULL);
|
display->wayland_windows = g_hash_table_new (NULL, NULL);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -1581,6 +1583,68 @@ meta_display_unregister_wayland_window (MetaDisplay *display,
|
|||||||
g_hash_table_remove (display->wayland_windows, window);
|
g_hash_table_remove (display->wayland_windows, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetaWindow*
|
||||||
|
meta_display_lookup_stamp (MetaDisplay *display,
|
||||||
|
guint64 stamp)
|
||||||
|
{
|
||||||
|
return g_hash_table_lookup (display->stamps, &stamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_display_register_stamp (MetaDisplay *display,
|
||||||
|
guint64 *stampp,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
g_return_if_fail (g_hash_table_lookup (display->stamps, stampp) == NULL);
|
||||||
|
|
||||||
|
g_hash_table_insert (display->stamps, stampp, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_display_unregister_stamp (MetaDisplay *display,
|
||||||
|
guint64 stamp)
|
||||||
|
{
|
||||||
|
g_return_if_fail (g_hash_table_lookup (display->stamps, &stamp) != NULL);
|
||||||
|
|
||||||
|
g_hash_table_remove (display->stamps, &stamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWindow*
|
||||||
|
meta_display_lookup_stack_id (MetaDisplay *display,
|
||||||
|
guint64 stack_id)
|
||||||
|
{
|
||||||
|
if (META_STACK_ID_IS_X11 (stack_id))
|
||||||
|
return meta_display_lookup_x_window (display, (Window)stack_id);
|
||||||
|
else
|
||||||
|
return meta_display_lookup_stamp (display, stack_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We return a pointer into a ring of static buffers. This is to make
|
||||||
|
* using this function for debug-logging convenient and avoid tempory
|
||||||
|
* strings that must be freed. */
|
||||||
|
const char *
|
||||||
|
meta_display_describe_stack_id (MetaDisplay *display,
|
||||||
|
guint64 stack_id)
|
||||||
|
{
|
||||||
|
/* 0x<64-bit: 16 characters> (<10 characters of title>)\0' */
|
||||||
|
static char buffer[5][32];
|
||||||
|
MetaWindow *window;
|
||||||
|
static int pos = 0;
|
||||||
|
char *result;
|
||||||
|
|
||||||
|
result = buffer[pos];
|
||||||
|
pos = (pos + 1) % 5;
|
||||||
|
|
||||||
|
window = meta_display_lookup_stack_id (display, stack_id);
|
||||||
|
|
||||||
|
if (window && window->title)
|
||||||
|
snprintf (result, sizeof(buffer[0]), "%#" G_GINT64_MODIFIER "x (%.10s)", stack_id, window->title);
|
||||||
|
else
|
||||||
|
snprintf (result, sizeof(buffer[0]), "%#" G_GINT64_MODIFIER "x", stack_id);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* We store sync alarms in the window ID hash table, because they are
|
/* We store sync alarms in the window ID hash table, because they are
|
||||||
* just more types of XIDs in the same global space, but we have
|
* just more types of XIDs in the same global space, but we have
|
||||||
* typesafe functions to register/unregister for readability.
|
* typesafe functions to register/unregister for readability.
|
||||||
|
@ -39,7 +39,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
XSetWindowAttributes attrs;
|
XSetWindowAttributes attrs;
|
||||||
Visual *visual;
|
Visual *visual;
|
||||||
gulong create_serial;
|
gulong create_serial;
|
||||||
MetaStackWindow stack_window;
|
|
||||||
|
|
||||||
if (window->frame)
|
if (window->frame)
|
||||||
return;
|
return;
|
||||||
@ -95,10 +94,8 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
frame->rect.height,
|
frame->rect.height,
|
||||||
frame->window->screen->number,
|
frame->window->screen->number,
|
||||||
&create_serial);
|
&create_serial);
|
||||||
stack_window.any.type = META_WINDOW_CLIENT_TYPE_X11;
|
|
||||||
stack_window.x11.xwindow = frame->xwindow;
|
|
||||||
meta_stack_tracker_record_add (window->screen->stack_tracker,
|
meta_stack_tracker_record_add (window->screen->stack_tracker,
|
||||||
&stack_window,
|
frame->xwindow,
|
||||||
create_serial);
|
create_serial);
|
||||||
|
|
||||||
meta_verbose ("Frame for %s is 0x%lx\n", frame->window->desc, frame->xwindow);
|
meta_verbose ("Frame for %s is 0x%lx\n", frame->window->desc, frame->xwindow);
|
||||||
@ -132,9 +129,8 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
window->unmaps_pending += 1;
|
window->unmaps_pending += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
stack_window.x11.xwindow = window->xwindow;
|
|
||||||
meta_stack_tracker_record_remove (window->screen->stack_tracker,
|
meta_stack_tracker_record_remove (window->screen->stack_tracker,
|
||||||
&stack_window,
|
window->xwindow,
|
||||||
XNextRequest (window->display->xdisplay));
|
XNextRequest (window->display->xdisplay));
|
||||||
XReparentWindow (window->display->xdisplay,
|
XReparentWindow (window->display->xdisplay,
|
||||||
window->xwindow,
|
window->xwindow,
|
||||||
@ -179,7 +175,6 @@ meta_window_destroy_frame (MetaWindow *window)
|
|||||||
{
|
{
|
||||||
MetaFrame *frame;
|
MetaFrame *frame;
|
||||||
MetaFrameBorders borders;
|
MetaFrameBorders borders;
|
||||||
MetaStackWindow stack_window;
|
|
||||||
|
|
||||||
if (window->frame == NULL)
|
if (window->frame == NULL)
|
||||||
return;
|
return;
|
||||||
@ -206,10 +201,8 @@ meta_window_destroy_frame (MetaWindow *window)
|
|||||||
"Incrementing unmaps_pending on %s for reparent back to root\n", window->desc);
|
"Incrementing unmaps_pending on %s for reparent back to root\n", window->desc);
|
||||||
window->unmaps_pending += 1;
|
window->unmaps_pending += 1;
|
||||||
}
|
}
|
||||||
stack_window.any.type = META_WINDOW_CLIENT_TYPE_X11;
|
|
||||||
stack_window.x11.xwindow = window->xwindow;
|
|
||||||
meta_stack_tracker_record_add (window->screen->stack_tracker,
|
meta_stack_tracker_record_add (window->screen->stack_tracker,
|
||||||
&stack_window,
|
window->xwindow,
|
||||||
XNextRequest (window->display->xdisplay));
|
XNextRequest (window->display->xdisplay));
|
||||||
XReparentWindow (window->display->xdisplay,
|
XReparentWindow (window->display->xdisplay,
|
||||||
window->xwindow,
|
window->xwindow,
|
||||||
|
@ -441,7 +441,6 @@ create_guard_window (Display *xdisplay, MetaScreen *screen)
|
|||||||
XSetWindowAttributes attributes;
|
XSetWindowAttributes attributes;
|
||||||
Window guard_window;
|
Window guard_window;
|
||||||
gulong create_serial;
|
gulong create_serial;
|
||||||
MetaStackWindow stack_window;
|
|
||||||
|
|
||||||
attributes.event_mask = NoEventMask;
|
attributes.event_mask = NoEventMask;
|
||||||
attributes.override_redirect = True;
|
attributes.override_redirect = True;
|
||||||
@ -487,14 +486,12 @@ create_guard_window (Display *xdisplay, MetaScreen *screen)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stack_window.any.type = META_WINDOW_CLIENT_TYPE_X11;
|
|
||||||
stack_window.x11.xwindow = guard_window;
|
|
||||||
meta_stack_tracker_record_add (screen->stack_tracker,
|
meta_stack_tracker_record_add (screen->stack_tracker,
|
||||||
&stack_window,
|
guard_window,
|
||||||
create_serial);
|
create_serial);
|
||||||
|
|
||||||
meta_stack_tracker_record_lower (screen->stack_tracker,
|
meta_stack_tracker_record_lower (screen->stack_tracker,
|
||||||
&stack_window,
|
guard_window,
|
||||||
XNextRequest (xdisplay));
|
XNextRequest (xdisplay));
|
||||||
XLowerWindow (xdisplay, guard_window);
|
XLowerWindow (xdisplay, guard_window);
|
||||||
XMapWindow (xdisplay, guard_window);
|
XMapWindow (xdisplay, guard_window);
|
||||||
@ -884,19 +881,20 @@ meta_screen_create_guard_window (MetaScreen *screen)
|
|||||||
void
|
void
|
||||||
meta_screen_manage_all_windows (MetaScreen *screen)
|
meta_screen_manage_all_windows (MetaScreen *screen)
|
||||||
{
|
{
|
||||||
MetaStackWindow *_children;
|
guint64 *_children;
|
||||||
MetaStackWindow *children;
|
guint64 *children;
|
||||||
int n_children, i;
|
int n_children, i;
|
||||||
|
|
||||||
meta_stack_freeze (screen->stack);
|
meta_stack_freeze (screen->stack);
|
||||||
meta_stack_tracker_get_stack (screen->stack_tracker, &_children, &n_children);
|
meta_stack_tracker_get_stack (screen->stack_tracker, &_children, &n_children);
|
||||||
|
|
||||||
/* Copy the stack as it will be modified as part of the loop */
|
/* Copy the stack as it will be modified as part of the loop */
|
||||||
children = g_memdup (_children, sizeof (MetaStackWindow) * n_children);
|
children = g_memdup (_children, sizeof (guint64) * n_children);
|
||||||
|
|
||||||
for (i = 0; i < n_children; ++i)
|
for (i = 0; i < n_children; ++i)
|
||||||
{
|
{
|
||||||
meta_window_x11_new (screen->display, children[i].x11.xwindow, TRUE,
|
g_assert (META_STACK_ID_IS_X11 (children[i]));
|
||||||
|
meta_window_x11_new (screen->display, children[i], TRUE,
|
||||||
META_COMP_EFFECT_NONE);
|
META_COMP_EFFECT_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,29 +96,29 @@ union _MetaStackOp
|
|||||||
struct {
|
struct {
|
||||||
MetaStackOpType type;
|
MetaStackOpType type;
|
||||||
gulong serial;
|
gulong serial;
|
||||||
MetaStackWindow window;
|
guint64 window;
|
||||||
} any;
|
} any;
|
||||||
struct {
|
struct {
|
||||||
MetaStackOpType type;
|
MetaStackOpType type;
|
||||||
gulong serial;
|
gulong serial;
|
||||||
MetaStackWindow window;
|
guint64 window;
|
||||||
} add;
|
} add;
|
||||||
struct {
|
struct {
|
||||||
MetaStackOpType type;
|
MetaStackOpType type;
|
||||||
gulong serial;
|
gulong serial;
|
||||||
MetaStackWindow window;
|
guint64 window;
|
||||||
} remove;
|
} remove;
|
||||||
struct {
|
struct {
|
||||||
MetaStackOpType type;
|
MetaStackOpType type;
|
||||||
gulong serial;
|
gulong serial;
|
||||||
MetaStackWindow window;
|
guint64 window;
|
||||||
MetaStackWindow sibling;
|
guint64 sibling;
|
||||||
} raise_above;
|
} raise_above;
|
||||||
struct {
|
struct {
|
||||||
MetaStackOpType type;
|
MetaStackOpType type;
|
||||||
gulong serial;
|
gulong serial;
|
||||||
MetaStackWindow window;
|
guint64 window;
|
||||||
MetaStackWindow sibling;
|
guint64 sibling;
|
||||||
} lower_below;
|
} lower_below;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -157,95 +157,65 @@ struct _MetaStackTracker
|
|||||||
guint sync_stack_later;
|
guint sync_stack_later;
|
||||||
};
|
};
|
||||||
|
|
||||||
static gboolean
|
static inline const char *
|
||||||
meta_stack_window_is_set (const MetaStackWindow *window)
|
get_window_desc (MetaStackTracker *tracker,
|
||||||
|
guint64 window)
|
||||||
{
|
{
|
||||||
if (window->any.type == META_WINDOW_CLIENT_TYPE_X11)
|
return meta_display_describe_stack_id (tracker->screen->display, window);
|
||||||
return window->x11.xwindow == None ? FALSE : TRUE;
|
|
||||||
else
|
|
||||||
return window->wayland.meta_window ? TRUE : FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
meta_stack_window_equal (const MetaStackWindow *a,
|
|
||||||
const MetaStackWindow *b)
|
|
||||||
{
|
|
||||||
if (a->any.type == b->any.type)
|
|
||||||
{
|
|
||||||
if (a->any.type == META_WINDOW_CLIENT_TYPE_X11)
|
|
||||||
return a->x11.xwindow == b->x11.xwindow;
|
|
||||||
else
|
|
||||||
return a->wayland.meta_window == b->wayland.meta_window;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
get_window_id (MetaStackWindow *window)
|
|
||||||
{
|
|
||||||
if (window->any.type == META_WINDOW_CLIENT_TYPE_X11)
|
|
||||||
return g_strdup_printf ("X11:%lx", window->x11.xwindow);
|
|
||||||
else
|
|
||||||
return g_strdup_printf ("Wayland:%p", window->wayland.meta_window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_stack_op_dump (MetaStackOp *op,
|
meta_stack_op_dump (MetaStackTracker *tracker,
|
||||||
const char *prefix,
|
MetaStackOp *op,
|
||||||
const char *suffix)
|
const char *prefix,
|
||||||
|
const char *suffix)
|
||||||
{
|
{
|
||||||
char *window_id = get_window_id (&op->any.window);
|
const char *window_desc = get_window_desc (tracker, op->any.window);
|
||||||
|
|
||||||
switch (op->any.type)
|
switch (op->any.type)
|
||||||
{
|
{
|
||||||
case STACK_OP_ADD:
|
case STACK_OP_ADD:
|
||||||
meta_topic (META_DEBUG_STACK, "%sADD(%s; %ld)%s",
|
meta_topic (META_DEBUG_STACK, "%sADD(%s; %ld)%s",
|
||||||
prefix, window_id, op->any.serial, suffix);
|
prefix, window_desc, op->any.serial, suffix);
|
||||||
break;
|
break;
|
||||||
case STACK_OP_REMOVE:
|
case STACK_OP_REMOVE:
|
||||||
meta_topic (META_DEBUG_STACK, "%sREMOVE(%s; %ld)%s",
|
meta_topic (META_DEBUG_STACK, "%sREMOVE(%s; %ld)%s",
|
||||||
prefix, window_id, op->any.serial, suffix);
|
prefix, window_desc, op->any.serial, suffix);
|
||||||
break;
|
break;
|
||||||
case STACK_OP_RAISE_ABOVE:
|
case STACK_OP_RAISE_ABOVE:
|
||||||
{
|
{
|
||||||
char *sibling_id = get_window_id (&op->raise_above.sibling);
|
|
||||||
meta_topic (META_DEBUG_STACK, "%sRAISE_ABOVE(%s, %s; %ld)%s",
|
meta_topic (META_DEBUG_STACK, "%sRAISE_ABOVE(%s, %s; %ld)%s",
|
||||||
prefix,
|
prefix,
|
||||||
window_id, sibling_id,
|
window_desc,
|
||||||
|
get_window_desc (tracker, op->raise_above.sibling),
|
||||||
op->any.serial,
|
op->any.serial,
|
||||||
suffix);
|
suffix);
|
||||||
g_free (sibling_id);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case STACK_OP_LOWER_BELOW:
|
case STACK_OP_LOWER_BELOW:
|
||||||
{
|
{
|
||||||
char *sibling_id = get_window_id (&op->lower_below.sibling);
|
|
||||||
meta_topic (META_DEBUG_STACK, "%sLOWER_BELOW(%s, %s; %ld)%s",
|
meta_topic (META_DEBUG_STACK, "%sLOWER_BELOW(%s, %s; %ld)%s",
|
||||||
prefix,
|
prefix,
|
||||||
window_id, sibling_id,
|
window_desc,
|
||||||
|
get_window_desc (tracker, op->lower_below.sibling),
|
||||||
op->any.serial,
|
op->any.serial,
|
||||||
suffix);
|
suffix);
|
||||||
g_free (sibling_id);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (window_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
stack_dump (GArray *stack)
|
stack_dump (MetaStackTracker *tracker,
|
||||||
|
GArray *stack)
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
meta_push_no_msg_prefix ();
|
meta_push_no_msg_prefix ();
|
||||||
for (i = 0; i < stack->len; i++)
|
for (i = 0; i < stack->len; i++)
|
||||||
{
|
{
|
||||||
MetaStackWindow *window = &g_array_index (stack, MetaStackWindow, i);
|
guint64 window = g_array_index (stack, guint64, i);
|
||||||
char *window_id = get_window_id (window);
|
meta_topic (META_DEBUG_STACK, " %s", get_window_desc (tracker, window));
|
||||||
meta_topic (META_DEBUG_STACK, " %s", window_id);
|
|
||||||
g_free (window_id);
|
|
||||||
}
|
}
|
||||||
meta_topic (META_DEBUG_STACK, "\n");
|
meta_topic (META_DEBUG_STACK, "\n");
|
||||||
meta_pop_no_msg_prefix ();
|
meta_pop_no_msg_prefix ();
|
||||||
@ -260,20 +230,20 @@ meta_stack_tracker_dump (MetaStackTracker *tracker)
|
|||||||
meta_push_no_msg_prefix ();
|
meta_push_no_msg_prefix ();
|
||||||
meta_topic (META_DEBUG_STACK, " xserver_serial: %ld\n", tracker->xserver_serial);
|
meta_topic (META_DEBUG_STACK, " xserver_serial: %ld\n", tracker->xserver_serial);
|
||||||
meta_topic (META_DEBUG_STACK, " xserver_stack: ");
|
meta_topic (META_DEBUG_STACK, " xserver_stack: ");
|
||||||
stack_dump (tracker->xserver_stack);
|
stack_dump (tracker, tracker->xserver_stack);
|
||||||
meta_topic (META_DEBUG_STACK, " verfied_stack: ");
|
meta_topic (META_DEBUG_STACK, " verfied_stack: ");
|
||||||
stack_dump (tracker->verified_stack);
|
stack_dump (tracker, tracker->verified_stack);
|
||||||
meta_topic (META_DEBUG_STACK, " unverified_predictions: [");
|
meta_topic (META_DEBUG_STACK, " unverified_predictions: [");
|
||||||
for (l = tracker->unverified_predictions->head; l; l = l->next)
|
for (l = tracker->unverified_predictions->head; l; l = l->next)
|
||||||
{
|
{
|
||||||
MetaStackOp *op = l->data;
|
MetaStackOp *op = l->data;
|
||||||
meta_stack_op_dump (op, "", l->next ? ", " : "");
|
meta_stack_op_dump (tracker, op, "", l->next ? ", " : "");
|
||||||
}
|
}
|
||||||
meta_topic (META_DEBUG_STACK, "]\n");
|
meta_topic (META_DEBUG_STACK, "]\n");
|
||||||
if (tracker->predicted_stack)
|
if (tracker->predicted_stack)
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_STACK, "\n predicted_stack: ");
|
meta_topic (META_DEBUG_STACK, "\n predicted_stack: ");
|
||||||
stack_dump (tracker->predicted_stack);
|
stack_dump (tracker, tracker->predicted_stack);
|
||||||
}
|
}
|
||||||
meta_pop_no_msg_prefix ();
|
meta_pop_no_msg_prefix ();
|
||||||
}
|
}
|
||||||
@ -285,23 +255,16 @@ meta_stack_op_free (MetaStackOp *op)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
find_window (GArray *window_stack,
|
find_window (GArray *window_stack,
|
||||||
MetaStackWindow *window)
|
guint64 window)
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
for (i = 0; i < window_stack->len; i++)
|
for (i = 0; i < window_stack->len; i++)
|
||||||
{
|
{
|
||||||
MetaStackWindow *current = &g_array_index (window_stack, MetaStackWindow, i);
|
guint64 current = g_array_index (window_stack, guint64, i);
|
||||||
if (current->any.type == window->any.type)
|
if (current == window)
|
||||||
{
|
return i;
|
||||||
if (current->any.type == META_WINDOW_CLIENT_TYPE_X11 &&
|
|
||||||
current->x11.xwindow == window->x11.xwindow)
|
|
||||||
return i;
|
|
||||||
else
|
|
||||||
if (current->wayland.meta_window == window->wayland.meta_window)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@ -309,33 +272,30 @@ find_window (GArray *window_stack,
|
|||||||
|
|
||||||
/* Returns TRUE if stack was changed */
|
/* Returns TRUE if stack was changed */
|
||||||
static gboolean
|
static gboolean
|
||||||
move_window_above (GArray *stack,
|
move_window_above (GArray *stack,
|
||||||
MetaStackWindow *window,
|
guint64 window,
|
||||||
int old_pos,
|
int old_pos,
|
||||||
int above_pos)
|
int above_pos)
|
||||||
{
|
{
|
||||||
/* Copy the window by-value before we start shifting things around
|
|
||||||
* in the stack in case window points into the stack itself. */
|
|
||||||
MetaStackWindow window_val = *window;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (old_pos < above_pos)
|
if (old_pos < above_pos)
|
||||||
{
|
{
|
||||||
for (i = old_pos; i < above_pos; i++)
|
for (i = old_pos; i < above_pos; i++)
|
||||||
g_array_index (stack, MetaStackWindow, i) =
|
g_array_index (stack, guint64, i) =
|
||||||
g_array_index (stack, MetaStackWindow, i + 1);
|
g_array_index (stack, guint64, i + 1);
|
||||||
|
|
||||||
g_array_index (stack, MetaStackWindow, above_pos) = window_val;
|
g_array_index (stack, guint64, above_pos) = window;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else if (old_pos > above_pos + 1)
|
else if (old_pos > above_pos + 1)
|
||||||
{
|
{
|
||||||
for (i = old_pos; i > above_pos + 1; i--)
|
for (i = old_pos; i > above_pos + 1; i--)
|
||||||
g_array_index (stack, MetaStackWindow, i) =
|
g_array_index (stack, guint64, i) =
|
||||||
g_array_index (stack, MetaStackWindow, i - 1);
|
g_array_index (stack, guint64, i - 1);
|
||||||
|
|
||||||
g_array_index (stack, MetaStackWindow, above_pos + 1) = window_val;
|
g_array_index (stack, guint64, above_pos + 1) = window;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -345,20 +305,19 @@ move_window_above (GArray *stack,
|
|||||||
|
|
||||||
/* Returns TRUE if stack was changed */
|
/* Returns TRUE if stack was changed */
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_stack_op_apply (MetaStackOp *op,
|
meta_stack_op_apply (MetaStackTracker *tracker,
|
||||||
GArray *stack)
|
MetaStackOp *op,
|
||||||
|
GArray *stack)
|
||||||
{
|
{
|
||||||
switch (op->any.type)
|
switch (op->any.type)
|
||||||
{
|
{
|
||||||
case STACK_OP_ADD:
|
case STACK_OP_ADD:
|
||||||
{
|
{
|
||||||
int old_pos = find_window (stack, &op->add.window);
|
int old_pos = find_window (stack, op->add.window);
|
||||||
if (old_pos >= 0)
|
if (old_pos >= 0)
|
||||||
{
|
{
|
||||||
char *window_id = get_window_id (&op->add.window);
|
|
||||||
g_warning ("STACK_OP_ADD: window %s already in stack",
|
g_warning ("STACK_OP_ADD: window %s already in stack",
|
||||||
window_id);
|
get_window_desc (tracker, op->add.window));
|
||||||
g_free (window_id);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,13 +326,11 @@ meta_stack_op_apply (MetaStackOp *op,
|
|||||||
}
|
}
|
||||||
case STACK_OP_REMOVE:
|
case STACK_OP_REMOVE:
|
||||||
{
|
{
|
||||||
int old_pos = find_window (stack, &op->remove.window);
|
int old_pos = find_window (stack, op->remove.window);
|
||||||
if (old_pos < 0)
|
if (old_pos < 0)
|
||||||
{
|
{
|
||||||
char *window_id = get_window_id (&op->remove.window);
|
|
||||||
g_warning ("STACK_OP_REMOVE: window %s not in stack",
|
g_warning ("STACK_OP_REMOVE: window %s not in stack",
|
||||||
window_id);
|
get_window_desc (tracker, op->remove.window));
|
||||||
g_free (window_id);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,26 +339,22 @@ meta_stack_op_apply (MetaStackOp *op,
|
|||||||
}
|
}
|
||||||
case STACK_OP_RAISE_ABOVE:
|
case STACK_OP_RAISE_ABOVE:
|
||||||
{
|
{
|
||||||
int old_pos = find_window (stack, &op->raise_above.window);
|
int old_pos = find_window (stack, op->raise_above.window);
|
||||||
int above_pos;
|
int above_pos;
|
||||||
if (old_pos < 0)
|
if (old_pos < 0)
|
||||||
{
|
{
|
||||||
char *window_id = get_window_id (&op->raise_above.window);
|
|
||||||
g_warning ("STACK_OP_RAISE_ABOVE: window %s not in stack",
|
g_warning ("STACK_OP_RAISE_ABOVE: window %s not in stack",
|
||||||
window_id);
|
get_window_desc (tracker, op->raise_above.window));
|
||||||
g_free (window_id);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meta_stack_window_is_set (&op->raise_above.sibling))
|
if (op->raise_above.sibling)
|
||||||
{
|
{
|
||||||
above_pos = find_window (stack, &op->raise_above.sibling);
|
above_pos = find_window (stack, op->raise_above.sibling);
|
||||||
if (above_pos < 0)
|
if (above_pos < 0)
|
||||||
{
|
{
|
||||||
char *sibling_id = get_window_id (&op->raise_above.sibling);
|
|
||||||
g_warning ("STACK_OP_RAISE_ABOVE: sibling window %s not in stack",
|
g_warning ("STACK_OP_RAISE_ABOVE: sibling window %s not in stack",
|
||||||
sibling_id);
|
get_window_desc (tracker, op->raise_above.sibling));
|
||||||
g_free (sibling_id);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -410,30 +363,26 @@ meta_stack_op_apply (MetaStackOp *op,
|
|||||||
above_pos = -1;
|
above_pos = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return move_window_above (stack, &op->raise_above.window, old_pos, above_pos);
|
return move_window_above (stack, op->raise_above.window, old_pos, above_pos);
|
||||||
}
|
}
|
||||||
case STACK_OP_LOWER_BELOW:
|
case STACK_OP_LOWER_BELOW:
|
||||||
{
|
{
|
||||||
int old_pos = find_window (stack, &op->lower_below.window);
|
int old_pos = find_window (stack, op->lower_below.window);
|
||||||
int above_pos;
|
int above_pos;
|
||||||
if (old_pos < 0)
|
if (old_pos < 0)
|
||||||
{
|
{
|
||||||
char *window_id = get_window_id (&op->lower_below.window);
|
|
||||||
g_warning ("STACK_OP_LOWER_BELOW: window %s not in stack",
|
g_warning ("STACK_OP_LOWER_BELOW: window %s not in stack",
|
||||||
window_id);
|
get_window_desc (tracker, op->lower_below.window));
|
||||||
g_free (window_id);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meta_stack_window_is_set (&op->lower_below.sibling))
|
if (op->lower_below.sibling)
|
||||||
{
|
{
|
||||||
int below_pos = find_window (stack, &op->lower_below.sibling);
|
int below_pos = find_window (stack, op->lower_below.sibling);
|
||||||
if (below_pos < 0)
|
if (below_pos < 0)
|
||||||
{
|
{
|
||||||
char *sibling_id = get_window_id (&op->lower_below.sibling);
|
|
||||||
g_warning ("STACK_OP_LOWER_BELOW: sibling window %s not in stack",
|
g_warning ("STACK_OP_LOWER_BELOW: sibling window %s not in stack",
|
||||||
sibling_id);
|
get_window_desc (tracker, op->lower_below.sibling));
|
||||||
g_free (sibling_id);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,7 +393,7 @@ meta_stack_op_apply (MetaStackOp *op,
|
|||||||
above_pos = stack->len - 1;
|
above_pos = stack->len - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return move_window_above (stack, &op->lower_below.window, old_pos, above_pos);
|
return move_window_above (stack, op->lower_below.window, old_pos, above_pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,11 +404,11 @@ meta_stack_op_apply (MetaStackOp *op,
|
|||||||
static GArray *
|
static GArray *
|
||||||
copy_stack (GArray *stack)
|
copy_stack (GArray *stack)
|
||||||
{
|
{
|
||||||
GArray *copy = g_array_sized_new (FALSE, FALSE, sizeof (MetaStackWindow), stack->len);
|
GArray *copy = g_array_sized_new (FALSE, FALSE, sizeof (guint64), stack->len);
|
||||||
|
|
||||||
g_array_set_size (copy, stack->len);
|
g_array_set_size (copy, stack->len);
|
||||||
|
|
||||||
memcpy (copy->data, stack->data, sizeof (MetaStackWindow) * stack->len);
|
memcpy (copy->data, stack->data, sizeof (guint64) * stack->len);
|
||||||
|
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
@ -482,15 +431,11 @@ requery_xserver_stack (MetaStackTracker *tracker)
|
|||||||
screen->xroot,
|
screen->xroot,
|
||||||
&ignored1, &ignored2, &children, &n_children);
|
&ignored1, &ignored2, &children, &n_children);
|
||||||
|
|
||||||
tracker->xserver_stack = g_array_sized_new (FALSE, FALSE, sizeof (MetaStackWindow), n_children);
|
tracker->xserver_stack = g_array_sized_new (FALSE, FALSE, sizeof (guint64), n_children);
|
||||||
g_array_set_size (tracker->xserver_stack, n_children);
|
g_array_set_size (tracker->xserver_stack, n_children);
|
||||||
|
|
||||||
for (i = 0; i < n_children; i++)
|
for (i = 0; i < n_children; i++)
|
||||||
{
|
g_array_index (tracker->xserver_stack, guint64, i) = children[i];
|
||||||
MetaStackWindow *window = &g_array_index (tracker->xserver_stack, MetaStackWindow, i);
|
|
||||||
window->any.type = META_WINDOW_CLIENT_TYPE_X11;
|
|
||||||
window->x11.xwindow = children[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
XFree (children);
|
XFree (children);
|
||||||
}
|
}
|
||||||
@ -542,22 +487,22 @@ stack_tracker_apply_prediction (MetaStackTracker *tracker,
|
|||||||
* we can apply it immediately so long as it doesn't depend on any
|
* we can apply it immediately so long as it doesn't depend on any
|
||||||
* unverified X operations...
|
* unverified X operations...
|
||||||
*/
|
*/
|
||||||
if (op->any.window.any.type == META_WINDOW_CLIENT_TYPE_WAYLAND &&
|
if (!META_STACK_ID_IS_X11 (op->any.window) &&
|
||||||
tracker->unverified_predictions->length == 0)
|
tracker->unverified_predictions->length == 0)
|
||||||
{
|
{
|
||||||
if (meta_stack_op_apply (op, tracker->verified_stack))
|
if (meta_stack_op_apply (tracker, op, tracker->verified_stack))
|
||||||
meta_stack_tracker_queue_sync_stack (tracker);
|
meta_stack_tracker_queue_sync_stack (tracker);
|
||||||
|
|
||||||
free_at_end = TRUE;
|
free_at_end = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
meta_stack_op_dump (op, "Predicting: ", "\n");
|
meta_stack_op_dump (tracker, op, "Predicting: ", "\n");
|
||||||
g_queue_push_tail (tracker->unverified_predictions, op);
|
g_queue_push_tail (tracker->unverified_predictions, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tracker->predicted_stack ||
|
if (!tracker->predicted_stack ||
|
||||||
meta_stack_op_apply (op, tracker->predicted_stack))
|
meta_stack_op_apply (tracker, op, tracker->predicted_stack))
|
||||||
meta_stack_tracker_queue_sync_stack (tracker);
|
meta_stack_tracker_queue_sync_stack (tracker);
|
||||||
|
|
||||||
if (free_at_end)
|
if (free_at_end)
|
||||||
@ -567,38 +512,38 @@ stack_tracker_apply_prediction (MetaStackTracker *tracker,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_stack_tracker_record_add (MetaStackTracker *tracker,
|
meta_stack_tracker_record_add (MetaStackTracker *tracker,
|
||||||
const MetaStackWindow *window,
|
guint64 window,
|
||||||
gulong serial)
|
gulong serial)
|
||||||
{
|
{
|
||||||
MetaStackOp *op = g_slice_new (MetaStackOp);
|
MetaStackOp *op = g_slice_new (MetaStackOp);
|
||||||
|
|
||||||
op->any.type = STACK_OP_ADD;
|
op->any.type = STACK_OP_ADD;
|
||||||
op->any.serial = serial;
|
op->any.serial = serial;
|
||||||
op->any.window = *window;
|
op->any.window = window;
|
||||||
|
|
||||||
stack_tracker_apply_prediction (tracker, op);
|
stack_tracker_apply_prediction (tracker, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_stack_tracker_record_remove (MetaStackTracker *tracker,
|
meta_stack_tracker_record_remove (MetaStackTracker *tracker,
|
||||||
const MetaStackWindow *window,
|
guint64 window,
|
||||||
gulong serial)
|
gulong serial)
|
||||||
{
|
{
|
||||||
MetaStackOp *op = g_slice_new (MetaStackOp);
|
MetaStackOp *op = g_slice_new (MetaStackOp);
|
||||||
|
|
||||||
op->any.type = STACK_OP_REMOVE;
|
op->any.type = STACK_OP_REMOVE;
|
||||||
op->any.serial = serial;
|
op->any.serial = serial;
|
||||||
op->any.window = *window;
|
op->any.window = window;
|
||||||
|
|
||||||
stack_tracker_apply_prediction (tracker, op);
|
stack_tracker_apply_prediction (tracker, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_stack_tracker_record_restack_windows (MetaStackTracker *tracker,
|
meta_stack_tracker_record_restack_windows (MetaStackTracker *tracker,
|
||||||
const MetaStackWindow *windows,
|
const guint64 *windows,
|
||||||
int n_windows,
|
int n_windows,
|
||||||
gulong serial)
|
gulong serial)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int n_x_windows = 0;
|
int n_x_windows = 0;
|
||||||
@ -619,14 +564,14 @@ meta_stack_tracker_record_restack_windows (MetaStackTracker *tracker,
|
|||||||
* events with intermediate serials, set n_complete rather than
|
* events with intermediate serials, set n_complete rather than
|
||||||
* removing the op from the queue.
|
* removing the op from the queue.
|
||||||
*/
|
*/
|
||||||
if (n_windows && windows[0].any.type == META_WINDOW_CLIENT_TYPE_X11)
|
if (n_windows && META_STACK_ID_IS_X11 (windows[0]))
|
||||||
n_x_windows++;
|
n_x_windows++;
|
||||||
for (i = 0; i < n_windows - 1; i++)
|
for (i = 0; i < n_windows - 1; i++)
|
||||||
{
|
{
|
||||||
const MetaStackWindow *lower = &windows[i + 1];
|
guint64 lower = windows[i + 1];
|
||||||
gboolean involves_x = FALSE;
|
gboolean involves_x = FALSE;
|
||||||
|
|
||||||
if (lower->any.type == META_WINDOW_CLIENT_TYPE_X11)
|
if (META_STACK_ID_IS_X11 (lower))
|
||||||
{
|
{
|
||||||
n_x_windows++;
|
n_x_windows++;
|
||||||
|
|
||||||
@ -637,61 +582,49 @@ meta_stack_tracker_record_restack_windows (MetaStackTracker *tracker,
|
|||||||
involves_x = TRUE;
|
involves_x = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_stack_tracker_record_lower_below (tracker, lower, &windows[i],
|
meta_stack_tracker_record_lower_below (tracker, lower, windows[i],
|
||||||
involves_x ? serial++ : 0);
|
involves_x ? serial++ : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_stack_tracker_record_raise_above (MetaStackTracker *tracker,
|
meta_stack_tracker_record_raise_above (MetaStackTracker *tracker,
|
||||||
const MetaStackWindow *window,
|
guint64 window,
|
||||||
const MetaStackWindow *sibling,
|
guint64 sibling,
|
||||||
gulong serial)
|
gulong serial)
|
||||||
{
|
{
|
||||||
MetaStackOp *op = g_slice_new (MetaStackOp);
|
MetaStackOp *op = g_slice_new (MetaStackOp);
|
||||||
|
|
||||||
op->any.type = STACK_OP_RAISE_ABOVE;
|
op->any.type = STACK_OP_RAISE_ABOVE;
|
||||||
op->any.serial = serial;
|
op->any.serial = serial;
|
||||||
op->any.window = *window;
|
op->any.window = window;
|
||||||
if (sibling)
|
op->raise_above.sibling = sibling;
|
||||||
op->raise_above.sibling = *sibling;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
op->raise_above.sibling.any.type = META_WINDOW_CLIENT_TYPE_X11;
|
|
||||||
op->raise_above.sibling.x11.xwindow = None;
|
|
||||||
}
|
|
||||||
|
|
||||||
stack_tracker_apply_prediction (tracker, op);
|
stack_tracker_apply_prediction (tracker, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_stack_tracker_record_lower_below (MetaStackTracker *tracker,
|
meta_stack_tracker_record_lower_below (MetaStackTracker *tracker,
|
||||||
const MetaStackWindow *window,
|
guint64 window,
|
||||||
const MetaStackWindow *sibling,
|
guint64 sibling,
|
||||||
gulong serial)
|
gulong serial)
|
||||||
{
|
{
|
||||||
MetaStackOp *op = g_slice_new (MetaStackOp);
|
MetaStackOp *op = g_slice_new (MetaStackOp);
|
||||||
|
|
||||||
op->any.type = STACK_OP_LOWER_BELOW;
|
op->any.type = STACK_OP_LOWER_BELOW;
|
||||||
op->any.serial = serial;
|
op->any.serial = serial;
|
||||||
op->any.window = *window;
|
op->any.window = window;
|
||||||
if (sibling)
|
op->lower_below.sibling = sibling;
|
||||||
op->lower_below.sibling = *sibling;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
op->lower_below.sibling.any.type = META_WINDOW_CLIENT_TYPE_X11;
|
|
||||||
op->lower_below.sibling.x11.xwindow = None;
|
|
||||||
}
|
|
||||||
|
|
||||||
stack_tracker_apply_prediction (tracker, op);
|
stack_tracker_apply_prediction (tracker, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_stack_tracker_record_lower (MetaStackTracker *tracker,
|
meta_stack_tracker_record_lower (MetaStackTracker *tracker,
|
||||||
const MetaStackWindow *window,
|
guint64 window,
|
||||||
gulong serial)
|
gulong serial)
|
||||||
{
|
{
|
||||||
meta_stack_tracker_record_raise_above (tracker, window, NULL, serial);
|
meta_stack_tracker_record_raise_above (tracker, window, None, serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @op is an operation derived from an X event from the server and we
|
/* @op is an operation derived from an X event from the server and we
|
||||||
@ -720,7 +653,7 @@ stack_tracker_verify_predictions (MetaStackTracker *tracker,
|
|||||||
|
|
||||||
/* Wayland operations don't need to be verified and shouldn't end up
|
/* Wayland operations don't need to be verified and shouldn't end up
|
||||||
* passed to this api. */
|
* passed to this api. */
|
||||||
g_return_val_if_fail (op->any.window.any.type == META_WINDOW_CLIENT_TYPE_X11, FALSE);
|
g_return_val_if_fail (META_STACK_ID_IS_X11 (op->any.window), FALSE);
|
||||||
|
|
||||||
meta_topic (META_DEBUG_STACK, "Verifying predictions:\n");
|
meta_topic (META_DEBUG_STACK, "Verifying predictions:\n");
|
||||||
|
|
||||||
@ -737,69 +670,61 @@ stack_tracker_verify_predictions (MetaStackTracker *tracker,
|
|||||||
if (current_op->any.serial > op->any.serial)
|
if (current_op->any.serial > op->any.serial)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
modified_stack |= meta_stack_op_apply (current_op, predicted_stack);
|
modified_stack |= meta_stack_op_apply (tracker, current_op, predicted_stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
predicted_stack = tracker->verified_stack;
|
predicted_stack = tracker->verified_stack;
|
||||||
|
|
||||||
meta_topic (META_DEBUG_STACK, " predicted_stack: ");
|
meta_topic (META_DEBUG_STACK, " predicted_stack: ");
|
||||||
stack_dump (predicted_stack);
|
stack_dump (tracker, predicted_stack);
|
||||||
|
|
||||||
switch (op->any.type)
|
switch (op->any.type)
|
||||||
{
|
{
|
||||||
case STACK_OP_ADD:
|
case STACK_OP_ADD:
|
||||||
if (!find_window (predicted_stack, &op->any.window))
|
if (!find_window (predicted_stack, op->any.window))
|
||||||
{
|
{
|
||||||
char *window_id = get_window_id (&op->any.window);
|
|
||||||
meta_topic (META_DEBUG_STACK, "Verify STACK_OP_ADD: window %s not found\n",
|
meta_topic (META_DEBUG_STACK, "Verify STACK_OP_ADD: window %s not found\n",
|
||||||
window_id);
|
get_window_desc (tracker, op->any.window));
|
||||||
g_free (window_id);
|
|
||||||
goto not_verified;
|
goto not_verified;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STACK_OP_REMOVE:
|
case STACK_OP_REMOVE:
|
||||||
if (find_window (predicted_stack, &op->any.window))
|
if (find_window (predicted_stack, op->any.window))
|
||||||
{
|
{
|
||||||
char *window_id = get_window_id (&op->any.window);
|
|
||||||
meta_topic (META_DEBUG_STACK, "Verify STACK_OP_REMOVE: window %s was unexpectedly found\n",
|
meta_topic (META_DEBUG_STACK, "Verify STACK_OP_REMOVE: window %s was unexpectedly found\n",
|
||||||
window_id);
|
get_window_desc (tracker, op->any.window));
|
||||||
g_free (window_id);
|
|
||||||
goto not_verified;
|
goto not_verified;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STACK_OP_RAISE_ABOVE:
|
case STACK_OP_RAISE_ABOVE:
|
||||||
{
|
{
|
||||||
Window last_xwindow = None;
|
Window last_xwindow = None;
|
||||||
char *window_id;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
/* This code is only intended for verifying operations based
|
/* This code is only intended for verifying operations based
|
||||||
* on XEvents where we can assume the sibling refers to
|
* on XEvents where we can assume the sibling refers to
|
||||||
* another X window... */
|
* another X window... */
|
||||||
g_return_val_if_fail (op->raise_above.sibling.any.type ==
|
g_return_val_if_fail (META_STACK_ID_IS_X11 (op->raise_above.sibling), FALSE);
|
||||||
META_WINDOW_CLIENT_TYPE_X11, FALSE);
|
|
||||||
|
|
||||||
for (i = 0; i < predicted_stack->len; i++)
|
for (i = 0; i < predicted_stack->len; i++)
|
||||||
{
|
{
|
||||||
MetaStackWindow *window = &g_array_index (predicted_stack, MetaStackWindow, i);
|
guint64 window = g_array_index (predicted_stack, guint64, i);
|
||||||
|
|
||||||
if (meta_stack_window_equal (window, &op->any.window))
|
if (window == op->any.window)
|
||||||
{
|
{
|
||||||
if (last_xwindow == op->raise_above.sibling.x11.xwindow)
|
if (last_xwindow == op->raise_above.sibling)
|
||||||
goto verified;
|
goto verified;
|
||||||
else
|
else
|
||||||
goto not_verified;
|
goto not_verified;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->any.type == META_WINDOW_CLIENT_TYPE_X11)
|
if (META_STACK_ID_IS_X11 (window))
|
||||||
last_xwindow = window->x11.xwindow;
|
last_xwindow = window;
|
||||||
}
|
}
|
||||||
|
|
||||||
window_id = get_window_id (&op->any.window);
|
|
||||||
meta_topic (META_DEBUG_STACK, "Verify STACK_OP_RAISE_ABOVE: window %s not found\n",
|
meta_topic (META_DEBUG_STACK, "Verify STACK_OP_RAISE_ABOVE: window %s not found\n",
|
||||||
window_id);
|
get_window_desc (tracker, op->any.window));
|
||||||
g_free (window_id);
|
|
||||||
goto not_verified;
|
goto not_verified;
|
||||||
}
|
}
|
||||||
case STACK_OP_LOWER_BELOW:
|
case STACK_OP_LOWER_BELOW:
|
||||||
@ -861,7 +786,7 @@ resync_verified_stack_with_xserver_stack (MetaStackTracker *tracker)
|
|||||||
{
|
{
|
||||||
GList *l;
|
GList *l;
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
MetaStackWindow *expected_xwindow;
|
guint64 expected_xwindow;
|
||||||
gboolean modified_stack = FALSE;
|
gboolean modified_stack = FALSE;
|
||||||
|
|
||||||
/* Overview of the algorithm:
|
/* Overview of the algorithm:
|
||||||
@ -896,29 +821,28 @@ resync_verified_stack_with_xserver_stack (MetaStackTracker *tracker)
|
|||||||
|
|
||||||
for (l = tracker->unverified_predictions->head; l; l = l->next)
|
for (l = tracker->unverified_predictions->head; l; l = l->next)
|
||||||
{
|
{
|
||||||
meta_stack_op_apply (l->data, tracker->verified_stack);
|
meta_stack_op_apply (tracker, l->data, tracker->verified_stack);
|
||||||
meta_stack_op_free (l->data);
|
meta_stack_op_free (l->data);
|
||||||
}
|
}
|
||||||
g_queue_clear (tracker->unverified_predictions);
|
g_queue_clear (tracker->unverified_predictions);
|
||||||
|
|
||||||
j = 0;
|
j = 0;
|
||||||
expected_xwindow = &g_array_index (tracker->xserver_stack, MetaStackWindow, j);
|
expected_xwindow = g_array_index (tracker->xserver_stack, guint64, j);
|
||||||
|
|
||||||
for (i = 0; i < tracker->verified_stack->len; )
|
for (i = 0; i < tracker->verified_stack->len; )
|
||||||
{
|
{
|
||||||
MetaStackWindow *current = &g_array_index (tracker->verified_stack, MetaStackWindow, i);
|
guint64 current = g_array_index (tracker->verified_stack, guint64, i);
|
||||||
|
|
||||||
if (current->any.type != META_WINDOW_CLIENT_TYPE_X11)
|
if (!META_STACK_ID_IS_X11 (current))
|
||||||
{
|
{
|
||||||
/* Progress i but not j */
|
/* Progress i but not j */
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current->x11.xwindow != expected_xwindow->x11.xwindow)
|
if (current != expected_xwindow)
|
||||||
{
|
{
|
||||||
MetaStackWindow new;
|
guint64 expected;
|
||||||
MetaStackWindow *expected;
|
|
||||||
int expected_index;
|
int expected_index;
|
||||||
|
|
||||||
/* If the current window corresponds to a window that's not
|
/* If the current window corresponds to a window that's not
|
||||||
@ -947,17 +871,14 @@ resync_verified_stack_with_xserver_stack (MetaStackTracker *tracker)
|
|||||||
|
|
||||||
if (expected_index >= 0)
|
if (expected_index >= 0)
|
||||||
{
|
{
|
||||||
expected = &g_array_index (tracker->verified_stack,
|
expected = g_array_index (tracker->verified_stack,
|
||||||
MetaStackWindow, expected_index);
|
guint64, expected_index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
new.any.type = META_WINDOW_CLIENT_TYPE_X11;
|
g_array_append_val (tracker->verified_stack, expected_xwindow);
|
||||||
new.x11.xwindow = expected_xwindow->x11.xwindow;
|
|
||||||
|
|
||||||
g_array_append_val (tracker->verified_stack, new);
|
expected = expected_xwindow;
|
||||||
|
|
||||||
expected = &new;
|
|
||||||
expected_index = tracker->verified_stack->len - 1;
|
expected_index = tracker->verified_stack->len - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -981,7 +902,7 @@ resync_verified_stack_with_xserver_stack (MetaStackTracker *tracker)
|
|||||||
i++;
|
i++;
|
||||||
|
|
||||||
j++;
|
j++;
|
||||||
expected_xwindow = &g_array_index (tracker->xserver_stack, MetaStackWindow, j);
|
expected_xwindow = g_array_index (tracker->xserver_stack, guint64, j);
|
||||||
|
|
||||||
if (j >= tracker->xserver_stack->len)
|
if (j >= tracker->xserver_stack->len)
|
||||||
break;
|
break;
|
||||||
@ -991,9 +912,9 @@ resync_verified_stack_with_xserver_stack (MetaStackTracker *tracker)
|
|||||||
* xserver_stack and so we can remove them. */
|
* xserver_stack and so we can remove them. */
|
||||||
while (i < tracker->verified_stack->len)
|
while (i < tracker->verified_stack->len)
|
||||||
{
|
{
|
||||||
MetaStackWindow *current = &g_array_index (tracker->verified_stack, MetaStackWindow, i);
|
guint64 current = g_array_index (tracker->verified_stack, guint64, i);
|
||||||
|
|
||||||
if (current->any.type == META_WINDOW_CLIENT_TYPE_X11)
|
if (META_STACK_ID_IS_X11 (current))
|
||||||
g_array_remove_index (tracker->verified_stack, i);
|
g_array_remove_index (tracker->verified_stack, i);
|
||||||
else
|
else
|
||||||
i++;
|
i++;
|
||||||
@ -1005,8 +926,8 @@ resync_verified_stack_with_xserver_stack (MetaStackTracker *tracker)
|
|||||||
* entries in xserver_stack then append them all to the end */
|
* entries in xserver_stack then append them all to the end */
|
||||||
for (; j < tracker->xserver_stack->len; j++)
|
for (; j < tracker->xserver_stack->len; j++)
|
||||||
{
|
{
|
||||||
MetaStackWindow *current = &g_array_index (tracker->xserver_stack, MetaStackWindow, j);
|
guint64 current = g_array_index (tracker->xserver_stack, guint64, j);
|
||||||
g_array_append_val (tracker->verified_stack, *current);
|
g_array_append_val (tracker->verified_stack, current);
|
||||||
|
|
||||||
modified_stack = TRUE;
|
modified_stack = TRUE;
|
||||||
}
|
}
|
||||||
@ -1034,7 +955,7 @@ stack_tracker_event_received (MetaStackTracker *tracker,
|
|||||||
if (op->any.serial < tracker->xserver_serial)
|
if (op->any.serial < tracker->xserver_serial)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
meta_stack_op_dump (op, "Stack op event received: ", "\n");
|
meta_stack_op_dump (tracker, op, "Stack op event received: ", "\n");
|
||||||
|
|
||||||
tracker->xserver_serial = op->any.serial;
|
tracker->xserver_serial = op->any.serial;
|
||||||
|
|
||||||
@ -1047,7 +968,7 @@ stack_tracker_event_received (MetaStackTracker *tracker,
|
|||||||
*
|
*
|
||||||
* TODO: remove tracker->xserver_stack.
|
* TODO: remove tracker->xserver_stack.
|
||||||
*/
|
*/
|
||||||
meta_stack_op_apply (op, tracker->xserver_stack);
|
meta_stack_op_apply (tracker, op, tracker->xserver_stack);
|
||||||
|
|
||||||
if (!stack_tracker_verify_predictions (tracker, op))
|
if (!stack_tracker_verify_predictions (tracker, op))
|
||||||
resync_verified_stack_with_xserver_stack (tracker);
|
resync_verified_stack_with_xserver_stack (tracker);
|
||||||
@ -1063,8 +984,7 @@ meta_stack_tracker_create_event (MetaStackTracker *tracker,
|
|||||||
|
|
||||||
op.any.type = STACK_OP_ADD;
|
op.any.type = STACK_OP_ADD;
|
||||||
op.any.serial = event->serial;
|
op.any.serial = event->serial;
|
||||||
op.add.window.any.type = META_WINDOW_CLIENT_TYPE_X11;
|
op.add.window = event->window;
|
||||||
op.add.window.x11.xwindow = event->window;
|
|
||||||
|
|
||||||
stack_tracker_event_received (tracker, &op);
|
stack_tracker_event_received (tracker, &op);
|
||||||
}
|
}
|
||||||
@ -1077,8 +997,7 @@ meta_stack_tracker_destroy_event (MetaStackTracker *tracker,
|
|||||||
|
|
||||||
op.any.type = STACK_OP_REMOVE;
|
op.any.type = STACK_OP_REMOVE;
|
||||||
op.any.serial = event->serial;
|
op.any.serial = event->serial;
|
||||||
op.remove.window.any.type = META_WINDOW_CLIENT_TYPE_X11;
|
op.remove.window = event->window;
|
||||||
op.remove.window.x11.xwindow = event->window;
|
|
||||||
|
|
||||||
stack_tracker_event_received (tracker, &op);
|
stack_tracker_event_received (tracker, &op);
|
||||||
}
|
}
|
||||||
@ -1093,8 +1012,7 @@ meta_stack_tracker_reparent_event (MetaStackTracker *tracker,
|
|||||||
|
|
||||||
op.any.type = STACK_OP_ADD;
|
op.any.type = STACK_OP_ADD;
|
||||||
op.any.serial = event->serial;
|
op.any.serial = event->serial;
|
||||||
op.add.window.any.type = META_WINDOW_CLIENT_TYPE_X11;
|
op.add.window = event->window;
|
||||||
op.add.window.x11.xwindow = event->window;
|
|
||||||
|
|
||||||
stack_tracker_event_received (tracker, &op);
|
stack_tracker_event_received (tracker, &op);
|
||||||
}
|
}
|
||||||
@ -1104,8 +1022,7 @@ meta_stack_tracker_reparent_event (MetaStackTracker *tracker,
|
|||||||
|
|
||||||
op.any.type = STACK_OP_REMOVE;
|
op.any.type = STACK_OP_REMOVE;
|
||||||
op.any.serial = event->serial;
|
op.any.serial = event->serial;
|
||||||
op.remove.window.any.type = META_WINDOW_CLIENT_TYPE_X11;
|
op.remove.window = event->window;
|
||||||
op.remove.window.x11.xwindow = event->window;
|
|
||||||
|
|
||||||
stack_tracker_event_received (tracker, &op);
|
stack_tracker_event_received (tracker, &op);
|
||||||
}
|
}
|
||||||
@ -1119,10 +1036,8 @@ meta_stack_tracker_configure_event (MetaStackTracker *tracker,
|
|||||||
|
|
||||||
op.any.type = STACK_OP_RAISE_ABOVE;
|
op.any.type = STACK_OP_RAISE_ABOVE;
|
||||||
op.any.serial = event->serial;
|
op.any.serial = event->serial;
|
||||||
op.raise_above.window.any.type = META_WINDOW_CLIENT_TYPE_X11;
|
op.raise_above.window = event->window;
|
||||||
op.raise_above.window.x11.xwindow = event->window;
|
op.raise_above.sibling = event->above;
|
||||||
op.raise_above.sibling.any.type = META_WINDOW_CLIENT_TYPE_X11;
|
|
||||||
op.raise_above.sibling.x11.xwindow = event->above;
|
|
||||||
|
|
||||||
stack_tracker_event_received (tracker, &op);
|
stack_tracker_event_received (tracker, &op);
|
||||||
}
|
}
|
||||||
@ -1146,7 +1061,7 @@ meta_stack_tracker_configure_event (MetaStackTracker *tracker,
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
meta_stack_tracker_get_stack (MetaStackTracker *tracker,
|
meta_stack_tracker_get_stack (MetaStackTracker *tracker,
|
||||||
MetaStackWindow **windows,
|
guint64 **windows,
|
||||||
int *n_windows)
|
int *n_windows)
|
||||||
{
|
{
|
||||||
GArray *stack;
|
GArray *stack;
|
||||||
@ -1165,7 +1080,7 @@ meta_stack_tracker_get_stack (MetaStackTracker *tracker,
|
|||||||
for (l = tracker->unverified_predictions->head; l; l = l->next)
|
for (l = tracker->unverified_predictions->head; l; l = l->next)
|
||||||
{
|
{
|
||||||
MetaStackOp *op = l->data;
|
MetaStackOp *op = l->data;
|
||||||
meta_stack_op_apply (op, tracker->predicted_stack);
|
meta_stack_op_apply (tracker, op, tracker->predicted_stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1176,7 +1091,7 @@ meta_stack_tracker_get_stack (MetaStackTracker *tracker,
|
|||||||
meta_stack_tracker_dump (tracker);
|
meta_stack_tracker_dump (tracker);
|
||||||
|
|
||||||
if (windows)
|
if (windows)
|
||||||
*windows = (MetaStackWindow *)stack->data;
|
*windows = (guint64 *)stack->data;
|
||||||
if (n_windows)
|
if (n_windows)
|
||||||
*n_windows = stack->len;
|
*n_windows = stack->len;
|
||||||
}
|
}
|
||||||
@ -1191,7 +1106,7 @@ meta_stack_tracker_get_stack (MetaStackTracker *tracker,
|
|||||||
void
|
void
|
||||||
meta_stack_tracker_sync_stack (MetaStackTracker *tracker)
|
meta_stack_tracker_sync_stack (MetaStackTracker *tracker)
|
||||||
{
|
{
|
||||||
MetaStackWindow *windows;
|
guint64 *windows;
|
||||||
GList *meta_windows;
|
GList *meta_windows;
|
||||||
int n_windows;
|
int n_windows;
|
||||||
int i;
|
int i;
|
||||||
@ -1207,12 +1122,12 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker)
|
|||||||
meta_windows = NULL;
|
meta_windows = NULL;
|
||||||
for (i = 0; i < n_windows; i++)
|
for (i = 0; i < n_windows; i++)
|
||||||
{
|
{
|
||||||
MetaStackWindow *window = &windows[i];
|
guint64 window = windows[i];
|
||||||
|
|
||||||
if (window->any.type == META_WINDOW_CLIENT_TYPE_X11)
|
if (META_STACK_ID_IS_X11 (window))
|
||||||
{
|
{
|
||||||
MetaWindow *meta_window =
|
MetaWindow *meta_window =
|
||||||
meta_display_lookup_x_window (tracker->screen->display, windows[i].x11.xwindow);
|
meta_display_lookup_x_window (tracker->screen->display, (Window)window);
|
||||||
|
|
||||||
/* When mapping back from xwindow to MetaWindow we have to be a bit careful;
|
/* When mapping back from xwindow to MetaWindow we have to be a bit careful;
|
||||||
* children of the root could include unmapped windows created by toolkits
|
* children of the root could include unmapped windows created by toolkits
|
||||||
@ -1221,12 +1136,13 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker)
|
|||||||
* see window-prop.c:reload_net_wm_user_time_window() for registration.)
|
* see window-prop.c:reload_net_wm_user_time_window() for registration.)
|
||||||
*/
|
*/
|
||||||
if (meta_window &&
|
if (meta_window &&
|
||||||
(windows[i].x11.xwindow == meta_window->xwindow ||
|
((Window)window == meta_window->xwindow ||
|
||||||
(meta_window->frame && windows[i].x11.xwindow == meta_window->frame->xwindow)))
|
(meta_window->frame && (Window)window == meta_window->frame->xwindow)))
|
||||||
meta_windows = g_list_prepend (meta_windows, meta_window);
|
meta_windows = g_list_prepend (meta_windows, meta_window);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
meta_windows = g_list_prepend (meta_windows, window->wayland.meta_window);
|
meta_windows = g_list_prepend (meta_windows,
|
||||||
|
meta_display_lookup_stamp (tracker->screen->display, window));
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_compositor_sync_stack (tracker->screen->display->compositor,
|
meta_compositor_sync_stack (tracker->screen->display->compositor,
|
||||||
|
@ -39,51 +39,33 @@
|
|||||||
|
|
||||||
typedef struct _MetaStackTracker MetaStackTracker;
|
typedef struct _MetaStackTracker MetaStackTracker;
|
||||||
|
|
||||||
typedef union _MetaStackWindow
|
|
||||||
{
|
|
||||||
struct {
|
|
||||||
MetaWindowClientType type;
|
|
||||||
} any;
|
|
||||||
struct {
|
|
||||||
MetaWindowClientType type;
|
|
||||||
Window xwindow;
|
|
||||||
} x11;
|
|
||||||
struct {
|
|
||||||
MetaWindowClientType type;
|
|
||||||
MetaWindow *meta_window;
|
|
||||||
} wayland;
|
|
||||||
} MetaStackWindow;
|
|
||||||
|
|
||||||
gboolean meta_stack_window_equal (const MetaStackWindow *a,
|
|
||||||
const MetaStackWindow *b);
|
|
||||||
|
|
||||||
MetaStackTracker *meta_stack_tracker_new (MetaScreen *screen);
|
MetaStackTracker *meta_stack_tracker_new (MetaScreen *screen);
|
||||||
void meta_stack_tracker_free (MetaStackTracker *tracker);
|
void meta_stack_tracker_free (MetaStackTracker *tracker);
|
||||||
|
|
||||||
/* These functions are called when we make an X call that changes the
|
/* These functions are called when we make an X call that changes the
|
||||||
* stacking order; this allows MetaStackTracker to predict stacking
|
* stacking order; this allows MetaStackTracker to predict stacking
|
||||||
* order before it receives events back from the X server */
|
* order before it receives events back from the X server */
|
||||||
void meta_stack_tracker_record_add (MetaStackTracker *tracker,
|
void meta_stack_tracker_record_add (MetaStackTracker *tracker,
|
||||||
const MetaStackWindow *window,
|
guint64 window,
|
||||||
gulong serial);
|
gulong serial);
|
||||||
void meta_stack_tracker_record_remove (MetaStackTracker *tracker,
|
void meta_stack_tracker_record_remove (MetaStackTracker *tracker,
|
||||||
const MetaStackWindow *window,
|
guint64 window,
|
||||||
gulong serial);
|
gulong serial);
|
||||||
void meta_stack_tracker_record_restack_windows (MetaStackTracker *tracker,
|
void meta_stack_tracker_record_restack_windows (MetaStackTracker *tracker,
|
||||||
const MetaStackWindow *windows,
|
const guint64 *windows,
|
||||||
int n_windows,
|
int n_windows,
|
||||||
gulong serial);
|
gulong serial);
|
||||||
void meta_stack_tracker_record_raise_above (MetaStackTracker *tracker,
|
void meta_stack_tracker_record_raise_above (MetaStackTracker *tracker,
|
||||||
const MetaStackWindow *window,
|
guint64 window,
|
||||||
const MetaStackWindow *sibling,
|
guint64 sibling,
|
||||||
gulong serial);
|
gulong serial);
|
||||||
void meta_stack_tracker_record_lower_below (MetaStackTracker *tracker,
|
void meta_stack_tracker_record_lower_below (MetaStackTracker *tracker,
|
||||||
const MetaStackWindow *window,
|
guint64 window,
|
||||||
const MetaStackWindow *sibling,
|
guint64 sibling,
|
||||||
gulong serial);
|
gulong serial);
|
||||||
void meta_stack_tracker_record_lower (MetaStackTracker *tracker,
|
void meta_stack_tracker_record_lower (MetaStackTracker *tracker,
|
||||||
const MetaStackWindow *window,
|
guint64 window,
|
||||||
gulong serial);
|
gulong serial);
|
||||||
|
|
||||||
/* These functions are used to update the stack when we get events
|
/* These functions are used to update the stack when we get events
|
||||||
* reflecting changes to the stacking order */
|
* reflecting changes to the stacking order */
|
||||||
@ -96,9 +78,9 @@ void meta_stack_tracker_reparent_event (MetaStackTracker *tracker,
|
|||||||
void meta_stack_tracker_configure_event (MetaStackTracker *tracker,
|
void meta_stack_tracker_configure_event (MetaStackTracker *tracker,
|
||||||
XConfigureEvent *event);
|
XConfigureEvent *event);
|
||||||
|
|
||||||
void meta_stack_tracker_get_stack (MetaStackTracker *tracker,
|
void meta_stack_tracker_get_stack (MetaStackTracker *tracker,
|
||||||
MetaStackWindow **windows,
|
guint64 **windows,
|
||||||
int *n_entries);
|
int *n_entries);
|
||||||
|
|
||||||
void meta_stack_tracker_sync_stack (MetaStackTracker *tracker);
|
void meta_stack_tracker_sync_stack (MetaStackTracker *tracker);
|
||||||
void meta_stack_tracker_queue_sync_stack (MetaStackTracker *tracker);
|
void meta_stack_tracker_queue_sync_stack (MetaStackTracker *tracker);
|
||||||
|
172
src/core/stack.c
172
src/core/stack.c
@ -1030,12 +1030,12 @@ stack_ensure_sorted (MetaStack *stack)
|
|||||||
stack_do_resort (stack);
|
stack_do_resort (stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaStackWindow *
|
static guint64
|
||||||
find_top_most_managed_window (MetaScreen *screen,
|
find_top_most_managed_window (MetaScreen *screen,
|
||||||
const MetaStackWindow *ignore)
|
guint64 ignore)
|
||||||
{
|
{
|
||||||
MetaStackTracker *stack_tracker = screen->stack_tracker;
|
MetaStackTracker *stack_tracker = screen->stack_tracker;
|
||||||
MetaStackWindow *windows;
|
guint64 *windows;
|
||||||
int n_windows;
|
int n_windows;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -1048,12 +1048,9 @@ find_top_most_managed_window (MetaScreen *screen,
|
|||||||
*/
|
*/
|
||||||
for (i = n_windows -1; i >= 0; i--)
|
for (i = n_windows -1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
MetaStackWindow *other_window = &windows[i];
|
guint64 other_window = windows[i];
|
||||||
|
|
||||||
if (other_window->any.type == ignore->any.type &&
|
if (other_window == ignore)
|
||||||
((other_window->any.type == META_WINDOW_CLIENT_TYPE_X11 &&
|
|
||||||
other_window->x11.xwindow == ignore->x11.xwindow) ||
|
|
||||||
other_window->wayland.meta_window == ignore->wayland.meta_window))
|
|
||||||
{
|
{
|
||||||
/* Do nothing. This means we're already the topmost managed
|
/* Do nothing. This means we're already the topmost managed
|
||||||
* window, but it DOES NOT mean we are already just above
|
* window, but it DOES NOT mean we are already just above
|
||||||
@ -1067,10 +1064,10 @@ find_top_most_managed_window (MetaScreen *screen,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (other_window->any.type == META_WINDOW_CLIENT_TYPE_X11)
|
if (META_STACK_ID_IS_X11 (other_window))
|
||||||
{
|
{
|
||||||
MetaWindow *other = meta_display_lookup_x_window (screen->display,
|
MetaWindow *other = meta_display_lookup_x_window (screen->display,
|
||||||
other_window->x11.xwindow);
|
other_window);
|
||||||
|
|
||||||
if (other != NULL && !other->override_redirect)
|
if (other != NULL && !other->override_redirect)
|
||||||
return other_window;
|
return other_window;
|
||||||
@ -1085,7 +1082,7 @@ find_top_most_managed_window (MetaScreen *screen,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When moving an X window we sometimes need an X based sibling.
|
/* When moving an X window we sometimes need an X based sibling.
|
||||||
@ -1094,17 +1091,17 @@ find_top_most_managed_window (MetaScreen *screen,
|
|||||||
* otherwise it searches downwards looking for the nearest X window.
|
* otherwise it searches downwards looking for the nearest X window.
|
||||||
*
|
*
|
||||||
* If no X based sibling could be found return NULL. */
|
* If no X based sibling could be found return NULL. */
|
||||||
static MetaStackWindow *
|
static Window
|
||||||
find_x11_sibling_downwards (MetaScreen *screen,
|
find_x11_sibling_downwards (MetaScreen *screen,
|
||||||
MetaStackWindow *sibling)
|
guint64 sibling)
|
||||||
{
|
{
|
||||||
MetaStackTracker *stack_tracker = screen->stack_tracker;
|
MetaStackTracker *stack_tracker = screen->stack_tracker;
|
||||||
MetaStackWindow *windows;
|
guint64 *windows;
|
||||||
int n_windows;
|
int n_windows;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (sibling->any.type == META_WINDOW_CLIENT_TYPE_X11)
|
if (META_STACK_ID_IS_X11 (sibling))
|
||||||
return sibling;
|
return (Window)sibling;
|
||||||
|
|
||||||
meta_stack_tracker_get_stack (stack_tracker,
|
meta_stack_tracker_get_stack (stack_tracker,
|
||||||
&windows, &n_windows);
|
&windows, &n_windows);
|
||||||
@ -1114,16 +1111,16 @@ find_x11_sibling_downwards (MetaScreen *screen,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
for (i = n_windows - 1; i >= 0; i--)
|
for (i = n_windows - 1; i >= 0; i--)
|
||||||
if (meta_stack_window_equal (&windows[i], sibling))
|
if (windows[i] == sibling)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for (; i >= 0; i--)
|
for (; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if (windows[i].any.type == META_WINDOW_CLIENT_TYPE_X11)
|
if (META_STACK_ID_IS_X11 (windows[i]))
|
||||||
return &windows[i];
|
return (Window)windows[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1150,20 +1147,20 @@ find_x11_sibling_downwards (MetaScreen *screen,
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
raise_window_relative_to_managed_windows (MetaScreen *screen,
|
raise_window_relative_to_managed_windows (MetaScreen *screen,
|
||||||
const MetaStackWindow *window)
|
guint64 stack_id)
|
||||||
{
|
{
|
||||||
gulong serial = 0;
|
gulong serial = 0;
|
||||||
MetaStackWindow *sibling;
|
guint64 sibling;
|
||||||
|
|
||||||
sibling = find_top_most_managed_window (screen, window);
|
sibling = find_top_most_managed_window (screen, stack_id);
|
||||||
if (!sibling)
|
if (!sibling)
|
||||||
{
|
{
|
||||||
if (window->any.type == META_WINDOW_CLIENT_TYPE_X11)
|
if (META_STACK_ID_IS_X11 (stack_id))
|
||||||
{
|
{
|
||||||
serial = XNextRequest (screen->display->xdisplay);
|
serial = XNextRequest (screen->display->xdisplay);
|
||||||
meta_error_trap_push (screen->display);
|
meta_error_trap_push (screen->display);
|
||||||
XLowerWindow (screen->display->xdisplay,
|
XLowerWindow (screen->display->xdisplay,
|
||||||
window->x11.xwindow);
|
stack_id);
|
||||||
meta_error_trap_pop (screen->display);
|
meta_error_trap_pop (screen->display);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1171,31 +1168,31 @@ raise_window_relative_to_managed_windows (MetaScreen *screen,
|
|||||||
* to be sure we're below any override redirect windows.
|
* to be sure we're below any override redirect windows.
|
||||||
*/
|
*/
|
||||||
meta_stack_tracker_record_lower (screen->stack_tracker,
|
meta_stack_tracker_record_lower (screen->stack_tracker,
|
||||||
window,
|
stack_id,
|
||||||
serial);
|
serial);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* window is the topmost managed child */
|
/* window is the topmost managed child */
|
||||||
meta_topic (META_DEBUG_STACK,
|
meta_topic (META_DEBUG_STACK,
|
||||||
"Moving 0x%lx above topmost managed child window 0x%lx\n",
|
"Moving %s above topmost managed child window %s\n",
|
||||||
window->any.type == META_WINDOW_CLIENT_TYPE_X11 ? window->x11.xwindow: 0,
|
meta_display_describe_stack_id (screen->display, stack_id),
|
||||||
sibling->any.type == META_WINDOW_CLIENT_TYPE_X11 ? sibling->x11.xwindow: 0);
|
meta_display_describe_stack_id (screen->display, sibling));
|
||||||
|
|
||||||
if (window->any.type == META_WINDOW_CLIENT_TYPE_X11)
|
if (META_STACK_ID_IS_X11 (stack_id))
|
||||||
{
|
{
|
||||||
XWindowChanges changes;
|
XWindowChanges changes;
|
||||||
MetaStackWindow *x11_sibling = find_x11_sibling_downwards (screen, sibling);
|
Window x11_sibling = find_x11_sibling_downwards (screen, sibling);
|
||||||
serial = XNextRequest (screen->display->xdisplay);
|
serial = XNextRequest (screen->display->xdisplay);
|
||||||
|
|
||||||
if (x11_sibling)
|
if (x11_sibling)
|
||||||
{
|
{
|
||||||
changes.sibling = x11_sibling->x11.xwindow;
|
changes.sibling = x11_sibling;
|
||||||
changes.stack_mode = Above;
|
changes.stack_mode = Above;
|
||||||
|
|
||||||
meta_error_trap_push (screen->display);
|
meta_error_trap_push (screen->display);
|
||||||
XConfigureWindow (screen->display->xdisplay,
|
XConfigureWindow (screen->display->xdisplay,
|
||||||
window->x11.xwindow,
|
(Window)stack_id,
|
||||||
CWSibling | CWStackMode,
|
CWSibling | CWStackMode,
|
||||||
&changes);
|
&changes);
|
||||||
meta_error_trap_pop (screen->display);
|
meta_error_trap_pop (screen->display);
|
||||||
@ -1207,13 +1204,13 @@ raise_window_relative_to_managed_windows (MetaScreen *screen,
|
|||||||
*/
|
*/
|
||||||
meta_error_trap_push (screen->display);
|
meta_error_trap_push (screen->display);
|
||||||
XLowerWindow (screen->display->xdisplay,
|
XLowerWindow (screen->display->xdisplay,
|
||||||
window->x11.xwindow);
|
(Window)stack_id);
|
||||||
meta_error_trap_pop (screen->display);
|
meta_error_trap_pop (screen->display);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_stack_tracker_record_raise_above (screen->stack_tracker,
|
meta_stack_tracker_record_raise_above (screen->stack_tracker,
|
||||||
window,
|
stack_id,
|
||||||
sibling,
|
sibling,
|
||||||
serial);
|
serial);
|
||||||
}
|
}
|
||||||
@ -1239,9 +1236,8 @@ stack_sync_to_xserver (MetaStack *stack)
|
|||||||
GArray *all_root_children_stacked; /* wayland OR x11 */
|
GArray *all_root_children_stacked; /* wayland OR x11 */
|
||||||
GList *tmp;
|
GList *tmp;
|
||||||
GArray *x11_hidden;
|
GArray *x11_hidden;
|
||||||
GArray *x11_hidden_stack_windows;
|
GArray *x11_hidden_stack_ids;
|
||||||
int n_override_redirect = 0;
|
int n_override_redirect = 0;
|
||||||
MetaStackWindow guard_stack_window;
|
|
||||||
|
|
||||||
/* Bail out if frozen */
|
/* Bail out if frozen */
|
||||||
if (stack->freeze_count > 0)
|
if (stack->freeze_count > 0)
|
||||||
@ -1258,10 +1254,10 @@ stack_sync_to_xserver (MetaStack *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 (MetaStackWindow));
|
all_root_children_stacked = g_array_new (FALSE, FALSE, sizeof (guint64));
|
||||||
x11_root_children_stacked = g_array_new (FALSE, FALSE, sizeof (Window));
|
x11_root_children_stacked = g_array_new (FALSE, FALSE, sizeof (Window));
|
||||||
|
|
||||||
x11_hidden_stack_windows = g_array_new (FALSE, FALSE, sizeof (MetaStackWindow));
|
x11_hidden_stack_ids = g_array_new (FALSE, FALSE, sizeof (guint64));
|
||||||
x11_hidden = g_array_new (FALSE, FALSE, sizeof (Window));
|
x11_hidden = g_array_new (FALSE, FALSE, sizeof (Window));
|
||||||
|
|
||||||
/* The screen guard window sits above all hidden windows and acts as
|
/* The screen guard window sits above all hidden windows and acts as
|
||||||
@ -1275,9 +1271,7 @@ stack_sync_to_xserver (MetaStack *stack)
|
|||||||
{
|
{
|
||||||
MetaWindow *w = tmp->data;
|
MetaWindow *w = tmp->data;
|
||||||
Window top_level_window;
|
Window top_level_window;
|
||||||
MetaStackWindow stack_window;
|
guint64 stack_id;
|
||||||
|
|
||||||
stack_window.any.type = w->client_type;
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_STACK, "%u:%d - %s ",
|
meta_topic (META_DEBUG_STACK, "%u:%d - %s ",
|
||||||
w->layer, w->stack_position, w->desc);
|
w->layer, w->stack_position, w->desc);
|
||||||
@ -1294,9 +1288,9 @@ stack_sync_to_xserver (MetaStack *stack)
|
|||||||
top_level_window = w->xwindow;
|
top_level_window = w->xwindow;
|
||||||
|
|
||||||
if (w->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
if (w->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||||
stack_window.x11.xwindow = top_level_window;
|
stack_id = top_level_window;
|
||||||
else
|
else
|
||||||
stack_window.wayland.meta_window = w;
|
stack_id = w->stamp;
|
||||||
|
|
||||||
/* We don't restack hidden windows along with the rest, though they are
|
/* We don't restack hidden windows along with the rest, though they are
|
||||||
* reflected in the _NET hints. Hidden windows all get pushed below
|
* reflected in the _NET hints. Hidden windows all get pushed below
|
||||||
@ -1305,18 +1299,15 @@ stack_sync_to_xserver (MetaStack *stack)
|
|||||||
{
|
{
|
||||||
if (w->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
if (w->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||||
{
|
{
|
||||||
MetaStackWindow stack_window;
|
guint64 stack_id = top_level_window;
|
||||||
|
|
||||||
stack_window.any.type = META_WINDOW_CLIENT_TYPE_X11;
|
g_array_append_val (x11_hidden_stack_ids, stack_id);
|
||||||
stack_window.x11.xwindow = top_level_window;
|
|
||||||
|
|
||||||
g_array_append_val (x11_hidden_stack_windows, stack_window);
|
|
||||||
g_array_append_val (x11_hidden, top_level_window);
|
g_array_append_val (x11_hidden, top_level_window);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_array_append_val (all_root_children_stacked, stack_window);
|
g_array_append_val (all_root_children_stacked, stack_id);
|
||||||
|
|
||||||
/* build XRestackWindows() array from top to bottom */
|
/* build XRestackWindows() array from top to bottom */
|
||||||
if (w->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
if (w->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||||
@ -1356,7 +1347,7 @@ stack_sync_to_xserver (MetaStack *stack)
|
|||||||
x11_root_children_stacked->len);
|
x11_root_children_stacked->len);
|
||||||
}
|
}
|
||||||
meta_stack_tracker_record_restack_windows (stack->screen->stack_tracker,
|
meta_stack_tracker_record_restack_windows (stack->screen->stack_tracker,
|
||||||
(MetaStackWindow *) all_root_children_stacked->data,
|
(guint64 *) all_root_children_stacked->data,
|
||||||
all_root_children_stacked->len,
|
all_root_children_stacked->len,
|
||||||
serial);
|
serial);
|
||||||
}
|
}
|
||||||
@ -1369,34 +1360,31 @@ stack_sync_to_xserver (MetaStack *stack)
|
|||||||
* was saved, then we may have inefficiency, but I don't think things
|
* was saved, then we may have inefficiency, but I don't think things
|
||||||
* break...
|
* break...
|
||||||
*/
|
*/
|
||||||
const MetaStackWindow *old_stack = (MetaStackWindow *) stack->last_all_root_children_stacked->data;
|
const guint64 *old_stack = (guint64 *) stack->last_all_root_children_stacked->data;
|
||||||
const MetaStackWindow *new_stack = (MetaStackWindow *) all_root_children_stacked->data;
|
const guint64 *new_stack = (guint64 *) all_root_children_stacked->data;
|
||||||
const int old_len = stack->last_all_root_children_stacked->len;
|
const int old_len = stack->last_all_root_children_stacked->len;
|
||||||
const int new_len = all_root_children_stacked->len;
|
const int new_len = all_root_children_stacked->len;
|
||||||
const MetaStackWindow *oldp = old_stack;
|
const guint64 *oldp = old_stack;
|
||||||
const MetaStackWindow *newp = new_stack;
|
const guint64 *newp = new_stack;
|
||||||
const MetaStackWindow *old_end = old_stack + old_len;
|
const guint64 *old_end = old_stack + old_len;
|
||||||
const MetaStackWindow *new_end = new_stack + new_len;
|
const guint64 *new_end = new_stack + new_len;
|
||||||
Window last_xwindow = None;
|
Window last_xwindow = None;
|
||||||
const MetaStackWindow *last_window = NULL;
|
guint64 last_window = 0;
|
||||||
|
|
||||||
while (oldp != old_end &&
|
while (oldp != old_end &&
|
||||||
newp != new_end)
|
newp != new_end)
|
||||||
{
|
{
|
||||||
if (meta_stack_window_equal (oldp, newp))
|
if (*oldp == *newp)
|
||||||
{
|
{
|
||||||
/* Stacks are the same here, move on */
|
/* Stacks are the same here, move on */
|
||||||
++oldp;
|
++oldp;
|
||||||
if (newp->any.type == META_WINDOW_CLIENT_TYPE_X11)
|
if (META_STACK_ID_IS_X11 (*newp))
|
||||||
last_xwindow = newp->x11.xwindow;
|
last_xwindow = (Window)*newp;
|
||||||
last_window = newp;
|
last_window = *newp;
|
||||||
++newp;
|
++newp;
|
||||||
}
|
}
|
||||||
else if ((oldp->any.type == META_WINDOW_CLIENT_TYPE_X11 &&
|
else if (meta_display_lookup_stack_id (stack->screen->display,
|
||||||
meta_display_lookup_x_window (stack->screen->display,
|
*oldp) == NULL)
|
||||||
oldp->x11.xwindow) == NULL) ||
|
|
||||||
(oldp->any.type == META_WINDOW_CLIENT_TYPE_WAYLAND &&
|
|
||||||
oldp->wayland.meta_window == NULL))
|
|
||||||
{
|
{
|
||||||
/* *oldp is no longer known to us (probably destroyed),
|
/* *oldp is no longer known to us (probably destroyed),
|
||||||
* so we can just skip it
|
* so we can just skip it
|
||||||
@ -1408,12 +1396,12 @@ stack_sync_to_xserver (MetaStack *stack)
|
|||||||
/* Move *newp below the last_window */
|
/* Move *newp below the last_window */
|
||||||
if (!last_window)
|
if (!last_window)
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_STACK, "Using window 0x%lx as topmost (but leaving it in-place)\n",
|
meta_topic (META_DEBUG_STACK, "Using window %s as topmost (but leaving it in-place)\n",
|
||||||
newp->x11.xwindow);
|
meta_display_describe_stack_id (stack->screen->display, *newp));
|
||||||
|
|
||||||
raise_window_relative_to_managed_windows (stack->screen, newp);
|
raise_window_relative_to_managed_windows (stack->screen, *newp);
|
||||||
}
|
}
|
||||||
else if (newp->any.type == META_WINDOW_CLIENT_TYPE_X11 &&
|
else if (META_STACK_ID_IS_X11 (*newp) &&
|
||||||
last_xwindow == None)
|
last_xwindow == None)
|
||||||
{
|
{
|
||||||
/* In this case we have an X window that we need to
|
/* In this case we have an X window that we need to
|
||||||
@ -1432,10 +1420,10 @@ stack_sync_to_xserver (MetaStack *stack)
|
|||||||
* know last_window isn't an X window).
|
* know last_window isn't an X window).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
raise_window_relative_to_managed_windows (stack->screen, newp);
|
raise_window_relative_to_managed_windows (stack->screen, *newp);
|
||||||
|
|
||||||
meta_stack_tracker_record_lower_below (stack->screen->stack_tracker,
|
meta_stack_tracker_record_lower_below (stack->screen->stack_tracker,
|
||||||
newp, last_window,
|
*newp, last_window,
|
||||||
0); /* no x request serial */
|
0); /* no x request serial */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1447,11 +1435,11 @@ stack_sync_to_xserver (MetaStack *stack)
|
|||||||
* unmanaging last_xwindow, we'll fix it up.
|
* unmanaging last_xwindow, we'll fix it up.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
meta_topic (META_DEBUG_STACK, "Placing window 0x%lx below 0x%lx\n",
|
meta_topic (META_DEBUG_STACK, "Placing window %s below 0x%lx\n",
|
||||||
newp->any.type == META_WINDOW_CLIENT_TYPE_X11 ? newp->x11.xwindow : 0,
|
meta_display_describe_stack_id (stack->screen->display, *newp),
|
||||||
last_xwindow);
|
last_xwindow);
|
||||||
|
|
||||||
if (newp->any.type == META_WINDOW_CLIENT_TYPE_X11)
|
if (META_STACK_ID_IS_X11 (*newp))
|
||||||
{
|
{
|
||||||
XWindowChanges changes;
|
XWindowChanges changes;
|
||||||
serial = XNextRequest (stack->screen->display->xdisplay);
|
serial = XNextRequest (stack->screen->display->xdisplay);
|
||||||
@ -1460,26 +1448,26 @@ stack_sync_to_xserver (MetaStack *stack)
|
|||||||
changes.stack_mode = Below;
|
changes.stack_mode = Below;
|
||||||
|
|
||||||
XConfigureWindow (stack->screen->display->xdisplay,
|
XConfigureWindow (stack->screen->display->xdisplay,
|
||||||
newp->x11.xwindow,
|
(Window)*newp,
|
||||||
CWSibling | CWStackMode,
|
CWSibling | CWStackMode,
|
||||||
&changes);
|
&changes);
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_stack_tracker_record_lower_below (stack->screen->stack_tracker,
|
meta_stack_tracker_record_lower_below (stack->screen->stack_tracker,
|
||||||
newp, last_window,
|
*newp, last_window,
|
||||||
serial);
|
serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newp->any.type == META_WINDOW_CLIENT_TYPE_X11)
|
if (META_STACK_ID_IS_X11 (*newp))
|
||||||
last_xwindow = newp->x11.xwindow;
|
last_xwindow = *newp;
|
||||||
last_window = newp;
|
last_window = *newp;
|
||||||
++newp;
|
++newp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newp != new_end)
|
if (newp != new_end)
|
||||||
{
|
{
|
||||||
const MetaStackWindow *x_ref;
|
const guint64 *x_ref;
|
||||||
unsigned long serial = 0;
|
unsigned long serial = 0;
|
||||||
|
|
||||||
/* Restack remaining windows */
|
/* Restack remaining windows */
|
||||||
@ -1490,7 +1478,7 @@ stack_sync_to_xserver (MetaStack *stack)
|
|||||||
* as a reference point for re-stacking remaining X windows */
|
* as a reference point for re-stacking remaining X windows */
|
||||||
if (newp != new_stack)
|
if (newp != new_stack)
|
||||||
for (x_ref = newp - 1;
|
for (x_ref = newp - 1;
|
||||||
x_ref->any.type != META_WINDOW_CLIENT_TYPE_X11 && x_ref > new_stack;
|
META_STACK_ID_IS_X11 (*x_ref) && x_ref > new_stack;
|
||||||
x_ref--)
|
x_ref--)
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
@ -1499,16 +1487,16 @@ stack_sync_to_xserver (MetaStack *stack)
|
|||||||
/* If we didn't find an X window looking backwards then walk forwards
|
/* If we didn't find an X window looking backwards then walk forwards
|
||||||
* through the remaining windows to find the first remaining X window
|
* through the remaining windows to find the first remaining X window
|
||||||
* instead. */
|
* instead. */
|
||||||
if (x_ref->any.type != META_WINDOW_CLIENT_TYPE_X11)
|
if (META_STACK_ID_IS_X11 (*x_ref))
|
||||||
{
|
{
|
||||||
for (x_ref = newp;
|
for (x_ref = newp;
|
||||||
x_ref->any.type != META_WINDOW_CLIENT_TYPE_X11 && x_ref < new_end;
|
META_STACK_ID_IS_X11 (*x_ref) && x_ref < new_end;
|
||||||
x_ref++)
|
x_ref++)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there are any X windows remaining unstacked then restack them */
|
/* If there are any X windows remaining unstacked then restack them */
|
||||||
if (x_ref->any.type == META_WINDOW_CLIENT_TYPE_X11)
|
if (META_STACK_ID_IS_X11 (*x_ref))
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -1516,7 +1504,7 @@ stack_sync_to_xserver (MetaStack *stack)
|
|||||||
{
|
{
|
||||||
Window *reference = &g_array_index (x11_root_children_stacked, Window, i);
|
Window *reference = &g_array_index (x11_root_children_stacked, Window, i);
|
||||||
|
|
||||||
if (*reference == x_ref->x11.xwindow)
|
if (*reference == (Window)*x_ref)
|
||||||
{
|
{
|
||||||
int n = x11_root_children_stacked->len - i;
|
int n = x11_root_children_stacked->len - i;
|
||||||
|
|
||||||
@ -1545,21 +1533,19 @@ stack_sync_to_xserver (MetaStack *stack)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Push hidden X windows to the bottom of the stack under the guard window */
|
/* Push hidden X windows to the bottom of the stack under the guard window */
|
||||||
guard_stack_window.any.type = META_WINDOW_CLIENT_TYPE_X11;
|
|
||||||
guard_stack_window.x11.xwindow = stack->screen->guard_window;
|
|
||||||
meta_stack_tracker_record_lower (stack->screen->stack_tracker,
|
meta_stack_tracker_record_lower (stack->screen->stack_tracker,
|
||||||
&guard_stack_window,
|
stack->screen->guard_window,
|
||||||
XNextRequest (stack->screen->display->xdisplay));
|
XNextRequest (stack->screen->display->xdisplay));
|
||||||
XLowerWindow (stack->screen->display->xdisplay, stack->screen->guard_window);
|
XLowerWindow (stack->screen->display->xdisplay, stack->screen->guard_window);
|
||||||
meta_stack_tracker_record_restack_windows (stack->screen->stack_tracker,
|
meta_stack_tracker_record_restack_windows (stack->screen->stack_tracker,
|
||||||
(MetaStackWindow *)x11_hidden_stack_windows->data,
|
(guint64 *)x11_hidden_stack_ids->data,
|
||||||
x11_hidden_stack_windows->len,
|
x11_hidden_stack_ids->len,
|
||||||
XNextRequest (stack->screen->display->xdisplay));
|
XNextRequest (stack->screen->display->xdisplay));
|
||||||
XRestackWindows (stack->screen->display->xdisplay,
|
XRestackWindows (stack->screen->display->xdisplay,
|
||||||
(Window *)x11_hidden->data,
|
(Window *)x11_hidden->data,
|
||||||
x11_hidden->len);
|
x11_hidden->len);
|
||||||
g_array_free (x11_hidden, TRUE);
|
g_array_free (x11_hidden, TRUE);
|
||||||
g_array_free (x11_hidden_stack_windows, TRUE);
|
g_array_free (x11_hidden_stack_ids, TRUE);
|
||||||
|
|
||||||
meta_error_trap_pop (stack->screen->display);
|
meta_error_trap_pop (stack->screen->display);
|
||||||
/* on error, a window was destroyed; it should eventually
|
/* on error, a window was destroyed; it should eventually
|
||||||
|
@ -92,6 +92,7 @@ struct _MetaWindow
|
|||||||
|
|
||||||
MetaDisplay *display;
|
MetaDisplay *display;
|
||||||
MetaScreen *screen;
|
MetaScreen *screen;
|
||||||
|
guint64 stamp;
|
||||||
const MetaMonitorInfo *monitor;
|
const MetaMonitorInfo *monitor;
|
||||||
MetaWorkspace *workspace;
|
MetaWorkspace *workspace;
|
||||||
MetaWindowClientType client_type;
|
MetaWindowClientType client_type;
|
||||||
|
@ -71,6 +71,10 @@
|
|||||||
|
|
||||||
static int destroying_windows_disallowed = 0;
|
static int destroying_windows_disallowed = 0;
|
||||||
|
|
||||||
|
// Each window has a "stamp" which is a non-recycled 64-bit ID. They
|
||||||
|
// start after the end of the XID space so that, for stacking
|
||||||
|
// we can keep a guint64 that represents one or the other
|
||||||
|
static guint64 next_window_stamp = G_GUINT64_CONSTANT(0x100000000);
|
||||||
|
|
||||||
static void invalidate_work_areas (MetaWindow *window);
|
static void invalidate_work_areas (MetaWindow *window);
|
||||||
static void set_wm_state (MetaWindow *window);
|
static void set_wm_state (MetaWindow *window);
|
||||||
@ -642,6 +646,7 @@ meta_window_class_init (MetaWindowClass *klass)
|
|||||||
static void
|
static void
|
||||||
meta_window_init (MetaWindow *self)
|
meta_window_init (MetaWindow *self)
|
||||||
{
|
{
|
||||||
|
self->stamp = next_window_stamp++;
|
||||||
meta_prefs_add_listener (prefs_changed_callback, self);
|
meta_prefs_add_listener (prefs_changed_callback, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -803,6 +808,8 @@ _meta_window_shared_new (MetaDisplay *display,
|
|||||||
* type
|
* type
|
||||||
*/
|
*/
|
||||||
window->display = display;
|
window->display = display;
|
||||||
|
meta_display_register_stamp (window->display, &window->stamp, window);
|
||||||
|
|
||||||
window->workspace = NULL;
|
window->workspace = NULL;
|
||||||
|
|
||||||
window->sync_request_counter = None;
|
window->sync_request_counter = None;
|
||||||
@ -1239,6 +1246,8 @@ meta_window_unmanage (MetaWindow *window,
|
|||||||
meta_bug ("Tried to destroy window %s while destruction was not allowed\n",
|
meta_bug ("Tried to destroy window %s while destruction was not allowed\n",
|
||||||
window->desc);
|
window->desc);
|
||||||
|
|
||||||
|
meta_display_unregister_stamp (window->display, window->stamp);
|
||||||
|
|
||||||
window->unmanaging = TRUE;
|
window->unmanaging = TRUE;
|
||||||
|
|
||||||
if (meta_prefs_get_attach_modal_dialogs ())
|
if (meta_prefs_get_attach_modal_dialogs ())
|
||||||
|
@ -512,7 +512,7 @@ test_case_assert_stacking (TestCase *test,
|
|||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
MetaDisplay *display = meta_get_display ();
|
MetaDisplay *display = meta_get_display ();
|
||||||
MetaStackWindow *windows;
|
guint64 *windows;
|
||||||
int n_windows;
|
int n_windows;
|
||||||
GString *stack_string = g_string_new (NULL);
|
GString *stack_string = g_string_new (NULL);
|
||||||
GString *expected_string = g_string_new (NULL);
|
GString *expected_string = g_string_new (NULL);
|
||||||
@ -521,22 +521,14 @@ test_case_assert_stacking (TestCase *test,
|
|||||||
meta_stack_tracker_get_stack (display->screen->stack_tracker, &windows, &n_windows);
|
meta_stack_tracker_get_stack (display->screen->stack_tracker, &windows, &n_windows);
|
||||||
for (i = 0; i < n_windows; i++)
|
for (i = 0; i < n_windows; i++)
|
||||||
{
|
{
|
||||||
MetaWindow *window;
|
MetaWindow *window = meta_display_lookup_stack_id (display, windows[i]);
|
||||||
|
|
||||||
if (windows[i].any.type == META_WINDOW_CLIENT_TYPE_X11)
|
|
||||||
window = meta_display_lookup_x_window (display,
|
|
||||||
windows[i].x11.xwindow);
|
|
||||||
else
|
|
||||||
window = windows[i].wayland.meta_window;
|
|
||||||
|
|
||||||
if (window != NULL && window->title)
|
if (window != NULL && window->title)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* See comment in meta_ui_new() about why the dummy window for GTK+ theming
|
/* See comment in meta_ui_new() about why the dummy window for GTK+ theming
|
||||||
* is managed as a MetaWindow.
|
* is managed as a MetaWindow.
|
||||||
*/
|
*/
|
||||||
if (windows[i].any.type == META_WINDOW_CLIENT_TYPE_X11 &&
|
if (META_STACK_ID_IS_X11 (windows[i]) &&
|
||||||
meta_ui_window_is_dummy (display->screen->ui, windows[i].x11.xwindow))
|
meta_ui_window_is_dummy (display->screen->ui, windows[i]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (stack_string->len > 0)
|
if (stack_string->len > 0)
|
||||||
@ -579,18 +571,18 @@ test_case_check_xserver_stacking (TestCase *test,
|
|||||||
GString *x11_string = g_string_new (NULL);
|
GString *x11_string = g_string_new (NULL);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
MetaStackWindow *windows;
|
guint64 *windows;
|
||||||
int n_windows;
|
int n_windows;
|
||||||
meta_stack_tracker_get_stack (display->screen->stack_tracker, &windows, &n_windows);
|
meta_stack_tracker_get_stack (display->screen->stack_tracker, &windows, &n_windows);
|
||||||
|
|
||||||
for (i = 0; i < n_windows; i++)
|
for (i = 0; i < n_windows; i++)
|
||||||
{
|
{
|
||||||
if (windows[i].any.type == META_WINDOW_CLIENT_TYPE_X11)
|
if (META_STACK_ID_IS_X11 (windows[i]))
|
||||||
{
|
{
|
||||||
if (local_string->len > 0)
|
if (local_string->len > 0)
|
||||||
g_string_append_c (local_string, ' ');
|
g_string_append_c (local_string, ' ');
|
||||||
|
|
||||||
g_string_append_printf (local_string, "%#lx", windows[i].x11.xwindow);
|
g_string_append_printf (local_string, "%#lx", (Window)windows[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,11 +60,8 @@ meta_window_wayland_manage (MetaWindow *window)
|
|||||||
meta_display_register_wayland_window (display, window);
|
meta_display_register_wayland_window (display, window);
|
||||||
|
|
||||||
{
|
{
|
||||||
MetaStackWindow stack_window;
|
|
||||||
stack_window.any.type = META_WINDOW_CLIENT_TYPE_WAYLAND;
|
|
||||||
stack_window.wayland.meta_window = window;
|
|
||||||
meta_stack_tracker_record_add (window->screen->stack_tracker,
|
meta_stack_tracker_record_add (window->screen->stack_tracker,
|
||||||
&stack_window,
|
window->stamp,
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,11 +70,8 @@ static void
|
|||||||
meta_window_wayland_unmanage (MetaWindow *window)
|
meta_window_wayland_unmanage (MetaWindow *window)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
MetaStackWindow stack_window;
|
|
||||||
stack_window.any.type = META_WINDOW_CLIENT_TYPE_WAYLAND;
|
|
||||||
stack_window.wayland.meta_window = window;
|
|
||||||
meta_stack_tracker_record_remove (window->screen->stack_tracker,
|
meta_stack_tracker_record_remove (window->screen->stack_tracker,
|
||||||
&stack_window,
|
window->stamp,
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user