1
0
Fork 0

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
This commit is contained in:
Emanuele Aina 2012-11-16 15:33:00 +00:00 committed by Emmanuele Bassi
parent 060b05cc29
commit cea8ea06f3
3 changed files with 10 additions and 11 deletions

View file

@ -1369,12 +1369,12 @@ clutter_events_pending (void)
guint32 guint32
clutter_get_current_event_time (void) 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) if (event != NULL)
return context->last_event_time; return clutter_event_get_time (event);
return CLUTTER_CURRENT_TIME; return CLUTTER_CURRENT_TIME;
} }
@ -1399,7 +1399,7 @@ clutter_get_current_event (void)
g_return_val_if_fail (context != NULL, NULL); g_return_val_if_fail (context != NULL, NULL);
return context->current_event; return context->current_event != NULL ? context->current_event->data : NULL;
} }
/** /**

View file

@ -2792,16 +2792,15 @@ _clutter_process_event (ClutterEvent *event)
return; 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 * add an event parameter to all signals that can be emitted within
* an event chain * an event chain
*/ */
context->last_event_time = clutter_event_get_time (event); context->current_event = g_slist_prepend (context->current_event, event);
context->current_event = event;
_clutter_process_event_details (stage, context, 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);
} }
/** /**

View file

@ -163,8 +163,8 @@ struct _ClutterMainContext
PangoContext *pango_context; /* Global Pango context */ PangoContext *pango_context; /* Global Pango context */
CoglPangoFontMap *font_map; /* Global font map */ CoglPangoFontMap *font_map; /* Global font map */
ClutterEvent *current_event; /* stack of #ClutterEvent */
guint32 last_event_time; GSList *current_event;
/* list of repaint functions installed through /* list of repaint functions installed through
* clutter_threads_add_repaint_func() * clutter_threads_add_repaint_func()