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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2342>
This commit is contained in:
parent
ccb49f75e4
commit
0f0466fa8e
@ -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:
|
||||
|
@ -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__ */
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user