From 0f0466fa8e8e0acd85138b9dbd1af3d177547a21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Mon, 4 Apr 2022 00:07:44 +0200 Subject: [PATCH] clutter: Make the stage the central instance emitting events Right now and due to loads of refactorings lately, the event emission paths are a bit cluttered (ha ha ha) around in Clutter. For example the event target actor gets set in clutter-main.c, but event emission is actually managed by ClutterStage these days. Since we'll introduce implicit grabbing of touch/button-press sequences soon, let's shuffle things around a bit to make that easier: Move event emission to the stage, it now gets a ClutterEvent without any extra context like the target actor from clutter-main. The stage then looks up the target actor itself and emits the event to the appropriate actors in the scenegraph. A special path is introduced for emitting crossing events, because here the event-receiving actors don't follow the "capture+bubble from pointer actor to grab actor" rule. Part-of: --- clutter/clutter/clutter-main.c | 79 +--------------- clutter/clutter/clutter-stage-private.h | 3 + clutter/clutter/clutter-stage.c | 116 +++++++++++++++++++++++- 3 files changed, 119 insertions(+), 79 deletions(-) diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c index 03658a6c6..b5924648a 100644 --- a/clutter/clutter/clutter-main.c +++ b/clutter/clutter/clutter-main.c @@ -674,29 +674,19 @@ _clutter_boolean_continue_accumulator (GSignalInvocationHint *ihint, return continue_emission; } -static inline void -emit_event_chain (ClutterActor *target, - ClutterEvent *event) -{ - _clutter_actor_handle_event (target, - clutter_stage_get_grab_actor (event->any.stage), - event); -} - /* * Emits a pointer event after having prepared the event for delivery (setting * source, generating enter/leave etc.). */ static inline void -emit_event (ClutterActor *target, - ClutterEvent *event) +emit_event (ClutterEvent *event) { if (event->type == CLUTTER_KEY_PRESS || event->type == CLUTTER_KEY_RELEASE) cally_snoop_key_event ((ClutterKeyEvent *) event); - emit_event_chain (target, event); + clutter_stage_emit_event (event->any.stage, event); } static ClutterActor * @@ -836,10 +826,6 @@ _clutter_process_event_details (ClutterActor *stage, ClutterMainContext *context, ClutterEvent *event) { - ClutterInputDevice *device = clutter_event_get_device (event); - ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); - ClutterActor *target; - switch (event->type) { case CLUTTER_NOTHING: @@ -854,32 +840,8 @@ _clutter_process_event_details (ClutterActor *stage, case CLUTTER_IM_COMMIT: case CLUTTER_IM_DELETE: case CLUTTER_IM_PREEDIT: - { - ClutterActor *actor = NULL; - - actor = clutter_stage_get_key_focus (CLUTTER_STAGE (stage)); - if (G_UNLIKELY (actor == NULL)) - { - g_warning ("No key focus set, discarding"); - return; - } - - emit_event (actor, event); - } - break; - case CLUTTER_ENTER: - target = clutter_stage_get_device_actor (CLUTTER_STAGE (stage), - device, sequence); - emit_event (target, event); - break; - case CLUTTER_LEAVE: - target = clutter_stage_get_device_actor (CLUTTER_STAGE (stage), - device, sequence); - emit_event (target, event); - break; - case CLUTTER_MOTION: case CLUTTER_BUTTON_PRESS: case CLUTTER_BUTTON_RELEASE: @@ -887,48 +849,13 @@ _clutter_process_event_details (ClutterActor *stage, case CLUTTER_TOUCHPAD_PINCH: case CLUTTER_TOUCHPAD_SWIPE: case CLUTTER_TOUCHPAD_HOLD: - { - gfloat x, y; - - target = clutter_stage_get_device_actor (CLUTTER_STAGE (stage), - device, sequence); - clutter_event_get_coords (event, &x, &y); - - CLUTTER_NOTE (EVENT, - "Reactive event received at %.2f, %.2f - actor: %p", - x, y, target); - - emit_event (target, event); - break; - } - case CLUTTER_TOUCH_UPDATE: case CLUTTER_TOUCH_BEGIN: case CLUTTER_TOUCH_CANCEL: case CLUTTER_TOUCH_END: - { - gfloat x, y; - - target = clutter_stage_get_device_actor (CLUTTER_STAGE (stage), - device, sequence); - clutter_event_get_coords (event, &x, &y); - - CLUTTER_NOTE (EVENT, - "Reactive event received at %.2f, %.2f - actor: %p", - x, y, target); - - emit_event (target, event); - break; - } - case CLUTTER_PROXIMITY_IN: case CLUTTER_PROXIMITY_OUT: - if (!clutter_actor_event (stage, event, TRUE)) - { - /* and bubbling phase */ - clutter_actor_event (stage, event, FALSE); - } - + emit_event (event); break; case CLUTTER_DEVICE_REMOVED: diff --git a/clutter/clutter/clutter-stage-private.h b/clutter/clutter/clutter-stage-private.h index f297ac05a..309861612 100644 --- a/clutter/clutter/clutter-stage-private.h +++ b/clutter/clutter/clutter-stage-private.h @@ -168,6 +168,9 @@ void clutter_stage_invalidate_focus (ClutterStage *self, void clutter_stage_maybe_invalidate_focus (ClutterStage *self, ClutterActor *actor); +void clutter_stage_emit_event (ClutterStage *self, + const ClutterEvent *event); + G_END_DECLS #endif /* __CLUTTER_STAGE_PRIVATE_H__ */ diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index 548faf8b1..0b2ada5b6 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -3413,6 +3413,15 @@ create_crossing_event (ClutterStage *stage, return event; } +static void +clutter_stage_emit_crossing_event (ClutterStage *self, + const ClutterEvent *event, + ClutterActor *deepmost, + ClutterActor *topmost) +{ + _clutter_actor_handle_event (deepmost, topmost, event); +} + void clutter_stage_update_device (ClutterStage *stage, ClutterInputDevice *device, @@ -3483,7 +3492,12 @@ clutter_stage_update_device (ClutterStage *stage, old_actor, new_actor, point, time_ms); if (!_clutter_event_process_filters (event, old_actor)) - _clutter_actor_handle_event (old_actor, root, event); + { + clutter_stage_emit_crossing_event (stage, + event, + old_actor, + root); + } clutter_event_free (event); } @@ -3497,7 +3511,12 @@ clutter_stage_update_device (ClutterStage *stage, new_actor, old_actor, point, time_ms); if (!_clutter_event_process_filters (event, new_actor)) - _clutter_actor_handle_event (new_actor, root, event); + { + clutter_stage_emit_crossing_event (stage, + event, + new_actor, + root); + } clutter_event_free (event); } @@ -3681,7 +3700,13 @@ clutter_stage_notify_grab_on_pointer_entry (ClutterStage *stage, entry->coords, CLUTTER_CURRENT_TIME); if (!_clutter_event_process_filters (event, entry->current_actor)) - _clutter_actor_handle_event (deepmost, topmost, event); + { + clutter_stage_emit_crossing_event (stage, + event, + deepmost, + topmost); + } + clutter_event_free (event); } } @@ -3994,3 +4019,88 @@ clutter_stage_get_event_actor (ClutterStage *stage, return NULL; } + +void +clutter_stage_emit_event (ClutterStage *self, + const ClutterEvent *event) +{ + ClutterStagePrivate *priv = self->priv; + ClutterInputDevice *device = clutter_event_get_device (event); + ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); + PointerDeviceEntry *entry; + ClutterActor *target_actor = NULL; + + if (sequence != NULL) + entry = g_hash_table_lookup (priv->touch_sequences, sequence); + else + entry = g_hash_table_lookup (priv->pointer_devices, device); + + switch (event->type) + { + case CLUTTER_NOTHING: + case CLUTTER_DEVICE_REMOVED: + case CLUTTER_DEVICE_ADDED: + case CLUTTER_EVENT_LAST: + return; + + case CLUTTER_KEY_PRESS: + case CLUTTER_KEY_RELEASE: + case CLUTTER_PAD_BUTTON_PRESS: + case CLUTTER_PAD_BUTTON_RELEASE: + case CLUTTER_PAD_STRIP: + case CLUTTER_PAD_RING: + case CLUTTER_IM_COMMIT: + case CLUTTER_IM_DELETE: + case CLUTTER_IM_PREEDIT: + { + target_actor = priv->key_focused_actor ? + priv->key_focused_actor : CLUTTER_ACTOR (self); + break; + } + + /* x11 stage enter/leave events */ + case CLUTTER_ENTER: + case CLUTTER_LEAVE: + { + target_actor = entry->current_actor; + break; + } + + case CLUTTER_MOTION: + case CLUTTER_BUTTON_PRESS: + case CLUTTER_BUTTON_RELEASE: + case CLUTTER_SCROLL: + case CLUTTER_TOUCHPAD_PINCH: + case CLUTTER_TOUCHPAD_SWIPE: + case CLUTTER_TOUCHPAD_HOLD: + case CLUTTER_TOUCH_UPDATE: + case CLUTTER_TOUCH_BEGIN: + case CLUTTER_TOUCH_CANCEL: + case CLUTTER_TOUCH_END: + { + float x, y; + + clutter_event_get_coords (event, &x, &y); + + CLUTTER_NOTE (EVENT, + "Reactive event received at %.2f, %.2f - actor: %p", + x, y, entry->current_actor); + + target_actor = entry->current_actor; + break; + } + + case CLUTTER_PROXIMITY_IN: + case CLUTTER_PROXIMITY_OUT: + { + target_actor = CLUTTER_ACTOR (self); + break; + } + } + + g_assert (target_actor != NULL); + + _clutter_actor_handle_event (target_actor, + clutter_stage_get_grab_actor (self), + event); +}