122 lines
4.2 KiB
Diff
122 lines
4.2 KiB
Diff
|
diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h
|
||
|
index ebbcfd479e2c8bec747f2ef37ca344eb8cb48645..1946873ae846dcb1b26596fa61962b08b1e57228 100644
|
||
|
--- a/include/wlr/types/wlr_seat.h
|
||
|
+++ b/include/wlr/types/wlr_seat.h
|
||
|
@@ -119,9 +119,11 @@ struct wlr_touch_grab_interface {
|
||
|
void (*enter)(struct wlr_seat_touch_grab *grab, uint32_t time_msec,
|
||
|
struct wlr_touch_point *point);
|
||
|
void (*frame)(struct wlr_seat_touch_grab *grab);
|
||
|
- // XXX this will conflict with the actual touch cancel which is different so
|
||
|
- // we need to rename this
|
||
|
+ // Cancel grab
|
||
|
void (*cancel)(struct wlr_seat_touch_grab *grab);
|
||
|
+ // Send wl_touch::cancel
|
||
|
+ void (*wl_cancel)(struct wlr_seat_touch_grab *grab,
|
||
|
+ struct wlr_surface *surface);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
@@ -613,6 +615,14 @@ void wlr_seat_touch_send_up(struct wlr_seat *seat, uint32_t time_msec,
|
||
|
void wlr_seat_touch_send_motion(struct wlr_seat *seat, uint32_t time_msec,
|
||
|
int32_t touch_id, double sx, double sy);
|
||
|
|
||
|
+/**
|
||
|
+ * Notify the seat that this is a global gesture and the client should cancel
|
||
|
+ * processing it. The event will go to the client for the surface given.
|
||
|
+ * This function does not respect touch grabs: you probably want
|
||
|
+ * `wlr_seat_touch_notify_cancel()` instead.
|
||
|
+ */
|
||
|
+void wlr_seat_touch_send_cancel(struct wlr_seat *seat, struct wlr_surface *surface);
|
||
|
+
|
||
|
void wlr_seat_touch_send_frame(struct wlr_seat *seat);
|
||
|
|
||
|
/**
|
||
|
@@ -639,6 +649,13 @@ void wlr_seat_touch_notify_up(struct wlr_seat *seat, uint32_t time_msec,
|
||
|
void wlr_seat_touch_notify_motion(struct wlr_seat *seat, uint32_t time_msec,
|
||
|
int32_t touch_id, double sx, double sy);
|
||
|
|
||
|
+/**
|
||
|
+ * Notify the seat that this is a global gesture and the client should
|
||
|
+ * cancel processing it. Defers to any grab of the touch device.
|
||
|
+ */
|
||
|
+void wlr_seat_touch_notify_cancel(struct wlr_seat *seat,
|
||
|
+ struct wlr_surface *surface);
|
||
|
+
|
||
|
void wlr_seat_touch_notify_frame(struct wlr_seat *seat);
|
||
|
|
||
|
/**
|
||
|
diff --git a/types/seat/wlr_seat_touch.c b/types/seat/wlr_seat_touch.c
|
||
|
index 65a8c7c06c1d9ec35c68e0cb8e7b46ca3039fb3c..abc17ae2ce7a04bb1d533c794a754f30eb681375 100644
|
||
|
--- a/types/seat/wlr_seat_touch.c
|
||
|
+++ b/types/seat/wlr_seat_touch.c
|
||
|
@@ -41,6 +41,11 @@ static void default_touch_cancel(struct wlr_seat_touch_grab *grab) {
|
||
|
// cannot be cancelled
|
||
|
}
|
||
|
|
||
|
+static void default_touch_wl_cancel(struct wlr_seat_touch_grab *grab,
|
||
|
+ struct wlr_surface *surface) {
|
||
|
+ wlr_seat_touch_send_cancel(grab->seat, surface);
|
||
|
+}
|
||
|
+
|
||
|
const struct wlr_touch_grab_interface default_touch_grab_impl = {
|
||
|
.down = default_touch_down,
|
||
|
.up = default_touch_up,
|
||
|
@@ -48,6 +53,7 @@ const struct wlr_touch_grab_interface default_touch_grab_impl = {
|
||
|
.enter = default_touch_enter,
|
||
|
.frame = default_touch_frame,
|
||
|
.cancel = default_touch_cancel,
|
||
|
+ .wl_cancel = default_touch_wl_cancel,
|
||
|
};
|
||
|
|
||
|
|
||
|
@@ -238,6 +244,26 @@ void wlr_seat_touch_notify_frame(struct wlr_seat *seat) {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+void wlr_seat_touch_notify_cancel(struct wlr_seat *seat,
|
||
|
+ struct wlr_surface *surface) {
|
||
|
+ struct wlr_seat_touch_grab *grab = seat->touch_state.grab;
|
||
|
+ if (grab->interface->wl_cancel) {
|
||
|
+ grab->interface->wl_cancel(grab, surface);
|
||
|
+ }
|
||
|
+
|
||
|
+ struct wl_client *client = wl_resource_get_client(surface->resource);
|
||
|
+ struct wlr_seat_client *seat_client = wlr_seat_client_for_wl_client(seat, client);
|
||
|
+ if (seat_client == NULL) {
|
||
|
+ return;
|
||
|
+ }
|
||
|
+ struct wlr_touch_point *point, *tmp;
|
||
|
+ wl_list_for_each_safe(point, tmp, &seat->touch_state.touch_points, link) {
|
||
|
+ if (point->client == seat_client) {
|
||
|
+ touch_point_destroy(point);
|
||
|
+ }
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
static void handle_point_focus_destroy(struct wl_listener *listener,
|
||
|
void *data) {
|
||
|
struct wlr_touch_point *point =
|
||
|
@@ -376,6 +402,22 @@ void wlr_seat_touch_send_frame(struct wlr_seat *seat) {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+void wlr_seat_touch_send_cancel(struct wlr_seat *seat, struct wlr_surface *surface) {
|
||
|
+ struct wl_client *client = wl_resource_get_client(surface->resource);
|
||
|
+ struct wlr_seat_client *seat_client = wlr_seat_client_for_wl_client(seat, client);
|
||
|
+ if (seat_client == NULL) {
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ struct wl_resource *resource;
|
||
|
+ wl_resource_for_each(resource, &seat_client->touches) {
|
||
|
+ if (seat_client_from_touch_resource(resource) == NULL) {
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+ wl_touch_send_cancel(resource);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
int wlr_seat_touch_num_points(struct wlr_seat *seat) {
|
||
|
return wl_list_length(&seat->touch_state.touch_points);
|
||
|
}
|