mirror of
https://github.com/brl/mutter.git
synced 2024-12-27 21:32:14 +00:00
window: Move some display level window processing to MetaDisplay
meta_window_(un)queue() was implemented with global arrays in window.c that managed MetaLater handle IDs and lists of window queues. In order to rely less on scattered static variables and making it clearer that we're dealing with per display window management and not something specific to a single window, move the window resize/calc-showing queue management to MetaDisplay. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2264>
This commit is contained in:
parent
ac5d728abd
commit
169dd2fb7a
@ -432,4 +432,12 @@ gboolean meta_display_init_x11_finish (MetaDisplay *display,
|
||||
|
||||
void meta_display_shutdown_x11 (MetaDisplay *display);
|
||||
|
||||
void meta_display_queue_window (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
MetaQueueType queue_types);
|
||||
|
||||
void meta_display_unqueue_window (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
MetaQueueType queue_types);
|
||||
|
||||
#endif
|
||||
|
@ -124,6 +124,9 @@ typedef struct
|
||||
typedef struct _MetaDisplayPrivate
|
||||
{
|
||||
MetaContext *context;
|
||||
|
||||
guint queue_later_ids[META_N_QUEUE_TYPES];
|
||||
GList *queue_windows[META_N_QUEUE_TYPES];
|
||||
} MetaDisplayPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaDisplay, meta_display, G_TYPE_OBJECT)
|
||||
@ -163,6 +166,7 @@ enum
|
||||
WORKAREAS_CHANGED,
|
||||
CLOSING,
|
||||
INIT_XSERVER,
|
||||
WINDOW_VISIBILITY_UPDATED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@ -525,6 +529,16 @@ meta_display_class_init (MetaDisplayClass *klass)
|
||||
NULL, NULL,
|
||||
G_TYPE_BOOLEAN, 1, G_TYPE_TASK);
|
||||
|
||||
display_signals[WINDOW_VISIBILITY_UPDATED] =
|
||||
g_signal_new ("window-visibility-updated",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 3,
|
||||
G_TYPE_POINTER,
|
||||
G_TYPE_POINTER,
|
||||
G_TYPE_POINTER);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_COMPOSITOR_MODIFIERS,
|
||||
g_param_spec_flags ("compositor-modifiers",
|
||||
@ -3933,3 +3947,192 @@ meta_display_get_selection (MetaDisplay *display)
|
||||
{
|
||||
return display->selection;
|
||||
}
|
||||
|
||||
#ifdef WITH_VERBOSE_MODE
|
||||
static const char* meta_window_queue_names[META_N_QUEUE_TYPES] =
|
||||
{
|
||||
"calc-showing",
|
||||
"move-resize",
|
||||
};
|
||||
#endif
|
||||
|
||||
static int
|
||||
window_stack_cmp (gconstpointer a,
|
||||
gconstpointer b)
|
||||
{
|
||||
MetaWindow *aw = (gpointer) a;
|
||||
MetaWindow *bw = (gpointer) b;
|
||||
|
||||
return meta_stack_windows_cmp (aw->display->stack,
|
||||
aw, bw);
|
||||
}
|
||||
|
||||
static void
|
||||
warn_on_incorrectly_unmanaged_window (MetaWindow *window)
|
||||
{
|
||||
g_warn_if_fail (!window->unmanaging);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_window_visibilities_idle (gpointer user_data)
|
||||
{
|
||||
MetaDisplay *display = META_DISPLAY (user_data);
|
||||
MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
|
||||
int queue_idx;
|
||||
g_autoptr (GList) windows = NULL;
|
||||
g_autoptr (GList) unplaced = NULL;
|
||||
g_autoptr (GList) should_show = NULL;
|
||||
g_autoptr (GList) should_hide = NULL;
|
||||
GList *l;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (MetaDisplayUpdateVisibility,
|
||||
"Display: Update visibility");
|
||||
|
||||
queue_idx = __builtin_ctz (META_QUEUE_CALC_SHOWING);
|
||||
|
||||
windows = g_steal_pointer (&priv->queue_windows[queue_idx]);
|
||||
priv->queue_later_ids[queue_idx] = 0;
|
||||
|
||||
for (l = windows; l; l = l->next)
|
||||
{
|
||||
MetaWindow *window = l->data;
|
||||
|
||||
if (!window->placed)
|
||||
unplaced = g_list_prepend (unplaced, window);
|
||||
else if (meta_window_should_be_showing (window))
|
||||
should_show = g_list_prepend (should_show, window);
|
||||
else
|
||||
should_hide = g_list_prepend (should_hide, window);
|
||||
}
|
||||
|
||||
/* Sort bottom to top */
|
||||
unplaced = g_list_sort (unplaced, window_stack_cmp);
|
||||
should_hide = g_list_sort (should_hide, window_stack_cmp);
|
||||
|
||||
/* Sort top to bottom */
|
||||
should_show = g_list_sort (should_show, window_stack_cmp);
|
||||
should_show = g_list_reverse (should_show);
|
||||
|
||||
COGL_TRACE_BEGIN (MetaDisplayShowUnplacedWindows,
|
||||
"Display: Show unplaced windows");
|
||||
g_list_foreach (unplaced, (GFunc) meta_window_update_visibility, NULL);
|
||||
COGL_TRACE_END (MetaDisplayShowUnplacedWindows);
|
||||
|
||||
meta_stack_freeze (display->stack);
|
||||
|
||||
COGL_TRACE_BEGIN (MetaDisplayShowWindows, "Display: Show windows");
|
||||
g_list_foreach (should_show, (GFunc) meta_window_update_visibility, NULL);
|
||||
COGL_TRACE_END (MetaDisplayShowWindows);
|
||||
|
||||
COGL_TRACE_BEGIN (MetaDisplayHideWindows, "Display: Show windows");
|
||||
g_list_foreach (should_hide, (GFunc) meta_window_update_visibility, NULL);
|
||||
COGL_TRACE_END (MetaDisplayHideWindows);
|
||||
|
||||
meta_stack_thaw (display->stack);
|
||||
|
||||
g_list_foreach (windows, (GFunc) meta_window_clear_queued, NULL);
|
||||
|
||||
g_signal_emit (display, display_signals[WINDOW_VISIBILITY_UPDATED], 0,
|
||||
unplaced, should_show, should_hide);
|
||||
|
||||
g_list_foreach (windows, (GFunc) warn_on_incorrectly_unmanaged_window, NULL);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
move_resize_idle (gpointer user_data)
|
||||
{
|
||||
MetaDisplay *display = META_DISPLAY (user_data);
|
||||
MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
|
||||
int queue_idx;
|
||||
g_autoptr (GList) windows = NULL;
|
||||
|
||||
queue_idx = __builtin_ctz (META_QUEUE_MOVE_RESIZE);
|
||||
|
||||
windows = g_steal_pointer (&priv->queue_windows[queue_idx]);
|
||||
priv->queue_later_ids[queue_idx] = 0;
|
||||
|
||||
g_list_foreach (windows, (GFunc) meta_window_update_layout, NULL);
|
||||
g_list_foreach (windows, (GFunc) warn_on_incorrectly_unmanaged_window, NULL);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_queue_window (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
MetaQueueType queue_types)
|
||||
{
|
||||
MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
|
||||
MetaCompositor *compositor = display->compositor;
|
||||
MetaLaters *laters = meta_compositor_get_laters (compositor);
|
||||
int queue_idx;
|
||||
|
||||
for (queue_idx = 0; queue_idx < META_N_QUEUE_TYPES; queue_idx++)
|
||||
{
|
||||
const MetaLaterType window_queue_later_when[META_N_QUEUE_TYPES] =
|
||||
{
|
||||
META_LATER_CALC_SHOWING,
|
||||
META_LATER_RESIZE,
|
||||
};
|
||||
|
||||
const GSourceFunc window_queue_later_handler[META_N_QUEUE_TYPES] =
|
||||
{
|
||||
update_window_visibilities_idle,
|
||||
move_resize_idle,
|
||||
};
|
||||
|
||||
if (!(queue_types & 1 << queue_idx))
|
||||
continue;
|
||||
|
||||
meta_topic (META_DEBUG_WINDOW_STATE,
|
||||
"Queueing %s for window '%s'",
|
||||
meta_window_queue_names[queue_idx],
|
||||
meta_window_get_description (window));
|
||||
|
||||
priv->queue_windows[queue_idx] =
|
||||
g_list_prepend (priv->queue_windows[queue_idx], window);
|
||||
|
||||
if (!priv->queue_later_ids[queue_idx])
|
||||
{
|
||||
meta_laters_add (laters,
|
||||
window_queue_later_when[queue_idx],
|
||||
window_queue_later_handler[queue_idx],
|
||||
display, NULL);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_unqueue_window (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
MetaQueueType queue_types)
|
||||
{
|
||||
MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
|
||||
MetaCompositor *compositor = display->compositor;
|
||||
MetaLaters *laters = meta_compositor_get_laters (compositor);
|
||||
int queue_idx;
|
||||
|
||||
for (queue_idx = 0; queue_idx < META_N_QUEUE_TYPES; queue_idx++)
|
||||
{
|
||||
if (!(queue_types & 1 << queue_idx))
|
||||
continue;
|
||||
|
||||
meta_topic (META_DEBUG_WINDOW_STATE,
|
||||
"Unqueuing %s for window '%s'",
|
||||
meta_window_queue_names[queue_idx],
|
||||
window->desc);
|
||||
|
||||
priv->queue_windows[queue_idx] =
|
||||
g_list_remove (priv->queue_windows[queue_idx], window);
|
||||
|
||||
if (!priv->queue_windows[queue_idx] && priv->queue_later_ids[queue_idx])
|
||||
{
|
||||
meta_laters_remove (laters,
|
||||
priv->queue_later_ids[queue_idx]);
|
||||
priv->queue_later_ids[queue_idx] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,4 +28,10 @@ typedef enum _MetaX11DisplayPolicy
|
||||
META_X11_DISPLAY_POLICY_DISABLED,
|
||||
} MetaX11DisplayPolicy;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_QUEUE_CALC_SHOWING = 1 << 0,
|
||||
META_QUEUE_MOVE_RESIZE = 1 << 1,
|
||||
} MetaQueueType;
|
||||
|
||||
#endif /* META_PRIVATE_ENUMS_H */
|
||||
|
@ -416,6 +416,8 @@ meta_stack_thaw (MetaStack *stack)
|
||||
{
|
||||
g_return_if_fail (stack->freeze_count > 0);
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (MetaStackThaw, "Stack: thaw");
|
||||
|
||||
stack->freeze_count -= 1;
|
||||
meta_stack_changed (stack);
|
||||
meta_stack_update_window_tile_matches (stack, NULL);
|
||||
|
@ -56,13 +56,7 @@ typedef enum
|
||||
META_CLIENT_TYPE_MAX_RECOGNIZED = 2
|
||||
} MetaClientType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_QUEUE_CALC_SHOWING = 1 << 0,
|
||||
META_QUEUE_MOVE_RESIZE = 1 << 1,
|
||||
} MetaQueueType;
|
||||
|
||||
#define NUMBER_OF_QUEUES 2
|
||||
#define META_N_QUEUE_TYPES 2
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@ -397,9 +391,6 @@ struct _MetaWindow
|
||||
/* Are we in meta_window_new()? */
|
||||
guint constructing : 1;
|
||||
|
||||
/* Are we in the various queues? (Bitfield: see META_WINDOW_IS_IN_QUEUE) */
|
||||
guint is_in_queues : NUMBER_OF_QUEUES;
|
||||
|
||||
/* Used by keybindings.c */
|
||||
guint keys_grabbed : 1; /* normal keybindings grabbed */
|
||||
guint grab_on_frame : 1; /* grabs are on the frame */
|
||||
@ -915,4 +906,10 @@ gboolean meta_window_unit_cgroup_equal (MetaWindow *window1,
|
||||
void meta_window_check_alive_on_event (MetaWindow *window,
|
||||
uint32_t timestamp);
|
||||
|
||||
void meta_window_update_visibility (MetaWindow *window);
|
||||
|
||||
void meta_window_clear_queued (MetaWindow *window);
|
||||
|
||||
void meta_window_update_layout (MetaWindow *window);
|
||||
|
||||
#endif
|
||||
|
@ -109,8 +109,6 @@
|
||||
|
||||
#define SNAP_SECURITY_LABEL_PREFIX "snap."
|
||||
|
||||
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
|
||||
@ -131,8 +129,6 @@ static void meta_window_save_rect (MetaWindow *window);
|
||||
static void ensure_mru_position_after (MetaWindow *window,
|
||||
MetaWindow *after_this_one);
|
||||
|
||||
static void meta_window_move_resize_now (MetaWindow *window);
|
||||
|
||||
static void meta_window_unqueue (MetaWindow *window,
|
||||
MetaQueueType queuebits);
|
||||
|
||||
@ -170,17 +166,12 @@ static MetaWindow * meta_window_find_tile_match (MetaWindow *window,
|
||||
MetaTileMode mode);
|
||||
static void update_edge_constraints (MetaWindow *window);
|
||||
|
||||
/* Idle handlers for the three queues (run with meta_later_add()). The
|
||||
* "data" parameter in each case will be a GINT_TO_POINTER of the
|
||||
* index into the queue arrays to use.
|
||||
*
|
||||
* TODO: Possibly there is still some code duplication among these, which we
|
||||
* need to sort out at some point.
|
||||
*/
|
||||
static gboolean idle_calc_showing (gpointer data);
|
||||
static gboolean idle_move_resize (gpointer data);
|
||||
typedef struct _MetaWindowPrivate
|
||||
{
|
||||
MetaQueueType queued_types;
|
||||
} MetaWindowPrivate;
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (MetaWindow, meta_window, G_TYPE_OBJECT);
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaWindow, meta_window, G_TYPE_OBJECT)
|
||||
|
||||
enum
|
||||
{
|
||||
@ -1083,7 +1074,6 @@ _meta_window_shared_new (MetaDisplay *display,
|
||||
window->placed = ((window->mapped && !window->hidden) || window->override_redirect);
|
||||
window->denied_focus_and_not_transient = FALSE;
|
||||
window->unmanaging = FALSE;
|
||||
window->is_in_queues = 0;
|
||||
window->keys_grabbed = FALSE;
|
||||
window->grab_on_frame = FALSE;
|
||||
window->all_keys_grabbed = FALSE;
|
||||
@ -1458,10 +1448,6 @@ meta_window_unmanage (MetaWindow *window,
|
||||
meta_compositor_remove_window (window->display->compositor, window);
|
||||
window->known_to_compositor = FALSE;
|
||||
|
||||
if (destroying_windows_disallowed > 0)
|
||||
meta_bug ("Tried to destroy window %s while destruction was not allowed",
|
||||
window->desc);
|
||||
|
||||
meta_display_unregister_stamp (window->display, window->stamp);
|
||||
|
||||
if (meta_prefs_get_attach_modal_dialogs ())
|
||||
@ -1774,289 +1760,65 @@ implement_showing (MetaWindow *window,
|
||||
sync_client_window_mapped (window);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_calc_showing (MetaWindow *window)
|
||||
void
|
||||
meta_window_update_visibility (MetaWindow *window)
|
||||
{
|
||||
implement_showing (window, meta_window_should_be_showing (window));
|
||||
}
|
||||
|
||||
static guint queue_later[NUMBER_OF_QUEUES] = {};
|
||||
static GSList *queue_pending[NUMBER_OF_QUEUES] = {};
|
||||
|
||||
static int
|
||||
stackcmp (gconstpointer a, gconstpointer b)
|
||||
void
|
||||
meta_window_clear_queued (MetaWindow *window)
|
||||
{
|
||||
MetaWindow *aw = (gpointer) a;
|
||||
MetaWindow *bw = (gpointer) b;
|
||||
MetaWindowPrivate *priv = meta_window_get_instance_private (window);
|
||||
|
||||
return meta_stack_windows_cmp (aw->display->stack,
|
||||
aw, bw);
|
||||
priv->queued_types &= ~META_QUEUE_CALC_SHOWING;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
idle_calc_showing (gpointer data)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
GSList *tmp;
|
||||
GSList *copy;
|
||||
GSList *should_show;
|
||||
GSList *should_hide;
|
||||
GSList *unplaced;
|
||||
GSList *displays;
|
||||
guint queue_index = GPOINTER_TO_INT (data);
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (MetaWindowCalcShowing, "Window: Calc showing");
|
||||
|
||||
g_return_val_if_fail (queue_pending[queue_index] != NULL, FALSE);
|
||||
|
||||
meta_topic (META_DEBUG_WINDOW_STATE,
|
||||
"Clearing the calc_showing queue");
|
||||
|
||||
/* Work with a copy, for reentrancy. The allowed reentrancy isn't
|
||||
* complete; destroying a window while we're in here would result in
|
||||
* badness. But it's OK to queue/unqueue calc_showings.
|
||||
*/
|
||||
copy = g_slist_copy (queue_pending[queue_index]);
|
||||
g_slist_free (queue_pending[queue_index]);
|
||||
queue_pending[queue_index] = NULL;
|
||||
queue_later[queue_index] = 0;
|
||||
|
||||
destroying_windows_disallowed += 1;
|
||||
|
||||
/* We map windows from top to bottom and unmap from bottom to
|
||||
* top, to avoid extra expose events. The exception is
|
||||
* for unplaced windows, which have to be mapped from bottom to
|
||||
* top so placement works.
|
||||
*/
|
||||
should_show = NULL;
|
||||
should_hide = NULL;
|
||||
unplaced = NULL;
|
||||
displays = NULL;
|
||||
|
||||
COGL_TRACE_BEGIN (MetaWindowCalcShowingCalc, "Window: Calc showing (calc)");
|
||||
|
||||
tmp = copy;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *window;
|
||||
|
||||
window = tmp->data;
|
||||
|
||||
if (!window->placed)
|
||||
unplaced = g_slist_prepend (unplaced, window);
|
||||
else if (meta_window_should_be_showing (window))
|
||||
should_show = g_slist_prepend (should_show, window);
|
||||
else
|
||||
should_hide = g_slist_prepend (should_hide, window);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
/* bottom to top */
|
||||
unplaced = g_slist_sort (unplaced, stackcmp);
|
||||
should_hide = g_slist_sort (should_hide, stackcmp);
|
||||
/* top to bottom */
|
||||
should_show = g_slist_sort (should_show, stackcmp);
|
||||
should_show = g_slist_reverse (should_show);
|
||||
|
||||
COGL_TRACE_END (MetaWindowCalcShowingCalc);
|
||||
|
||||
COGL_TRACE_BEGIN (MetaWindowCalcShowingUnplaced,
|
||||
"Window: Calc showing (calc unplaced)");
|
||||
|
||||
tmp = unplaced;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *window;
|
||||
|
||||
window = tmp->data;
|
||||
|
||||
meta_window_calc_showing (window);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
COGL_TRACE_END (MetaWindowCalcShowingUnplaced);
|
||||
|
||||
meta_stack_freeze (display->stack);
|
||||
|
||||
COGL_TRACE_BEGIN (MetaWindowCalcShowingShow, "Window: Calc showing (show)");
|
||||
tmp = should_show;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *window;
|
||||
|
||||
window = tmp->data;
|
||||
|
||||
implement_showing (window, TRUE);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
COGL_TRACE_END (MetaWindowCalcShowingShow);
|
||||
|
||||
COGL_TRACE_BEGIN (MetaWindowCalcShowingHide, "Window: Calc showing (hide)");
|
||||
tmp = should_hide;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *window;
|
||||
|
||||
window = tmp->data;
|
||||
|
||||
implement_showing (window, FALSE);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
COGL_TRACE_END (MetaWindowCalcShowingHide);
|
||||
|
||||
COGL_TRACE_BEGIN (MetaWindowCalcShowingSync,
|
||||
"Window: Calc showing (sync stack)");
|
||||
meta_stack_thaw (display->stack);
|
||||
COGL_TRACE_END (MetaWindowCalcShowingSync);
|
||||
|
||||
tmp = copy;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *window;
|
||||
|
||||
window = tmp->data;
|
||||
|
||||
/* important to set this here for reentrancy -
|
||||
* if we queue a window again while it's in "copy",
|
||||
* then queue_calc_showing will just return since
|
||||
* we are still in the calc_showing queue
|
||||
*/
|
||||
window->is_in_queues &= ~META_QUEUE_CALC_SHOWING;
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
if (meta_prefs_get_focus_mode () != G_DESKTOP_FOCUS_MODE_CLICK)
|
||||
{
|
||||
/* When display->mouse_mode is false, we want to ignore
|
||||
* EnterNotify events unless they come from mouse motion. To do
|
||||
* that, we set a sentinel property on the root window if we're
|
||||
* not in mouse_mode.
|
||||
*/
|
||||
tmp = should_show;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *window = tmp->data;
|
||||
MetaDisplay *display = window->display;
|
||||
|
||||
if (display->x11_display && !display->mouse_mode)
|
||||
meta_x11_display_increment_focus_sentinel (display->x11_display);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
g_slist_free (copy);
|
||||
|
||||
g_slist_free (unplaced);
|
||||
g_slist_free (should_show);
|
||||
g_slist_free (should_hide);
|
||||
g_slist_free (displays);
|
||||
|
||||
destroying_windows_disallowed -= 1;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef WITH_VERBOSE_MODE
|
||||
static const gchar* meta_window_queue_names[NUMBER_OF_QUEUES] =
|
||||
{"calc_showing", "move_resize", };
|
||||
#endif
|
||||
|
||||
static void
|
||||
meta_window_unqueue (MetaWindow *window,
|
||||
MetaQueueType queuebits)
|
||||
MetaQueueType queue_types)
|
||||
{
|
||||
int queuenum;
|
||||
MetaWindowPrivate *priv = meta_window_get_instance_private (window);
|
||||
|
||||
for (queuenum = 0; queuenum < NUMBER_OF_QUEUES; queuenum++)
|
||||
{
|
||||
if ((queuebits & 1 << queuenum) &&
|
||||
(window->is_in_queues & 1 << queuenum))
|
||||
{
|
||||
queue_types &= priv->queued_types;
|
||||
|
||||
meta_topic (META_DEBUG_WINDOW_STATE,
|
||||
"Removing %s from the %s queue",
|
||||
window->desc,
|
||||
meta_window_queue_names[queuenum]);
|
||||
if (!queue_types)
|
||||
return;
|
||||
|
||||
queue_pending[queuenum] = g_slist_remove (queue_pending[queuenum], window);
|
||||
window->is_in_queues &= ~(1 << queuenum);
|
||||
|
||||
if (queue_pending[queuenum] == NULL && queue_later[queuenum] != 0)
|
||||
{
|
||||
meta_later_remove (queue_later[queuenum]);
|
||||
queue_later[queuenum] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
meta_display_unqueue_window (window->display, window, queue_types);
|
||||
priv->queued_types &= ~queue_types;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_flush_calc_showing (MetaWindow *window)
|
||||
{
|
||||
if (window->is_in_queues & META_QUEUE_CALC_SHOWING)
|
||||
MetaWindowPrivate *priv = meta_window_get_instance_private (window);
|
||||
|
||||
if (priv->queued_types & META_QUEUE_CALC_SHOWING)
|
||||
{
|
||||
meta_window_unqueue (window, META_QUEUE_CALC_SHOWING);
|
||||
meta_window_calc_showing (window);
|
||||
meta_window_update_visibility (window);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_queue (MetaWindow *window,
|
||||
MetaQueueType queuebits)
|
||||
MetaQueueType queue_types)
|
||||
{
|
||||
unsigned int queuenum;
|
||||
MetaWindowPrivate *priv = meta_window_get_instance_private (window);
|
||||
|
||||
g_return_if_fail (!window->override_redirect ||
|
||||
(queuebits & META_QUEUE_MOVE_RESIZE) == 0);
|
||||
(queue_types & META_QUEUE_MOVE_RESIZE) == 0);
|
||||
|
||||
for (queuenum = 0; queuenum < NUMBER_OF_QUEUES; queuenum++)
|
||||
{
|
||||
if (queuebits & 1 << queuenum)
|
||||
{
|
||||
const MetaLaterType window_queue_later_when[NUMBER_OF_QUEUES] =
|
||||
{
|
||||
META_LATER_CALC_SHOWING,
|
||||
META_LATER_RESIZE,
|
||||
};
|
||||
if (window->unmanaging)
|
||||
return;
|
||||
|
||||
const GSourceFunc window_queue_later_handler[NUMBER_OF_QUEUES] =
|
||||
{
|
||||
idle_calc_showing,
|
||||
idle_move_resize,
|
||||
};
|
||||
queue_types &= ~priv->queued_types;
|
||||
if (!queue_types)
|
||||
return;
|
||||
|
||||
if (window->unmanaging)
|
||||
break;
|
||||
|
||||
if (window->is_in_queues & 1 << queuenum)
|
||||
break;
|
||||
|
||||
meta_topic (META_DEBUG_WINDOW_STATE,
|
||||
"Putting %s in the %s queue",
|
||||
window->desc,
|
||||
meta_window_queue_names[queuenum]);
|
||||
|
||||
window->is_in_queues |= 1 << queuenum;
|
||||
|
||||
if (queue_later[queuenum] == 0)
|
||||
{
|
||||
queue_later[queuenum] =
|
||||
meta_later_add (window_queue_later_when[queuenum],
|
||||
window_queue_later_handler[queuenum],
|
||||
GUINT_TO_POINTER (queuenum),
|
||||
NULL);
|
||||
}
|
||||
|
||||
queue_pending[queuenum] = g_slist_prepend (queue_pending[queuenum],
|
||||
window);
|
||||
}
|
||||
}
|
||||
priv->queued_types |= queue_types;
|
||||
meta_display_queue_window (window->display, window, queue_types);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -4090,7 +3852,7 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
}
|
||||
|
||||
/* If we did placement, then we need to save the position that the window
|
||||
* was placed at to make sure that meta_window_move_resize_now places the
|
||||
* was placed at to make sure that meta_window_update_layout() places the
|
||||
* window correctly.
|
||||
*/
|
||||
if (did_placement)
|
||||
@ -4367,8 +4129,8 @@ meta_window_resize_frame_with_gravity (MetaWindow *window,
|
||||
meta_window_move_resize_internal (window, flags, gravity, rect);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_move_resize_now (MetaWindow *window)
|
||||
void
|
||||
meta_window_update_layout (MetaWindow *window)
|
||||
{
|
||||
meta_window_move_resize_frame (window, FALSE,
|
||||
window->unconstrained_rect.x,
|
||||
@ -4377,46 +4139,6 @@ meta_window_move_resize_now (MetaWindow *window)
|
||||
window->unconstrained_rect.height);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
idle_move_resize (gpointer data)
|
||||
{
|
||||
GSList *tmp;
|
||||
GSList *copy;
|
||||
guint queue_index = GPOINTER_TO_INT (data);
|
||||
|
||||
meta_topic (META_DEBUG_GEOMETRY, "Clearing the move_resize queue");
|
||||
|
||||
/* Work with a copy, for reentrancy. The allowed reentrancy isn't
|
||||
* complete; destroying a window while we're in here would result in
|
||||
* badness. But it's OK to queue/unqueue move_resizes.
|
||||
*/
|
||||
copy = g_slist_copy (queue_pending[queue_index]);
|
||||
g_slist_free (queue_pending[queue_index]);
|
||||
queue_pending[queue_index] = NULL;
|
||||
queue_later[queue_index] = 0;
|
||||
|
||||
destroying_windows_disallowed += 1;
|
||||
|
||||
tmp = copy;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *window;
|
||||
|
||||
window = tmp->data;
|
||||
|
||||
/* As a side effect, sets window->move_resize_queued = FALSE */
|
||||
meta_window_move_resize_now (window);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
g_slist_free (copy);
|
||||
|
||||
destroying_windows_disallowed -= 1;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_get_gravity_position (MetaWindow *window,
|
||||
MetaGravity gravity,
|
||||
|
@ -1104,6 +1104,25 @@ meta_x11_init_gdk_display (GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_window_visibility_updated (MetaDisplay *display,
|
||||
GList *placed_windows,
|
||||
GList *shown_windows,
|
||||
GList *hidden_windows,
|
||||
MetaX11Display *x11_display)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
|
||||
return;
|
||||
|
||||
if (display->mouse_mode)
|
||||
return;
|
||||
|
||||
for (l = shown_windows; l; l = l->next)
|
||||
meta_x11_display_increment_focus_sentinel (x11_display);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_x11_display_new:
|
||||
*
|
||||
@ -1236,6 +1255,10 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
|
||||
G_CALLBACK (update_cursor_theme),
|
||||
x11_display,
|
||||
G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (display,
|
||||
"window-visibility-updated",
|
||||
G_CALLBACK (on_window_visibility_updated),
|
||||
x11_display, 0);
|
||||
|
||||
update_cursor_theme (x11_display);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user