diff --git a/include/rootston/seat.h b/include/rootston/seat.h index e5a1dc71..c9dc883c 100644 --- a/include/rootston/seat.h +++ b/include/rootston/seat.h @@ -26,6 +26,9 @@ struct roots_seat { struct wl_list link; struct wl_list drag_icons; + // coordinates of the touch grab if one exists + double touch_grab_x, touch_grab_y; + struct roots_view *focus; struct wl_list keyboards; diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index ee13f99d..716e37c5 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -321,6 +321,11 @@ uint32_t wlr_seat_pointer_notify_button(struct wlr_seat *wlr_seat, void wlr_seat_pointer_notify_axis(struct wlr_seat *wlr_seat, uint32_t time, enum wlr_axis_orientation orientation, double value); +/** + * Whether or not the pointer has a grab other than the default grab. + */ +bool wlr_seat_pointer_has_grab(struct wlr_seat *seat); + /** * Set this keyboard as the active keyboard for the seat. */ @@ -388,6 +393,11 @@ void wlr_seat_keyboard_enter(struct wlr_seat *wlr_seat, */ void wlr_seat_keyboard_clear_focus(struct wlr_seat *wlr_seat); +/** + * Whether or not the keyboard has a grab other than the default grab + */ +bool wlr_seat_keyboard_has_grab(struct wlr_seat *seat); + /** * Start a grab of the touch device of this seat. The grabber is responsible for * handling all touch events until the grab ends. @@ -477,4 +487,9 @@ void wlr_seat_touch_send_up(struct wlr_seat *seat, uint32_t time, void wlr_seat_touch_send_motion(struct wlr_seat *seat, uint32_t time, int32_t touch_id, double sx, double sy); +/** + * Whether or not the seat has a touch grab other than the default grab. + */ +bool wlr_seat_touch_has_grab(struct wlr_seat *seat); + #endif diff --git a/rootston/cursor.c b/rootston/cursor.c index 16441f4b..7e261234 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -270,6 +270,11 @@ void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, wlr_seat_touch_point_clear_focus(cursor->seat->seat, event->time_msec, event->slot); } + + if (wlr_seat_touch_has_grab(cursor->seat->seat)) { + cursor->seat->touch_grab_x = lx; + cursor->seat->touch_grab_y = ly; + } } void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, diff --git a/rootston/output.c b/rootston/output.c index 82760632..0b13a959 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -209,8 +209,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { struct wlr_touch_point *point = wlr_seat_touch_get_point(seat->seat, drag_icon->touch_id); if (point) { - icon_x = point->sx + drag_icon->sx; // TODO plus view x - icon_y = point->sy + drag_icon->sy; // TODO plus view y + icon_x = seat->touch_grab_x + drag_icon->sx; + icon_y = seat->touch_grab_y + drag_icon->sy; render_surface(icon, desktop, wlr_output, &now, icon_x, icon_y, 0); } } diff --git a/types/wlr_seat.c b/types/wlr_seat.c index eb73b174..8d9201bb 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -672,6 +672,10 @@ void wlr_seat_pointer_notify_axis(struct wlr_seat *wlr_seat, uint32_t time, grab->interface->axis(grab, time, orientation, value); } +bool wlr_seat_pointer_has_grab(struct wlr_seat *seat) { + return seat->pointer_state.grab->interface != &default_pointer_grab_impl; +} + void wlr_seat_keyboard_send_key(struct wlr_seat *wlr_seat, uint32_t time, uint32_t key, uint32_t state) { struct wlr_seat_client *client = wlr_seat->keyboard_state.focused_client; @@ -869,6 +873,10 @@ void wlr_seat_keyboard_clear_focus(struct wlr_seat *seat) { wlr_seat_keyboard_enter(seat, NULL); } +bool wlr_seat_keyboard_has_grab(struct wlr_seat *seat) { + return seat->keyboard_state.grab->interface != &default_keyboard_grab_impl; +} + void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat) { clock_gettime(CLOCK_MONOTONIC, &seat->last_event); struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab; @@ -1129,3 +1137,7 @@ void wlr_seat_touch_send_motion(struct wlr_seat *seat, uint32_t time, int32_t to wl_fixed_from_double(sx), wl_fixed_from_double(sy)); wl_touch_send_frame(point->client->touch); } + +bool wlr_seat_touch_has_grab(struct wlr_seat *seat) { + return seat->touch_state.grab->interface != &default_touch_grab_impl; +}