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;
|
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
|
* Emits a pointer event after having prepared the event for delivery (setting
|
||||||
* source, generating enter/leave etc.).
|
* source, generating enter/leave etc.).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
emit_event (ClutterActor *target,
|
emit_event (ClutterEvent *event)
|
||||||
ClutterEvent *event)
|
|
||||||
{
|
{
|
||||||
if (event->type == CLUTTER_KEY_PRESS ||
|
if (event->type == CLUTTER_KEY_PRESS ||
|
||||||
event->type == CLUTTER_KEY_RELEASE)
|
event->type == CLUTTER_KEY_RELEASE)
|
||||||
cally_snoop_key_event ((ClutterKeyEvent *) event);
|
cally_snoop_key_event ((ClutterKeyEvent *) event);
|
||||||
|
|
||||||
emit_event_chain (target, event);
|
clutter_stage_emit_event (event->any.stage, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ClutterActor *
|
static ClutterActor *
|
||||||
@ -836,10 +826,6 @@ _clutter_process_event_details (ClutterActor *stage,
|
|||||||
ClutterMainContext *context,
|
ClutterMainContext *context,
|
||||||
ClutterEvent *event)
|
ClutterEvent *event)
|
||||||
{
|
{
|
||||||
ClutterInputDevice *device = clutter_event_get_device (event);
|
|
||||||
ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
|
|
||||||
ClutterActor *target;
|
|
||||||
|
|
||||||
switch (event->type)
|
switch (event->type)
|
||||||
{
|
{
|
||||||
case CLUTTER_NOTHING:
|
case CLUTTER_NOTHING:
|
||||||
@ -854,32 +840,8 @@ _clutter_process_event_details (ClutterActor *stage,
|
|||||||
case CLUTTER_IM_COMMIT:
|
case CLUTTER_IM_COMMIT:
|
||||||
case CLUTTER_IM_DELETE:
|
case CLUTTER_IM_DELETE:
|
||||||
case CLUTTER_IM_PREEDIT:
|
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:
|
case CLUTTER_ENTER:
|
||||||
target = clutter_stage_get_device_actor (CLUTTER_STAGE (stage),
|
|
||||||
device, sequence);
|
|
||||||
emit_event (target, event);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CLUTTER_LEAVE:
|
case CLUTTER_LEAVE:
|
||||||
target = clutter_stage_get_device_actor (CLUTTER_STAGE (stage),
|
|
||||||
device, sequence);
|
|
||||||
emit_event (target, event);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CLUTTER_MOTION:
|
case CLUTTER_MOTION:
|
||||||
case CLUTTER_BUTTON_PRESS:
|
case CLUTTER_BUTTON_PRESS:
|
||||||
case CLUTTER_BUTTON_RELEASE:
|
case CLUTTER_BUTTON_RELEASE:
|
||||||
@ -887,48 +849,13 @@ _clutter_process_event_details (ClutterActor *stage,
|
|||||||
case CLUTTER_TOUCHPAD_PINCH:
|
case CLUTTER_TOUCHPAD_PINCH:
|
||||||
case CLUTTER_TOUCHPAD_SWIPE:
|
case CLUTTER_TOUCHPAD_SWIPE:
|
||||||
case CLUTTER_TOUCHPAD_HOLD:
|
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_UPDATE:
|
||||||
case CLUTTER_TOUCH_BEGIN:
|
case CLUTTER_TOUCH_BEGIN:
|
||||||
case CLUTTER_TOUCH_CANCEL:
|
case CLUTTER_TOUCH_CANCEL:
|
||||||
case CLUTTER_TOUCH_END:
|
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_IN:
|
||||||
case CLUTTER_PROXIMITY_OUT:
|
case CLUTTER_PROXIMITY_OUT:
|
||||||
if (!clutter_actor_event (stage, event, TRUE))
|
emit_event (event);
|
||||||
{
|
|
||||||
/* and bubbling phase */
|
|
||||||
clutter_actor_event (stage, event, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLUTTER_DEVICE_REMOVED:
|
case CLUTTER_DEVICE_REMOVED:
|
||||||
|
@ -168,6 +168,9 @@ void clutter_stage_invalidate_focus (ClutterStage *self,
|
|||||||
void clutter_stage_maybe_invalidate_focus (ClutterStage *self,
|
void clutter_stage_maybe_invalidate_focus (ClutterStage *self,
|
||||||
ClutterActor *actor);
|
ClutterActor *actor);
|
||||||
|
|
||||||
|
void clutter_stage_emit_event (ClutterStage *self,
|
||||||
|
const ClutterEvent *event);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __CLUTTER_STAGE_PRIVATE_H__ */
|
#endif /* __CLUTTER_STAGE_PRIVATE_H__ */
|
||||||
|
@ -3413,6 +3413,15 @@ create_crossing_event (ClutterStage *stage,
|
|||||||
return event;
|
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
|
void
|
||||||
clutter_stage_update_device (ClutterStage *stage,
|
clutter_stage_update_device (ClutterStage *stage,
|
||||||
ClutterInputDevice *device,
|
ClutterInputDevice *device,
|
||||||
@ -3483,7 +3492,12 @@ clutter_stage_update_device (ClutterStage *stage,
|
|||||||
old_actor, new_actor,
|
old_actor, new_actor,
|
||||||
point, time_ms);
|
point, time_ms);
|
||||||
if (!_clutter_event_process_filters (event, old_actor))
|
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);
|
clutter_event_free (event);
|
||||||
}
|
}
|
||||||
@ -3497,7 +3511,12 @@ clutter_stage_update_device (ClutterStage *stage,
|
|||||||
new_actor, old_actor,
|
new_actor, old_actor,
|
||||||
point, time_ms);
|
point, time_ms);
|
||||||
if (!_clutter_event_process_filters (event, new_actor))
|
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);
|
clutter_event_free (event);
|
||||||
}
|
}
|
||||||
@ -3681,7 +3700,13 @@ clutter_stage_notify_grab_on_pointer_entry (ClutterStage *stage,
|
|||||||
entry->coords,
|
entry->coords,
|
||||||
CLUTTER_CURRENT_TIME);
|
CLUTTER_CURRENT_TIME);
|
||||||
if (!_clutter_event_process_filters (event, entry->current_actor))
|
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);
|
clutter_event_free (event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3994,3 +4019,88 @@ clutter_stage_get_event_actor (ClutterStage *stage,
|
|||||||
|
|
||||||
return NULL;
|
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