summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmanuele Aina <emanuele.aina@collabora.com>2012-11-16 15:33:00 +0000
committerEmmanuele Bassi <ebassi@gnome.org>2012-12-18 01:27:32 +0000
commitcea8ea06f33019c48807ba422f2ff1fa94f28c5a (patch)
tree5da53035bd279190f9c4b3e08c4a8c8e23c6a561
parent060b05cc29f74d610159a33d880f0fe6582d260c (diff)
downloadclutter-cea8ea06f33019c48807ba422f2ff1fa94f28c5a.tar.gz
events: Make _clutter_process_event() reentrant
The _clutter_process_event() function may get called while already servicing a _clutter_process_event() invocation (eg. when generating ENTER events before emitting TOUCH_BEGIN). In these cases clutter_get_current_event() would return NULL after the inner call to _clutter_process_event() has finished, thereafter making the current event inaccessible during the remaining portion of the outer event emission. By stacking the current events in ClutterMainContext instead of simply replacing them we do not lose track of the real current event. Also update clutter_get_current_event_time() to be consistent from a reentrancy perspective. https://bugzilla.gnome.org/show_bug.cgi?id=688457
-rw-r--r--clutter/clutter-event.c10
-rw-r--r--clutter/clutter-main.c7
-rw-r--r--clutter/clutter-private.h4
3 files changed, 10 insertions, 11 deletions
diff --git a/clutter/clutter-event.c b/clutter/clutter-event.c
index e963c283c..c0ef2c21d 100644
--- a/clutter/clutter-event.c
+++ b/clutter/clutter-event.c
@@ -1369,12 +1369,12 @@ clutter_events_pending (void)
guint32
clutter_get_current_event_time (void)
{
- ClutterMainContext *context = _clutter_context_get_default ();
+ const ClutterEvent* event;
- g_return_val_if_fail (context != NULL, FALSE);
+ event = clutter_get_current_event ();
- if (context->last_event_time != 0)
- return context->last_event_time;
+ if (event != NULL)
+ return clutter_event_get_time (event);
return CLUTTER_CURRENT_TIME;
}
@@ -1399,7 +1399,7 @@ clutter_get_current_event (void)
g_return_val_if_fail (context != NULL, NULL);
- return context->current_event;
+ return context->current_event != NULL ? context->current_event->data : NULL;
}
/**
diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c
index b1b8fbbc5..da7fe8317 100644
--- a/clutter/clutter-main.c
+++ b/clutter/clutter-main.c
@@ -2792,16 +2792,15 @@ _clutter_process_event (ClutterEvent *event)
return;
}
- /* keep a pointer to the event and time, so that we don't need to
+ /* push events on a stack, so that we don't need to
* add an event parameter to all signals that can be emitted within
* an event chain
*/
- context->last_event_time = clutter_event_get_time (event);
- context->current_event = event;
+ context->current_event = g_slist_prepend (context->current_event, event);
_clutter_process_event_details (stage, context, event);
- context->current_event = NULL;
+ context->current_event = g_slist_delete_link (context->current_event, context->current_event);
}
/**
diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h
index 1d28ee0fa..2136efe75 100644
--- a/clutter/clutter-private.h
+++ b/clutter/clutter-private.h
@@ -163,8 +163,8 @@ struct _ClutterMainContext
PangoContext *pango_context; /* Global Pango context */
CoglPangoFontMap *font_map; /* Global font map */
- ClutterEvent *current_event;
- guint32 last_event_time;
+ /* stack of #ClutterEvent */
+ GSList *current_event;
/* list of repaint functions installed through
* clutter_threads_add_repaint_func()