mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 19:00:08 +00:00
wayland: Implement touchpad gesture events
On wayland, the gestures protocol defines a wl_pointer_gestures global object, that will match in number with wl_seats, swipe and pinch interfaces can be obtained from it, which events are translated into GdkEventTouchpadSwipe/Pinch events.
This commit is contained in:
parent
b037d4d628
commit
45d15b302e
@ -29,6 +29,7 @@
|
||||
#include "gdkkeysyms.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdevicemanagerprivate.h"
|
||||
#include "pointer-gestures-client-protocol.h"
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
@ -54,6 +55,8 @@ struct _GdkWaylandDeviceData
|
||||
struct wl_pointer *wl_pointer;
|
||||
struct wl_keyboard *wl_keyboard;
|
||||
struct wl_touch *wl_touch;
|
||||
struct _wl_pointer_gesture_swipe *wl_pointer_gesture_swipe;
|
||||
struct _wl_pointer_gesture_pinch *wl_pointer_gesture_pinch;
|
||||
|
||||
GdkDisplay *display;
|
||||
GdkDeviceManager *device_manager;
|
||||
@ -99,6 +102,10 @@ struct _GdkWaylandDeviceData
|
||||
|
||||
/* Source/dest for non-local dnd */
|
||||
GdkWindow *foreign_dnd_window;
|
||||
|
||||
/* Some tracking on gesture events */
|
||||
guint gesture_n_fingers;
|
||||
gdouble gesture_scale;
|
||||
};
|
||||
|
||||
struct _GdkWaylandDevice
|
||||
@ -1653,6 +1660,213 @@ touch_handle_cancel (void *data,
|
||||
GDK_NOTE (EVENTS, g_message ("touch cancel"));
|
||||
}
|
||||
|
||||
static void
|
||||
emit_gesture_swipe_event (GdkWaylandDeviceData *device,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
guint32 _time,
|
||||
guint32 n_fingers,
|
||||
gdouble dx,
|
||||
gdouble dy)
|
||||
{
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
|
||||
GdkEvent *event;
|
||||
|
||||
if (!device->pointer_focus)
|
||||
return;
|
||||
|
||||
device->time = _time;
|
||||
|
||||
event = gdk_event_new (GDK_TOUCHPAD_SWIPE);
|
||||
event->touchpad_swipe.phase = phase;
|
||||
event->touchpad_swipe.window = g_object_ref (device->pointer_focus);
|
||||
gdk_event_set_device (event, device->master_pointer);
|
||||
gdk_event_set_source_device (event, device->pointer);
|
||||
event->touchpad_swipe.time = _time;
|
||||
event->touchpad_swipe.state = device->button_modifiers | device->key_modifiers;
|
||||
gdk_event_set_screen (event, display->screen);
|
||||
event->touchpad_swipe.dx = dx;
|
||||
event->touchpad_swipe.dy = dy;
|
||||
event->touchpad_swipe.n_fingers = n_fingers;
|
||||
|
||||
get_coordinates (device,
|
||||
&event->touchpad_swipe.x,
|
||||
&event->touchpad_swipe.y,
|
||||
&event->touchpad_swipe.x_root,
|
||||
&event->touchpad_swipe.y_root);
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("swipe event %d, coords: %f %f, device %p state %d",
|
||||
event->type, event->touchpad_swipe.x,
|
||||
event->touchpad_swipe.y, device,
|
||||
event->touchpad_swipe.state));
|
||||
|
||||
_gdk_wayland_display_deliver_event (device->display, event);
|
||||
}
|
||||
|
||||
static void
|
||||
gesture_swipe_begin (void *data,
|
||||
struct _wl_pointer_gesture_swipe *swipe,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
struct wl_surface *surface,
|
||||
uint32_t fingers)
|
||||
{
|
||||
GdkWaylandDeviceData *device = data;
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
|
||||
|
||||
_gdk_wayland_display_update_serial (display, serial);
|
||||
|
||||
emit_gesture_swipe_event (device,
|
||||
GDK_TOUCHPAD_GESTURE_PHASE_BEGIN,
|
||||
time, fingers, 0, 0);
|
||||
device->gesture_n_fingers = fingers;
|
||||
}
|
||||
|
||||
static void
|
||||
gesture_swipe_update (void *data,
|
||||
struct _wl_pointer_gesture_swipe *swipe,
|
||||
uint32_t time,
|
||||
wl_fixed_t dx,
|
||||
wl_fixed_t dy)
|
||||
{
|
||||
GdkWaylandDeviceData *device = data;
|
||||
|
||||
emit_gesture_swipe_event (device,
|
||||
GDK_TOUCHPAD_GESTURE_PHASE_UPDATE,
|
||||
time,
|
||||
device->gesture_n_fingers,
|
||||
wl_fixed_to_double (dx),
|
||||
wl_fixed_to_double (dy));
|
||||
}
|
||||
|
||||
static void
|
||||
gesture_swipe_end (void *data,
|
||||
struct _wl_pointer_gesture_swipe *swipe,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
int32_t cancelled)
|
||||
{
|
||||
GdkWaylandDeviceData *device = data;
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
|
||||
GdkTouchpadGesturePhase phase;
|
||||
|
||||
_gdk_wayland_display_update_serial (display, serial);
|
||||
|
||||
phase = (cancelled) ?
|
||||
GDK_TOUCHPAD_GESTURE_PHASE_CANCEL :
|
||||
GDK_TOUCHPAD_GESTURE_PHASE_END;
|
||||
|
||||
emit_gesture_swipe_event (device, phase, time,
|
||||
device->gesture_n_fingers, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_gesture_pinch_event (GdkWaylandDeviceData *device,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
guint32 _time,
|
||||
guint n_fingers,
|
||||
gdouble dx,
|
||||
gdouble dy,
|
||||
gdouble scale,
|
||||
gdouble angle_delta)
|
||||
{
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
|
||||
GdkEvent *event;
|
||||
|
||||
if (!device->pointer_focus)
|
||||
return;
|
||||
|
||||
device->time = _time;
|
||||
|
||||
event = gdk_event_new (GDK_TOUCHPAD_PINCH);
|
||||
event->touchpad_pinch.phase = phase;
|
||||
event->touchpad_pinch.window = g_object_ref (device->pointer_focus);
|
||||
gdk_event_set_device (event, device->master_pointer);
|
||||
gdk_event_set_source_device (event, device->pointer);
|
||||
event->touchpad_pinch.time = _time;
|
||||
event->touchpad_pinch.state = device->button_modifiers | device->key_modifiers;
|
||||
gdk_event_set_screen (event, display->screen);
|
||||
event->touchpad_pinch.dx = dx;
|
||||
event->touchpad_pinch.dy = dy;
|
||||
event->touchpad_pinch.scale = scale;
|
||||
event->touchpad_pinch.angle_delta = angle_delta * G_PI / 180;
|
||||
event->touchpad_pinch.n_fingers = n_fingers;
|
||||
|
||||
get_coordinates (device,
|
||||
&event->touchpad_pinch.x,
|
||||
&event->touchpad_pinch.y,
|
||||
&event->touchpad_pinch.x_root,
|
||||
&event->touchpad_pinch.y_root);
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("pinch event %d, coords: %f %f, device %p state %d",
|
||||
event->type, event->touchpad_pinch.x,
|
||||
event->touchpad_pinch.y, device,
|
||||
event->touchpad_pinch.state));
|
||||
|
||||
_gdk_wayland_display_deliver_event (device->display, event);
|
||||
}
|
||||
|
||||
static void
|
||||
gesture_pinch_begin (void *data,
|
||||
struct _wl_pointer_gesture_pinch *pinch,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
struct wl_surface *surface,
|
||||
uint32_t fingers)
|
||||
{
|
||||
GdkWaylandDeviceData *device = data;
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
|
||||
|
||||
_gdk_wayland_display_update_serial (display, serial);
|
||||
emit_gesture_pinch_event (device,
|
||||
GDK_TOUCHPAD_GESTURE_PHASE_BEGIN,
|
||||
time, fingers, 0, 0, 1, 0);
|
||||
device->gesture_n_fingers = fingers;
|
||||
}
|
||||
|
||||
static void
|
||||
gesture_pinch_update (void *data,
|
||||
struct _wl_pointer_gesture_pinch *pinch,
|
||||
uint32_t time,
|
||||
wl_fixed_t dx,
|
||||
wl_fixed_t dy,
|
||||
wl_fixed_t scale,
|
||||
wl_fixed_t rotation)
|
||||
{
|
||||
GdkWaylandDeviceData *device = data;
|
||||
|
||||
emit_gesture_pinch_event (device,
|
||||
GDK_TOUCHPAD_GESTURE_PHASE_UPDATE, time,
|
||||
device->gesture_n_fingers,
|
||||
wl_fixed_to_double (dx),
|
||||
wl_fixed_to_double (dy),
|
||||
wl_fixed_to_double (scale),
|
||||
wl_fixed_to_double (rotation));
|
||||
}
|
||||
|
||||
static void
|
||||
gesture_pinch_end (void *data,
|
||||
struct _wl_pointer_gesture_pinch *pinch,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
int32_t cancelled)
|
||||
{
|
||||
GdkWaylandDeviceData *device = data;
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
|
||||
GdkTouchpadGesturePhase phase;
|
||||
|
||||
_gdk_wayland_display_update_serial (display, serial);
|
||||
|
||||
phase = (cancelled) ?
|
||||
GDK_TOUCHPAD_GESTURE_PHASE_CANCEL :
|
||||
GDK_TOUCHPAD_GESTURE_PHASE_END;
|
||||
|
||||
emit_gesture_pinch_event (device, phase,
|
||||
time, device->gesture_n_fingers,
|
||||
0, 0, 1, 0);
|
||||
}
|
||||
|
||||
static const struct wl_pointer_listener pointer_listener = {
|
||||
pointer_handle_enter,
|
||||
pointer_handle_leave,
|
||||
@ -1678,6 +1892,18 @@ static const struct wl_touch_listener touch_listener = {
|
||||
touch_handle_cancel
|
||||
};
|
||||
|
||||
static const struct _wl_pointer_gesture_swipe_listener gesture_swipe_listener = {
|
||||
gesture_swipe_begin,
|
||||
gesture_swipe_update,
|
||||
gesture_swipe_end
|
||||
};
|
||||
|
||||
static const struct _wl_pointer_gesture_pinch_listener gesture_pinch_listener = {
|
||||
gesture_pinch_begin,
|
||||
gesture_pinch_update,
|
||||
gesture_pinch_end
|
||||
};
|
||||
|
||||
static void
|
||||
seat_handle_capabilities (void *data,
|
||||
struct wl_seat *seat,
|
||||
@ -1685,6 +1911,7 @@ seat_handle_capabilities (void *data,
|
||||
{
|
||||
GdkWaylandDeviceData *device = data;
|
||||
GdkWaylandDeviceManager *device_manager = GDK_WAYLAND_DEVICE_MANAGER (device->device_manager);
|
||||
GdkWaylandDisplay *wayland_display = GDK_WAYLAND_DISPLAY (device->display);
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("seat %p with %s%s%s", seat,
|
||||
@ -1715,6 +1942,24 @@ seat_handle_capabilities (void *data,
|
||||
|
||||
device->drop_context = _gdk_wayland_drop_context_new (device->master_pointer,
|
||||
device->data_device);
|
||||
if (wayland_display->pointer_gestures)
|
||||
{
|
||||
device->wl_pointer_gesture_swipe =
|
||||
_wl_pointer_gestures_get_swipe_gesture (wayland_display->pointer_gestures,
|
||||
device->wl_pointer);
|
||||
_wl_pointer_gesture_swipe_set_user_data (device->wl_pointer_gesture_swipe,
|
||||
device);
|
||||
_wl_pointer_gesture_swipe_add_listener (device->wl_pointer_gesture_swipe,
|
||||
&gesture_swipe_listener, device);
|
||||
|
||||
device->wl_pointer_gesture_pinch =
|
||||
_wl_pointer_gestures_get_pinch_gesture (wayland_display->pointer_gestures,
|
||||
device->wl_pointer);
|
||||
_wl_pointer_gesture_pinch_set_user_data (device->wl_pointer_gesture_pinch,
|
||||
device);
|
||||
_wl_pointer_gesture_pinch_add_listener (device->wl_pointer_gesture_pinch,
|
||||
&gesture_pinch_listener, device);
|
||||
}
|
||||
|
||||
g_signal_emit_by_name (device_manager, "device-added", device->pointer);
|
||||
}
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "gdkkeysprivate.h"
|
||||
#include "gdkprivate-wayland.h"
|
||||
#include "gdkglcontext-wayland.h"
|
||||
#include "pointer-gestures-client-protocol.h"
|
||||
|
||||
/**
|
||||
* SECTION:wayland_interaction
|
||||
@ -357,6 +358,11 @@ gdk_registry_handle_global (void *data,
|
||||
display_wayland->subcompositor =
|
||||
wl_registry_bind (display_wayland->wl_registry, id, &wl_subcompositor_interface, 1);
|
||||
}
|
||||
else if (strcmp (interface, "_wl_pointer_gestures") == 0)
|
||||
{
|
||||
display_wayland->pointer_gestures =
|
||||
wl_registry_bind (display_wayland->wl_registry, id, &_wl_pointer_gestures_interface, 1);
|
||||
}
|
||||
else
|
||||
handled = FALSE;
|
||||
|
||||
|
@ -71,6 +71,7 @@ struct _GdkWaylandDisplay
|
||||
struct wl_input_device *input_device;
|
||||
struct wl_data_device_manager *data_device_manager;
|
||||
struct wl_subcompositor *subcompositor;
|
||||
struct _wl_pointer_gestures *pointer_gestures;
|
||||
|
||||
GList *async_roundtrips;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user