gesture: Cancel sequences that make a gesture exceed the number of touches as they happen

This makes it possible to track those through gtk_gesture_handles_sequence(),
without guessing from last event type or sequence state.
This commit is contained in:
Carlos Garnacho
2014-05-06 15:20:56 +02:00
parent 134acf3fda
commit 5c9f4bd078
2 changed files with 19 additions and 14 deletions

View File

@ -268,7 +268,9 @@ _gtk_gesture_check_recognized (GtkGesture *gesture,
current_n_points = _gtk_gesture_effective_n_points (gesture); current_n_points = _gtk_gesture_effective_n_points (gesture);
if (priv->recognized && current_n_points != priv->n_points) if (priv->recognized &&
(current_n_points != priv->n_points ||
g_hash_table_size (priv->points) != priv->n_points))
_gtk_gesture_set_recognized (gesture, FALSE, sequence); _gtk_gesture_set_recognized (gesture, FALSE, sequence);
else if (!priv->recognized && else if (!priv->recognized &&
current_n_points == priv->n_points && current_n_points == priv->n_points &&
@ -351,6 +353,7 @@ _gtk_gesture_update_point (GtkGesture *gesture,
GdkWindow *widget_window; GdkWindow *widget_window;
GtkGesturePrivate *priv; GtkGesturePrivate *priv;
GdkDevice *device; GdkDevice *device;
gboolean existed;
PointData *data; PointData *data;
gdouble x, y; gdouble x, y;
@ -384,9 +387,9 @@ _gtk_gesture_update_point (GtkGesture *gesture,
return FALSE; return FALSE;
sequence = gdk_event_get_event_sequence (event); sequence = gdk_event_get_event_sequence (event);
existed = g_hash_table_lookup_extended (priv->points, sequence,
if (!g_hash_table_lookup_extended (priv->points, sequence, NULL, (gpointer *) &data);
NULL, (gpointer *) &data)) if (!existed)
{ {
if (!add) if (!add)
return FALSE; return FALSE;
@ -407,6 +410,14 @@ _gtk_gesture_update_point (GtkGesture *gesture,
data->event = gdk_event_copy (event); data->event = gdk_event_copy (event);
_update_widget_coordinates (gesture, data); _update_widget_coordinates (gesture, data);
/* Deny the sequence right away if the expected
* number of points is exceeded, so this sequence
* can be tracked with gtk_gesture_handles_sequence().
*/
if (!existed && g_hash_table_size (priv->points) > priv->n_points)
gtk_gesture_set_sequence_state (gesture, sequence,
GTK_EVENT_SEQUENCE_DENIED);
return TRUE; return TRUE;
} }

View File

@ -650,19 +650,13 @@ scrolled_window_drag_update_cb (GtkScrolledWindow *scrolled_window,
static void static void
scrolled_window_drag_end_cb (GtkScrolledWindow *scrolled_window, scrolled_window_drag_end_cb (GtkScrolledWindow *scrolled_window,
gdouble offset_x, GdkEventSequence *sequence,
gdouble offset_y,
GtkGesture *gesture) GtkGesture *gesture)
{ {
GtkScrolledWindowPrivate *priv = scrolled_window->priv; GtkScrolledWindowPrivate *priv = scrolled_window->priv;
GdkEventSequence *current, *last;
current = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture)); if (!priv->in_drag || !gtk_gesture_handles_sequence (gesture, sequence))
last = gtk_gesture_get_last_updated_sequence (gesture); gtk_gesture_set_state (gesture, GTK_EVENT_SEQUENCE_DENIED);
if (!priv->in_drag || current != last)
gtk_gesture_set_sequence_state (gesture, current,
GTK_EVENT_SEQUENCE_DENIED);
} }
static void static void
@ -759,7 +753,7 @@ gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window)
g_signal_connect_swapped (priv->drag_gesture, "drag-update", g_signal_connect_swapped (priv->drag_gesture, "drag-update",
G_CALLBACK (scrolled_window_drag_update_cb), G_CALLBACK (scrolled_window_drag_update_cb),
scrolled_window); scrolled_window);
g_signal_connect_swapped (priv->drag_gesture, "drag-end", g_signal_connect_swapped (priv->drag_gesture, "end",
G_CALLBACK (scrolled_window_drag_end_cb), G_CALLBACK (scrolled_window_drag_end_cb),
scrolled_window); scrolled_window);