From d6a0f7eb6132f23201856bcc9bd850622c2fb4d1 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Tue, 21 Aug 2012 15:26:30 +0100 Subject: [PATCH] input-device: don't reset a device's stage until all touch points are gone 803b3bafb617c2df703aa8b834ff0df2f0c5c26c introduced a new issue for multi touch events. In the case where 2 touch events for 2 different touch points are processed in the same iteration, a call to _clutter_stage_remove_device() when processing the first event will remove the stage setting of the InputDevice. That means Clutter will skip the second event, because it can't find a stage to which relate the event, so no related actor and so no emission. To fix this we move the _clutter_stage_(add/remove)_device() calls into the input device. This way the input device can find out exactly when to call these functions (i.e. when no touch point were previously active or when no touch point remain active). https://bugzilla.gnome.org/show_bug.cgi?id=682362 --- clutter/clutter-device-manager-private.h | 11 ++-- clutter/clutter-input-device.c | 76 ++++++++++++++---------- clutter/clutter-main.c | 10 +--- clutter/clutter-stage.c | 2 +- clutter/x11/clutter-device-manager-xi2.c | 6 -- 5 files changed, 52 insertions(+), 53 deletions(-) diff --git a/clutter/clutter-device-manager-private.h b/clutter/clutter-device-manager-private.h index f503d4e22..8bc5330d7 100644 --- a/clutter/clutter-device-manager-private.h +++ b/clutter/clutter-device-manager-private.h @@ -159,14 +159,15 @@ ClutterBackend *_clutter_device_manager_get_backend (ClutterDeviceMa /* input device */ gboolean _clutter_input_device_has_sequence (ClutterInputDevice *device, ClutterEventSequence *sequence); -void _clutter_input_device_add_sequence (ClutterInputDevice *device, - ClutterEventSequence *sequence); -void _clutter_input_device_remove_sequence (ClutterInputDevice *device, - ClutterEventSequence *sequence); +void _clutter_input_device_add_event_sequence (ClutterInputDevice *device, + ClutterEvent *event); +void _clutter_input_device_remove_event_sequence (ClutterInputDevice *device, + ClutterEvent *event); void _clutter_input_device_set_coords (ClutterInputDevice *device, ClutterEventSequence *sequence, gint x, - gint y); + gint y, + ClutterStage *stage); void _clutter_input_device_set_state (ClutterInputDevice *device, ClutterModifierType state); void _clutter_input_device_set_time (ClutterInputDevice *device, diff --git a/clutter/clutter-input-device.c b/clutter/clutter-input-device.c index 0917dad79..868c2f28d 100644 --- a/clutter/clutter-input-device.c +++ b/clutter/clutter-input-device.c @@ -394,6 +394,28 @@ clutter_input_device_init (ClutterInputDevice *self) self->inv_touch_sequence_actors = g_hash_table_new (NULL, NULL); } +static ClutterTouchInfo * +_clutter_input_device_ensure_touch_info (ClutterInputDevice *device, + ClutterEventSequence *sequence, + ClutterStage *stage) +{ + ClutterTouchInfo *info; + + info = g_hash_table_lookup (device->touch_sequences_info, sequence); + + if (info == NULL) + { + info = g_slice_new0 (ClutterTouchInfo); + info->sequence = sequence; + g_hash_table_insert (device->touch_sequences_info, sequence, info); + + if (g_hash_table_size (device->touch_sequences_info) == 1) + _clutter_input_device_set_stage (device, stage); + } + + return info; +} + /*< private > * clutter_input_device_set_coords: * @device: a #ClutterInputDevice @@ -407,7 +429,8 @@ void _clutter_input_device_set_coords (ClutterInputDevice *device, ClutterEventSequence *sequence, gint x, - gint y) + gint y, + ClutterStage *stage) { g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); @@ -421,16 +444,8 @@ _clutter_input_device_set_coords (ClutterInputDevice *device, } else { - ClutterTouchInfo *info = - g_hash_table_lookup (device->touch_sequences_info, sequence); - - if (info == NULL) - { - info = g_slice_new0 (ClutterTouchInfo); - info->sequence = sequence; - g_hash_table_insert (device->touch_sequences_info, sequence, info); - } - + ClutterTouchInfo *info; + info = _clutter_input_device_ensure_touch_info (device, sequence, stage); info->current_x = x; info->current_y = y; } @@ -538,18 +553,12 @@ _clutter_input_device_associate_actor (ClutterInputDevice *device, device->cursor_actor = actor; else { - ClutterTouchInfo *info = - g_hash_table_lookup (device->touch_sequences_info, sequence); GList *sequences = g_hash_table_lookup (device->inv_touch_sequence_actors, actor); + ClutterTouchInfo *info; + ClutterStage *stage = CLUTTER_STAGE (clutter_actor_get_stage (actor)); - if (info == NULL) - { - info = g_new0 (ClutterTouchInfo, 1); - info->sequence = sequence; - g_hash_table_insert (device->touch_sequences_info, sequence, info); - } - + info = _clutter_input_device_ensure_touch_info (device, sequence, stage); info->actor = actor; g_hash_table_insert (device->inv_touch_sequence_actors, @@ -1073,7 +1082,7 @@ clutter_input_device_update_from_event (ClutterInputDevice *device, sequence = clutter_event_get_event_sequence (event); clutter_event_get_coords (event, &event_x, &event_y); - _clutter_input_device_set_coords (device, sequence, event_x, event_y); + _clutter_input_device_set_coords (device, sequence, event_x, event_y, event_stage); _clutter_input_device_set_state (device, event_state); _clutter_input_device_set_time (device, event_time); @@ -1467,23 +1476,20 @@ _clutter_input_device_remove_slave (ClutterInputDevice *master, * actor underneath the touch point). */ void -_clutter_input_device_add_sequence (ClutterInputDevice *device, - ClutterEventSequence *sequence) +_clutter_input_device_add_event_sequence (ClutterInputDevice *device, + ClutterEvent *event) { - ClutterTouchInfo *info; + ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); + ClutterStage *stage; if (sequence == NULL) return; - info = - g_hash_table_lookup (device->touch_sequences_info, sequence); - - if (info != NULL) + stage = clutter_event_get_stage (event); + if (stage == NULL) return; - info = g_new0 (ClutterTouchInfo, 1); - info->sequence = sequence; - g_hash_table_insert (device->touch_sequences_info, sequence, info); + _clutter_input_device_ensure_touch_info (device, sequence, stage); } /*< private > @@ -1494,9 +1500,10 @@ _clutter_input_device_add_sequence (ClutterInputDevice *device, * Stop tracking informations related to a touch point. */ void -_clutter_input_device_remove_sequence (ClutterInputDevice *device, - ClutterEventSequence *sequence) +_clutter_input_device_remove_event_sequence (ClutterInputDevice *device, + ClutterEvent *event) { + ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); ClutterTouchInfo *info = g_hash_table_lookup (device->touch_sequences_info, sequence); @@ -1515,6 +1522,9 @@ _clutter_input_device_remove_sequence (ClutterInputDevice *device, } g_hash_table_remove (device->touch_sequences_info, sequence); + + if (g_hash_table_size (device->touch_sequences_info) == 0) + _clutter_input_device_set_stage (device, NULL); } /** diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index ed995d344..370160501 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -2678,10 +2678,7 @@ _clutter_process_event_details (ClutterActor *stage, clutter_event_get_event_sequence (event); if (event->type == CLUTTER_TOUCH_BEGIN) - { - _clutter_input_device_set_stage (device, CLUTTER_STAGE (stage)); - _clutter_input_device_add_sequence (device, sequence); - } + _clutter_input_device_add_event_sequence (device, event); clutter_event_get_coords (event, &x, &y); @@ -2716,10 +2713,7 @@ _clutter_process_event_details (ClutterActor *stage, emit_touch_event (event, device); if (event->type == CLUTTER_TOUCH_END) - { - _clutter_input_device_set_stage (device, NULL); - _clutter_input_device_remove_sequence (device, sequence); - } + _clutter_input_device_remove_event_sequence (device, event); break; } diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index f551de687..7862edfb6 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -946,7 +946,7 @@ _clutter_stage_queue_event (ClutterStage *stage, clutter_event_get_coords (event, &event_x, &event_y); - _clutter_input_device_set_coords (device, sequence, event_x, event_y); + _clutter_input_device_set_coords (device, sequence, event_x, event_y, stage); _clutter_input_device_set_state (device, event_state); _clutter_input_device_set_time (device, event_time); } diff --git a/clutter/x11/clutter-device-manager-xi2.c b/clutter/x11/clutter-device-manager-xi2.c index a714f8d49..292ee76d6 100644 --- a/clutter/x11/clutter-device-manager-xi2.c +++ b/clutter/x11/clutter-device-manager-xi2.c @@ -1086,9 +1086,6 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, stage_x11, &xev->valuators); - if (source_device != NULL && device->stage != NULL) - _clutter_input_device_set_stage (source_device, device->stage); - if (xi_event->evtype == XI_TouchBegin) { event->touch.modifier_state |= CLUTTER_BUTTON1_MASK; @@ -1139,9 +1136,6 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, stage_x11, &xev->valuators); - if (source_device != NULL && device->stage != NULL) - _clutter_input_device_set_stage (source_device, device->stage); - event->touch.modifier_state = _clutter_input_device_xi2_translate_state (&xev->mods, &xev->buttons);