mirror of
https://github.com/brl/mutter.git
synced 2024-11-29 11:30:45 -05:00
MetaLater: Invoke later callbacks queued by earlier ones
If a MetaLater callback queued another MetaLater with a scheduling
later than the one currently being invoked, make it so that the newly
scheduled callback will actually be invoked.
The fact that it doesn't already do this is a regression from
cd7a968093
.
https://bugzilla.gnome.org/show_bug.cgi?id=755605
This commit is contained in:
parent
00139755ff
commit
35da6a9078
103
src/core/util.c
103
src/core/util.c
@ -49,6 +49,9 @@ meta_topic_real_valist (MetaDebugTopic topic,
|
|||||||
va_list args) G_GNUC_PRINTF(2, 0);
|
va_list args) G_GNUC_PRINTF(2, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_later_remove_from_list (guint later_id, GSList **laters_list);
|
||||||
|
|
||||||
static gint verbose_topics = 0;
|
static gint verbose_topics = 0;
|
||||||
static gboolean is_debugging = FALSE;
|
static gboolean is_debugging = FALSE;
|
||||||
static gboolean replace_current = FALSE;
|
static gboolean replace_current = FALSE;
|
||||||
@ -739,7 +742,14 @@ typedef struct
|
|||||||
gboolean run_once;
|
gboolean run_once;
|
||||||
} MetaLater;
|
} MetaLater;
|
||||||
|
|
||||||
static GSList *laters = NULL;
|
static GSList *laters[] = {
|
||||||
|
NULL, /* META_LATER_RESIZE */
|
||||||
|
NULL, /* META_LATER_CALC_SHOWING */
|
||||||
|
NULL, /* META_LATER_CHECK_FULLSCREEN */
|
||||||
|
NULL, /* META_LATER_SYNC_STACK */
|
||||||
|
NULL, /* META_LATER_BEFORE_REDRAW */
|
||||||
|
NULL, /* META_LATER_IDLE */
|
||||||
|
};
|
||||||
/* This is a dummy timeline used to get the Clutter master clock running */
|
/* This is a dummy timeline used to get the Clutter master clock running */
|
||||||
static ClutterTimeline *later_timeline;
|
static ClutterTimeline *later_timeline;
|
||||||
static guint later_repaint_func = 0;
|
static guint later_repaint_func = 0;
|
||||||
@ -772,25 +782,14 @@ destroy_later (MetaLater *later)
|
|||||||
unref_later (later);
|
unref_later (later);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Used to sort the list of laters with the highest priority
|
static void
|
||||||
* functions first.
|
run_repaint_laters (GSList **laters_list)
|
||||||
*/
|
|
||||||
static int
|
|
||||||
compare_laters (gconstpointer a,
|
|
||||||
gconstpointer b)
|
|
||||||
{
|
|
||||||
return ((const MetaLater *)a)->when - ((const MetaLater *)b)->when;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
run_repaint_laters (gpointer data)
|
|
||||||
{
|
{
|
||||||
GSList *laters_copy;
|
GSList *laters_copy;
|
||||||
GSList *l;
|
GSList *l;
|
||||||
gboolean keep_timeline_running = FALSE;
|
|
||||||
|
|
||||||
laters_copy = NULL;
|
laters_copy = NULL;
|
||||||
for (l = laters; l; l = l->next)
|
for (l = *laters_list; l; l = l->next)
|
||||||
{
|
{
|
||||||
MetaLater *later = l->data;
|
MetaLater *later = l->data;
|
||||||
if (later->source == 0 ||
|
if (later->source == 0 ||
|
||||||
@ -806,22 +805,41 @@ run_repaint_laters (gpointer data)
|
|||||||
{
|
{
|
||||||
MetaLater *later = l->data;
|
MetaLater *later = l->data;
|
||||||
|
|
||||||
if (later->func && later->func (later->data))
|
if (!later->func || !later->func (later->data))
|
||||||
|
meta_later_remove_from_list (later->id, laters_list);
|
||||||
|
unref_later (later);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_slist_free (laters_copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
run_all_repaint_laters (gpointer data)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
GSList *l;
|
||||||
|
gboolean keep_timeline_running = FALSE;
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (laters); i++)
|
||||||
{
|
{
|
||||||
|
run_repaint_laters (&laters[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (laters); i++)
|
||||||
|
{
|
||||||
|
for (l = laters[i]; l; l = l->next)
|
||||||
|
{
|
||||||
|
MetaLater *later = l->data;
|
||||||
|
|
||||||
if (later->source == 0)
|
if (later->source == 0)
|
||||||
keep_timeline_running = TRUE;
|
keep_timeline_running = TRUE;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
meta_later_remove (later->id);
|
|
||||||
unref_later (later);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!keep_timeline_running)
|
if (!keep_timeline_running)
|
||||||
clutter_timeline_stop (later_timeline);
|
clutter_timeline_stop (later_timeline);
|
||||||
|
|
||||||
g_slist_free (laters_copy);
|
/* Just keep the repaint func around - it's cheap if the lists are empty */
|
||||||
|
|
||||||
/* Just keep the repaint func around - it's cheap if the list is empty */
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -832,7 +850,7 @@ ensure_later_repaint_func (void)
|
|||||||
later_timeline = clutter_timeline_new (G_MAXUINT);
|
later_timeline = clutter_timeline_new (G_MAXUINT);
|
||||||
|
|
||||||
if (later_repaint_func == 0)
|
if (later_repaint_func == 0)
|
||||||
later_repaint_func = clutter_threads_add_repaint_func (run_repaint_laters,
|
later_repaint_func = clutter_threads_add_repaint_func (run_all_repaint_laters,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
|
||||||
/* Make sure the repaint function gets run */
|
/* Make sure the repaint function gets run */
|
||||||
@ -888,7 +906,7 @@ meta_later_add (MetaLaterType when,
|
|||||||
later->data = data;
|
later->data = data;
|
||||||
later->notify = notify;
|
later->notify = notify;
|
||||||
|
|
||||||
laters = g_slist_insert_sorted (laters, later, compare_laters);
|
laters[when] = g_slist_prepend (laters[when], later);
|
||||||
|
|
||||||
switch (when)
|
switch (when)
|
||||||
{
|
{
|
||||||
@ -920,6 +938,29 @@ meta_later_add (MetaLaterType when,
|
|||||||
return later->id;
|
return later->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_later_remove_from_list (guint later_id, GSList **laters_list)
|
||||||
|
{
|
||||||
|
GSList *l;
|
||||||
|
|
||||||
|
for (l = *laters_list; l; l = l->next)
|
||||||
|
{
|
||||||
|
MetaLater *later = l->data;
|
||||||
|
|
||||||
|
if (later->id == later_id)
|
||||||
|
{
|
||||||
|
*laters_list = g_slist_delete_link (*laters_list, l);
|
||||||
|
/* If this was a "repaint func" later, we just let the
|
||||||
|
* repaint func run and get removed
|
||||||
|
*/
|
||||||
|
destroy_later (later);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* meta_later_remove:
|
* meta_later_remove:
|
||||||
* @later_id: the integer ID returned from meta_later_add()
|
* @later_id: the integer ID returned from meta_later_add()
|
||||||
@ -929,21 +970,13 @@ meta_later_add (MetaLaterType when,
|
|||||||
void
|
void
|
||||||
meta_later_remove (guint later_id)
|
meta_later_remove (guint later_id)
|
||||||
{
|
{
|
||||||
GSList *l;
|
guint i;
|
||||||
|
|
||||||
for (l = laters; l; l = l->next)
|
for (i = 0; i < G_N_ELEMENTS (laters); i++)
|
||||||
{
|
{
|
||||||
MetaLater *later = l->data;
|
if (meta_later_remove_from_list (later_id, &laters[i]))
|
||||||
if (later->id == later_id)
|
|
||||||
{
|
|
||||||
laters = g_slist_delete_link (laters, l);
|
|
||||||
/* If this was a "repaint func" later, we just let the
|
|
||||||
* repaint func run and get removed
|
|
||||||
*/
|
|
||||||
destroy_later (later);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaLocaleDirection
|
MetaLocaleDirection
|
||||||
|
Loading…
Reference in New Issue
Block a user