mirror of
https://codeberg.org/dwl/dwl-patches.git
synced 2025-12-15 01:13:20 +00:00
It's declared in the later versions of the patch but here it was not and It was causing compilation errors and adding the function manually from the later version causes seg faults. From what I see it's not required in dwl 0.7 with wlroots 0.18 I just removed the line and kept the patch as it is to keep the credits for who made this update and also I tested it and it worked with no problem.
358 lines
13 KiB
Diff
358 lines
13 KiB
Diff
From 9221dab35862605bd8768652488f8d6211f15a3e Mon Sep 17 00:00:00 2001
|
|
From: Fernando Otto <fernandootto369@gmail.com>
|
|
Date: Tue, 14 Oct 2025 12:52:30 -0300
|
|
Subject: [PATCH] Fixing disconnect with the graphics tablet
|
|
|
|
---
|
|
Makefile | 6 +-
|
|
config.def.h | 1 +
|
|
dwl.c | 226 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
3 files changed, 232 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/Makefile b/Makefile
|
|
index 3358bae..47a2bb2 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -21,7 +21,8 @@ dwl: dwl.o util.o
|
|
$(CC) dwl.o util.o $(DWLCFLAGS) $(LDFLAGS) $(LDLIBS) -o $@
|
|
dwl.o: dwl.c client.h config.h config.mk cursor-shape-v1-protocol.h \
|
|
pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h \
|
|
- wlr-output-power-management-unstable-v1-protocol.h xdg-shell-protocol.h
|
|
+ wlr-output-power-management-unstable-v1-protocol.h xdg-shell-protocol.h \
|
|
+ tablet-v2-protocol.h
|
|
util.o: util.c util.h
|
|
|
|
# wayland-scanner is a tool which generates C headers and rigging for Wayland
|
|
@@ -45,6 +46,9 @@ wlr-output-power-management-unstable-v1-protocol.h:
|
|
xdg-shell-protocol.h:
|
|
$(WAYLAND_SCANNER) server-header \
|
|
$(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@
|
|
+tablet-v2-protocol.h:
|
|
+ $(WAYLAND_SCANNER) server-header \
|
|
+ $(WAYLAND_PROTOCOLS)/unstable/tablet/tablet-unstable-v2.xml $@
|
|
|
|
config.h:
|
|
cp config.def.h $@
|
|
diff --git a/config.def.h b/config.def.h
|
|
index 22d2171..3ad98ef 100644
|
|
--- a/config.def.h
|
|
+++ b/config.def.h
|
|
@@ -4,6 +4,7 @@
|
|
((hex >> 8) & 0xFF) / 255.0f, \
|
|
(hex & 0xFF) / 255.0f }
|
|
/* appearance */
|
|
+static const int tabletmaptosurface = 0; /* map tablet input to surface(1) or monitor(0) */
|
|
static const int sloppyfocus = 1; /* focus follows mouse */
|
|
static const int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */
|
|
static const unsigned int borderpx = 1; /* border pixel of windows */
|
|
diff --git a/dwl.c b/dwl.c
|
|
index a2711f6..97d3d53 100644
|
|
--- a/dwl.c
|
|
+++ b/dwl.c
|
|
@@ -50,6 +50,9 @@
|
|
#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_tablet_tool.h>
|
|
+#include <wlr/types/wlr_tablet_pad.h>
|
|
+#include <wlr/types/wlr_tablet_v2.h>
|
|
#include <wlr/types/wlr_viewporter.h>
|
|
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
|
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
|
@@ -270,6 +273,7 @@ static void createnotify(struct wl_listener *listener, void *data);
|
|
static void createpointer(struct wlr_pointer *pointer);
|
|
static void createpointerconstraint(struct wl_listener *listener, void *data);
|
|
static void createpopup(struct wl_listener *listener, void *data);
|
|
+static void createtablet(struct wlr_input_device *device);
|
|
static void cursorconstrain(struct wlr_pointer_constraint_v1 *constraint);
|
|
static void cursorframe(struct wl_listener *listener, void *data);
|
|
static void cursorwarptohint(void);
|
|
@@ -284,6 +288,9 @@ static void destroypointerconstraint(struct wl_listener *listener, void *data);
|
|
static void destroysessionlock(struct wl_listener *listener, void *data);
|
|
static void destroysessionmgr(struct wl_listener *listener, void *data);
|
|
static void destroykeyboardgroup(struct wl_listener *listener, void *data);
|
|
+static void destroytablet(struct wl_listener *listener, void *data);
|
|
+static void destroytabletsurfacenotify(struct wl_listener *listener, void *data);
|
|
+static void destroytablettool(struct wl_listener *listener, void *data);
|
|
static Monitor *dirtomon(enum wlr_direction dir);
|
|
static void focusclient(Client *c, int lift);
|
|
static void focusmon(const Arg *arg);
|
|
@@ -337,6 +344,11 @@ static void spawn(const Arg *arg);
|
|
static void startdrag(struct wl_listener *listener, void *data);
|
|
static void tag(const Arg *arg);
|
|
static void tagmon(const Arg *arg);
|
|
+static void tablettoolmotion(struct wlr_tablet_v2_tablet_tool *tool, bool change_x, bool change_y, double x, double y, double dx, double dy);
|
|
+static void tablettoolproximity(struct wl_listener *listener, void *data);
|
|
+static void tablettoolaxis(struct wl_listener *listener, void *data);
|
|
+static void tablettoolbutton(struct wl_listener *listener, void *data);
|
|
+static void tablettooltip(struct wl_listener *listener, void *data);
|
|
static void tile(Monitor *m);
|
|
static void togglefloating(const Arg *arg);
|
|
static void togglefullscreen(const Arg *arg);
|
|
@@ -396,6 +408,13 @@ static struct wlr_pointer_constraint_v1 *active_constraint;
|
|
static struct wlr_cursor *cursor;
|
|
static struct wlr_xcursor_manager *cursor_mgr;
|
|
|
|
+static struct wlr_tablet_manager_v2 *tablet_mgr;
|
|
+static struct wlr_tablet_v2_tablet *tablet = NULL;
|
|
+static struct wlr_tablet_v2_tablet_tool *tablet_tool = NULL;
|
|
+static struct wlr_tablet_v2_tablet_pad *tablet_pad = NULL;
|
|
+static struct wlr_surface *tablet_curr_surface = NULL;
|
|
+static struct wl_listener destroy_tablet_surface_listener = {.notify = destroytabletsurfacenotify};
|
|
+
|
|
static struct wlr_scene_rect *root_bg;
|
|
static struct wlr_session_lock_manager_v1 *session_lock_mgr;
|
|
static struct wlr_scene_rect *locked_bg;
|
|
@@ -1133,6 +1152,28 @@ createpopup(struct wl_listener *listener, void *data)
|
|
LISTEN_STATIC(&popup->base->surface->events.commit, commitpopup);
|
|
}
|
|
|
|
+void
|
|
+createtablet(struct wlr_input_device *device)
|
|
+{
|
|
+ if (!tablet) {
|
|
+ struct libinput_device *device_handle = NULL;
|
|
+ if (!wlr_input_device_is_libinput(device) ||
|
|
+ !(device_handle = wlr_libinput_get_device_handle(device)))
|
|
+ return;
|
|
+
|
|
+ tablet = wlr_tablet_create(tablet_mgr, seat, device);
|
|
+ LISTEN_STATIC(&tablet->wlr_device->events.destroy, destroytablet);
|
|
+ if (libinput_device_config_send_events_get_modes(device_handle)) {
|
|
+ libinput_device_config_send_events_set_mode(device_handle, send_events_mode);
|
|
+ wlr_cursor_attach_input_device(cursor, device);
|
|
+ }
|
|
+ } else if (device == tablet->wlr_device) {
|
|
+ wlr_log(WLR_ERROR, "createtablet: duplicate device");
|
|
+ } else {
|
|
+ wlr_log(WLR_ERROR, "createtablet: already have one tablet");
|
|
+ }
|
|
+}
|
|
+
|
|
void
|
|
cursorconstrain(struct wlr_pointer_constraint_v1 *constraint)
|
|
{
|
|
@@ -1320,6 +1361,29 @@ destroykeyboardgroup(struct wl_listener *listener, void *data)
|
|
free(group);
|
|
}
|
|
|
|
+void
|
|
+destroytablet(struct wl_listener *listener, void *data)
|
|
+{
|
|
+
|
|
+ wlr_cursor_detach_input_device(cursor, tablet->wlr_device);
|
|
+ tablet = NULL;
|
|
+}
|
|
+
|
|
+void
|
|
+destroytabletsurfacenotify(struct wl_listener *listener, void *data)
|
|
+{
|
|
+ if (tablet_curr_surface)
|
|
+ wl_list_remove(&destroy_tablet_surface_listener.link);
|
|
+ tablet_curr_surface = NULL;
|
|
+}
|
|
+
|
|
+void
|
|
+destroytablettool(struct wl_listener *listener, void *data)
|
|
+{
|
|
+ destroytabletsurfacenotify(NULL, NULL);
|
|
+ tablet_tool = NULL;
|
|
+}
|
|
+
|
|
Monitor *
|
|
dirtomon(enum wlr_direction dir)
|
|
{
|
|
@@ -1539,6 +1603,12 @@ inputdevice(struct wl_listener *listener, void *data)
|
|
case WLR_INPUT_DEVICE_POINTER:
|
|
createpointer(wlr_pointer_from_input_device(device));
|
|
break;
|
|
+ case WLR_INPUT_DEVICE_TABLET:
|
|
+ createtablet(device);
|
|
+ break;
|
|
+ case WLR_INPUT_DEVICE_TABLET_PAD:
|
|
+ tablet_pad = wlr_tablet_pad_create(tablet_mgr, seat, device);
|
|
+ break;
|
|
default:
|
|
/* TODO handle other input device types */
|
|
break;
|
|
@@ -2566,6 +2636,8 @@ setup(void)
|
|
|
|
relative_pointer_mgr = wlr_relative_pointer_manager_v1_create(dpy);
|
|
|
|
+ tablet_mgr = wlr_tablet_v2_create(dpy);
|
|
+
|
|
/*
|
|
* Creates a cursor, which is a wlroots utility for tracking the cursor
|
|
* image shown on screen.
|
|
@@ -2595,6 +2667,10 @@ setup(void)
|
|
LISTEN_STATIC(&cursor->events.button, buttonpress);
|
|
LISTEN_STATIC(&cursor->events.axis, axisnotify);
|
|
LISTEN_STATIC(&cursor->events.frame, cursorframe);
|
|
+ LISTEN_STATIC(&cursor->events.tablet_tool_proximity, tablettoolproximity);
|
|
+ LISTEN_STATIC(&cursor->events.tablet_tool_axis, tablettoolaxis);
|
|
+ LISTEN_STATIC(&cursor->events.tablet_tool_button, tablettoolbutton);
|
|
+ LISTEN_STATIC(&cursor->events.tablet_tool_tip, tablettooltip);
|
|
|
|
cursor_shape_mgr = wlr_cursor_shape_manager_v1_create(dpy, 1);
|
|
LISTEN_STATIC(&cursor_shape_mgr->events.request_set_shape, setcursorshape);
|
|
@@ -2688,6 +2764,156 @@ tagmon(const Arg *arg)
|
|
setmon(sel, dirtomon(arg->i), 0);
|
|
}
|
|
|
|
+void
|
|
+tabletapplymap(double x, double y, struct wlr_input_device *dev)
|
|
+{
|
|
+ Client *p;
|
|
+ struct wlr_box geom = {0};
|
|
+ if (tabletmaptosurface && tablet_curr_surface) {
|
|
+ toplevel_from_wlr_surface(tablet_curr_surface, &p, NULL);
|
|
+ if (p) {
|
|
+ for (; client_get_parent(p); p = client_get_parent(p));
|
|
+ geom.x = p->geom.x + p->bw;
|
|
+ geom.y = p->geom.y + p->bw;
|
|
+ geom.width = p->geom.width - 2 * p->bw;
|
|
+ geom.height = p->geom.height - 2 * p->bw;
|
|
+ }
|
|
+ }
|
|
+ wlr_cursor_map_input_to_region(cursor, dev, &geom);
|
|
+ wlr_cursor_map_input_to_output(cursor, dev, selmon->wlr_output);
|
|
+}
|
|
+
|
|
+void
|
|
+tablettoolmotion(struct wlr_tablet_v2_tablet_tool *tool, bool change_x, bool change_y,
|
|
+ double x, double y, double dx, double dy)
|
|
+{
|
|
+ struct wlr_surface *surface = NULL;
|
|
+ double sx, sy;
|
|
+
|
|
+ if (!change_x && !change_y)
|
|
+ return;
|
|
+
|
|
+ tabletapplymap(x, y, tablet->wlr_device);
|
|
+
|
|
+ // TODO: apply constraints
|
|
+ switch (tablet_tool->wlr_tool->type) {
|
|
+ case WLR_TABLET_TOOL_TYPE_LENS:
|
|
+ case WLR_TABLET_TOOL_TYPE_MOUSE:
|
|
+ wlr_cursor_move(cursor, tablet->wlr_device, dx, dy);
|
|
+ break;
|
|
+ default:
|
|
+ wlr_cursor_warp_absolute(cursor, tablet->wlr_device, change_x ? x : NAN, change_y ? y : NAN);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ motionnotify(0, NULL, 0, 0, 0, 0);
|
|
+
|
|
+ xytonode(cursor->x, cursor->y, &surface, NULL, NULL, &sx, &sy);
|
|
+ if (surface && !wlr_surface_accepts_tablet_v2(tablet, surface))
|
|
+ surface = NULL;
|
|
+
|
|
+ if (surface != tablet_curr_surface) {
|
|
+ if (tablet_curr_surface) {
|
|
+ // TODO: wait until all buttons released before leaving
|
|
+ if (tablet_tool)
|
|
+ wlr_tablet_v2_tablet_tool_notify_proximity_out(tablet_tool);
|
|
+ if (tablet_pad)
|
|
+ wlr_tablet_v2_tablet_pad_notify_leave(tablet_pad, tablet_curr_surface);
|
|
+ wl_list_remove(&destroy_tablet_surface_listener.link);
|
|
+ }
|
|
+ if (surface) {
|
|
+ if (tablet_pad)
|
|
+ wlr_tablet_v2_tablet_pad_notify_enter(tablet_pad, tablet, surface);
|
|
+ if (tablet_tool)
|
|
+ wlr_tablet_v2_tablet_tool_notify_proximity_in(tablet_tool, tablet, surface);
|
|
+ wl_signal_add(&surface->events.destroy, &destroy_tablet_surface_listener);
|
|
+ }
|
|
+ tablet_curr_surface = surface;
|
|
+ }
|
|
+
|
|
+ if (surface)
|
|
+ wlr_tablet_v2_tablet_tool_notify_motion(tablet_tool, sx, sy);
|
|
+}
|
|
+
|
|
+void
|
|
+tablettoolproximity(struct wl_listener *listener, void *data)
|
|
+{
|
|
+ struct wlr_tablet_tool_proximity_event *event = data;
|
|
+ struct wlr_tablet_tool *tool = event->tool;
|
|
+
|
|
+ if (!tablet_tool) {
|
|
+ tablet_tool = wlr_tablet_tool_create(tablet_mgr, seat, tool);
|
|
+ LISTEN_STATIC(&tablet_tool->wlr_tool->events.destroy, destroytablettool);
|
|
+ LISTEN_STATIC(&tablet_tool->events.set_cursor, setcursor);
|
|
+ }
|
|
+
|
|
+ switch (event->state) {
|
|
+ case WLR_TABLET_TOOL_PROXIMITY_OUT:
|
|
+ wlr_tablet_v2_tablet_tool_notify_proximity_out(tablet_tool);
|
|
+ destroytabletsurfacenotify(NULL, NULL);
|
|
+ break;
|
|
+ case WLR_TABLET_TOOL_PROXIMITY_IN:
|
|
+ tablettoolmotion(tablet_tool, true, true, event->x, event->y, 0, 0);
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+tablettoolaxis(struct wl_listener *listener, void *data)
|
|
+{
|
|
+ struct wlr_tablet_tool_axis_event *event = data;
|
|
+
|
|
+ tablettoolmotion(tablet_tool,
|
|
+ event->updated_axes & WLR_TABLET_TOOL_AXIS_X,
|
|
+ event->updated_axes & WLR_TABLET_TOOL_AXIS_Y,
|
|
+ event->x, event->y, event->dx, event->dy);
|
|
+
|
|
+ if (event->updated_axes & WLR_TABLET_TOOL_AXIS_PRESSURE)
|
|
+ wlr_tablet_v2_tablet_tool_notify_pressure(tablet_tool, event->pressure);
|
|
+ if (event->updated_axes & WLR_TABLET_TOOL_AXIS_DISTANCE)
|
|
+ wlr_tablet_v2_tablet_tool_notify_distance(tablet_tool, event->distance);
|
|
+ if (event->updated_axes & (WLR_TABLET_TOOL_AXIS_TILT_X | WLR_TABLET_TOOL_AXIS_TILT_Y))
|
|
+ wlr_tablet_v2_tablet_tool_notify_tilt(tablet_tool, event->tilt_x, event->tilt_y);
|
|
+ if (event->updated_axes & WLR_TABLET_TOOL_AXIS_ROTATION)
|
|
+ wlr_tablet_v2_tablet_tool_notify_rotation(tablet_tool, event->rotation);
|
|
+ if (event->updated_axes & WLR_TABLET_TOOL_AXIS_SLIDER)
|
|
+ wlr_tablet_v2_tablet_tool_notify_slider(tablet_tool, event->slider);
|
|
+ if (event->updated_axes & WLR_TABLET_TOOL_AXIS_WHEEL)
|
|
+ wlr_tablet_v2_tablet_tool_notify_wheel(tablet_tool, event->wheel_delta, 0);
|
|
+}
|
|
+
|
|
+void
|
|
+tablettoolbutton(struct wl_listener *listener, void *data)
|
|
+{
|
|
+ struct wlr_tablet_tool_button_event *event = data;
|
|
+ wlr_tablet_v2_tablet_tool_notify_button(tablet_tool, event->button,
|
|
+ (enum zwp_tablet_pad_v2_button_state)event->state);
|
|
+}
|
|
+
|
|
+void
|
|
+tablettooltip(struct wl_listener *listener, void *data)
|
|
+{
|
|
+ struct wlr_tablet_tool_tip_event *event = data;
|
|
+
|
|
+ if (!tablet_curr_surface) {
|
|
+ struct wlr_pointer_button_event fakeptrbtnevent = {
|
|
+ .button = BTN_LEFT,
|
|
+ .state = event->state == WLR_TABLET_TOOL_TIP_UP ?
|
|
+ WL_POINTER_BUTTON_STATE_RELEASED : WL_POINTER_BUTTON_STATE_PRESSED,
|
|
+ .time_msec = event->time_msec,
|
|
+ };
|
|
+ buttonpress(NULL, (void *)&fakeptrbtnevent);
|
|
+ }
|
|
+
|
|
+ if (event->state == WLR_TABLET_TOOL_TIP_UP) {
|
|
+ wlr_tablet_v2_tablet_tool_notify_up(tablet_tool);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ wlr_tablet_v2_tablet_tool_notify_down(tablet_tool);
|
|
+ wlr_tablet_tool_v2_start_implicit_grab(tablet_tool);
|
|
+}
|
|
+
|
|
void
|
|
tile(Monitor *m)
|
|
{
|
|
--
|
|
2.51.0
|
|
|