aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/types/wlr_data_device.h1
-rw-r--r--include/wlr/types/wlr_seat.h2
-rw-r--r--types/wlr_data_device.c60
-rw-r--r--types/wlr_seat.c3
4 files changed, 61 insertions, 5 deletions
diff --git a/include/wlr/types/wlr_data_device.h b/include/wlr/types/wlr_data_device.h
index f45c15a2..6e8d0a73 100644
--- a/include/wlr/types/wlr_data_device.h
+++ b/include/wlr/types/wlr_data_device.h
@@ -53,6 +53,7 @@ struct wlr_data_source {
struct wlr_drag {
struct wlr_seat_pointer_grab pointer_grab;
struct wlr_seat_keyboard_grab keyboard_grab;
+ struct wlr_seat_touch_grab touch_grab;
struct wlr_seat_client *seat_client;
struct wlr_seat_client *focus_client;
diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h
index f429fb8e..8950722f 100644
--- a/include/wlr/types/wlr_seat.h
+++ b/include/wlr/types/wlr_seat.h
@@ -143,6 +143,8 @@ struct wlr_seat_touch_state {
struct wlr_seat *seat;
struct wl_list touch_points; // wlr_touch_point::link
+ uint32_t grab_serial;
+
struct wlr_seat_touch_grab *grab;
struct wlr_seat_touch_grab *default_grab;
};
diff --git a/types/wlr_data_device.c b/types/wlr_data_device.c
index df18317b..ca18a4d6 100644
--- a/types/wlr_data_device.c
+++ b/types/wlr_data_device.c
@@ -521,6 +521,31 @@ wlr_pointer_grab_interface wlr_data_device_pointer_drag_interface = {
.cancel = pointer_drag_cancel,
};
+static void touch_drag_down(struct wlr_seat_touch_grab *grab, struct wlr_surface *surface,
+ uint32_t time, int32_t touch_id, double sx, double sy) {
+ // TODO
+}
+
+static void touch_drag_up(struct wlr_seat_touch_grab *grab, uint32_t time, int32_t touch_id) {
+ // TODO
+}
+
+static void touch_drag_motion(struct wlr_seat_touch_grab *grab, uint32_t time, int32_t
+ touch_id, double sx, double sy) {
+ // TODO
+}
+
+static void touch_drag_cancel(struct wlr_seat_touch_grab *grab) {
+ // TODO
+}
+
+const struct wlr_touch_grab_interface wlr_data_device_touch_drag_interface = {
+ .down = touch_drag_down,
+ .up = touch_drag_up,
+ .motion = touch_drag_motion,
+ .cancel = touch_drag_cancel,
+};
+
static void keyboard_drag_enter(struct wlr_seat_keyboard_grab *grab,
struct wlr_surface *surface) {
// nothing has keyboard focus during drags
@@ -562,12 +587,30 @@ static void drag_handle_drag_source_destroy(struct wl_listener *listener,
}
static bool seat_client_start_drag(struct wlr_seat_client *client,
- struct wlr_data_source *source, struct wlr_surface *icon) {
+ struct wlr_data_source *source, struct wlr_surface *icon,
+ struct wlr_surface *origin, uint32_t serial) {
struct wlr_drag *drag = calloc(1, sizeof(struct wlr_drag));
if (drag == NULL) {
return false;
}
+ struct wlr_seat_pointer_state pointer_state = client->seat->pointer_state;
+ struct wlr_seat_touch_state touch_state = client->seat->touch_state;
+
+ bool is_pointer_grab = client->pointer &&
+ pointer_state.button_count == 1 &&
+ pointer_state.grab_serial == serial &&
+ pointer_state.focused_surface &&
+ pointer_state.focused_surface == origin;
+
+ bool is_touch_grab = client->touch &&
+ wl_list_length(&touch_state.touch_points) == 1 &&
+ touch_state.grab_serial == serial;
+
+ if (!is_pointer_grab || !is_touch_grab) {
+ return true;
+ }
+
struct wlr_seat *seat = client->seat;
if (icon) {
@@ -587,13 +630,20 @@ static bool seat_client_start_drag(struct wlr_seat_client *client,
drag->pointer_grab.data = drag;
drag->pointer_grab.interface = &wlr_data_device_pointer_drag_interface;
+ drag->touch_grab.data = drag;
+ drag->touch_grab.interface = &wlr_data_device_touch_drag_interface;
+
drag->keyboard_grab.data = drag;
drag->keyboard_grab.interface = &wlr_data_device_keyboard_drag_interface;
- wlr_seat_pointer_clear_focus(seat);
-
wlr_seat_keyboard_start_grab(seat, &drag->keyboard_grab);
- wlr_seat_pointer_start_grab(seat, &drag->pointer_grab);
+
+ if (is_pointer_grab) {
+ wlr_seat_pointer_clear_focus(seat);
+ wlr_seat_pointer_start_grab(seat, &drag->pointer_grab);
+ } else {
+ wlr_seat_touch_start_grab(seat, &drag->touch_grab);
+ }
return true;
}
@@ -634,7 +684,7 @@ static void data_device_start_drag(struct wl_client *client,
// TODO touch grab
- if (!seat_client_start_drag(seat_client, source, icon)) {
+ if (!seat_client_start_drag(seat_client, source, icon, origin, serial)) {
wl_resource_post_no_memory(device_resource);
} else {
source->seat_client = seat_client;
diff --git a/types/wlr_seat.c b/types/wlr_seat.c
index 2d6d800f..212373df 100644
--- a/types/wlr_seat.c
+++ b/types/wlr_seat.c
@@ -961,6 +961,9 @@ void wlr_seat_touch_notify_down(struct wlr_seat *seat,
double sy) {
struct wlr_seat_touch_grab *grab = seat->touch_state.grab;
grab->interface->down(grab, surface, time, touch_id, sx, sy);
+ if (wl_list_length(&seat->touch_state.touch_points) == 1) {
+ seat->touch_state.grab_serial = wl_display_get_serial(seat->display);
+ }
}
void wlr_seat_touch_notify_up(struct wlr_seat *seat, uint32_t time,