dotfiles/pkgs/rofi-wayland/0001-wip-touch-support.patch

182 lines
5.9 KiB
Diff

From 637fe90e0c69d77d2ad24576d924b041525fd941 Mon Sep 17 00:00:00 2001
From: chayleaf <chayleaf-git@pavluk.org>
Date: Sat, 24 Aug 2024 12:10:16 +0700
Subject: [PATCH 1/3] wip touch support
---
include/wayland-internal.h | 7 +++
source/wayland/display.c | 115 +++++++++++++++++++++++++++++++++++++
2 files changed, 122 insertions(+)
diff --git a/include/wayland-internal.h b/include/wayland-internal.h
index e6d248ce..77aaaf9d 100644
--- a/include/wayland-internal.h
+++ b/include/wayland-internal.h
@@ -84,6 +84,8 @@ typedef struct {
uint32_t layer_height;
} wayland_stuff;
+#define MAX_TOUCHPOINTS 10
+
struct _wayland_seat {
wayland_stuff *context;
uint32_t global_name;
@@ -99,6 +101,11 @@ struct _wayland_seat {
uint32_t pointer_serial;
struct wl_keyboard *keyboard;
struct wl_pointer *pointer;
+ struct wl_touch *touch;
+ struct {
+ int32_t x, start_y, move_y;
+ uint32_t start_time, move_time;
+ } touches[MAX_TOUCHPOINTS];
#ifdef HAVE_WAYLAND_CURSOR_SHAPE
struct wp_cursor_shape_device_v1 *cursor_shape_device;
diff --git a/source/wayland/display.c b/source/wayland/display.c
index 6cdc7d2f..381c402d 100644
--- a/source/wayland/display.c
+++ b/source/wayland/display.c
@@ -526,6 +526,101 @@ static const struct wl_keyboard_listener wayland_keyboard_listener = {
.repeat_info = wayland_keyboard_repeat_info,
};
+static void wayland_touch_down(void *data, struct wl_touch *wl_touch,
+ uint32_t serial, uint32_t time, struct wl_surface *wl_surface,
+ int32_t id, wl_fixed_t surface_x, wl_fixed_t surface_y) {
+ wayland_seat *self = data;
+ if (id >= MAX_TOUCHPOINTS) {
+ return;
+ }
+ self->touches[id].x = wl_fixed_to_int(surface_x);
+ self->touches[id].start_y = self->touches[id].move_y = wl_fixed_to_int(surface_y);
+ self->touches[id].start_time = self->touches[id].move_time = time;
+ RofiViewState *state = rofi_view_get_active();
+
+ if (state == NULL) {
+ return;
+ }
+ rofi_view_handle_mouse_motion(state, self->touches[id].x, self->touches[id].start_y,
+ FALSE);
+}
+
+static void wayland_touch_up(void *data, struct wl_touch *wl_touch,
+ uint32_t serial, uint32_t time, int32_t id) {
+ wayland_seat *self = data;
+ if (id >= MAX_TOUCHPOINTS) {
+ return;
+ }
+ gboolean is_move =
+ time - self->touches[id].start_time > 500
+ || self->touches[id].start_time != self->touches[id].move_time;
+ if (is_move) {
+ return;
+ }
+ RofiViewState *state = rofi_view_get_active();
+
+ if (state == NULL) {
+ return;
+ }
+ //rofi_view_handle_mouse_motion(state, self->touches[id].x, self->touches[id].start_y,
+ // FALSE);
+ nk_bindings_seat_handle_key(wayland->bindings_seat, NULL,
+ KEY_ENTER + 8,
+ NK_BINDINGS_KEY_STATE_PRESS);
+ rofi_view_maybe_update(state);
+}
+
+static int32_t y_offset_to_line_offset(int32_t y_offset) {
+ static const int32_t line_height = 20;
+ return -(y_offset / line_height);
+}
+
+static void wayland_touch_motion(void *data, struct wl_touch *wl_touch,
+ uint32_t time, int32_t id, wl_fixed_t surface_x, wl_fixed_t surface_y) {
+ wayland_seat *self = data;
+ if (id >= MAX_TOUCHPOINTS) {
+ return;
+ }
+ RofiViewState *state = rofi_view_get_active();
+
+ if (state == NULL) {
+ return;
+ }
+ int32_t x = wl_fixed_to_int(surface_x);
+ int32_t y = wl_fixed_to_int(surface_y);
+
+ int last_pos = y_offset_to_line_offset(self->touches[id].move_y - self->touches[id].start_y);
+ int cur_pos = y_offset_to_line_offset(y - self->touches[id].start_y);
+
+ if (cur_pos != last_pos) {
+ rofi_view_handle_mouse_motion(state, x, y, FALSE);
+ nk_bindings_seat_handle_scroll(wayland->bindings_seat, NULL,
+ NK_BINDINGS_SCROLL_AXIS_VERTICAL,
+ cur_pos - last_pos);
+ self->touches[id].x = x;
+ self->touches[id].move_y = y;
+ self->touches[id].move_time = time;
+ rofi_view_maybe_update(state);
+ }
+}
+
+static void wayland_touch_frame(void *data, struct wl_touch *wl_touch) { }
+static void wayland_touch_cancel(void *data, struct wl_touch *wl_touch) { }
+static void wayland_touch_shape(void *data, struct wl_touch *wl_touch,
+ int32_t id, wl_fixed_t major, wl_fixed_t minor) { }
+static void wayland_touch_orientation(void *data, struct wl_touch *wl_touch,
+ int32_t id, wl_fixed_t orientation) { }
+
+static const struct wl_touch_listener wayland_touch_listener = {
+ .down = wayland_touch_down,
+ .up = wayland_touch_up,
+ .motion = wayland_touch_motion,
+ .frame = wayland_touch_frame,
+ .cancel = wayland_touch_cancel,
+ .shape = wayland_touch_shape,
+ .orientation = wayland_touch_orientation,
+};
+
static gboolean wayland_cursor_reload_theme(guint scale);
static void wayland_cursor_set_image(int i) {
@@ -1081,9 +1176,20 @@ static void wayland_pointer_release(wayland_seat *self) {
self->pointer = NULL;
}
+static void wayland_touch_release(wayland_seat *self) {
+ if (self->touch == NULL) {
+ return;
+ }
+
+ wl_touch_release(self->touch);
+
+ self->touch = NULL;
+}
+
static void wayland_seat_release(wayland_seat *self) {
wayland_keyboard_release(self);
wayland_pointer_release(self);
+ wayland_touch_release(self);
wl_seat_release(self->seat);
@@ -1113,6 +1219,15 @@ static void wayland_seat_capabilities(void *data, struct wl_seat *seat,
wayland_pointer_release(self);
}
+ if ((capabilities & WL_SEAT_CAPABILITY_TOUCH) &&
+ (self->touch == NULL)) {
+ self->touch = wl_seat_get_touch(self->seat);
+ wl_touch_add_listener(self->touch, &wayland_touch_listener, self);
+ } else if ((!(capabilities & WL_SEAT_CAPABILITY_TOUCH)) &&
+ (self->touch != NULL)) {
+ wayland_touch_release(self);
+ }
+
if (wayland->data_device_manager != NULL) {
self->data_device = wl_data_device_manager_get_data_device(
wayland->data_device_manager, seat);
--
2.45.2