input-device: don't reset a device's stage until all touch points are gone
803b3bafb6
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
This commit is contained in:

committed by
Emmanuele Bassi

parent
d5332d1e4c
commit
d6a0f7eb61
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user