diff --git a/clutter/clutter/clutter-input-device-private.h b/clutter/clutter/clutter-input-device-private.h index 672f3cf79..a2168cc07 100644 --- a/clutter/clutter/clutter-input-device-private.h +++ b/clutter/clutter/clutter-input-device-private.h @@ -53,10 +53,6 @@ struct _ClutterInputDevice { GObject parent_instance; - /* the actor underneath the pointer */ - ClutterActor *cursor_actor; - GHashTable *inv_touch_sequence_actors; - /* the actor that has a grab in place for the device */ ClutterActor *pointer_grab_actor; ClutterActor *keyboard_grab_actor; @@ -67,9 +63,6 @@ struct _ClutterInputDevice int click_count; int current_button_number; - /* the current touch points targets */ - GHashTable *touch_sequence_actors; - /* the previous state, used for click count generation */ int previous_x; int previous_y; @@ -81,14 +74,4 @@ struct _ClutterInputDevice ClutterPtrA11yData *ptr_a11y_data; }; -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); - #endif /* CLUTTER_INPUT_DEVICE_PRIVATE_H */ diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index a6df00643..3a31cdc80 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -73,12 +73,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, }; typedef struct _ClutterInputDevicePrivate ClutterInputDevicePrivate; @@ -123,42 +117,6 @@ clutter_input_device_dispose (GObject *gobject) if (device->accessibility_virtual_device) g_clear_object (&device->accessibility_virtual_device); - 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); } @@ -476,180 +434,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); -} - -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, - ClutterStage *stage, - ClutterActor *actor, - gboolean emit_crossing, - graphene_point_t coords, - uint32_t time_ms) -{ - ClutterActor *old_actor = clutter_input_device_get_actor (device, sequence); - - if (old_actor == actor) - return; - - if (old_actor != NULL) - { - ClutterActor *tmp_old_actor; - - if (emit_crossing) - { - ClutterEvent *event; - - event = clutter_event_new (CLUTTER_LEAVE); - event->crossing.time = time_ms; - 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_ms; - 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); - } - } } /** @@ -674,106 +458,6 @@ clutter_input_device_get_device_type (ClutterInputDevice *device) return priv->device_type; } -/* - * 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); - ClutterInputDevicePrivate *priv = - clutter_input_device_get_instance_private (device); - ClutterInputDeviceType device_type = priv->device_type; - uint32_t time_ms; - - 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_ms = clutter_event_get_time (for_event); - } - else - { - clutter_seat_query_state (clutter_input_device_get_seat (device), - device, NULL, &point, NULL); - time_ms = 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 '%s', at %.2f, %.2f): %s", - clutter_input_device_get_device_name (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, - stage, - new_cursor_actor, - emit_crossing, - point, time_ms); - - 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 @@ -841,42 +525,6 @@ clutter_input_device_get_device_mode (ClutterInputDevice *device) return priv->device_mode; } -/*< 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; - - 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); - ClutterStage *stage = - CLUTTER_STAGE (clutter_actor_get_stage (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, stage, - NULL, TRUE, point, - clutter_event_get_time (event)); - g_hash_table_remove (device->touch_sequence_actors, sequence); - } -} - static void on_grab_actor_destroy (ClutterActor *actor, ClutterInputDevice *device) diff --git a/clutter/clutter/clutter-input-device.h b/clutter/clutter/clutter-input-device.h index 5e377cdcc..dff29496f 100644 --- a/clutter/clutter/clutter-input-device.h +++ b/clutter/clutter/clutter-input-device.h @@ -73,9 +73,6 @@ GType clutter_input_device_get_type (void) G_GNUC_CONST; CLUTTER_EXPORT ClutterInputDeviceType clutter_input_device_get_device_type (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 diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c index cd2e41c59..2b57079cc 100644 --- a/clutter/clutter/clutter-main.c +++ b/clutter/clutter/clutter-main.c @@ -1757,9 +1757,7 @@ _clutter_process_event_details (ClutterActor *stage, emit_crossing_event (event, device); - actor = clutter_input_device_update (device, NULL, - CLUTTER_STAGE (stage), FALSE, - event); + actor = update_device_for_event (CLUTTER_STAGE (stage), event, FALSE); if (actor != stage) { ClutterEvent *crossing; @@ -1785,13 +1783,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); @@ -1898,9 +1897,7 @@ _clutter_process_event_details (ClutterActor *stage, break; } - actor = clutter_input_device_update (device, NULL, - CLUTTER_STAGE (stage), - TRUE, event); + actor = update_device_for_event (CLUTTER_STAGE (stage), event, TRUE); if (actor == NULL) break; @@ -1970,12 +1967,8 @@ _clutter_process_event_details (ClutterActor *stage, case CLUTTER_TOUCH_END: { ClutterActor *actor; - ClutterEventSequence *sequence; gfloat x, y; - sequence = - clutter_event_get_event_sequence (event); - clutter_event_get_coords (event, &x, &y); /* Only do a pick to find the source if source is not already set @@ -2000,14 +1993,12 @@ _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); + remove_device_for_event (CLUTTER_STAGE (stage), event, TRUE); break; } - actor = clutter_input_device_update (device, sequence, - CLUTTER_STAGE (stage), - TRUE, event); + actor = update_device_for_event (CLUTTER_STAGE (stage), event, TRUE); if (actor == NULL) break; @@ -2028,7 +2019,7 @@ _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); + remove_device_for_event (CLUTTER_STAGE (stage), event, TRUE); break; } @@ -2047,10 +2038,26 @@ _clutter_process_event_details (ClutterActor *stage, break; case CLUTTER_DEVICE_ADDED: - case CLUTTER_DEVICE_REMOVED: _clutter_event_process_filters (event); break; + case CLUTTER_DEVICE_REMOVED: + { + ClutterInputDeviceType device_type; + + _clutter_event_process_filters (event); + + device_type = clutter_input_device_get_device_type (device); + if (device_type == CLUTTER_POINTER_DEVICE || + device_type == CLUTTER_TABLET_DEVICE || + device_type == CLUTTER_PEN_DEVICE || + device_type == CLUTTER_ERASER_DEVICE || + device_type == CLUTTER_CURSOR_DEVICE) + remove_device_for_event (CLUTTER_STAGE (stage), event, TRUE); + + break; + } + case CLUTTER_EVENT_LAST: break; } diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index 4222d76aa..748d21790 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -1005,6 +1005,7 @@ void clutter_stage_update_devices (ClutterStage *stage, GSList *devices) { + ClutterStagePrivate *priv = stage->priv; GSList *l; COGL_TRACE_BEGIN (ClutterStageUpdateDevices, "UpdateDevices"); @@ -1012,7 +1013,23 @@ 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); + PointerDeviceEntry *entry = NULL; + ClutterActor *new_actor; + + entry = g_hash_table_lookup (priv->pointer_devices, device); + g_assert (entry != NULL); + + new_actor = _clutter_stage_do_pick (stage, + entry->coords.x, + entry->coords.y, + CLUTTER_PICK_REACTIVE); + + clutter_stage_update_device (stage, + device, NULL, + entry->coords, + CLUTTER_CURRENT_TIME, + new_actor, + TRUE); } } @@ -3421,6 +3438,23 @@ on_device_actor_reactive_changed (ClutterActor *actor, GParamSpec *pspec, PointerDeviceEntry *entry) { + ClutterStage *self = entry->stage; + ClutterActor *new_device_actor; + + g_assert (!clutter_actor_get_reactive (actor)); + + new_device_actor = + _clutter_stage_do_pick (self, + entry->coords.x, + entry->coords.y, + CLUTTER_PICK_REACTIVE); + + clutter_stage_update_device (self, + entry->device, entry->sequence, + entry->coords, + CLUTTER_CURRENT_TIME, + new_device_actor, + TRUE); } static void diff --git a/src/core/window.c b/src/core/window.c index c43b83a25..07eb0cda2 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -8188,11 +8188,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 2a6bce4e7..0b563efcc 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -581,13 +581,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)) { @@ -1014,8 +1016,21 @@ 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_stage_get_device_coords (stage, pointer->device, NULL, &point); + new_actor = + clutter_stage_get_actor_at_pos (stage, CLUTTER_PICK_REACTIVE, + point.x, point.y); + + clutter_stage_update_device (stage, + pointer->device, NULL, + point, + CLUTTER_CURRENT_TIME, + new_actor, + FALSE); + repick_for_event (pointer, NULL); }