mirror of
https://codeberg.org/dwl/dwl-patches.git
synced 2025-10-28 18:44:22 +00:00
Add less-simple-touch-input
This commit is contained in:
parent
e071166664
commit
1bbf778597
236
less-simple-touch-input/less-simple-touch-input.patch
Normal file
236
less-simple-touch-input/less-simple-touch-input.patch
Normal file
@ -0,0 +1,236 @@
|
||||
From 81810896c3034d609ed1bf93e1e04641f9ddf818 Mon Sep 17 00:00:00 2001
|
||||
From: Micah N Gorrell <m@minego.net>
|
||||
Date: Fri, 9 Feb 2024 17:08:20 -0700
|
||||
Subject: [PATCH] Add support for touch screen input devices, and send the
|
||||
appropriate events to clients
|
||||
|
||||
---
|
||||
dwl.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 149 insertions(+)
|
||||
|
||||
diff --git a/dwl.c b/dwl.c
|
||||
index fa76db2..6bff6cd 100644
|
||||
--- a/dwl.c
|
||||
+++ b/dwl.c
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <wlr/types/wlr_session_lock_v1.h>
|
||||
#include <wlr/types/wlr_single_pixel_buffer_v1.h>
|
||||
#include <wlr/types/wlr_subcompositor.h>
|
||||
+#include <wlr/types/wlr_touch.h>
|
||||
#include <wlr/types/wlr_viewporter.h>
|
||||
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
||||
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
||||
@@ -158,6 +159,12 @@ typedef struct {
|
||||
struct wl_listener key;
|
||||
} KeyboardGroup;
|
||||
|
||||
+typedef struct TouchGroup {
|
||||
+ struct wl_list link;
|
||||
+ struct wlr_touch *touch;
|
||||
+ Monitor *m;
|
||||
+} TouchGroup;
|
||||
+
|
||||
typedef struct {
|
||||
/* Must keep these three elements in this order */
|
||||
unsigned int type; /* LayerShell */
|
||||
@@ -255,6 +262,7 @@ static void createlocksurface(struct wl_listener *listener, void *data);
|
||||
static void createmon(struct wl_listener *listener, void *data);
|
||||
static void createnotify(struct wl_listener *listener, void *data);
|
||||
static void createpointer(struct wlr_pointer *pointer);
|
||||
+static void createtouch(struct wlr_touch *touch);
|
||||
static void cursorframe(struct wl_listener *listener, void *data);
|
||||
static void destroydecoration(struct wl_listener *listener, void *data);
|
||||
static void destroydragicon(struct wl_listener *listener, void *data);
|
||||
@@ -321,6 +329,10 @@ static void togglefloating(const Arg *arg);
|
||||
static void togglefullscreen(const Arg *arg);
|
||||
static void toggletag(const Arg *arg);
|
||||
static void toggleview(const Arg *arg);
|
||||
+static void touchdown(struct wl_listener *listener, void *data);
|
||||
+static void touchup(struct wl_listener *listener, void *data);
|
||||
+static void touchframe(struct wl_listener *listener, void *data);
|
||||
+static void touchmotion(struct wl_listener *listener, void *data);
|
||||
static void unlocksession(struct wl_listener *listener, void *data);
|
||||
static void unmaplayersurfacenotify(struct wl_listener *listener, void *data);
|
||||
static void unmapnotify(struct wl_listener *listener, void *data);
|
||||
@@ -387,6 +399,7 @@ static struct wlr_output_layout *output_layout;
|
||||
static struct wlr_box sgeom;
|
||||
static struct wl_list mons;
|
||||
static Monitor *selmon;
|
||||
+static struct wl_list touches;
|
||||
|
||||
#ifdef XWAYLAND
|
||||
static void activatex11(struct wl_listener *listener, void *data);
|
||||
@@ -1015,6 +1028,16 @@ createpointer(struct wlr_pointer *pointer)
|
||||
wlr_cursor_attach_input_device(cursor, &pointer->base);
|
||||
}
|
||||
|
||||
+void
|
||||
+createtouch(struct wlr_touch *wlr_touch)
|
||||
+{
|
||||
+ TouchGroup *touch = ecalloc(1, sizeof(TouchGroup));
|
||||
+
|
||||
+ touch->touch = wlr_touch;
|
||||
+ wl_list_insert(&touches, &touch->link);
|
||||
+ wlr_cursor_attach_input_device(cursor, &wlr_touch->base);
|
||||
+}
|
||||
+
|
||||
void
|
||||
cursorframe(struct wl_listener *listener, void *data)
|
||||
{
|
||||
@@ -1344,6 +1367,9 @@ inputdevice(struct wl_listener *listener, void *data)
|
||||
case WLR_INPUT_DEVICE_POINTER:
|
||||
createpointer(wlr_pointer_from_input_device(device));
|
||||
break;
|
||||
+ case WLR_INPUT_DEVICE_TOUCH:
|
||||
+ createtouch(wlr_touch_from_input_device(device));
|
||||
+ break;
|
||||
default:
|
||||
/* TODO handle other input device types */
|
||||
break;
|
||||
@@ -1356,6 +1382,8 @@ inputdevice(struct wl_listener *listener, void *data)
|
||||
caps = WL_SEAT_CAPABILITY_POINTER;
|
||||
if (!wl_list_empty(&kb_group.wlr_group->devices))
|
||||
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
|
||||
+ if (!wl_list_empty(&touches))
|
||||
+ caps |= WL_SEAT_CAPABILITY_TOUCH;
|
||||
wlr_seat_set_capabilities(seat, caps);
|
||||
}
|
||||
|
||||
@@ -2325,6 +2353,13 @@ setup(void)
|
||||
LISTEN_STATIC(&cursor->events.axis, axisnotify);
|
||||
LISTEN_STATIC(&cursor->events.frame, cursorframe);
|
||||
|
||||
+ wl_list_init(&touches);
|
||||
+
|
||||
+ LISTEN_STATIC(&cursor->events.touch_down, touchdown);
|
||||
+ LISTEN_STATIC(&cursor->events.touch_frame, touchframe);
|
||||
+ LISTEN_STATIC(&cursor->events.touch_motion, touchmotion);
|
||||
+ LISTEN_STATIC(&cursor->events.touch_up, touchup);
|
||||
+
|
||||
cursor_shape_mgr = wlr_cursor_shape_manager_v1_create(dpy, 1);
|
||||
LISTEN_STATIC(&cursor_shape_mgr->events.request_set_shape, setcursorshape);
|
||||
|
||||
@@ -2541,6 +2576,120 @@ toggleview(const Arg *arg)
|
||||
printstatus();
|
||||
}
|
||||
|
||||
+void
|
||||
+touchdown(struct wl_listener *listener, void *data)
|
||||
+{
|
||||
+ struct wlr_touch_down_event *event = data;
|
||||
+ double lx, ly;
|
||||
+ double sx, sy;
|
||||
+ struct wlr_surface *surface;
|
||||
+ Client *c = NULL;
|
||||
+ uint32_t serial = 0;
|
||||
+ Monitor *m;
|
||||
+
|
||||
+ wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||
+
|
||||
+ // Map the input to the appropriate output, to ensure that rotation is
|
||||
+ // handled.
|
||||
+ wl_list_for_each(m, &mons, link) {
|
||||
+ if (m == NULL || m->wlr_output == NULL) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (event->touch->output_name != NULL && 0 != strcmp(event->touch->output_name, m->wlr_output->name)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ wlr_cursor_map_input_to_output(cursor, &event->touch->base, m->wlr_output);
|
||||
+ }
|
||||
+
|
||||
+ wlr_cursor_absolute_to_layout_coords(cursor, &event->touch->base, event->x, event->y, &lx, &ly);
|
||||
+
|
||||
+ /* Find the client under the pointer and send the event along. */
|
||||
+ xytonode(lx, ly, &surface, &c, NULL, &sx, &sy);
|
||||
+ // fprintf(stderr, "touch_down at %lf, %lf\n", lx, ly);
|
||||
+
|
||||
+ if (surface != NULL) {
|
||||
+ serial = wlr_seat_touch_notify_down(seat, surface, event->time_msec, event->touch_id, sx, sy);
|
||||
+ }
|
||||
+
|
||||
+ if (serial && wlr_seat_touch_num_points(seat) == 1) {
|
||||
+ /* Emulate a mouse click if the touch event wasn't handled */
|
||||
+ struct wlr_pointer_button_event *button_event = data;
|
||||
+
|
||||
+#ifdef POINTERCONSTRAINTS
|
||||
+ struct wlr_pointer_motion_absolute_event *event = data;
|
||||
+ double lx, ly, dx, dy;
|
||||
+
|
||||
+ wlr_cursor_absolute_to_layout_coords(cursor, &event->pointer->base, event->x, event->y, &lx, &ly);
|
||||
+ wlr_cursor_warp_closest(cursor, &event->pointer->base, lx, ly);
|
||||
+ dx = lx - cursor->x;
|
||||
+ dy = ly - cursor->y;
|
||||
+ motionnotify(event->time_msec, &event->pointer->base, dx, dy, dx, dy);
|
||||
+#else
|
||||
+ motionabsolute(listener, data);
|
||||
+#endif
|
||||
+
|
||||
+ button_event->button = BTN_LEFT;
|
||||
+ button_event->state = WLR_BUTTON_PRESSED;
|
||||
+ buttonpress(listener, button_event);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+touchup(struct wl_listener *listener, void *data)
|
||||
+{
|
||||
+ struct wlr_touch_up_event *event = data;
|
||||
+
|
||||
+ if (!wlr_seat_touch_get_point(seat, event->touch_id)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (wlr_seat_touch_num_points(seat) == 1) {
|
||||
+ struct wlr_pointer_button_event *button_event = data;
|
||||
+
|
||||
+ button_event->button = BTN_LEFT;
|
||||
+ button_event->state = WLR_BUTTON_RELEASED;
|
||||
+ buttonpress(listener, button_event);
|
||||
+ }
|
||||
+
|
||||
+ wlr_seat_touch_notify_up(seat, event->time_msec, event->touch_id);
|
||||
+ wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+touchframe(struct wl_listener *listener, void *data)
|
||||
+{
|
||||
+ wlr_seat_touch_notify_frame(seat);
|
||||
+ wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+touchmotion(struct wl_listener *listener, void *data)
|
||||
+{
|
||||
+ struct wlr_touch_motion_event *event = data;
|
||||
+ double lx, ly;
|
||||
+ double sx, sy;
|
||||
+ struct wlr_surface *surface;
|
||||
+ Client *c = NULL;
|
||||
+
|
||||
+ if (!wlr_seat_touch_get_point(seat, event->touch_id)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ wlr_cursor_absolute_to_layout_coords(cursor, &event->touch->base, event->x, event->y, &lx, &ly);
|
||||
+ xytonode(lx, ly, &surface, &c, NULL, &sx, &sy);
|
||||
+
|
||||
+ if (c != NULL) {
|
||||
+ wlr_seat_touch_point_focus(seat, surface, event->time_msec, event->touch_id, sx, sy);
|
||||
+ wlr_seat_touch_notify_motion(seat, event->time_msec, event->touch_id, sx, sy);
|
||||
+ } else {
|
||||
+ wlr_seat_touch_point_clear_focus(seat, event->time_msec, event->touch_id);
|
||||
+ }
|
||||
+
|
||||
+ wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||
+}
|
||||
+
|
||||
+
|
||||
void
|
||||
unlocksession(struct wl_listener *listener, void *data)
|
||||
{
|
||||
--
|
||||
2.43.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user