Compare commits

..

6 Commits

Author SHA1 Message Date
C4FE1 d8046ab6ec moveresizekb: support floating layout 2026-06-19 19:25:44 -03:00
6z7y 0935f95e01 restore floating window position on reattach 2026-06-20 01:10:20 +03:00
6z7y e2ba7017ea touch-input: Support osu! and fix touch motion issue 2026-06-19 23:02:39 +02:00
6z7y 493dc4c408 fix link to correct branch 2026-05-28 16:12:14 +03:00
André Desgualdo Pereira 33acb045a8 fix swapfocus README 2026-05-21 10:04:19 -03:00
André Desgualdo Pereira bbe1199e40 adds an alternative way to handle swapfocus, not allowing changing tags 2026-05-21 09:59:17 -03:00
9 changed files with 454 additions and 99 deletions
+2 -2
View File
@@ -13,8 +13,8 @@ This allows the user to change size and placement of floating windows using only
| <kbd>MODKEY</kbd> + <kbd>Shift</kbd> + <kbd>Right</kbd> | grow width 40px |
### Download
- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.5/moveresizekb)
- [v0.5](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/moveresizekb/moveresizekb.patch)
- [v0.8](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/moveresizekb/moveresizekb.patch)
### Authors
- [cana](https://codeberg.org/cana)
- [wochap](https://codeberg.org/wochap)
+32 -28
View File
@@ -1,38 +1,38 @@
From c8af428f964679089599e4ffbe7d28d08a4e875f Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Tue, 5 Mar 2024 23:42:55 -0500
Subject: [PATCH] implement keybindings to move and resize focused floating
window
From f19c162ba64c2c4860e5d16e48e08cebd7a7e46c Mon Sep 17 00:00:00 2001
From: C4FE1 <heitorcdesousa13@gmail.com>
Date: Wed, 10 Jun 2026 19:50:26 -0300
Subject: [PATCH] Change moveresizekb logic to allow it's use in floating
(NULL) Layout
---
config.def.h | 8 ++++++++
dwl.c | 19 +++++++++++++++++++
2 files changed, 27 insertions(+)
dwl.c | 23 +++++++++++++++++++++++
2 files changed, 31 insertions(+)
diff --git a/config.def.h b/config.def.h
index db0babc..d0570b8 100644
index 8a6eda0..b8398f9 100644
--- a/config.def.h
+++ b/config.def.h
@@ -135,6 +135,14 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_space, setlayout, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
+ { MODKEY, XKB_KEY_Down, moveresizekb, {.v = (int []){ 0, 40, 0, 0 }}},
+ { MODKEY, XKB_KEY_Up, moveresizekb, {.v = (int []){ 0, -40, 0, 0 }}},
+ { MODKEY, XKB_KEY_Right, moveresizekb, {.v = (int []){ 40, 0, 0, 0 }}},
+ { MODKEY, XKB_KEY_Left, moveresizekb, {.v = (int []){ -40, 0, 0, 0 }}},
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Down, moveresizekb, {.v = (int []){ 0, 0, 0, 40 }}},
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Up, moveresizekb, {.v = (int []){ 0, 0, 0, -40 }}},
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Right, moveresizekb, {.v = (int []){ 0, 0, 40, 0 }}},
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Left, moveresizekb, {.v = (int []){ 0, 0, -40, 0 }}},
{ MODKEY, XKB_KEY_0, view, {.ui = ~0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} },
{ MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} },
@@ -138,6 +138,14 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_space, setlayout, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
+ { MODKEY, XKB_KEY_Down, moveresizekb, {.v = (int []){ 0, 40, 0, 0 }}},
+ { MODKEY, XKB_KEY_Up, moveresizekb, {.v = (int []){ 0, -40, 0, 0 }}},
+ { MODKEY, XKB_KEY_Right, moveresizekb, {.v = (int []){ 40, 0, 0, 0 }}},
+ { MODKEY, XKB_KEY_Left, moveresizekb, {.v = (int []){ -40, 0, 0, 0 }}},
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Down, moveresizekb, {.v = (int []){ 0, 0, 0, 40 }}},
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Up, moveresizekb, {.v = (int []){ 0, 0, 0, -40 }}},
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Right, moveresizekb, {.v = (int []){ 0, 0, 40, 0 }}},
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Left, moveresizekb, {.v = (int []){ 0, 0, -40, 0 }}},
{ MODKEY, XKB_KEY_0, view, {.ui = ~0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} },
{ MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} },
diff --git a/dwl.c b/dwl.c
index ef27a1d..251472b 100644
index 44f3ad9..a6450f5 100644
--- a/dwl.c
+++ b/dwl.c
@@ -313,6 +313,7 @@ static void tagmon(const Arg *arg);
@@ -336,6 +336,7 @@ static void tagmon(const Arg *arg);
static void tile(Monitor *m);
static void togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg);
@@ -40,7 +40,7 @@ index ef27a1d..251472b 100644
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unlocksession(struct wl_listener *listener, void *data);
@@ -2454,6 +2455,24 @@ togglefullscreen(const Arg *arg)
@@ -2760,6 +2761,28 @@ togglefullscreen(const Arg *arg)
setfullscreen(sel, !sel->isfullscreen);
}
@@ -50,7 +50,11 @@ index ef27a1d..251472b 100644
+ Client *c = focustop(selmon);
+ Monitor *m = selmon;
+
+ if(!(m && arg && arg->v && c && c->isfloating)) {
+ if(!(m && arg && arg->v && c)){
+ return;
+ }
+
+ if(!(c->isfloating || m->lt[m->sellt]->arrange == NULL)){
+ return;
+ }
+
@@ -66,5 +70,5 @@ index ef27a1d..251472b 100644
toggletag(const Arg *arg)
{
--
2.42.0
2.54.0
+7 -3
View File
@@ -2,7 +2,11 @@
Moves clients to their old output when it is reattached.
### Download
- [git branch](https://codeberg.org/eyusupov/dwl/src/branch/restore-monitor)
- [2024-04-07](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/restore-monitor/restore-monitor.patch)
- [git branch](https://codeberg.org/6z7y/dwl-patches/src/branch/restore-monitor)
- [2026-06-20](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/restore-monitor/restore-monitor.patch)
### Authors
- [eyusupov](https://codeberg.org/eyusupov)
#### Current
- [6z7y](https://codeberg.org/6z7y)
#### Historic
- [eyusupov](https://codeberg.org/eyusupov)
+51 -35
View File
@@ -1,79 +1,95 @@
From e42ca1c539437d3098d80983cfe2ad6f938d7a08 Mon Sep 17 00:00:00 2001
From: Eldar Yusupov <eyusupov@gmail.com>
Date: Sun, 17 Mar 2024 19:12:29 +0300
Subject: [PATCH] Restore correct monitor for client when it is reattached
Subject: [PATCH] Restore correct monitor and floating position when reattached
---
dwl.c | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
dwl.c | 33 ++++++++++++++++++++++++++++++---
1 file changed, 30 insertions(+), 3 deletions(-)
diff --git a/dwl.c b/dwl.c
index bf763df..d8d8139 100644
index 44f3ad9..41548cd 100644
--- a/dwl.c
+++ b/dwl.c
@@ -107,6 +107,7 @@ typedef struct {
@@ -106,6 +106,8 @@ typedef struct {
unsigned int type; /* XDGShell or X11* */
struct wlr_box geom; /* layout-relative, includes border */
Monitor *mon;
+ char *output;
+ char *output;
+ struct wlr_box floatgeom; /* saved geom for floating restore after monitor reconnect */
struct wlr_scene_tree *scene;
struct wlr_scene_rect *border[4]; /* top, bottom, left, right */
struct wlr_scene_tree *scene_surface;
@@ -869,6 +870,7 @@ createmon(struct wl_listener *listener, void *data)
@@ -807,6 +809,13 @@ closemon(Monitor *m)
}
wl_list_for_each(c, &clients, link) {
+
+ /* Save floating geom now, before destroymon modifies it below.
+ * destroymon subtracts m->w.width from c->geom.x for floating
+ * windows, which corrupts the layout-absolute position we need
+ * to restore on reconnect. */
+ if (c->isfloating && c->mon == m) c->floatgeom = c->geom;
+
if (c->isfloating && c->geom.x > m->m.width)
resize(c, (struct wlr_box){.x = c->geom.x - m->w.width, .y = c->geom.y,
.width = c->geom.width, .height = c->geom.height}, 0);
@@ -1045,6 +1054,7 @@ createmon(struct wl_listener *listener, void *data)
size_t i;
struct wlr_output_state state;
Monitor *m;
+ Client *c;
+ Client *c;
if (!wlr_output_init_render(wlr_output, alloc, drw))
return;
@@ -938,6 +940,13 @@ createmon(struct wl_listener *listener, void *data)
@@ -1114,6 +1124,15 @@ createmon(struct wl_listener *listener, void *data)
wlr_output_layout_add_auto(output_layout, wlr_output);
else
wlr_output_layout_add(output_layout, wlr_output, m->m.x, m->m.y);
+
+ wl_list_for_each(c, &clients, link) {
+ if (strcmp(wlr_output->name, c->output) == 0) {
+ c->mon = m;
+ }
+ }
+ updatemons(NULL, NULL);
+
+ wl_list_for_each(c, &clients, link) {
+ if (!c->output || strcmp(wlr_output->name, c->output) != 0)
+ continue;
+ c->mon = m;
+ if (c->isfloating)
+ resize(c, c->floatgeom, 0);
+ }
+ updatemons(NULL, NULL);
}
void
@@ -1186,6 +1195,7 @@ destroynotify(struct wl_listener *listener, void *data)
wl_list_remove(&c->map.link);
@@ -1347,7 +1366,8 @@ destroynotify(struct wl_listener *listener, void *data)
wl_list_remove(&c->unmap.link);
wl_list_remove(&c->maximize.link);
}
+ free(c->output);
free(c);
- free(c);
+ free(c->output);
+ free(c);
}
@@ -1618,6 +1628,10 @@ mapnotify(struct wl_listener *listener, void *data)
void
@@ -1792,6 +1812,9 @@ mapnotify(struct wl_listener *listener, void *data)
} else {
applyrules(c);
}
+ c->output = strdup(c->mon->wlr_output->name);
+ if (c->output == NULL) {
+ die("oom");
+ }
+ c->output = strdup(c->mon->wlr_output->name);
+ if (c->output == NULL) die("oom");
+
printstatus();
unset_fullscreen:
@@ -2565,8 +2579,14 @@ void
@@ -2705,8 +2728,12 @@ void
tagmon(const Arg *arg)
{
Client *sel = focustop(selmon);
- if (sel)
- setmon(sel, dirtomon(arg->i), 0);
+ if (!sel)
+ return;
+ setmon(sel, dirtomon(arg->i), 0);
+ free(sel->output);
+ sel->output = strdup(sel->mon->wlr_output->name);
+ if (sel->output == NULL) {
+ die("oom");
+ }
+ if (!sel) return;
+
+ setmon(sel, dirtomon(arg->i), 0);
+ free(sel->output);
+ sel->output = strdup(sel->mon->wlr_output->name);
+ if (sel->output == NULL) die("oom");
}
void
+3 -1
View File
@@ -1,5 +1,7 @@
### Description
Swapfocus adds a new function on dwl: a shortcut to change the focus to the last focused window. If the last focused window is in another tag, then the focus will change to that tag.
Swapfocus adds a new function on dwl: a shortcut to change the focus to the last focused window.
- If the last focused window is in another tag, then the focus will change to that tag.
- Alternatively: edit the patch and uncomment and comment out the lines instructed to keep the swapfocus shortcut from changing to another tag.
### Download
- [v0.8](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/swapfocus/swapfocus.patch)
+50 -7
View File
@@ -1,12 +1,12 @@
From c4a9254ef63bbe1bae9ed525250e0b187668397f Mon Sep 17 00:00:00 2001
From 364b9f20b830886b9c0e6539ddba2cc206a286eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Desgualdo=20Pereira?= <desgua@gmail.com>
Date: Fri, 1 May 2026 08:17:28 -0300
Subject: [PATCH] swapfocus patch improvement
Date: Thu, 21 May 2026 09:50:03 -0300
Subject: [PATCH] swapfocus patch
---
config.def.h | 1 +
dwl.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+)
dwl.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 91 insertions(+)
diff --git a/config.def.h b/config.def.h
index 8a6eda0..23e502d 100644
@@ -21,7 +21,7 @@ index 8a6eda0..23e502d 100644
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
diff --git a/dwl.c b/dwl.c
index 101a45f..5e78719 100644
index 101a45f..c512323 100644
--- a/dwl.c
+++ b/dwl.c
@@ -332,6 +332,7 @@ static void setsel(struct wl_listener *listener, void *data);
@@ -61,7 +61,7 @@ index 101a45f..5e78719 100644
/* Put the new client atop the focus stack and select its monitor */
if (c && !client_is_unmanaged(c)) {
wl_list_remove(&c->flink);
@@ -2679,6 +2688,44 @@ spawn(const Arg *arg)
@@ -2679,6 +2688,87 @@ spawn(const Arg *arg)
}
}
@@ -93,13 +93,56 @@ index 101a45f..5e78719 100644
+ Arg a = {.ui = prevclient->tags};
+ selmon = prevclient->mon;
+ view(&a);
+
+ /* Comment out the 3 lines above and
+ * uncommment the following lines
+ * if changing tags isn't desired */
+
+// int current_tag_clients = 0;
+// Client *tmp;
+// wl_list_for_each(tmp, &clients, link) {
+// /* Make sure it's on the current monitor, visible on the current tag, and mapped */
+// if (tmp->mon == selmon && (tmp->tags & selmon->tagset[selmon->seltags]) && !client_is_unmanaged(tmp)) {
+// current_tag_clients++;
+// }
+// }
+//
+// /* If there's more than 1 window here, mimic Mod+k instead of switching tags */
+// if (current_tag_clients > 1) {
+// Arg arg_focus = {.i = -1};
+// focusstack(&arg_focus);
+// }
+
+ /* End of not changing tags logic */
+ } else {
+ /* Tag IS visible: Just swap focus within the same view */
+ focusclient(prevclient, 1);
+ }
+ } else {
+ Arg a = {.ui = 0};
+ selmon = prevclient->mon;
+ view(&a);
+
+ /* Comment out the 3 lines above and
+ * uncommment the following lines
+ * if changing tags isn't desired */
+
+ /* use the following if changing tags isn't desired */
+// int current_tag_clients = 0;
+// Client *tmp;
+// wl_list_for_each(tmp, &clients, link) {
+// /* Make sure it's on the current monitor, visible on the current tag, and mapped */
+// if (tmp->mon == selmon && (tmp->tags & selmon->tagset[selmon->seltags]) && !client_is_unmanaged(tmp)) {
+// current_tag_clients++;
+// }
+// }
+//
+// /* If there's more than 1 window here, mimic Mod+k instead of switching tags */
+// if (current_tag_clients > 1) {
+// Arg arg_focus = {.i = -1};
+// focusstack(&arg_focus);
+// }
+ /* end of not changing tags logic */
+ }
+}
+
+28 -22
View File
@@ -1,22 +1,28 @@
### Description
Adds touchscreen functionality.
KNOWN BUGS:
- Sometimes, the pointer moves to where the screen is pressed, but the button press doesn't occur until the screen is touched AGAIN. This means that if you touch to click button 'Q' on the screen (for instance), nothing happens; then you touch elsewhere on the screen and THEN button 'Q' registers a click. This is annoying, doesn't always happen, and I don't yet know how to fix it.
### Download
- [git branch](https://codeberg.org/fauxmight/dwl/src/branch/touch-input)
- [touch-input-wlroots-next-f4249db.patch](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/touch-input/touch-input-wlroots-next-f4249db.patch)
- [touch-input-0.8.patch](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/touch-input/touch-input-0.8.patch)
### Authors
- [fauxmight](https://codeberg.org/fauxmight)
- [minego](https://codeberg.org/minego)
- [Unprex](https://github.com/Unprex)
### Changelog
- 2026-02-26 Update patch for dwl v0.8 and dwl wlroots-next branch commit f4249db
- 2025-01-01 @fauxmight took over maintenance. Previous maintainer @minego notes [lack of available time](https://codeberg.org/dwl/dwl-patches/pulls/102#issuecomment-2557944)
- 2024-02-11 Corrected issue where motion events where not sending notifications for unfocused clients such as an on screen keyboard
- 2024-03-26 Rebased, and removed #ifdef's for the pointer constraints patch which has been merged into upstream
- 2024-03-28 Removed debug
### Description
Adds touchscreen functionality.
KNOWN BUGS:
- Sometimes, the pointer moves to where the screen is pressed, but the button press doesn't occur until the screen is touched AGAIN. This means that if you touch to click button 'Q' on the screen (for instance), nothing happens; then you touch elsewhere on the screen and THEN button 'Q' registers a click. This is annoying, doesn't always happen, and I don't yet know how to fix it.
### Download
- [git branch](https://codeberg.org/fauxmight/dwl/src/branch/touch-input)
- [touch-input-wlroots-next-f4249db.patch](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/touch-input/touch-input-wlroots-next-f4249db.patch)
- [touch-input-0.8.patch](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/touch-input/touch-input-0.8.patch)
- [touch-input-0.8-osu-ver.patch](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/touch-input/touch-input-0.8-osu-ver.patch)
### Authors
#### Current
- [fauxmight](https://codeberg.org/fauxmight)
- [6z7y](https://codeberg.org/6z7y) -- maintaining `osu!` version of the `touch-input` patch
#### Historic
- [minego](https://codeberg.org/minego)
- [Unprex](https://github.com/Unprex)
### Changelog
- 2026-06-15 Add support for osu! fullscreen touch input (fix cursor stuck issue)
- 2026-02-26 Update patch for dwl v0.8 and dwl wlroots-next branch commit f4249db
- 2025-01-01 @fauxmight took over maintenance. Previous maintainer @minego notes [lack of available time](https://codeberg.org/dwl/dwl-patches/pulls/102#issuecomment-2557944)
- 2024-02-11 Corrected issue where motion events where not sending notifications for unfocused clients such as an on screen keyboard
- 2024-03-26 Rebased, and removed #ifdef's for the pointer constraints patch which has been merged into upstream
- 2024-03-28 Removed debug
+279
View File
@@ -0,0 +1,279 @@
diff --git a/dwl.c b/dwl.c
index 44f3ad9..977f2c8 100644
--- a/dwl.c
+++ b/dwl.c
@@ -24,6 +24,7 @@
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_drm.h>
#include <wlr/types/wlr_export_dmabuf_v1.h>
+#include <wlr/types/wlr_ext_data_control_v1.h>
#include <wlr/types/wlr_fractional_scale_v1.h>
#include <wlr/types/wlr_gamma_control_v1.h>
#include <wlr/types/wlr_idle_inhibit_v1.h>
@@ -51,6 +52,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>
@@ -161,6 +163,12 @@ typedef struct {
struct wl_listener destroy;
} KeyboardGroup;
+typedef struct TouchGroup {
+ struct wl_list link;
+ struct wlr_touch *touch;
+ Monitor *m;
+} TouchGroup;
+
typedef struct {
/* Must keep this field first */
unsigned int type; /* LayerShell */
@@ -269,6 +277,7 @@ 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 cursorconstrain(struct wlr_pointer_constraint_v1 *constraint);
+static void createtouch(struct wlr_touch *touch);
static void cursorframe(struct wl_listener *listener, void *data);
static void cursorwarptohint(void);
static void destroydecoration(struct wl_listener *listener, void *data);
@@ -338,6 +347,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);
@@ -405,6 +418,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;
/* global event handlers */
static struct wl_listener cursor_axis = {.notify = axisnotify};
@@ -434,6 +448,10 @@ static struct wl_listener request_set_sel = {.notify = setsel};
static struct wl_listener request_set_cursor_shape = {.notify = setcursorshape};
static struct wl_listener request_start_drag = {.notify = requeststartdrag};
static struct wl_listener start_drag = {.notify = startdrag};
+static struct wl_listener touch_down = {.notify = touchdown};
+static struct wl_listener touch_frame = {.notify = touchframe};
+static struct wl_listener touch_motion = {.notify = touchmotion};
+static struct wl_listener touch_up = {.notify = touchup};
static struct wl_listener new_session_lock = {.notify = locksession};
#ifdef XWAYLAND
@@ -585,7 +603,7 @@ arrangelayers(Monitor *m)
arrange(m);
}
- /* Arrange non-exlusive surfaces from top->bottom */
+ /* Arrange non-exclusive surfaces from top->bottom */
for (i = 3; i >= 0; i--)
arrangelayer(m, &m->layers[i], &usable_area, 0);
@@ -781,6 +799,10 @@ cleanuplisteners(void)
wl_list_remove(&request_set_cursor_shape.link);
wl_list_remove(&request_start_drag.link);
wl_list_remove(&start_drag.link);
+ wl_list_remove(&touch_down.link);
+ wl_list_remove(&touch_frame.link);
+ wl_list_remove(&touch_motion.link);
+ wl_list_remove(&touch_up.link);
wl_list_remove(&new_session_lock.link);
#ifdef XWAYLAND
wl_list_remove(&new_xwayland_surface.link);
@@ -1199,6 +1221,16 @@ createpopup(struct wl_listener *listener, void *data)
LISTEN_STATIC(&popup->base->surface->events.commit, commitpopup);
}
+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
cursorconstrain(struct wlr_pointer_constraint_v1 *constraint)
{
@@ -1590,6 +1622,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;
@@ -1602,6 +1637,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);
}
@@ -2133,7 +2170,7 @@ powermgrsetmode(struct wl_listener *listener, void *data)
if (!m)
return;
- m->gamma_lut_changed = 1; /* Reapply gamma LUT when re-enabling the ouput */
+ m->gamma_lut_changed = 1; /* Reapply gamma LUT when re-enabling the output */
wlr_output_state_set_enabled(&state, event->mode);
wlr_output_commit_state(m->wlr_output, &state);
@@ -2455,7 +2492,7 @@ setup(void)
wlr_log_init(log_level, NULL);
/* The Wayland display is managed by libwayland. It handles accepting
- * clients from the Unix socket, manging Wayland globals, and so on. */
+ * clients from the Unix socket, managing Wayland globals, and so on. */
dpy = wl_display_create();
event_loop = wl_display_get_event_loop(dpy);
@@ -2518,6 +2555,7 @@ setup(void)
wlr_export_dmabuf_manager_v1_create(dpy);
wlr_screencopy_manager_v1_create(dpy);
wlr_data_control_manager_v1_create(dpy);
+ wlr_ext_data_control_manager_v1_create(dpy, 1);
wlr_primary_selection_v1_device_manager_create(dpy);
wlr_viewporter_create(dpy);
wlr_single_pixel_buffer_manager_v1_create(dpy);
@@ -2615,6 +2653,13 @@ setup(void)
wl_signal_add(&cursor->events.axis, &cursor_axis);
wl_signal_add(&cursor->events.frame, &cursor_frame);
+ wl_list_init(&touches);
+
+ wl_signal_add(&cursor->events.touch_down, &touch_down);
+ wl_signal_add(&cursor->events.touch_frame, &touch_frame);
+ wl_signal_add(&cursor->events.touch_motion, &touch_motion);
+ wl_signal_add(&cursor->events.touch_up, &touch_up);
+
cursor_shape_mgr = wlr_cursor_shape_manager_v1_create(dpy, 1);
wl_signal_add(&cursor_shape_mgr->events.request_set_shape, &request_set_cursor_shape);
@@ -2787,6 +2832,111 @@ 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;
+ Monitor *m;
+
+ wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
+
+ // Map the input to the appropriate output
+ 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 touch point */
+ xytonode(lx, ly, &surface, &c, NULL, &sx, &sy);
+ if (sloppyfocus && c)
+ focusclient(c, 0);
+
+ // Send touch event to client (if any)
+ if (surface != NULL) {
+ wlr_seat_touch_notify_down(seat, surface, event->time_msec,
+ event->touch_id, sx, sy);
+ }
+
+ // ALWAYS move cursor and send click - no conditions!
+ wlr_cursor_warp_closest(cursor, NULL, lx, ly);
+ motionnotify(0, NULL, 0, 0, 0, 0);
+
+ wlr_seat_pointer_notify_button(seat, event->time_msec,
+ BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED);
+ wlr_seat_pointer_notify_frame(seat);
+}
+
+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;
+
+ wlr_seat_touch_notify_up(seat, event->time_msec, event->touch_id);
+
+ // Always send click release
+ wlr_seat_pointer_notify_button(seat, event->time_msec,
+ BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED);
+ wlr_seat_pointer_notify_frame(seat);
+
+ 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);
+ wlr_cursor_warp_closest(cursor, NULL, lx, ly);
+ motionnotify(0, NULL, 0, 0, 0, 0);
+ wlr_seat_pointer_notify_frame(seat);
+
+ xytonode(lx, ly, &surface, &c, NULL, &sx, &sy);
+
+ if (c != NULL && surface != NULL) {
+ if (sloppyfocus)
+ focusclient(c, 0);
+ wlr_seat_touch_point_focus(seat, surface, event->time_msec, event->touch_id, sx, sy);
+ } else {
+ if (sloppyfocus)
+ focusclient(NULL, 0);
+ wlr_seat_touch_point_clear_focus(seat, event->time_msec, event->touch_id);
+ }
+ wlr_seat_touch_notify_motion(seat, event->time_msec, event->touch_id, sx, sy);
+
+ wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
+}
+
+
void
unlocksession(struct wl_listener *listener, void *data)
{
+2 -1
View File
@@ -9,8 +9,9 @@ This patch comes in **two versions**:
- **`zerotag.patch`** - No dependencies.
### Download
- [git branch](https://codeberg.org/6z7y/dwl-patches/raw/branch/main/patches/zerotag/zerotag.patch)
- [git branch](https://codeberg.org/6z7y/dwl-patches/raw/branch/zerotag/patches/zerotag/zerotag.patch)
- [main 2026-02-25](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/zerotag/zerotag.patch)
### Authors
- [6z7y](https://codeberg.org/6z7y)