diff options
author | Jonas Dreßler <verdre@v0yd.nl> | 2020-10-15 16:53:44 +0200 |
---|---|---|
committer | Jonas Dreßler <verdre@v0yd.nl> | 2020-10-15 16:58:50 +0200 |
commit | e38cebc90218da4e68ef329a6551a32c886fa6f3 (patch) | |
tree | 3d8793ea248bdfa1d405ccb6e4df8b14cb89dc0e | |
parent | 387bb20b6e516b8d2abb4029bbd723f2ebe4dace (diff) | |
download | mutter-wip/verdre/device-actors-stage.tar.gz |
clutter: Switch to storing device->actor associations in ClutterStagewip/verdre/device-actors-stage
As planned and prepared with the last commits, now let ClutterStage take
care of tracking inputdevices and their actors and the remove the old
infrastructure from ClutterInputDevice.
-rw-r--r-- | clutter/clutter/clutter-input-device-private.h | 9 | ||||
-rw-r--r-- | clutter/clutter/clutter-input-device.c | 355 | ||||
-rw-r--r-- | clutter/clutter/clutter-input-device.h | 3 | ||||
-rw-r--r-- | clutter/clutter/clutter-main.c | 48 | ||||
-rw-r--r-- | clutter/clutter/clutter-stage.c | 13 | ||||
-rw-r--r-- | src/core/window.c | 4 | ||||
-rw-r--r-- | src/wayland/meta-wayland-pointer.c | 20 |
7 files changed, 67 insertions, 385 deletions
diff --git a/clutter/clutter/clutter-input-device-private.h b/clutter/clutter/clutter-input-device-private.h index a085947e0..d4527a7c3 100644 --- a/clutter/clutter/clutter-input-device-private.h +++ b/clutter/clutter/clutter-input-device-private.h @@ -162,15 +162,6 @@ CLUTTER_EXPORT void clutter_input_device_update_from_tool (ClutterInputDevice *device, ClutterInputDeviceTool *tool); CLUTTER_EXPORT -ClutterActor * clutter_input_device_update (ClutterInputDevice *device, - ClutterEventSequence *sequence, - ClutterStage *stage, - gboolean emit_crossing, - ClutterEvent *for_event); -CLUTTER_EXPORT -void _clutter_input_device_remove_event_sequence (ClutterInputDevice *device, - ClutterEvent *event); -CLUTTER_EXPORT void _clutter_input_device_set_n_keys (ClutterInputDevice *device, guint n_keys); CLUTTER_EXPORT diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index 651ed4836..200e9bf50 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -75,12 +75,6 @@ enum PROP_LAST }; -static void on_cursor_actor_destroy (ClutterActor *actor, - ClutterInputDevice *device); -static void on_cursor_actor_reactive_changed (ClutterActor *actor, - GParamSpec *pspec, - ClutterInputDevice *device); - static GParamSpec *obj_props[PROP_LAST] = { NULL, }; G_DEFINE_TYPE (ClutterInputDevice, clutter_input_device, G_TYPE_OBJECT); @@ -111,41 +105,6 @@ clutter_input_device_dispose (GObject *gobject) g_clear_pointer (&device->axes, g_array_unref); g_clear_pointer (&device->keys, g_array_unref); g_clear_pointer (&device->scroll_info, g_array_unref); - g_clear_pointer (&device->touch_sequence_actors, g_hash_table_unref); - - if (device->cursor_actor) - { - g_signal_handlers_disconnect_by_func (device->cursor_actor, - G_CALLBACK (on_cursor_actor_destroy), - device); - g_signal_handlers_disconnect_by_func (device->cursor_actor, - G_CALLBACK (on_cursor_actor_reactive_changed), - device); - _clutter_actor_set_has_pointer (device->cursor_actor, FALSE); - device->cursor_actor = NULL; - } - - if (device->inv_touch_sequence_actors) - { - GHashTableIter iter; - gpointer key, value; - - g_hash_table_iter_init (&iter, device->inv_touch_sequence_actors); - while (g_hash_table_iter_next (&iter, &key, &value)) - { - g_signal_handlers_disconnect_by_func (key, - G_CALLBACK (on_cursor_actor_destroy), - device); - g_signal_handlers_disconnect_by_func (device->cursor_actor, - G_CALLBACK (on_cursor_actor_reactive_changed), - device); - _clutter_actor_set_has_pointer (key, FALSE); - g_list_free (value); - } - - g_hash_table_unref (device->inv_touch_sequence_actors); - device->inv_touch_sequence_actors = NULL; - } G_OBJECT_CLASS (clutter_input_device_parent_class)->dispose (gobject); } @@ -486,9 +445,6 @@ clutter_input_device_init (ClutterInputDevice *self) self->previous_x = -1; self->previous_y = -1; self->current_button_number = self->previous_button_number = -1; - - self->touch_sequence_actors = g_hash_table_new (NULL, NULL); - self->inv_touch_sequence_actors = g_hash_table_new (NULL, NULL); } /** @@ -518,188 +474,6 @@ clutter_input_device_get_modifier_state (ClutterInputDevice *device) return modifiers; } -static void -_clutter_input_device_associate_actor (ClutterInputDevice *device, - ClutterEventSequence *sequence, - ClutterActor *actor) -{ - if (sequence == NULL) - device->cursor_actor = actor; - else - { - GList *sequences = - g_hash_table_lookup (device->inv_touch_sequence_actors, actor); - - g_hash_table_insert (device->touch_sequence_actors, sequence, actor); - g_hash_table_insert (device->inv_touch_sequence_actors, - actor, g_list_prepend (sequences, sequence)); - } - - g_signal_connect (actor, - "destroy", G_CALLBACK (on_cursor_actor_destroy), - device); - g_signal_connect (actor, - "notify::reactive", G_CALLBACK (on_cursor_actor_reactive_changed), - device); - _clutter_actor_set_has_pointer (actor, TRUE); -} - -static void -_clutter_input_device_unassociate_actor (ClutterInputDevice *device, - ClutterActor *actor, - gboolean destroyed) -{ - if (device->cursor_actor == actor) - device->cursor_actor = NULL; - else - { - GList *l, *sequences = - g_hash_table_lookup (device->inv_touch_sequence_actors, - actor); - - for (l = sequences; l != NULL; l = l->next) - g_hash_table_remove (device->touch_sequence_actors, l->data); - - g_list_free (sequences); - g_hash_table_remove (device->inv_touch_sequence_actors, actor); - } - - if (destroyed == FALSE) - { - g_signal_handlers_disconnect_by_func (actor, - G_CALLBACK (on_cursor_actor_destroy), - device); - g_signal_handlers_disconnect_by_func (actor, - G_CALLBACK (on_cursor_actor_reactive_changed), - device); - _clutter_actor_set_has_pointer (actor, FALSE); - } -} - -static void -on_cursor_actor_destroy (ClutterActor *actor, - ClutterInputDevice *device) -{ - _clutter_input_device_unassociate_actor (device, actor, TRUE); -} - -static void -on_cursor_actor_reactive_changed (ClutterActor *actor, - GParamSpec *pspec, - ClutterInputDevice *device) -{ - if (!clutter_actor_get_reactive (actor)) - _clutter_input_device_unassociate_actor (device, actor, FALSE); -} - -/*< private > - * clutter_input_device_set_actor: - * @device: a #ClutterInputDevice - * @actor: a #ClutterActor - * @emit_crossing: %TRUE to emit crossing events - * - * Sets the actor under the pointer coordinates of @device - * - * This function is called by clutter_input_device_update() - * and it will: - * - * - queue a %CLUTTER_LEAVE event on the previous pointer actor - * of @device, if any - * - set to %FALSE the :has-pointer property of the previous - * pointer actor of @device, if any - * - queue a %CLUTTER_ENTER event on the new pointer actor - * - set to %TRUE the :has-pointer property of the new pointer - * actor - */ -static void -_clutter_input_device_set_actor (ClutterInputDevice *device, - ClutterEventSequence *sequence, - ClutterActor *actor, - gboolean emit_crossing, - graphene_point_t coords, - uint32_t time_) -{ - ClutterActor *old_actor = clutter_input_device_get_actor (device, sequence); - ClutterStage *stage = NULL; - - if (old_actor == actor) - return; - - if (emit_crossing) - { - if (actor) - stage = CLUTTER_STAGE (clutter_actor_get_stage (actor)); - else if (old_actor) - stage = CLUTTER_STAGE (clutter_actor_get_stage (old_actor)); - - if (!stage) - return; - } - - if (old_actor != NULL) - { - ClutterActor *tmp_old_actor; - - if (emit_crossing) - { - ClutterEvent *event; - - event = clutter_event_new (CLUTTER_LEAVE); - event->crossing.time = time_; - event->crossing.flags = 0; - event->crossing.stage = stage; - event->crossing.source = old_actor; - event->crossing.x = coords.x; - event->crossing.y = coords.y; - event->crossing.related = actor; - event->crossing.sequence = sequence; - clutter_event_set_device (event, device); - - /* we need to make sure that this event is processed - * before any other event we might have queued up until - * now, so we go on, and synthesize the event emission - * ourselves - */ - _clutter_process_event (event); - - clutter_event_free (event); - } - - /* processing the event might have destroyed the actor */ - tmp_old_actor = clutter_input_device_get_actor (device, sequence); - _clutter_input_device_unassociate_actor (device, - old_actor, - tmp_old_actor == NULL); - old_actor = tmp_old_actor; - } - - if (actor != NULL) - { - _clutter_input_device_associate_actor (device, sequence, actor); - - if (emit_crossing) - { - ClutterEvent *event; - - event = clutter_event_new (CLUTTER_ENTER); - event->crossing.time = time_; - event->crossing.flags = 0; - event->crossing.stage = stage; - event->crossing.x = coords.x; - event->crossing.y = coords.y; - event->crossing.source = actor; - event->crossing.related = old_actor; - event->crossing.sequence = sequence; - clutter_event_set_device (event, device); - - /* see above */ - _clutter_process_event (event); - - clutter_event_free (event); - } - } -} - /** * clutter_input_device_get_device_type: * @device: a #ClutterInputDevice @@ -768,102 +542,6 @@ clutter_input_device_get_coords (ClutterInputDevice *device, return clutter_seat_query_state (seat, device, sequence, point, NULL); } -/* - * clutter_input_device_update: - * @device: a #ClutterInputDevice - * - * Updates the input @device by determining the #ClutterActor underneath the - * pointer's cursor - * - * This function calls _clutter_input_device_set_actor() if needed. - * - * This function only works for #ClutterInputDevice of type - * %CLUTTER_POINTER_DEVICE. - * - * Since: 1.2 - */ -ClutterActor * -clutter_input_device_update (ClutterInputDevice *device, - ClutterEventSequence *sequence, - ClutterStage *stage, - gboolean emit_crossing, - ClutterEvent *for_event) -{ - ClutterActor *new_cursor_actor; - ClutterActor *old_cursor_actor; - graphene_point_t point = GRAPHENE_POINT_INIT (-1.0f, -1.0f); - ClutterInputDeviceType device_type = device->device_type; - uint32_t time_; - - g_assert (device_type != CLUTTER_KEYBOARD_DEVICE && - device_type != CLUTTER_PAD_DEVICE); - - if (for_event) - { - clutter_event_get_coords (for_event, &point.x, &point.y); - time_ = clutter_event_get_time (for_event); - } - else - { - clutter_input_device_get_coords (device, sequence, &point); - time_ = CLUTTER_CURRENT_TIME; - } - - old_cursor_actor = clutter_input_device_get_actor (device, sequence); - new_cursor_actor = - _clutter_stage_do_pick (stage, point.x, point.y, CLUTTER_PICK_REACTIVE); - - /* if the pick could not find an actor then we do not update the - * input device, to avoid ghost enter/leave events; the pick should - * never fail, except for bugs in the glReadPixels() implementation - * in which case this is the safest course of action anyway - */ - if (new_cursor_actor == NULL) - return NULL; - - CLUTTER_NOTE (EVENT, - "Actor under cursor (device %d, at %.2f, %.2f): %s", - clutter_input_device_get_device_id (device), - point.x, - point.y, - _clutter_actor_get_debug_name (new_cursor_actor)); - - /* short-circuit here */ - if (new_cursor_actor == old_cursor_actor) - return old_cursor_actor; - - _clutter_input_device_set_actor (device, sequence, - new_cursor_actor, - emit_crossing, - point, time_); - - return new_cursor_actor; -} - -/** - * clutter_input_device_get_actor: - * @device: a #ClutterInputDevice - * @sequence: (allow-none): an optional #ClutterEventSequence - * - * Retrieves the #ClutterActor underneath the pointer or touchpoint - * of @device and @sequence. - * - * Return value: (transfer none): a pointer to the #ClutterActor or %NULL - * - * Since: 1.2 - */ -ClutterActor * -clutter_input_device_get_actor (ClutterInputDevice *device, - ClutterEventSequence *sequence) -{ - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); - - if (sequence == NULL) - return device->cursor_actor; - - return g_hash_table_lookup (device->touch_sequence_actors, sequence); -} - /** * clutter_input_device_get_device_name: * @device: a #ClutterInputDevice @@ -1302,39 +980,6 @@ _clutter_input_device_remove_physical_device (ClutterInputDevice *logical, logical->physical_devices = g_list_remove (logical->physical_devices, physical); } -/*< private > - * clutter_input_device_remove_sequence: - * @device: a #ClutterInputDevice - * @sequence: a #ClutterEventSequence - * - * Stop tracking information related to a touch point. - */ -void -_clutter_input_device_remove_event_sequence (ClutterInputDevice *device, - ClutterEvent *event) -{ - ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); - ClutterActor *actor = - g_hash_table_lookup (device->touch_sequence_actors, sequence); - - if (actor != NULL) - { - GList *sequences = - g_hash_table_lookup (device->inv_touch_sequence_actors, actor); - graphene_point_t point; - - sequences = g_list_remove (sequences, sequence); - - g_hash_table_replace (device->inv_touch_sequence_actors, - actor, sequences); - clutter_event_get_coords (event, &point.x, &point.y); - _clutter_input_device_set_actor (device, sequence, NULL, TRUE, point, - clutter_event_get_time (event)); - } - - g_hash_table_remove (device->touch_sequence_actors, sequence); -} - /** * clutter_input_device_get_physical_devices: * @device: a #ClutterInputDevice diff --git a/clutter/clutter/clutter-input-device.h b/clutter/clutter/clutter-input-device.h index d849d7f8f..a361da434 100644 --- a/clutter/clutter/clutter-input-device.h +++ b/clutter/clutter/clutter-input-device.h @@ -92,9 +92,6 @@ gboolean clutter_input_device_get_coords (ClutterInputDevi CLUTTER_EXPORT ClutterModifierType clutter_input_device_get_modifier_state (ClutterInputDevice *device); CLUTTER_EXPORT -ClutterActor * clutter_input_device_get_actor (ClutterInputDevice *device, - ClutterEventSequence *sequence); -CLUTTER_EXPORT const gchar * clutter_input_device_get_device_name (ClutterInputDevice *device); CLUTTER_EXPORT ClutterInputMode clutter_input_device_get_device_mode (ClutterInputDevice *device); diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c index bbd368718..e2f849080 100644 --- a/clutter/clutter/clutter-main.c +++ b/clutter/clutter/clutter-main.c @@ -1743,9 +1743,8 @@ _clutter_process_event_details (ClutterActor *stage, emit_crossing_event (event, device); - actor = clutter_input_device_update (device, NULL, - CLUTTER_STAGE (stage), FALSE, - event); + actor = repick_device_actor_for_event (CLUTTER_STAGE (stage), + event, FALSE); if (actor != stage) { ClutterEvent *crossing; @@ -1771,13 +1770,14 @@ _clutter_process_event_details (ClutterActor *stage, */ if (event->any.source == stage && event->crossing.related == NULL && - device->cursor_actor != stage) + clutter_stage_get_device_actor (CLUTTER_STAGE (stage), device, NULL) != stage) { ClutterEvent *crossing; crossing = clutter_event_copy (event); crossing->crossing.related = stage; - crossing->crossing.source = device->cursor_actor; + crossing->crossing.source = + clutter_stage_get_device_actor (CLUTTER_STAGE (stage), device, NULL); emit_crossing_event (crossing, device); clutter_event_free (crossing); @@ -1894,9 +1894,8 @@ _clutter_process_event_details (ClutterActor *stage, break; } - actor = clutter_input_device_update (device, NULL, - CLUTTER_STAGE (stage), - TRUE, event); + actor = repick_device_actor_for_event (CLUTTER_STAGE (stage), + event, TRUE); if (actor == NULL) break; @@ -1996,14 +1995,25 @@ _clutter_process_event_details (ClutterActor *stage, if (event->type == CLUTTER_TOUCH_END || event->type == CLUTTER_TOUCH_CANCEL) - _clutter_input_device_remove_event_sequence (device, event); + { + graphene_point_t point; + uint32_t time; + + clutter_event_get_coords (event, &point.x, &point.y); + time = clutter_event_get_time (event); + + clutter_update_device_actor (CLUTTER_STAGE (stage), + device, sequence, + NULL, + point, time, + TRUE); + } break; } - actor = clutter_input_device_update (device, sequence, - CLUTTER_STAGE (stage), - TRUE, event); + actor = repick_device_actor_for_event (CLUTTER_STAGE (stage), + event, TRUE); if (actor == NULL) break; @@ -2024,7 +2034,19 @@ _clutter_process_event_details (ClutterActor *stage, if (event->type == CLUTTER_TOUCH_END || event->type == CLUTTER_TOUCH_CANCEL) - _clutter_input_device_remove_event_sequence (device, event); + { + graphene_point_t point; + uint32_t time; + + clutter_event_get_coords (event, &point.x, &point.y); + time = clutter_event_get_time (event); + + clutter_update_device_actor (CLUTTER_STAGE (stage), + device, sequence, + NULL, + point, time, + TRUE); + } break; } diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index 9ee0dfdb6..509d52504 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -1349,7 +1349,18 @@ clutter_stage_update_devices (ClutterStage *stage, for (l = devices; l; l = l->next) { ClutterInputDevice *device = l->data; - clutter_input_device_update (device, NULL, stage, TRUE, NULL); + graphene_point_t point; + ClutterActor *new_actor; + + clutter_input_device_get_coords (device, NULL, &point); + new_actor = + _clutter_stage_do_pick (stage, point.x, point.y, CLUTTER_PICK_REACTIVE); + + clutter_update_device_actor (stage, + device, NULL, + new_actor, + point, CLUTTER_CURRENT_TIME, + TRUE); } } diff --git a/src/core/window.c b/src/core/window.c index dd4882081..914856bba 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -8133,11 +8133,13 @@ window_has_pointer_wayland (MetaWindow *window) { ClutterSeat *seat; ClutterInputDevice *dev; + ClutterStage *stage; ClutterActor *pointer_actor, *window_actor; seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); dev = clutter_seat_get_pointer (seat); - pointer_actor = clutter_input_device_get_actor (dev, NULL); + stage = CLUTTER_STAGE (meta_backend_get_stage (meta_get_backend ())); + pointer_actor = clutter_stage_get_device_actor (stage, dev, NULL); window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window)); return pointer_actor && clutter_actor_contains (window_actor, pointer_actor); diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index c71a5eee1..8fb2c8449 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -615,13 +615,15 @@ static void repick_for_event (MetaWaylandPointer *pointer, const ClutterEvent *for_event) { + MetaBackend *backend = meta_get_backend (); + ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); ClutterActor *actor; MetaWaylandSurface *surface; if (for_event) actor = clutter_event_get_source (for_event); else - actor = clutter_input_device_get_actor (pointer->device, NULL); + actor = clutter_stage_get_device_actor (stage, pointer->device, NULL); if (META_IS_SURFACE_ACTOR_WAYLAND (actor)) { @@ -1047,8 +1049,20 @@ meta_wayland_pointer_repick (MetaWaylandPointer *pointer) MetaBackend *backend = meta_get_backend (); ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); - clutter_input_device_update (pointer->device, NULL, stage, FALSE, - CLUTTER_CURRENT_TIME); + graphene_point_t point; + ClutterActor *new_actor; + + clutter_input_device_get_coords (pointer->device, NULL, &point); + new_actor = + clutter_stage_get_actor_at_pos (stage, CLUTTER_PICK_REACTIVE, + point.x, point.y); + + clutter_update_device_actor (stage, + pointer->device, NULL, + new_actor, + point, CLUTTER_CURRENT_TIME, + FALSE); + repick_for_event (pointer, NULL); } |