From 930361b988d1a992132e3f69bd6eeb6af24b280c Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 22 Jul 2014 01:28:39 +0200 Subject: [PATCH] wayland: Handle window drags for touch events The grabbing state is now checked for both pointer/touch devices within the seat, and the grab start coordinates returned by meta_wayland_seat_get_grab_info(). https://bugzilla.gnome.org/show_bug.cgi?id=733631 --- src/wayland/meta-wayland-seat.c | 26 ++++++++++++--- src/wayland/meta-wayland-seat.h | 8 +++-- src/wayland/meta-wayland-surface.c | 29 ++++++++++------- src/wayland/meta-wayland-touch.c | 52 ++++++++++++++++++++++++++++++ src/wayland/meta-wayland-touch.h | 9 ++++++ 5 files changed, 105 insertions(+), 19 deletions(-) diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 9aaf51650..86ced3ec5 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -320,9 +320,27 @@ meta_wayland_seat_update_cursor_surface (MetaWaylandSeat *seat) } gboolean -meta_wayland_seat_can_grab_surface (MetaWaylandSeat *seat, - MetaWaylandSurface *surface, - uint32_t serial) +meta_wayland_seat_get_grab_info (MetaWaylandSeat *seat, + MetaWaylandSurface *surface, + uint32_t serial, + gfloat *x, + gfloat *y) { - return meta_wayland_pointer_can_grab_surface (&seat->pointer, surface, serial); + ClutterEventSequence *sequence; + + sequence = meta_wayland_touch_find_grab_sequence (&seat->touch, surface, serial); + + if (sequence) + meta_wayland_touch_get_press_coords (&seat->touch, sequence, x, y); + else if (meta_wayland_pointer_can_grab_surface (&seat->pointer, surface, serial)) + { + if (x) + *x = seat->pointer.grab_x; + if (y) + *y = seat->pointer.grab_y; + } + else + return FALSE; + + return TRUE; } diff --git a/src/wayland/meta-wayland-seat.h b/src/wayland/meta-wayland-seat.h index ee8e3d773..28034f34a 100644 --- a/src/wayland/meta-wayland-seat.h +++ b/src/wayland/meta-wayland-seat.h @@ -60,8 +60,10 @@ void meta_wayland_seat_set_input_focus (MetaWaylandSeat *seat, void meta_wayland_seat_repick (MetaWaylandSeat *seat); void meta_wayland_seat_update_cursor_surface (MetaWaylandSeat *seat); -gboolean meta_wayland_seat_can_grab_surface (MetaWaylandSeat *seat, - MetaWaylandSurface *surface, - uint32_t serial); +gboolean meta_wayland_seat_get_grab_info (MetaWaylandSeat *seat, + MetaWaylandSurface *surface, + uint32_t serial, + gfloat *x, + gfloat *y); #endif /* META_WAYLAND_SEAT_H */ diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 868ee5958..eed154ca3 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -811,7 +811,7 @@ xdg_surface_show_window_menu (struct wl_client *client, MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); MetaWaylandSurface *surface = wl_resource_get_user_data (resource); - if (!meta_wayland_seat_can_grab_surface (seat, surface, serial)) + if (!meta_wayland_seat_get_grab_info (seat, surface, serial, NULL, NULL)) return; meta_window_show_menu (surface->window, META_WINDOW_MENU_WM, x, y); @@ -820,7 +820,9 @@ xdg_surface_show_window_menu (struct wl_client *client, static gboolean begin_grab_op_on_surface (MetaWaylandSurface *surface, MetaWaylandSeat *seat, - MetaGrabOp grab_op) + MetaGrabOp grab_op, + gfloat x, + gfloat y) { MetaWindow *window = surface->window; @@ -836,8 +838,7 @@ begin_grab_op_on_surface (MetaWaylandSurface *surface, 1, /* button. XXX? */ 0, /* modmask */ meta_display_get_current_time_roundtrip (window->display), - seat->pointer.grab_x, - seat->pointer.grab_y); + x, y); } static void @@ -848,11 +849,12 @@ xdg_surface_move (struct wl_client *client, { MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + gfloat x, y; - if (!meta_wayland_seat_can_grab_surface (seat, surface, serial)) + if (!meta_wayland_seat_get_grab_info (seat, surface, serial, &x, &y)) return; - begin_grab_op_on_surface (surface, seat, META_GRAB_OP_MOVING); + begin_grab_op_on_surface (surface, seat, META_GRAB_OP_MOVING, x, y); } static MetaGrabOp @@ -891,11 +893,12 @@ xdg_surface_resize (struct wl_client *client, { MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + gfloat x, y; - if (!meta_wayland_seat_can_grab_surface (seat, surface, serial)) + if (!meta_wayland_seat_get_grab_info (seat, surface, serial, &x, &y)) return; - begin_grab_op_on_surface (surface, seat, grab_op_for_xdg_surface_resize_edge (edges)); + begin_grab_op_on_surface (surface, seat, grab_op_for_xdg_surface_resize_edge (edges), x, y); } static void @@ -1159,11 +1162,12 @@ wl_shell_surface_move (struct wl_client *client, { MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + gfloat x, y; - if (!meta_wayland_seat_can_grab_surface (seat, surface, serial)) + if (!meta_wayland_seat_get_grab_info (seat, surface, serial, &x, &y)) return; - begin_grab_op_on_surface (surface, seat, META_GRAB_OP_MOVING); + begin_grab_op_on_surface (surface, seat, META_GRAB_OP_MOVING, x, y); } static MetaGrabOp @@ -1202,11 +1206,12 @@ wl_shell_surface_resize (struct wl_client *client, { MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + gfloat x, y; - if (!meta_wayland_seat_can_grab_surface (seat, surface, serial)) + if (!meta_wayland_seat_get_grab_info (seat, surface, serial, &x, &y)) return; - begin_grab_op_on_surface (surface, seat, grab_op_for_wl_shell_surface_resize_edge (edges)); + begin_grab_op_on_surface (surface, seat, grab_op_for_wl_shell_surface_resize_edge (edges), x, y); } typedef enum { diff --git a/src/wayland/meta-wayland-touch.c b/src/wayland/meta-wayland-touch.c index e6470c12b..da86302ee 100644 --- a/src/wayland/meta-wayland-touch.c +++ b/src/wayland/meta-wayland-touch.c @@ -46,6 +46,8 @@ struct _MetaWaylandTouchInfo MetaWaylandTouchSurface *touch_surface; guint32 slot_serial; gint32 slot; + gfloat start_x; + gfloat start_y; gfloat x; gfloat y; guint updated : 1; @@ -231,6 +233,7 @@ meta_wayland_touch_update (MetaWaylandTouch *touch, touch_info = touch_get_info (touch, sequence, TRUE); touch_info->touch_surface = touch_surface_get (touch, surface); + clutter_event_get_coords (event, &touch_info->start_x, &touch_info->start_y); } else touch_info = touch_get_info (touch, sequence, FALSE); @@ -545,3 +548,52 @@ meta_wayland_touch_create_new_resource (MetaWaylandTouch *touch, wl_resource_set_implementation (cr, &touch_interface, touch, unbind_resource); wl_list_insert (&touch->resource_list, wl_resource_get_link (cr)); } + +ClutterEventSequence * +meta_wayland_touch_find_grab_sequence (MetaWaylandTouch *touch, + MetaWaylandSurface *surface, + uint32_t serial) +{ + MetaWaylandTouchInfo *touch_info; + ClutterEventSequence *sequence; + GHashTableIter iter; + + if (!touch->touches) + return NULL; + + g_hash_table_iter_init (&iter, touch->touches); + + while (g_hash_table_iter_next (&iter, (gpointer*) &sequence, + (gpointer*) &touch_info)) + { + if (touch_info->slot_serial == serial && + touch_info->touch_surface->surface == surface) + return sequence; + } + + return NULL; +} + +gboolean +meta_wayland_touch_get_press_coords (MetaWaylandTouch *touch, + ClutterEventSequence *sequence, + gfloat *x, + gfloat *y) +{ + MetaWaylandTouchInfo *touch_info; + + if (!touch->touches) + return FALSE; + + touch_info = g_hash_table_lookup (touch->touches, sequence); + + if (!touch_info) + return FALSE; + + if (x) + *x = touch_info->start_x; + if (y) + *y = touch_info->start_y; + + return TRUE; +} diff --git a/src/wayland/meta-wayland-touch.h b/src/wayland/meta-wayland-touch.h index 011e724be..beaf6caa5 100644 --- a/src/wayland/meta-wayland-touch.h +++ b/src/wayland/meta-wayland-touch.h @@ -61,4 +61,13 @@ void meta_wayland_touch_create_new_resource (MetaWaylandTouch *touch, void meta_wayland_touch_cancel (MetaWaylandTouch *touch); +ClutterEventSequence * meta_wayland_touch_find_grab_sequence (MetaWaylandTouch *touch, + MetaWaylandSurface *surface, + uint32_t serial); + +gboolean meta_wayland_touch_get_press_coords (MetaWaylandTouch *touch, + ClutterEventSequence *sequence, + gfloat *x, + gfloat *y); + #endif /* META_WAYLAND_TOUCH_H */