forked from AuroraMiddleware/gtk
Merge branch 'hold-gestures' into 'main'
Add hold gestures See merge request GNOME/gtk!3454
This commit is contained in:
commit
9a7750e339
@ -2496,7 +2496,8 @@ static const GdkEventTypeInfo gdk_touchpad_event_info = {
|
||||
GDK_DEFINE_EVENT_TYPE (GdkTouchpadEvent, gdk_touchpad_event,
|
||||
&gdk_touchpad_event_info,
|
||||
GDK_EVENT_TYPE_SLOT (GDK_TOUCHPAD_SWIPE)
|
||||
GDK_EVENT_TYPE_SLOT (GDK_TOUCHPAD_PINCH))
|
||||
GDK_EVENT_TYPE_SLOT (GDK_TOUCHPAD_PINCH)
|
||||
GDK_EVENT_TYPE_SLOT (GDK_TOUCHPAD_HOLD))
|
||||
|
||||
GdkEvent *
|
||||
gdk_touchpad_event_new_swipe (GdkSurface *surface,
|
||||
@ -2570,6 +2571,27 @@ gdk_touchpad_event_new_pinch (GdkSurface *surface,
|
||||
return (GdkEvent *) self;
|
||||
}
|
||||
|
||||
GdkEvent *
|
||||
gdk_touchpad_event_new_hold (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers)
|
||||
{
|
||||
GdkTouchpadEvent *self = gdk_event_alloc (GDK_TOUCHPAD_HOLD, surface, device, time);
|
||||
|
||||
self->state = state;
|
||||
self->phase = phase;
|
||||
self->x = x;
|
||||
self->y = y;
|
||||
self->n_fingers = n_fingers;
|
||||
|
||||
return (GdkEvent *) self;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_touchpad_event_get_gesture_phase:
|
||||
* @event: (type GdkTouchpadEvent): a touchpad event
|
||||
@ -2585,7 +2607,8 @@ gdk_touchpad_event_get_gesture_phase (GdkEvent *event)
|
||||
|
||||
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
|
||||
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_PINCH) ||
|
||||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_SWIPE), 0);
|
||||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_SWIPE) ||
|
||||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_HOLD), 0);
|
||||
|
||||
return self->phase;
|
||||
}
|
||||
@ -2605,7 +2628,8 @@ gdk_touchpad_event_get_n_fingers (GdkEvent *event)
|
||||
|
||||
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
|
||||
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_PINCH) ||
|
||||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_SWIPE), 0);
|
||||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_SWIPE) ||
|
||||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_HOLD), 0);
|
||||
|
||||
return self->n_fingers;
|
||||
}
|
||||
|
@ -169,6 +169,8 @@ typedef struct _GdkTouchpadEvent GdkTouchpadEvent;
|
||||
* @GDK_PAD_RING: A tablet pad axis event from a "ring".
|
||||
* @GDK_PAD_STRIP: A tablet pad axis event from a "strip".
|
||||
* @GDK_PAD_GROUP_MODE: A tablet pad group mode change.
|
||||
* @GDK_TOUCHPAD_HOLD: A touchpad hold gesture event, the current state
|
||||
* is determined by its phase field. Since: 4.6
|
||||
* @GDK_EVENT_LAST: marks the end of the GdkEventType enumeration.
|
||||
*
|
||||
* Specifies the type of the event.
|
||||
@ -203,6 +205,7 @@ typedef enum
|
||||
GDK_PAD_RING,
|
||||
GDK_PAD_STRIP,
|
||||
GDK_PAD_GROUP_MODE,
|
||||
GDK_TOUCHPAD_HOLD,
|
||||
GDK_EVENT_LAST /* helper variable for decls */
|
||||
} GdkEventType;
|
||||
|
||||
|
@ -533,6 +533,15 @@ GdkEvent * gdk_touchpad_event_new_pinch (GdkSurface *surface,
|
||||
double scale,
|
||||
double angle_delta);
|
||||
|
||||
GdkEvent * gdk_touchpad_event_new_hold (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers);
|
||||
|
||||
GdkEvent * gdk_pad_event_new_ring (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
|
@ -227,6 +227,7 @@ struct _GdkWaylandSeat
|
||||
struct wl_touch *wl_touch;
|
||||
struct zwp_pointer_gesture_swipe_v1 *wp_pointer_gesture_swipe;
|
||||
struct zwp_pointer_gesture_pinch_v1 *wp_pointer_gesture_pinch;
|
||||
struct zwp_pointer_gesture_hold_v1 *wp_pointer_gesture_hold;
|
||||
struct zwp_tablet_seat_v2 *wp_tablet_seat;
|
||||
|
||||
GdkDisplay *display;
|
||||
@ -2856,6 +2857,81 @@ gesture_pinch_end (void *data,
|
||||
0, 0, 1, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_gesture_hold_event (GdkWaylandSeat *seat,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
guint32 _time,
|
||||
guint32 n_fingers)
|
||||
{
|
||||
GdkEvent *event;
|
||||
|
||||
if (!seat->pointer_info.focus)
|
||||
return;
|
||||
|
||||
seat->pointer_info.time = _time;
|
||||
|
||||
event = gdk_touchpad_event_new_hold (seat->pointer_info.focus,
|
||||
seat->logical_pointer,
|
||||
_time,
|
||||
device_get_modifiers (seat->logical_pointer),
|
||||
phase,
|
||||
seat->pointer_info.surface_x,
|
||||
seat->pointer_info.surface_y,
|
||||
n_fingers);
|
||||
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (gdk_seat_get_display (GDK_SEAT (seat)), EVENTS))
|
||||
{
|
||||
double x, y;
|
||||
gdk_event_get_position (event, &x, &y);
|
||||
g_message ("hold event %d, coords: %f %f, seat %p state %d",
|
||||
gdk_event_get_event_type (event),
|
||||
x, y, seat,
|
||||
gdk_event_get_modifier_state (event));
|
||||
}
|
||||
|
||||
_gdk_wayland_display_deliver_event (seat->display, event);
|
||||
}
|
||||
|
||||
static void
|
||||
gesture_hold_begin (void *data,
|
||||
struct zwp_pointer_gesture_hold_v1 *hold,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
struct wl_surface *surface,
|
||||
uint32_t fingers)
|
||||
{
|
||||
GdkWaylandSeat *seat = data;
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
|
||||
|
||||
_gdk_wayland_display_update_serial (display, serial);
|
||||
|
||||
emit_gesture_hold_event (seat,
|
||||
GDK_TOUCHPAD_GESTURE_PHASE_BEGIN,
|
||||
time, fingers);
|
||||
seat->gesture_n_fingers = fingers;
|
||||
}
|
||||
|
||||
static void
|
||||
gesture_hold_end (void *data,
|
||||
struct zwp_pointer_gesture_hold_v1 *hold,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
int32_t cancelled)
|
||||
{
|
||||
GdkWaylandSeat *seat = data;
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
|
||||
GdkTouchpadGesturePhase phase;
|
||||
|
||||
_gdk_wayland_display_update_serial (display, serial);
|
||||
|
||||
phase = (cancelled) ?
|
||||
GDK_TOUCHPAD_GESTURE_PHASE_CANCEL :
|
||||
GDK_TOUCHPAD_GESTURE_PHASE_END;
|
||||
|
||||
emit_gesture_hold_event (seat, phase, time,
|
||||
seat->gesture_n_fingers);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_wayland_seat_remove_tool (GdkWaylandSeat *seat,
|
||||
GdkWaylandTabletToolData *tool)
|
||||
@ -3065,6 +3141,11 @@ static const struct zwp_pointer_gesture_pinch_v1_listener gesture_pinch_listener
|
||||
gesture_pinch_end
|
||||
};
|
||||
|
||||
static const struct zwp_pointer_gesture_hold_v1_listener gesture_hold_listener = {
|
||||
gesture_hold_begin,
|
||||
gesture_hold_end
|
||||
};
|
||||
|
||||
static const struct zwp_tablet_v2_listener tablet_listener = {
|
||||
tablet_handle_name,
|
||||
tablet_handle_id,
|
||||
@ -3120,6 +3201,17 @@ seat_handle_capabilities (void *data,
|
||||
seat);
|
||||
zwp_pointer_gesture_pinch_v1_add_listener (seat->wp_pointer_gesture_pinch,
|
||||
&gesture_pinch_listener, seat);
|
||||
|
||||
if (display_wayland->pointer_gestures_version >= ZWP_POINTER_GESTURES_V1_GET_HOLD_GESTURE_SINCE_VERSION)
|
||||
{
|
||||
seat->wp_pointer_gesture_hold =
|
||||
zwp_pointer_gestures_v1_get_hold_gesture (display_wayland->pointer_gestures,
|
||||
seat->wl_pointer);
|
||||
zwp_pointer_gesture_hold_v1_set_user_data (seat->wp_pointer_gesture_hold,
|
||||
seat);
|
||||
zwp_pointer_gesture_hold_v1_add_listener (seat->wp_pointer_gesture_hold,
|
||||
&gesture_hold_listener, seat);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && seat->wl_pointer)
|
||||
|
@ -431,6 +431,9 @@ gdk_registry_handle_global (void *data,
|
||||
}
|
||||
else if (strcmp (interface, "zwp_pointer_gestures_v1") == 0)
|
||||
{
|
||||
display_wayland->pointer_gestures_version =
|
||||
MIN (version, GDK_ZWP_POINTER_GESTURES_V1_VERSION);
|
||||
|
||||
display_wayland->pointer_gestures =
|
||||
wl_registry_bind (display_wayland->wl_registry,
|
||||
id, &zwp_pointer_gestures_v1_interface,
|
||||
|
@ -52,7 +52,7 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_ZWP_POINTER_GESTURES_V1_VERSION 1
|
||||
#define GDK_ZWP_POINTER_GESTURES_V1_VERSION 3
|
||||
|
||||
typedef struct _GdkWaylandSelection GdkWaylandSelection;
|
||||
|
||||
@ -140,6 +140,7 @@ struct _GdkWaylandDisplay
|
||||
int data_device_manager_version;
|
||||
int gtk_shell_version;
|
||||
int xdg_output_manager_version;
|
||||
int pointer_gestures_version;
|
||||
int xdg_activation_version;
|
||||
|
||||
uint32_t server_decoration_mode;
|
||||
|
@ -66,6 +66,7 @@
|
||||
#include "gtkprivate.h"
|
||||
|
||||
#define SCROLL_CAPTURE_THRESHOLD_MS 150
|
||||
#define HOLD_TIMEOUT_MS 50
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -84,6 +85,7 @@ struct _GtkEventControllerScroll
|
||||
double cur_dx;
|
||||
double cur_dy;
|
||||
|
||||
guint hold_timeout_id;
|
||||
guint active : 1;
|
||||
};
|
||||
|
||||
@ -193,6 +195,7 @@ gtk_event_controller_scroll_finalize (GObject *object)
|
||||
GtkEventControllerScroll *scroll = GTK_EVENT_CONTROLLER_SCROLL (object);
|
||||
|
||||
g_array_unref (scroll->scroll_history);
|
||||
g_clear_handle_id (&scroll->hold_timeout_id, g_source_remove);
|
||||
|
||||
G_OBJECT_CLASS (gtk_event_controller_scroll_parent_class)->finalize (object);
|
||||
}
|
||||
@ -235,6 +238,107 @@ gtk_event_controller_scroll_get_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_event_controller_scroll_begin (GtkEventController *controller)
|
||||
{
|
||||
GtkEventControllerScroll *scroll = GTK_EVENT_CONTROLLER_SCROLL (controller);
|
||||
|
||||
if (scroll->active)
|
||||
return FALSE;
|
||||
|
||||
g_signal_emit (controller, signals[SCROLL_BEGIN], 0);
|
||||
scroll_history_reset (scroll);
|
||||
scroll->active = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_event_controller_scroll_end (GtkEventController *controller)
|
||||
{
|
||||
GtkEventControllerScroll *scroll = GTK_EVENT_CONTROLLER_SCROLL (controller);
|
||||
|
||||
if (!scroll->active)
|
||||
return FALSE;
|
||||
|
||||
g_signal_emit (controller, signals[SCROLL_END], 0);
|
||||
scroll->active = FALSE;
|
||||
|
||||
if (scroll->flags & GTK_EVENT_CONTROLLER_SCROLL_KINETIC)
|
||||
{
|
||||
double vel_x, vel_y;
|
||||
|
||||
scroll_history_finish (scroll, &vel_x, &vel_y);
|
||||
g_signal_emit (controller, signals[DECELERATE], 0, vel_x, vel_y);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_event_controller_scroll_hold_timeout (gpointer user_data)
|
||||
{
|
||||
GtkEventController *controller;
|
||||
GtkEventControllerScroll *scroll;
|
||||
|
||||
controller = user_data;
|
||||
scroll = GTK_EVENT_CONTROLLER_SCROLL (controller);
|
||||
|
||||
gtk_event_controller_scroll_end (controller);
|
||||
scroll->hold_timeout_id = 0;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_event_controller_scroll_handle_hold_event (GtkEventController *controller,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GtkEventControllerScroll *scroll = GTK_EVENT_CONTROLLER_SCROLL (controller);
|
||||
gboolean handled = GDK_EVENT_PROPAGATE;
|
||||
GdkTouchpadGesturePhase phase;
|
||||
guint n_fingers = 0;
|
||||
|
||||
if (gdk_event_get_event_type (event) != GDK_TOUCHPAD_HOLD)
|
||||
return handled;
|
||||
|
||||
n_fingers = gdk_touchpad_event_get_n_fingers (event);
|
||||
if (n_fingers != 1 && n_fingers != 2)
|
||||
return handled;
|
||||
|
||||
if (scroll->hold_timeout_id != 0)
|
||||
return handled;
|
||||
|
||||
phase = gdk_touchpad_event_get_gesture_phase (event);
|
||||
|
||||
switch (phase)
|
||||
{
|
||||
case GDK_TOUCHPAD_GESTURE_PHASE_BEGIN:
|
||||
handled = gtk_event_controller_scroll_begin (controller);
|
||||
break;
|
||||
|
||||
case GDK_TOUCHPAD_GESTURE_PHASE_END:
|
||||
handled = gtk_event_controller_scroll_end (controller);
|
||||
break;
|
||||
|
||||
case GDK_TOUCHPAD_GESTURE_PHASE_CANCEL:
|
||||
if (scroll->hold_timeout_id == 0)
|
||||
{
|
||||
scroll->hold_timeout_id =
|
||||
g_timeout_add (HOLD_TIMEOUT_MS,
|
||||
gtk_event_controller_scroll_hold_timeout,
|
||||
controller);
|
||||
}
|
||||
break;
|
||||
|
||||
case GDK_TOUCHPAD_GESTURE_PHASE_UPDATE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_event_controller_scroll_handle_event (GtkEventController *controller,
|
||||
GdkEvent *event,
|
||||
@ -245,26 +349,28 @@ gtk_event_controller_scroll_handle_event (GtkEventController *controller,
|
||||
GdkScrollDirection direction = GDK_SCROLL_SMOOTH;
|
||||
double dx = 0, dy = 0;
|
||||
gboolean handled = GDK_EVENT_PROPAGATE;
|
||||
GdkEventType event_type;
|
||||
|
||||
if (gdk_event_get_event_type (event) != GDK_SCROLL)
|
||||
event_type = gdk_event_get_event_type (event);
|
||||
|
||||
if (event_type == GDK_TOUCHPAD_HOLD)
|
||||
return gtk_event_controller_scroll_handle_hold_event (controller, event);
|
||||
|
||||
if (event_type != GDK_SCROLL)
|
||||
return FALSE;
|
||||
|
||||
if ((scroll->flags & (GTK_EVENT_CONTROLLER_SCROLL_VERTICAL |
|
||||
GTK_EVENT_CONTROLLER_SCROLL_HORIZONTAL)) == 0)
|
||||
return FALSE;
|
||||
|
||||
g_clear_handle_id (&scroll->hold_timeout_id, g_source_remove);
|
||||
|
||||
/* FIXME: Handle device changes */
|
||||
direction = gdk_scroll_event_get_direction (event);
|
||||
if (direction == GDK_SCROLL_SMOOTH)
|
||||
{
|
||||
gdk_scroll_event_get_deltas (event, &dx, &dy);
|
||||
|
||||
if (!scroll->active)
|
||||
{
|
||||
g_signal_emit (controller, signals[SCROLL_BEGIN], 0);
|
||||
scroll_history_reset (scroll);
|
||||
scroll->active = TRUE;
|
||||
}
|
||||
gtk_event_controller_scroll_begin (controller);
|
||||
|
||||
if ((scroll->flags & GTK_EVENT_CONTROLLER_SCROLL_VERTICAL) == 0)
|
||||
dy = 0;
|
||||
@ -334,17 +440,8 @@ gtk_event_controller_scroll_handle_event (GtkEventController *controller,
|
||||
|
||||
if (scroll->active && gdk_scroll_event_is_stop (event))
|
||||
{
|
||||
g_signal_emit (controller, signals[SCROLL_END], 0);
|
||||
scroll->active = FALSE;
|
||||
gtk_event_controller_scroll_end (controller);
|
||||
handled = FALSE;
|
||||
|
||||
if (scroll->flags & GTK_EVENT_CONTROLLER_SCROLL_KINETIC)
|
||||
{
|
||||
double vel_x, vel_y;
|
||||
|
||||
scroll_history_finish (scroll, &vel_x, &vel_y);
|
||||
g_signal_emit (controller, signals[DECELERATE], 0, vel_x, vel_y);
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
@ -462,6 +559,7 @@ gtk_event_controller_scroll_init (GtkEventControllerScroll *scroll)
|
||||
{
|
||||
scroll->scroll_history = g_array_new (FALSE, FALSE,
|
||||
sizeof (ScrollHistoryElem));
|
||||
scroll->hold_timeout_id = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -162,6 +162,7 @@ struct _GtkGesturePrivate
|
||||
GdkDevice *device;
|
||||
GList *group_link;
|
||||
guint n_points;
|
||||
guint hold_timeout_id;
|
||||
guint recognized : 1;
|
||||
guint touchpad : 1;
|
||||
};
|
||||
@ -171,7 +172,10 @@ static guint signals[N_SIGNALS] = { 0 };
|
||||
#define BUTTONS_MASK (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)
|
||||
|
||||
#define EVENT_IS_TOUCHPAD_GESTURE(e) (gdk_event_get_event_type (e) == GDK_TOUCHPAD_SWIPE || \
|
||||
gdk_event_get_event_type (e) == GDK_TOUCHPAD_PINCH)
|
||||
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);
|
||||
|
||||
@ -221,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);
|
||||
|
||||
@ -258,7 +263,8 @@ _gtk_gesture_get_n_touchpad_points (GtkGesture *gesture,
|
||||
if (only_active &&
|
||||
(data->state == GTK_EVENT_SEQUENCE_DENIED ||
|
||||
(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)))
|
||||
return 0;
|
||||
|
||||
return n_fingers;
|
||||
@ -390,8 +396,8 @@ _update_touchpad_deltas (PointData *data)
|
||||
{
|
||||
GdkEvent *event = data->event;
|
||||
GdkTouchpadGesturePhase phase;
|
||||
double dx;
|
||||
double dy;
|
||||
double dx = 0;
|
||||
double dy = 0;
|
||||
|
||||
if (!event)
|
||||
return;
|
||||
@ -399,7 +405,10 @@ _update_touchpad_deltas (PointData *data)
|
||||
if (EVENT_IS_TOUCHPAD_GESTURE (event))
|
||||
{
|
||||
phase = gdk_touchpad_event_get_gesture_phase (event);
|
||||
gdk_touchpad_event_get_deltas (event, &dx, &dy);
|
||||
|
||||
if (gdk_event_get_event_type (event) != GDK_TOUCHPAD_HOLD)
|
||||
gdk_touchpad_event_get_deltas (event, &dx, &dy);
|
||||
|
||||
if (phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN)
|
||||
data->accum_dx = data->accum_dy = 0;
|
||||
else if (phase == GDK_TOUCHPAD_GESTURE_PHASE_UPDATE)
|
||||
@ -574,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)
|
||||
@ -636,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;
|
||||
@ -668,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;
|
||||
|
||||
@ -712,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;
|
||||
@ -737,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));
|
||||
}
|
||||
|
||||
@ -908,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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -172,8 +172,9 @@ static gboolean
|
||||
gtk_gesture_rotate_filter_event (GtkEventController *controller,
|
||||
GdkEvent *event)
|
||||
{
|
||||
/* Let 2-finger touchpad pinch events go through */
|
||||
if (gdk_event_get_event_type (event) == GDK_TOUCHPAD_PINCH)
|
||||
/* Let 2-finger touchpad pinch and hold events go through */
|
||||
if (gdk_event_get_event_type (event) == GDK_TOUCHPAD_PINCH ||
|
||||
gdk_event_get_event_type (event) == GDK_TOUCHPAD_HOLD)
|
||||
{
|
||||
guint n_fingers;
|
||||
|
||||
|
@ -197,6 +197,10 @@ gtk_gesture_single_handle_event (GtkEventController *controller,
|
||||
}
|
||||
|
||||
break;
|
||||
case GDK_TOUCHPAD_HOLD:
|
||||
if (gdk_touchpad_event_get_n_fingers (event) == 1)
|
||||
return FALSE;
|
||||
/* fallthrough */
|
||||
case GDK_TOUCH_CANCEL:
|
||||
case GDK_GRAB_BROKEN:
|
||||
case GDK_TOUCHPAD_SWIPE:
|
||||
|
@ -84,8 +84,9 @@ static gboolean
|
||||
gtk_gesture_swipe_filter_event (GtkEventController *controller,
|
||||
GdkEvent *event)
|
||||
{
|
||||
/* Let touchpad swipe events go through, only if they match n-points */
|
||||
if (gdk_event_get_event_type (event) == GDK_TOUCHPAD_SWIPE)
|
||||
/* Let touchpad swipe and hold events go through, only if they match n-points */
|
||||
if (gdk_event_get_event_type (event) == GDK_TOUCHPAD_SWIPE ||
|
||||
gdk_event_get_event_type (event) == GDK_TOUCHPAD_HOLD)
|
||||
{
|
||||
guint n_points;
|
||||
guint n_fingers;
|
||||
|
@ -149,8 +149,9 @@ static gboolean
|
||||
gtk_gesture_zoom_filter_event (GtkEventController *controller,
|
||||
GdkEvent *event)
|
||||
{
|
||||
/* Let 2-finger touchpad pinch events go through */
|
||||
if (gdk_event_get_event_type (event) == GDK_TOUCHPAD_PINCH)
|
||||
/* Let 2-finger touchpad pinch and hold events go through */
|
||||
if (gdk_event_get_event_type (event) == GDK_TOUCHPAD_PINCH ||
|
||||
gdk_event_get_event_type (event) == GDK_TOUCHPAD_HOLD)
|
||||
{
|
||||
guint n_fingers;
|
||||
|
||||
|
@ -202,9 +202,7 @@ gtk_kinetic_scrolling_tick (GtkKineticScrolling *data,
|
||||
else if (fabs(data->velocity) < 1 ||
|
||||
(last_time != 0.0 && fabs(data->position - last_position) < 1))
|
||||
{
|
||||
data->phase = GTK_KINETIC_SCROLLING_PHASE_FINISHED;
|
||||
data->position = round(data->position);
|
||||
data->velocity = 0;
|
||||
gtk_kinetic_scrolling_stop (data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -249,3 +247,13 @@ gtk_kinetic_scrolling_tick (GtkKineticScrolling *data,
|
||||
return data->phase != GTK_KINETIC_SCROLLING_PHASE_FINISHED;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_kinetic_scrolling_stop (GtkKineticScrolling *data)
|
||||
{
|
||||
if (data->phase == GTK_KINETIC_SCROLLING_PHASE_DECELERATING)
|
||||
{
|
||||
data->phase = GTK_KINETIC_SCROLLING_PHASE_FINISHED;
|
||||
data->position = round (data->position);
|
||||
data->velocity = 0;
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,8 @@ gboolean gtk_kinetic_scrolling_tick (GtkKineticScrolling *data,
|
||||
double *position,
|
||||
double *velocity);
|
||||
|
||||
void gtk_kinetic_scrolling_stop (GtkKineticScrolling *data);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_KINETIC_SCROLLING_H__ */
|
||||
|
@ -915,6 +915,7 @@ rewrite_event_for_surface (GdkEvent *event,
|
||||
case GDK_TOUCH_CANCEL:
|
||||
case GDK_TOUCHPAD_SWIPE:
|
||||
case GDK_TOUCHPAD_PINCH:
|
||||
case GDK_TOUCHPAD_HOLD:
|
||||
gdk_event_get_position (event, &x, &y);
|
||||
gdk_surface_translate_coordinates (gdk_event_get_surface (event), new_surface, &x, &y);
|
||||
break;
|
||||
@ -981,6 +982,14 @@ rewrite_event_for_surface (GdkEvent *event,
|
||||
dx, dy,
|
||||
gdk_touchpad_event_get_pinch_scale (event),
|
||||
gdk_touchpad_event_get_pinch_angle_delta (event));
|
||||
case GDK_TOUCHPAD_HOLD:
|
||||
return gdk_touchpad_event_new_hold (new_surface,
|
||||
gdk_event_get_device (event),
|
||||
gdk_event_get_time (event),
|
||||
gdk_event_get_modifier_state (event),
|
||||
gdk_touchpad_event_get_gesture_phase (event),
|
||||
x, y,
|
||||
gdk_touchpad_event_get_n_fingers (event));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1020,6 +1029,7 @@ rewrite_event_for_grabs (GdkEvent *event)
|
||||
case GDK_TOUCH_CANCEL:
|
||||
case GDK_TOUCHPAD_SWIPE:
|
||||
case GDK_TOUCHPAD_PINCH:
|
||||
case GDK_TOUCHPAD_HOLD:
|
||||
display = gdk_event_get_display (event);
|
||||
device = gdk_event_get_device (event);
|
||||
|
||||
@ -1270,6 +1280,7 @@ is_pointing_event (GdkEvent *event)
|
||||
case GDK_TOUCH_CANCEL:
|
||||
case GDK_TOUCHPAD_PINCH:
|
||||
case GDK_TOUCHPAD_SWIPE:
|
||||
case GDK_TOUCHPAD_HOLD:
|
||||
case GDK_DRAG_ENTER:
|
||||
case GDK_DRAG_LEAVE:
|
||||
case GDK_DRAG_MOTION:
|
||||
@ -1353,7 +1364,8 @@ handle_pointing_event (GdkEvent *event)
|
||||
device = gdk_seat_get_pointer (gdk_event_get_seat (event));
|
||||
}
|
||||
else if (type == GDK_TOUCHPAD_PINCH ||
|
||||
type == GDK_TOUCHPAD_SWIPE)
|
||||
type == GDK_TOUCHPAD_SWIPE ||
|
||||
type == GDK_TOUCHPAD_HOLD)
|
||||
{
|
||||
/* Another bit of a kludge, touchpad gesture sequences do not
|
||||
* reflect on the pointer focus lookup.
|
||||
@ -1488,6 +1500,7 @@ handle_pointing_event (GdkEvent *event)
|
||||
case GDK_SCROLL:
|
||||
case GDK_TOUCHPAD_PINCH:
|
||||
case GDK_TOUCHPAD_SWIPE:
|
||||
case GDK_TOUCHPAD_HOLD:
|
||||
break;
|
||||
case GDK_GRAB_BROKEN:
|
||||
if (gdk_grab_broken_event_get_implicit (event))
|
||||
@ -1662,6 +1675,7 @@ gtk_main_do_event (GdkEvent *event)
|
||||
case GDK_TOUCH_CANCEL:
|
||||
case GDK_TOUCHPAD_SWIPE:
|
||||
case GDK_TOUCHPAD_PINCH:
|
||||
case GDK_TOUCHPAD_HOLD:
|
||||
case GDK_PAD_BUTTON_PRESS:
|
||||
case GDK_PAD_BUTTON_RELEASE:
|
||||
case GDK_PAD_RING:
|
||||
|
@ -1350,6 +1350,19 @@ scroll_controller_scroll_begin (GtkEventControllerScroll *scroll,
|
||||
priv->smooth_scroll = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
stop_kinetic_scrolling_cb (GtkEventControllerScroll *scroll,
|
||||
GtkScrolledWindow *scrolled_window)
|
||||
{
|
||||
GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (scrolled_window);
|
||||
|
||||
if (priv->hscrolling)
|
||||
gtk_kinetic_scrolling_stop (priv->hscrolling);
|
||||
|
||||
if (priv->vscrolling)
|
||||
gtk_kinetic_scrolling_stop (priv->vscrolling);
|
||||
}
|
||||
|
||||
static void
|
||||
scrolled_window_scroll (GtkScrolledWindow *scrolled_window,
|
||||
double delta_x,
|
||||
@ -2115,6 +2128,8 @@ gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window)
|
||||
controller = gtk_event_controller_scroll_new (GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES |
|
||||
GTK_EVENT_CONTROLLER_SCROLL_KINETIC);
|
||||
gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_CAPTURE);
|
||||
g_signal_connect (controller, "scroll-begin",
|
||||
G_CALLBACK (stop_kinetic_scrolling_cb), scrolled_window);
|
||||
g_signal_connect (controller, "scroll",
|
||||
G_CALLBACK (captured_scroll_cb), scrolled_window);
|
||||
g_signal_connect (controller, "decelerate",
|
||||
|
@ -16,7 +16,7 @@ fribidi_req = '>= 0.19.7'
|
||||
cairo_req = '>= 1.14.0'
|
||||
gdk_pixbuf_req = '>= 2.30.0'
|
||||
introspection_req = '>= 1.39.0'
|
||||
wayland_proto_req = '>= 1.21'
|
||||
wayland_proto_req = '>= 1.23'
|
||||
wayland_req = '>= 1.20.0'
|
||||
graphene_req = '>= 1.9.1'
|
||||
epoxy_req = '>= 1.4'
|
||||
|
Loading…
Reference in New Issue
Block a user