[mutter] MetaLater: Invoke later callbacks queued by earlier ones
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] MetaLater: Invoke later callbacks queued by earlier ones
- Date: Fri, 26 Feb 2016 09:54:22 +0000 (UTC)
commit 35da6a907854afb38556edb01fac4b3dbf55deb5
Author: Jonas Ådahl <jadahl gmail com>
Date: Mon Sep 14 22:31:32 2015 +0800
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
cd7a9680932868d1d2ef5447c77712cef9a443dd.
https://bugzilla.gnome.org/show_bug.cgi?id=755605
src/core/util.c | 103 ++++++++++++++++++++++++++++++++++++-------------------
1 files changed, 68 insertions(+), 35 deletions(-)
---
diff --git a/src/core/util.c b/src/core/util.c
index f4e56b9..22d4674 100644
--- a/src/core/util.c
+++ b/src/core/util.c
@@ -49,6 +49,9 @@ meta_topic_real_valist (MetaDebugTopic topic,
va_list args) G_GNUC_PRINTF(2, 0);
#endif
+static gboolean
+meta_later_remove_from_list (guint later_id, GSList **laters_list);
+
static gint verbose_topics = 0;
static gboolean is_debugging = FALSE;
static gboolean replace_current = FALSE;
@@ -739,7 +742,14 @@ typedef struct
gboolean run_once;
} 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 */
static ClutterTimeline *later_timeline;
static guint later_repaint_func = 0;
@@ -772,25 +782,14 @@ destroy_later (MetaLater *later)
unref_later (later);
}
-/* Used to sort the list of laters with the highest priority
- * functions first.
- */
-static int
-compare_laters (gconstpointer a,
- gconstpointer b)
-{
- return ((const MetaLater *)a)->when - ((const MetaLater *)b)->when;
-}
-
-static gboolean
-run_repaint_laters (gpointer data)
+static void
+run_repaint_laters (GSList **laters_list)
{
GSList *laters_copy;
GSList *l;
- gboolean keep_timeline_running = FALSE;
laters_copy = NULL;
- for (l = laters; l; l = l->next)
+ for (l = *laters_list; l; l = l->next)
{
MetaLater *later = l->data;
if (later->source == 0 ||
@@ -806,22 +805,41 @@ run_repaint_laters (gpointer 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)
keep_timeline_running = TRUE;
}
- else
- meta_later_remove (later->id);
- unref_later (later);
}
if (!keep_timeline_running)
clutter_timeline_stop (later_timeline);
- g_slist_free (laters_copy);
-
- /* Just keep the repaint func around - it's cheap if the list is empty */
+ /* Just keep the repaint func around - it's cheap if the lists are empty */
return TRUE;
}
@@ -832,7 +850,7 @@ ensure_later_repaint_func (void)
later_timeline = clutter_timeline_new (G_MAXUINT);
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);
/* Make sure the repaint function gets run */
@@ -888,7 +906,7 @@ meta_later_add (MetaLaterType when,
later->data = data;
later->notify = notify;
- laters = g_slist_insert_sorted (laters, later, compare_laters);
+ laters[when] = g_slist_prepend (laters[when], later);
switch (when)
{
@@ -920,30 +938,45 @@ meta_later_add (MetaLaterType when,
return later->id;
}
-/**
- * meta_later_remove:
- * @later_id: the integer ID returned from meta_later_add()
- *
- * Removes a callback added with meta_later_add()
- */
-void
-meta_later_remove (guint later_id)
+static gboolean
+meta_later_remove_from_list (guint later_id, GSList **laters_list)
{
GSList *l;
- for (l = laters; l; l = l->next)
+ for (l = *laters_list; l; l = l->next)
{
MetaLater *later = l->data;
+
if (later->id == later_id)
{
- laters = g_slist_delete_link (laters, l);
+ *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;
+ return TRUE;
}
}
+
+ return FALSE;
+}
+
+/**
+ * meta_later_remove:
+ * @later_id: the integer ID returned from meta_later_add()
+ *
+ * Removes a callback added with meta_later_add()
+ */
+void
+meta_later_remove (guint later_id)
+{
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (laters); i++)
+ {
+ if (meta_later_remove_from_list (later_id, &laters[i]))
+ return;
+ }
}
MetaLocaleDirection
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]