Avoid direct access to the main context events queue

The GQueue that stores the global events queue is handled all over the
place:

  • the structure is created in _clutter_backend_init_events();
  • the queue is handled in clutter-event.c, clutter-stage.c and
    clutter-backend.c;
  • ClutterStage::dispose cleans up the events associated with
    the stage being destroyed;
  • the queue is destroyed in ClutterBackend::dispose.

Since we need to have access to it in different places we cannot put it
inside ClutterBackendPrivate, hence it should stay in ClutterMainContext;
but we should still manage it from just one place - preferably by the
ClutterEvent API only.
This commit is contained in:
Emmanuele Bassi 2011-02-09 12:38:10 +00:00
parent 56d133f908
commit ef4688fd0e
5 changed files with 60 additions and 35 deletions

View File

@ -87,19 +87,11 @@ static void
clutter_backend_dispose (GObject *gobject)
{
ClutterBackendPrivate *priv = CLUTTER_BACKEND (gobject)->priv;
ClutterMainContext *clutter_context;
clutter_context = _clutter_context_get_default ();
if (clutter_context && clutter_context->events_queue)
{
g_queue_foreach (clutter_context->events_queue,
(GFunc) clutter_event_free,
NULL);
g_queue_free (clutter_context->events_queue);
clutter_context->events_queue = NULL;
}
/* clear the events still in the queue of the main context */
_clutter_clear_events_queue ();
/* remove all event translators */
if (priv->event_translators != NULL)
{
g_list_free (priv->event_translators);
@ -552,8 +544,6 @@ _clutter_backend_init_events (ClutterBackend *backend)
g_return_if_fail (CLUTTER_IS_BACKEND (backend));
g_return_if_fail (clutter_context != NULL);
clutter_context->events_queue = g_queue_new ();
klass = CLUTTER_BACKEND_GET_CLASS (backend);
if (klass->init_events)
klass->init_events (backend);

View File

@ -793,7 +793,7 @@ clutter_event_get (void)
{
ClutterMainContext *context = _clutter_context_get_default ();
if (!context->events_queue)
if (context->events_queue == NULL)
return NULL;
if (g_queue_is_empty (context->events_queue))
@ -835,9 +835,11 @@ _clutter_event_push (const ClutterEvent *event,
ClutterMainContext *context = _clutter_context_get_default ();
ClutterInputDevice *device;
/* FIXME: check queue is valid */
g_assert (context != NULL);
if (context->events_queue == NULL)
context->events_queue = g_queue_new ();
/* disabled devices don't propagate events */
device = clutter_event_get_device (event);
if (device != NULL)
@ -893,7 +895,7 @@ clutter_events_pending (void)
g_return_val_if_fail (context != NULL, FALSE);
if (!context->events_queue)
if (context->events_queue == NULL)
return FALSE;
return g_queue_is_empty (context->events_queue) == FALSE;

View File

@ -3267,3 +3267,47 @@ clutter_get_default_text_direction (void)
{
return clutter_text_direction;
}
/*< private >
* clutter_clear_events_queue:
*
* Clears the events queue stored in the main context.
*/
void
_clutter_clear_events_queue (void)
{
ClutterMainContext *context = _clutter_context_get_default ();
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;
}
}
void
_clutter_clear_events_queue_for_stage (ClutterStage *stage)
{
ClutterMainContext *context = _clutter_context_get_default ();
GList *l, *next;
if (context->events_queue == NULL)
return;
/* Remove any pending events for this stage from the event queue */
for (l = context->events_queue->head; l; l = next)
{
ClutterEvent *event = l->data;
next = l->next;
if (event->any.stage == stage)
{
g_queue_delete_link (context->events_queue, l);
clutter_event_free (event);
}
}
}

View File

@ -189,6 +189,10 @@ gboolean _clutter_feature_init (GError **error);
/* Reinjecting queued events for processing */
void _clutter_process_event (ClutterEvent *event);
/* clears the event queue inside the main context */
void _clutter_clear_events_queue (void);
void _clutter_clear_events_queue_for_stage (ClutterStage *stage);
/* Picking code */
ClutterActor *_clutter_do_pick (ClutterStage *stage,
gint x,

View File

@ -1163,29 +1163,14 @@ clutter_stage_dispose (GObject *object)
{
ClutterStage *stage = CLUTTER_STAGE (object);
ClutterStagePrivate *priv = stage->priv;
ClutterStageManager *stage_manager = clutter_stage_manager_get_default ();
ClutterMainContext *context;
GList *l, *next;
ClutterStageManager *stage_manager;
clutter_actor_hide (CLUTTER_ACTOR (object));
stage_manager = clutter_stage_manager_get_default ();
_clutter_stage_manager_remove_stage (stage_manager, stage);
context = _clutter_context_get_default ();
/* Remove any pending events for this stage from the event queue */
for (l = context->events_queue->head; l; l = next)
{
ClutterEvent *event = l->data;
next = l->next;
if (event->any.stage == stage)
{
g_queue_delete_link (context->events_queue, l);
clutter_event_free (event);
}
}
_clutter_clear_events_queue_for_stage (stage);
if (priv->impl != NULL)
{
@ -1204,7 +1189,7 @@ clutter_stage_finalize (GObject *object)
ClutterStage *stage = CLUTTER_STAGE (object);
ClutterStagePrivate *priv = stage->priv;
g_queue_foreach (priv->event_queue, (GFunc)clutter_event_free, NULL);
g_queue_foreach (priv->event_queue, (GFunc) clutter_event_free, NULL);
g_queue_free (priv->event_queue);
g_free (priv->title);