diff --git a/clutter/clutter/clutter-event.c b/clutter/clutter/clutter-event.c index 8b6cb9592..5dce2dc9b 100644 --- a/clutter/clutter/clutter-event.c +++ b/clutter/clutter/clutter-event.c @@ -1504,14 +1504,17 @@ ClutterEvent * clutter_event_get (void) { ClutterMainContext *context = _clutter_context_get_default (); + ClutterEvent *event; - if (context->events_queue == NULL) - return NULL; + event = g_async_queue_try_pop (context->events_queue); - if (g_queue_is_empty (context->events_queue)) - return NULL; + return event; +} - return g_queue_pop_tail (context->events_queue); +static gboolean +spin_context (gpointer data) +{ + return G_SOURCE_REMOVE; } void @@ -1522,9 +1525,6 @@ _clutter_event_push (const ClutterEvent *event, g_assert (context != NULL); - if (context->events_queue == NULL) - context->events_queue = g_queue_new (); - if (do_copy) { ClutterEvent *copy; @@ -1533,7 +1533,8 @@ _clutter_event_push (const ClutterEvent *event, event = copy; } - g_queue_push_head (context->events_queue, (gpointer) event); + g_async_queue_push (context->events_queue, (gpointer) event); + g_idle_add (spin_context, NULL); } /** @@ -1570,10 +1571,7 @@ clutter_events_pending (void) g_return_val_if_fail (context != NULL, FALSE); - if (context->events_queue == NULL) - return FALSE; - - return g_queue_is_empty (context->events_queue) == FALSE; + return g_async_queue_length (context->events_queue) > 0; } /** diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c index a4828fe73..c2faee883 100644 --- a/clutter/clutter/clutter-main.c +++ b/clutter/clutter/clutter-main.c @@ -697,6 +697,8 @@ _clutter_context_get_default (void) ctx->settings = clutter_settings_get_default (); _clutter_settings_set_backend (ctx->settings, ctx->backend); + ctx->events_queue = g_async_queue_new (); + ctx->last_repaint_id = 1; } @@ -2286,15 +2288,16 @@ void _clutter_clear_events_queue (void) { ClutterMainContext *context = _clutter_context_get_default (); + ClutterEvent *event; - if (context->events_queue != NULL) - { - g_queue_foreach (context->events_queue, - (GFunc) clutter_event_free, - NULL); - g_queue_free (context->events_queue); - context->events_queue = NULL; - } + /* Lock the queue for as long as it lives */ + g_async_queue_lock (context->events_queue); + + while ((event = g_async_queue_try_pop_unlocked (context->events_queue))) + clutter_event_free (event); + + g_async_queue_unref (context->events_queue); + context->events_queue = NULL; } ClutterPickMode diff --git a/clutter/clutter/clutter-private.h b/clutter/clutter/clutter-private.h index e4119b99f..549c39a20 100644 --- a/clutter/clutter/clutter-private.h +++ b/clutter/clutter/clutter-private.h @@ -122,7 +122,7 @@ struct _ClutterMainContext ClutterStageManager *stage_manager; /* the main event queue */ - GQueue *events_queue; + GAsyncQueue *events_queue; /* the event filters added via clutter_event_add_filter. these are * ordered from least recently added to most recently added */