mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-16 07:04:29 +00:00
gtkgesture: Handle hold gestures
Hold gestures are used to bring existing gestures on touchpad semantically closer to touchscreen gestures. Touchpad gestures observe hold gestures with a matching amount of fingers and emit their begin and end signals when fingers are detected or removed on/from the touchpad. When a hold cancel event is detected, it is required to wait a few milliseconds until the next event(s) are received to avoid emitting multiple begin signals. Part-of: <!3454>
This commit is contained in:
parent
382341e1bf
commit
3bfcc12ec0
@ -162,6 +162,7 @@ struct _GtkGesturePrivate
|
||||
GdkDevice *device;
|
||||
GList *group_link;
|
||||
guint n_points;
|
||||
guint hold_timeout_id;
|
||||
guint recognized : 1;
|
||||
guint touchpad : 1;
|
||||
};
|
||||
@ -174,6 +175,8 @@ static guint signals[N_SIGNALS] = { 0 };
|
||||
gdk_event_get_event_type (e) == GDK_TOUCHPAD_PINCH || \
|
||||
gdk_event_get_event_type (e) == GDK_TOUCHPAD_HOLD)
|
||||
|
||||
#define HOLD_TIMEOUT_MS 50
|
||||
|
||||
GList * _gtk_gesture_get_group_link (GtkGesture *gesture);
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GtkGesture, gtk_gesture, GTK_TYPE_EVENT_CONTROLLER)
|
||||
@ -222,6 +225,7 @@ gtk_gesture_finalize (GObject *object)
|
||||
|
||||
gtk_gesture_ungroup (gesture);
|
||||
g_list_free (priv->group_link);
|
||||
g_clear_handle_id (&priv->hold_timeout_id, g_source_remove);
|
||||
|
||||
g_hash_table_destroy (priv->points);
|
||||
|
||||
@ -579,6 +583,22 @@ _gtk_gesture_cancel_all (GtkGesture *gesture)
|
||||
_gtk_gesture_check_empty (gesture);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_gesture_hold_timeout (gpointer user_data)
|
||||
{
|
||||
GtkGesture *gesture;
|
||||
GtkGesturePrivate *priv;
|
||||
|
||||
gesture = user_data;
|
||||
priv = gtk_gesture_get_instance_private (gesture);
|
||||
|
||||
if (priv->touchpad)
|
||||
_gtk_gesture_cancel_sequence (gesture, priv->last_sequence);
|
||||
|
||||
priv->hold_timeout_id = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gesture_within_surface (GtkGesture *gesture,
|
||||
GdkSurface *surface)
|
||||
@ -641,8 +661,13 @@ gtk_gesture_handle_event (GtkEventController *controller,
|
||||
if (event_type == GDK_BUTTON_PRESS ||
|
||||
event_type == GDK_TOUCH_BEGIN ||
|
||||
(event_type == GDK_TOUCHPAD_SWIPE && phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN) ||
|
||||
(event_type == GDK_TOUCHPAD_PINCH && phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN))
|
||||
(event_type == GDK_TOUCHPAD_PINCH && phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN) ||
|
||||
(event_type == GDK_TOUCHPAD_HOLD && phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN))
|
||||
{
|
||||
if ((event_type == GDK_TOUCHPAD_PINCH || event_type == GDK_TOUCHPAD_SWIPE) &&
|
||||
_gtk_gesture_has_matching_touchpoints (gesture))
|
||||
g_clear_handle_id (&priv->hold_timeout_id, g_source_remove);
|
||||
|
||||
if (_gtk_gesture_update_point (gesture, event, target, x, y, TRUE))
|
||||
{
|
||||
gboolean triggered_recognition;
|
||||
@ -673,7 +698,8 @@ gtk_gesture_handle_event (GtkEventController *controller,
|
||||
else if (event_type == GDK_BUTTON_RELEASE ||
|
||||
event_type == GDK_TOUCH_END ||
|
||||
(event_type == GDK_TOUCHPAD_SWIPE && phase == GDK_TOUCHPAD_GESTURE_PHASE_END) ||
|
||||
(event_type == GDK_TOUCHPAD_PINCH && phase == GDK_TOUCHPAD_GESTURE_PHASE_END))
|
||||
(event_type == GDK_TOUCHPAD_PINCH && phase == GDK_TOUCHPAD_GESTURE_PHASE_END) ||
|
||||
(event_type == GDK_TOUCHPAD_HOLD && phase == GDK_TOUCHPAD_GESTURE_PHASE_END))
|
||||
{
|
||||
gboolean was_claimed = FALSE;
|
||||
|
||||
@ -717,6 +743,15 @@ gtk_gesture_handle_event (GtkEventController *controller,
|
||||
if (priv->touchpad)
|
||||
_gtk_gesture_cancel_sequence (gesture, sequence);
|
||||
}
|
||||
else if (event_type == GDK_TOUCHPAD_HOLD && phase == GDK_TOUCHPAD_GESTURE_PHASE_CANCEL)
|
||||
{
|
||||
if (priv->hold_timeout_id == 0)
|
||||
{
|
||||
priv->hold_timeout_id = g_timeout_add (HOLD_TIMEOUT_MS,
|
||||
gtk_gesture_hold_timeout,
|
||||
gesture);
|
||||
}
|
||||
}
|
||||
else if (event_type == GDK_GRAB_BROKEN)
|
||||
{
|
||||
GdkSurface *surface;
|
||||
@ -742,6 +777,10 @@ gtk_gesture_handle_event (GtkEventController *controller,
|
||||
static void
|
||||
gtk_gesture_reset (GtkEventController *controller)
|
||||
{
|
||||
GtkGesture *gesture = GTK_GESTURE (controller);
|
||||
GtkGesturePrivate *priv = gtk_gesture_get_instance_private (gesture);
|
||||
|
||||
g_clear_handle_id (&priv->hold_timeout_id, g_source_remove);
|
||||
_gtk_gesture_cancel_all (GTK_GESTURE (controller));
|
||||
}
|
||||
|
||||
@ -913,6 +952,7 @@ gtk_gesture_init (GtkGesture *gesture)
|
||||
priv->points = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) free_point_data);
|
||||
priv->group_link = g_list_prepend (NULL, gesture);
|
||||
priv->hold_timeout_id = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user