[clutter/wip/action-handle-event: 3/6] actor: Move event chain emission into ClutterActor
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter/wip/action-handle-event: 3/6] actor: Move event chain emission into ClutterActor
- Date: Tue, 26 Jun 2012 16:16:10 +0000 (UTC)
commit d8e17389ce8025f7ef22c76678a55807ba444826
Author: Emmanuele Bassi <ebassi gnome org>
Date: Sun Jun 24 09:58:12 2012 +0100
actor: Move event chain emission into ClutterActor
By moving the function that builds the event emission chain we can avoid
a bunch of checks and function calls.
clutter/clutter-actor-private.h | 3 +
clutter/clutter-actor.c | 52 ++++++++++++++++++++++++
clutter/clutter-main.c | 85 +++++++++++++-------------------------
3 files changed, 84 insertions(+), 56 deletions(-)
---
diff --git a/clutter/clutter-actor-private.h b/clutter/clutter-actor-private.h
index 07e2960..866d6a0 100644
--- a/clutter/clutter-actor-private.h
+++ b/clutter/clutter-actor-private.h
@@ -298,6 +298,9 @@ void _clutter_actor_shader_post_paint (ClutterActor *actor);
ClutterActorAlign _clutter_actor_get_effective_x_align (ClutterActor *self);
+void _clutter_actor_handle_event (ClutterActor *actor,
+ const ClutterEvent *event);
+
G_END_DECLS
#endif /* __CLUTTER_ACTOR_PRIVATE_H__ */
diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c
index e0cfd23..12d5fda 100644
--- a/clutter/clutter-actor.c
+++ b/clutter/clutter-actor.c
@@ -18886,3 +18886,55 @@ clutter_actor_get_content_repeat (ClutterActor *self)
return self->priv->content_repeat;
}
+
+void
+_clutter_actor_handle_event (ClutterActor *self,
+ const ClutterEvent *event)
+{
+ GPtrArray *event_tree;
+ ClutterActor *iter;
+ gboolean is_key_event;
+ gint i = 0;
+
+ /* XXX - for historical reasons that are now lost in the mists of time,
+ * key events are delivered regardless of whether an actor is set as
+ * reactive; this should be changed for 2.0.
+ */
+ is_key_event = event->type == CLUTTER_KEY_PRESS ||
+ event->type == CLUTTER_KEY_RELEASE;
+
+ event_tree = g_ptr_array_sized_new (64);
+ g_ptr_array_set_free_func (event_tree, (GDestroyNotify) g_object_unref);
+
+ /* build the list of of emitters for the event */
+ iter = self;
+ while (iter != NULL)
+ {
+ ClutterActor *parent = iter->priv->parent;
+
+ if (CLUTTER_ACTOR_IS_REACTIVE (iter) || /* an actor must be reactive */
+ parent == NULL || /* unless it's the stage */
+ is_key_event) /* or this is a key event */
+ {
+ /* keep a reference on the actor, so that it remains valid
+ * for the duration of the signal emission
+ */
+ g_ptr_array_add (event_tree, g_object_ref (iter));
+ }
+
+ iter = parent;
+ }
+
+ /* Capture: from top-level downwards */
+ for (i = event_tree->len - 1; i >= 0; i--)
+ if (clutter_actor_event (g_ptr_array_index (event_tree, i), event, TRUE))
+ goto done;
+
+ /* Bubble: from source upwards */
+ for (i = 0; i < event_tree->len; i++)
+ if (clutter_actor_event (g_ptr_array_index (event_tree, i), event, FALSE))
+ goto done;
+
+done:
+ g_ptr_array_free (event_tree, TRUE);
+}
diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c
index 1e9e8a0..8ab0682 100644
--- a/clutter/clutter-main.c
+++ b/clutter/clutter-main.c
@@ -97,7 +97,7 @@
#include <glib/gi18n-lib.h>
#include <locale.h>
-#include "clutter-actor.h"
+#include "clutter-actor-private.h"
#include "clutter-backend-private.h"
#include "clutter-config.h"
#include "clutter-debug.h"
@@ -2217,14 +2217,9 @@ event_click_count_generate (ClutterEvent *event)
}
static inline void
-emit_event (ClutterEvent *event,
- gboolean is_key_event)
+emit_event_chain (ClutterEvent *event)
{
- static gboolean lock = FALSE;
-
- GPtrArray *event_tree = NULL;
- ClutterActor *actor;
- gint i = 0;
+ static gboolean lock = FALSE;
if (event->any.source == NULL)
{
@@ -2241,42 +2236,7 @@ emit_event (ClutterEvent *event,
lock = TRUE;
- event_tree = g_ptr_array_sized_new (64);
-
- actor = event->any.source;
-
- /* Build 'tree' of emitters for the event */
- while (actor)
- {
- ClutterActor *parent;
-
- parent = clutter_actor_get_parent (actor);
-
- if (clutter_actor_get_reactive (actor) ||
- parent == NULL || /* stage gets all events */
- is_key_event) /* keyboard events are always emitted */
- {
- g_ptr_array_add (event_tree, g_object_ref (actor));
- }
-
- actor = parent;
- }
-
- /* Capture */
- for (i = event_tree->len - 1; i >= 0; i--)
- if (clutter_actor_event (g_ptr_array_index (event_tree, i), event, TRUE))
- goto done;
-
- /* Bubble */
- for (i = 0; i < event_tree->len; i++)
- if (clutter_actor_event (g_ptr_array_index (event_tree, i), event, FALSE))
- goto done;
-
-done:
- for (i = 0; i < event_tree->len; i++)
- g_object_unref (g_ptr_array_index (event_tree, i));
-
- g_ptr_array_free (event_tree, TRUE);
+ _clutter_actor_handle_event (event->any.source, event);
lock = FALSE;
}
@@ -2296,7 +2256,7 @@ emit_pointer_event (ClutterEvent *event,
(device == NULL || device->pointer_grab_actor == NULL))
{
/* no grab, time to capture and bubble */
- emit_event (event, FALSE);
+ emit_event_chain (event);
}
else
{
@@ -2317,19 +2277,23 @@ static inline void
emit_touch_event (ClutterEvent *event,
ClutterInputDevice *device)
{
- ClutterActor *grab_actor;
+ ClutterActor *grab_actor = NULL;
- if ((device->sequence_grab_actors != NULL) &&
- ((grab_actor = g_hash_table_lookup (device->sequence_grab_actors,
- event->touch.sequence)) != NULL))
+ if (device->sequence_grab_actors != NULL)
{
- /* sequence grab */
+ grab_actor = g_hash_table_lookup (device->sequence_grab_actors,
+ event->touch.sequence);
+ }
+
+ if (grab_actor != NULL)
+ {
+ /* per-device sequence grab */
clutter_actor_event (grab_actor, event, FALSE);
}
else
{
/* no grab, time to capture and bubble */
- emit_event (event, FALSE);
+ emit_event_chain (event);
}
}
@@ -2342,16 +2306,19 @@ emit_keyboard_event (ClutterEvent *event,
if (context->keyboard_grab_actor == NULL &&
(device == NULL || device->keyboard_grab_actor == NULL))
{
- emit_event (event, TRUE);
+ /* no grab, time to capture and bubble */
+ emit_event_chain (event);
}
else
{
if (context->keyboard_grab_actor != NULL)
{
+ /* global key grab */
clutter_actor_event (context->keyboard_grab_actor, event, FALSE);
}
else if (device != NULL && device->keyboard_grab_actor != NULL)
{
+ /* per-device key grab */
clutter_actor_event (context->keyboard_grab_actor, event, FALSE);
}
}
@@ -2701,14 +2668,20 @@ _clutter_process_event (ClutterEvent *event)
stage = CLUTTER_ACTOR (event->any.stage);
if (stage == NULL)
- return;
-
- CLUTTER_NOTE (EVENT, "Event received");
+ {
+ CLUTTER_NOTE (EVENT, "Discarding event withou a stage set");
+ return;
+ }
+ /* keep a pointer to the event and time, 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;
+
_clutter_process_event_details (stage, context, event);
+
context->current_event = NULL;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]