[clutter] events: Make _clutter_process_event() reentrant



commit cea8ea06f33019c48807ba422f2ff1fa94f28c5a
Author: Emanuele Aina <emanuele aina collabora com>
Date:   Fri Nov 16 15:33:00 2012 +0000

    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

 clutter/clutter-event.c   |   10 +++++-----
 clutter/clutter-main.c    |    7 +++----
 clutter/clutter-private.h |    4 ++--
 3 files changed, 10 insertions(+), 11 deletions(-)
---
diff --git a/clutter/clutter-event.c b/clutter/clutter-event.c
index e963c28..c0ef2c2 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 b1b8fbb..da7fe83 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 1d28ee0..2136efe 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()



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]