mirror of
https://codeberg.org/dwl/dwl-patches.git
synced 2026-03-22 00:41:30 +00:00
Merge branch 'main' into main
This commit is contained in:
commit
447397a44c
@ -47,9 +47,9 @@ If you target the unstable `main` branch, specify that in the `Download` link on
|
||||
You may choose to include screenshots (hosted in your patch's subdirectory) in your `README.md`. The process is described [here](https://docs.codeberg.org/markdown/using-images/).
|
||||
|
||||
8. Use the Codeberg web interface to send a pull request to [dwl-patches] (NOT to [dwl])
|
||||
9. WHEN YOUR PULL REQUEST IS APPROVED, your Codeberg account will also be granted commit access to [dwl-patches]. Once you have write access, you can make direct modifications/upates to your patches and you are free to create new patches rather than creating pull requests.
|
||||
9. WHEN YOUR PULL REQUEST IS APPROVED, your Codeberg account will also be granted commit access to [dwl-patches]. Once you have write access, you can make direct modifications/updates to your patches and you are free to create new patches rather than creating pull requests.
|
||||
|
||||
Individuals who have made known that they no longer intend to maintain their patches will have commit access to the [dwl-pathces] repository removed.
|
||||
Individuals who have made known that they no longer intend to maintain their patches will have commit access to the [dwl-patches] repository removed.
|
||||
|
||||
A returning user who formerly had commit access is welcome to open an issue on [dwl-patches] requesting commit access be reinstated. When doing so, please link to the original issue opened that granted commit access.
|
||||
|
||||
|
||||
31
patches/bar-modes/README.md
Normal file
31
patches/bar-modes/README.md
Normal file
@ -0,0 +1,31 @@
|
||||

|
||||
|
||||
### Description
|
||||
|
||||
Add a mode indicator to bar that tells which mode you are in, just like
|
||||
river-classic's [dam](https://codeberg.org/sewn/dam) bar.
|
||||
|
||||
The string from `modes_labels` defined in `config.h` is used, while normal mode
|
||||
is ignored.
|
||||
|
||||
Another usage is to serve as a hint for each modes keybindings:
|
||||
|
||||
```c
|
||||
enum {
|
||||
BROWSER,
|
||||
};
|
||||
const char *modes_labels[] = {
|
||||
"[f]irefox [b]rave [c]hromium [q]utebrowser",
|
||||
};
|
||||
```
|
||||
|
||||
### Dependencies
|
||||
this patch depends on:
|
||||
- [bar](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/bar/) patch
|
||||
- [modes](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/modes/) patch
|
||||
|
||||
### Download
|
||||
- [v0.8](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/bar-modes/bar-modes.patch)
|
||||
|
||||
### Authors
|
||||
- [unixchad](https://codeberg.org/unixchad/)
|
||||
131
patches/bar-modes/bar-modes.patch
Normal file
131
patches/bar-modes/bar-modes.patch
Normal file
@ -0,0 +1,131 @@
|
||||
From 4f2c8a99720d90a551bf38f2c8d25ad239346eef Mon Sep 17 00:00:00 2001
|
||||
From: nate zhou <gnuunixchad@outlook.com>
|
||||
Date: Mon, 2 Mar 2026 21:54:03 +0800
|
||||
Subject: [PATCH] Patch: bar-modes for 0.8
|
||||
|
||||
Add modes_labels indicator to bar, which behaves like river-classic's
|
||||
dam bar. This patch has to be applied after the bar and modes patch.
|
||||
---
|
||||
dwl.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++----------
|
||||
1 file changed, 59 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/dwl.c b/dwl.c
|
||||
index ae290ad..df525d3 100644
|
||||
--- a/dwl.c
|
||||
+++ b/dwl.c
|
||||
@@ -1585,19 +1585,26 @@ drawbar(Monitor *m)
|
||||
uint32_t i, occ = 0, urg = 0;
|
||||
Client *c;
|
||||
Buffer *buf;
|
||||
+ char mode_text[256] = "";
|
||||
+ int mode_width = 0;
|
||||
|
||||
if (!m->scene_buffer->node.enabled)
|
||||
return;
|
||||
if (!(buf = bufmon(m)))
|
||||
return;
|
||||
|
||||
- /* draw status first so it can be overdrawn by tags later */
|
||||
- if (m == selmon) { /* status is only drawn on selected monitor */
|
||||
- drwl_setscheme(m->drw, colors[SchemeNorm]);
|
||||
- tw = TEXTW(m, stext) - m->lrpad + 2; /* 2px right padding */
|
||||
- drwl_text(m->drw, m->b.width - tw, 0, tw, m->b.height, 0, stext, 0);
|
||||
+ /* get current mode text if in a mode (not normal) */
|
||||
+ if (active_mode_index >= 0 && active_mode_index < LENGTH(modes_labels) &&
|
||||
+ modes_labels[active_mode_index]) {
|
||||
+ strncpy(mode_text, modes_labels[active_mode_index], sizeof(mode_text) - 1);
|
||||
+ mode_text[sizeof(mode_text) - 1] = '\0';
|
||||
+ mode_width = TEXTW(m, mode_text);
|
||||
}
|
||||
|
||||
+ /* calculate status text width */
|
||||
+ drwl_setscheme(m->drw, colors[SchemeNorm]);
|
||||
+ tw = TEXTW(m, stext) - m->lrpad + 2;
|
||||
+
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (c->mon != m)
|
||||
continue;
|
||||
@@ -1607,6 +1614,8 @@ drawbar(Monitor *m)
|
||||
}
|
||||
x = 0;
|
||||
c = focustop(m);
|
||||
+
|
||||
+ /* draw tags (always shown) */
|
||||
for (i = 0; i < LENGTH(tags); i++) {
|
||||
w = TEXTW(m, tags[i]);
|
||||
drwl_setscheme(m->drw, colors[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
|
||||
@@ -1617,19 +1626,57 @@ drawbar(Monitor *m)
|
||||
urg & 1 << i);
|
||||
x += w;
|
||||
}
|
||||
+
|
||||
+ /* draw mode indicator after tags if in a mode */
|
||||
+ if (mode_text[0]) {
|
||||
+ drwl_setscheme(m->drw, colors[SchemeSel]);
|
||||
+ drwl_text(m->drw, x, 0, mode_width, m->b.height, m->lrpad / 2, mode_text, 0);
|
||||
+ x += mode_width;
|
||||
+ }
|
||||
+
|
||||
+ /* draw layout symbol after mode */
|
||||
w = TEXTW(m, m->ltsymbol);
|
||||
drwl_setscheme(m->drw, colors[SchemeNorm]);
|
||||
- x = drwl_text(m->drw, x, 0, w, m->b.height, m->lrpad / 2, m->ltsymbol, 0);
|
||||
+ drwl_text(m->drw, x, 0, w, m->b.height, m->lrpad / 2, m->ltsymbol, 0);
|
||||
+ x += w;
|
||||
+
|
||||
+ int remaining = m->b.width - x;
|
||||
|
||||
- if ((w = m->b.width - tw - x) > m->b.height) {
|
||||
- if (c) {
|
||||
+ if (mode_text[0]) {
|
||||
+ int title_width = remaining;
|
||||
+
|
||||
+ if (title_width > m->b.height && c) {
|
||||
drwl_setscheme(m->drw, colors[m == selmon ? SchemeSel : SchemeNorm]);
|
||||
- drwl_text(m->drw, x, 0, w, m->b.height, m->lrpad / 2, client_get_title(c), 0);
|
||||
+ drwl_text(m->drw, x, 0, title_width, m->b.height, m->lrpad / 2,
|
||||
+ client_get_title(c), 0);
|
||||
if (c && c->isfloating)
|
||||
drwl_rect(m->drw, x + boxs, boxs, boxw, boxw, 0, 0);
|
||||
- } else {
|
||||
+ } else if (title_width > 0) {
|
||||
+ drwl_setscheme(m->drw, colors[SchemeNorm]);
|
||||
+ drwl_rect(m->drw, x, 0, title_width, m->b.height, 1, 1);
|
||||
+ }
|
||||
+ /* no status text when in a mode - completely omitted */
|
||||
+ } else {
|
||||
+ /* not in a mode - normal behavior with status */
|
||||
+ if (remaining >= tw) {
|
||||
+ drwl_setscheme(m->drw, colors[SchemeNorm]);
|
||||
+ drwl_text(m->drw, m->b.width - tw, 0, tw, m->b.height, 0, stext, 0);
|
||||
+
|
||||
+ int title_space = remaining - tw;
|
||||
+ if (title_space > m->b.height && c) {
|
||||
+ drwl_setscheme(m->drw, colors[m == selmon ? SchemeSel : SchemeNorm]);
|
||||
+ drwl_text(m->drw, x, 0, title_space, m->b.height, m->lrpad / 2,
|
||||
+ client_get_title(c), 0);
|
||||
+ if (c && c->isfloating)
|
||||
+ drwl_rect(m->drw, x + boxs, boxs, boxw, boxw, 0, 0);
|
||||
+ } else if (title_space > 0) {
|
||||
+ drwl_setscheme(m->drw, colors[SchemeNorm]);
|
||||
+ drwl_rect(m->drw, x, 0, title_space, m->b.height, 1, 1);
|
||||
+ }
|
||||
+ } else if (remaining > 0) {
|
||||
drwl_setscheme(m->drw, colors[SchemeNorm]);
|
||||
- drwl_rect(m->drw, x, 0, w, m->b.height, 1, 1);
|
||||
+ drwl_text(m->drw, m->b.width - remaining, 0, remaining, m->b.height, 0,
|
||||
+ stext, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3437,6 +3484,7 @@ entermode(const Arg *arg)
|
||||
{
|
||||
active_mode_index = arg->i;
|
||||
printstatus();
|
||||
+ drawbars();
|
||||
}
|
||||
|
||||
#ifdef XWAYLAND
|
||||
--
|
||||
2.53.0
|
||||
|
||||
BIN
patches/bar-modes/example.png
Normal file
BIN
patches/bar-modes/example.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
@ -301,7 +301,7 @@ index 0000000..125312c
|
||||
+ pipefd = ecalloc(2, sizeof(int));
|
||||
+
|
||||
+ /*
|
||||
+ * Libdbus forbids calling dbus_connection_dipatch from the
|
||||
+ * Libdbus forbids calling dbus_connection_dispatch from the
|
||||
+ * DBusDispatchStatusFunction directly. Notify the event loop of
|
||||
+ * updates via a self-pipe.
|
||||
+ */
|
||||
|
||||
@ -3,7 +3,7 @@ From: wochap <gean.marroquin@gmail.com>
|
||||
Date: Tue, 4 Jun 2024 16:02:25 -0500
|
||||
Subject: [PATCH] implement borders patch
|
||||
|
||||
tihs patch adds 2 extra borders relative to the client, they don't
|
||||
this patch adds 2 extra borders relative to the client, they don't
|
||||
change the size of the client
|
||||
---
|
||||
client.h | 16 +++++++++++++---
|
||||
|
||||
@ -15,12 +15,14 @@ bstack (TTT) bstackhoriz (===)
|
||||
|
||||
|
||||
### Download
|
||||
- [v0.8](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/bottomstack/bottomstack.patch)
|
||||
- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.6-b/bottomstack)
|
||||
- [2024-07-09](https://codeberg.org/dwl/dwl-patches/raw/commit/20de07dc8759200c8a4c9651475acb331d245890/patches/bottomstack/bottomstack.patch)
|
||||
- [2024-04-11](https://codeberg.org/dwl/dwl-patches/raw/commit/0f4e40fee49d1b8b430778e241b29496ae3b3b70/bottomstack/bottomstack.patch)
|
||||
- [v0.5](https://codeberg.org/dwl/dwl-patches/raw/commit/5368aa392c7ebf8d7d24c232b80cfae1be457d41/bottomstack/bottomstack.patch)
|
||||
|
||||
### Authors
|
||||
- [unixchad](https://codeberg.org/unixchad)
|
||||
- [wochap](https://codeberg.org/wochap)
|
||||
- [DanielMowitz](https://github.com/DanielMowitz)
|
||||
- [Abanoub8](https://github.com/Abanoub8)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
From b352fb08f40b1ee2d8c4748be4922df711e3aaa9 Mon Sep 17 00:00:00 2001
|
||||
From: wochap <gean.marroquin@gmail.com>
|
||||
Date: Fri, 5 Jul 2024 10:44:29 -0500
|
||||
Subject: [PATCH] implement bottomstack
|
||||
From 86e379b187bcc9f8f5896a87309474fcf3736de9 Mon Sep 17 00:00:00 2001
|
||||
From: nate zhou <gnuunixchad@outlook.com>
|
||||
Date: Sat, 28 Feb 2026 21:29:53 +0800
|
||||
Subject: [PATCH] Patch: bottomstack-0.8.patch
|
||||
|
||||
---
|
||||
config.def.h | 4 +++
|
||||
@ -9,10 +9,10 @@ Subject: [PATCH] implement bottomstack
|
||||
2 files changed, 88 insertions(+)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index 22d2171..5aac3e9 100644
|
||||
index 8a6eda0..ae87518 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -34,6 +34,8 @@ static const Layout layouts[] = {
|
||||
@@ -33,6 +33,8 @@ static const Layout layouts[] = {
|
||||
{ "[]=", tile },
|
||||
{ "><>", NULL }, /* no layout function means floating behavior */
|
||||
{ "[M]", monocle },
|
||||
@ -21,20 +21,20 @@ index 22d2171..5aac3e9 100644
|
||||
};
|
||||
|
||||
/* monitors */
|
||||
@@ -139,6 +141,8 @@ static const Key keys[] = {
|
||||
{ MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
|
||||
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
|
||||
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
|
||||
+ { MODKEY, XKB_KEY_u, setlayout, {.v = &layouts[3]} },
|
||||
+ { MODKEY, XKB_KEY_o, setlayout, {.v = &layouts[4]} },
|
||||
{ MODKEY, XKB_KEY_space, setlayout, {0} },
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
|
||||
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
|
||||
@@ -135,6 +137,8 @@ static const Key keys[] = {
|
||||
{ MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
|
||||
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
|
||||
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
|
||||
+ { MODKEY, XKB_KEY_u, setlayout, {.v = &layouts[3]} },
|
||||
+ { MODKEY, XKB_KEY_o, setlayout, {.v = &layouts[4]} },
|
||||
{ MODKEY, XKB_KEY_space, setlayout, {0} },
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
|
||||
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
|
||||
diff --git a/dwl.c b/dwl.c
|
||||
index dc0437e..5648d5f 100644
|
||||
index 44f3ad9..68c25a5 100644
|
||||
--- a/dwl.c
|
||||
+++ b/dwl.c
|
||||
@@ -57,6 +57,7 @@
|
||||
@@ -59,6 +59,7 @@
|
||||
#include <wlr/types/wlr_xdg_decoration_v1.h>
|
||||
#include <wlr/types/wlr_xdg_output_v1.h>
|
||||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
@ -50,8 +50,8 @@ index dc0437e..5648d5f 100644
|
||||
+static void bstackhoriz(Monitor *m);
|
||||
|
||||
/* variables */
|
||||
static const char broken[] = "broken";
|
||||
@@ -3160,3 +3163,84 @@ main(int argc, char *argv[])
|
||||
static pid_t child_pid = -1;
|
||||
@@ -3213,3 +3216,84 @@ main(int argc, char *argv[])
|
||||
usage:
|
||||
die("Usage: %s [-v] [-d] [-s startup command]", argv[0]);
|
||||
}
|
||||
@ -137,4 +137,5 @@ index dc0437e..5648d5f 100644
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.45.1
|
||||
2.53.0
|
||||
|
||||
|
||||
@ -61,7 +61,7 @@ When a new client appears:
|
||||
btrtile adds couple variables to config.h to fine tune the mouse resizing of tiled clients.
|
||||
|
||||
1. **resize_factor**
|
||||
- A multiplier to transfer pointer movement to client weight ratio. Depends heavily on mouse sensivity.
|
||||
- A multiplier to transfer pointer movement to client weight ratio. Depends heavily on mouse sensitivity.
|
||||
Defaults to 0.0002f.
|
||||
|
||||
2. **resize_interval_ms**
|
||||
|
||||
@ -606,7 +606,7 @@ index 22d2171..92f3ad6 100644
|
||||
static const float urgentcolor[] = COLOR(0xff0000ff);
|
||||
/* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */
|
||||
static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */
|
||||
+static const float resize_factor = 0.0002f; /* Resize multiplier for mouse resizing, depends on mouse sensivity. */
|
||||
+static const float resize_factor = 0.0002f; /* Resize multiplier for mouse resizing, depends on mouse sensitivity. */
|
||||
+static const uint32_t resize_interval_ms = 16; /* Resize interval depends on framerate and screen refresh rate. */
|
||||
|
||||
+enum Direction { DIR_LEFT, DIR_RIGHT, DIR_UP, DIR_DOWN };
|
||||
|
||||
@ -587,7 +587,7 @@ index 22d2171..92f3ad6 100644
|
||||
static const float urgentcolor[] = COLOR(0xff0000ff);
|
||||
/* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */
|
||||
static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */
|
||||
+static const float resize_factor = 0.0002f; /* Resize multiplier for mouse resizing, depends on mouse sensivity. */
|
||||
+static const float resize_factor = 0.0002f; /* Resize multiplier for mouse resizing, depends on mouse sensitivity. */
|
||||
+static const uint32_t resize_interval_ms = 16; /* Resize interval depends on framerate and screen refresh rate. */
|
||||
|
||||
+enum Direction { DIR_LEFT, DIR_RIGHT, DIR_UP, DIR_DOWN };
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
### Description
|
||||
Generate a coredump if dwl exited abnormally (to be more usefull you need to
|
||||
Generate a coredump if dwl exited abnormally (to be more useful you need to
|
||||
compile dwl and wlroots with debug symbols)
|
||||
|
||||
### Download
|
||||
|
||||
@ -2,8 +2,9 @@
|
||||
Deck is a dwl-layout which is inspired by the dwm Deck layout (which is inspired by TTWM window manager). It applies the monocle-layout to the clients in the stack. The master-client is still visible. The stacked clients are like a deck of cards, hence the name.
|
||||
|
||||
### Download
|
||||
- [v0.8](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/decklayout/decklayout.patch)
|
||||
- [git branch](https://codeberg.org/Kana/dwl/src/branch/decklayout)
|
||||
- [main 2025-10-08](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/decklayout/decklayout.patch)
|
||||
- [main 2025-10-08](https://codeberg.org/dwl/dwl-patches/raw/commit/f8d1cfad116c19c01593f7436468ec0cb7a3297b/patches/decklayout/decklayout.patch)
|
||||
|
||||
### Authors
|
||||
- [André Desgualdo Pereira](https://codeberg.org/Kana)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
From 095439425e64f2567f141d5d941178b148ef0d3a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Andr=C3=A9=20Desgualdo=20Pereira?= <desgua@gmail.com>
|
||||
Date: Sun, 12 Oct 2025 11:44:26 -0300
|
||||
Subject: [PATCH] decklayout
|
||||
From c488515313e20f51ab961691002f9d483682ab16 Mon Sep 17 00:00:00 2001
|
||||
From: nate zhou <gnuunixchad@outlook.com>
|
||||
Date: Sat, 28 Feb 2026 21:32:46 +0800
|
||||
Subject: [PATCH] Patch: decklayout-0.8.patch
|
||||
|
||||
---
|
||||
config.def.h | 2 ++
|
||||
@ -9,10 +9,10 @@ Subject: [PATCH] decklayout
|
||||
2 files changed, 63 insertions(+)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index 95c2afa..cc846eb 100644
|
||||
index 8a6eda0..3ec9ceb 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -34,6 +34,7 @@ static const Layout layouts[] = {
|
||||
@@ -33,6 +33,7 @@ static const Layout layouts[] = {
|
||||
{ "[]=", tile },
|
||||
{ "><>", NULL }, /* no layout function means floating behavior */
|
||||
{ "[M]", monocle },
|
||||
@ -20,16 +20,16 @@ index 95c2afa..cc846eb 100644
|
||||
};
|
||||
|
||||
/* monitors */
|
||||
@@ -139,6 +140,7 @@ static const Key keys[] = {
|
||||
{ MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
|
||||
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
|
||||
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
|
||||
+ { MODKEY, XKB_KEY_a, setlayout, {.v = &layouts[3]} },
|
||||
{ MODKEY, XKB_KEY_space, setlayout, {0} },
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
|
||||
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
|
||||
@@ -135,6 +136,7 @@ static const Key keys[] = {
|
||||
{ MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
|
||||
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
|
||||
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
|
||||
+ { MODKEY, XKB_KEY_a, setlayout, {.v = &layouts[3]} },
|
||||
{ MODKEY, XKB_KEY_space, setlayout, {0} },
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
|
||||
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
|
||||
diff --git a/dwl.c b/dwl.c
|
||||
index 12f441e..227004f 100644
|
||||
index 44f3ad9..f13f48b 100644
|
||||
--- a/dwl.c
|
||||
+++ b/dwl.c
|
||||
@@ -278,6 +278,7 @@ static void destroylayersurfacenotify(struct wl_listener *listener, void *data);
|
||||
@ -40,7 +40,7 @@ index 12f441e..227004f 100644
|
||||
static void destroypointerconstraint(struct wl_listener *listener, void *data);
|
||||
static void destroysessionlock(struct wl_listener *listener, void *data);
|
||||
static void destroykeyboardgroup(struct wl_listener *listener, void *data);
|
||||
@@ -1837,6 +1838,66 @@ monocle(Monitor *m)
|
||||
@@ -1838,6 +1839,66 @@ monocle(Monitor *m)
|
||||
wlr_scene_node_raise_to_top(&c->scene->node);
|
||||
}
|
||||
|
||||
@ -108,5 +108,5 @@ index 12f441e..227004f 100644
|
||||
motionabsolute(struct wl_listener *listener, void *data)
|
||||
{
|
||||
--
|
||||
2.51.0
|
||||
2.53.0
|
||||
|
||||
|
||||
@ -8,7 +8,8 @@ There are also two functions that can be bound to a `Key` or `Button`,
|
||||
2. `toggledimmingclient`: Which toggles dimming for the focused window, as if the client had `neverdim` applied to it. This overwrites an applied `Rule`.
|
||||
|
||||
### Download
|
||||
- [2024-09-18](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/dim-unfocused/dim-unfocused.patch)
|
||||
- [2026-03-10](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/dim-unfocused/dim-unfocused.patch)
|
||||
- [2024-09-18](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/dim-unfocused/dim-unfocused-20240918.patch)
|
||||
- [2024-09-03](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/dim-unfocused/dim-unfocused-20240903.patch)
|
||||
- [2024-07-14](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/dim-unfocused/dim-unfocused-20240714.patch)
|
||||
- [2024-05-16](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/dim-unfocused/dim-unfocused-20240516.patch)
|
||||
|
||||
216
patches/dim-unfocused/dim-unfocused-20240918.patch
Normal file
216
patches/dim-unfocused/dim-unfocused-20240918.patch
Normal file
@ -0,0 +1,216 @@
|
||||
diff --git a/client.h b/client.h
|
||||
index dabea35..3a31c25 100644
|
||||
--- a/client.h
|
||||
+++ b/client.h
|
||||
@@ -319,6 +319,12 @@ client_set_border_color(Client *c, const float color[static 4])
|
||||
wlr_scene_rect_set_color(c->border[i], color);
|
||||
}
|
||||
|
||||
+static inline void
|
||||
+client_set_dimmer_state(Client *c, const int dim)
|
||||
+{
|
||||
+ wlr_scene_node_set_enabled(&c->dimmer->node, DIMOPT && !c->neverdim && dim);
|
||||
+}
|
||||
+
|
||||
static inline void
|
||||
client_set_fullscreen(Client *c, int fullscreen)
|
||||
{
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index 22d2171..4ca21c9 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -10,6 +10,7 @@ static const unsigned int borderpx = 1; /* border pixel of windows */
|
||||
static const float rootcolor[] = COLOR(0x222222ff);
|
||||
static const float bordercolor[] = COLOR(0x444444ff);
|
||||
static const float focuscolor[] = COLOR(0x005577ff);
|
||||
+static const float unfocuseddim[] = COLOR(0x00000088);
|
||||
static const float urgentcolor[] = COLOR(0xff0000ff);
|
||||
/* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */
|
||||
static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */
|
||||
@@ -22,10 +23,11 @@ static int log_level = WLR_ERROR;
|
||||
|
||||
/* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */
|
||||
static const Rule rules[] = {
|
||||
- /* app_id title tags mask isfloating monitor */
|
||||
- /* examples: */
|
||||
- { "Gimp_EXAMPLE", NULL, 0, 1, -1 }, /* Start on currently visible tags floating, not tiled */
|
||||
- { "firefox_EXAMPLE", NULL, 1 << 8, 0, -1 }, /* Start on ONLY tag "9" */
|
||||
+ /* app_id title tags mask isfloating neverdim monitor */
|
||||
+ /* examples:
|
||||
+ { "Gimp_example", NULL, 0, 1, 0, -1 },
|
||||
+ */
|
||||
+ { "firefox_example", NULL, 1 << 8, 0, 1, -1 },
|
||||
};
|
||||
|
||||
/* layout(s) */
|
||||
@@ -140,8 +142,9 @@ static const Key keys[] = {
|
||||
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
|
||||
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
|
||||
{ MODKEY, XKB_KEY_space, setlayout, {0} },
|
||||
+ { MODKEY, XKB_KEY_apostrophe, toggledimming, {0} },
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
|
||||
- { MODKEY, XKB_KEY_e, togglefullscreen, {0} },
|
||||
+ { MODKEY, XKB_KEY_e, togglefullscreen, {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} },
|
||||
@@ -172,5 +175,6 @@ static const Key keys[] = {
|
||||
static const Button buttons[] = {
|
||||
{ MODKEY, BTN_LEFT, moveresize, {.ui = CurMove} },
|
||||
{ MODKEY, BTN_MIDDLE, togglefloating, {0} },
|
||||
+ { MODKEY|ShiftMask, BTN_MIDDLE, toggledimmingclient, {0} },
|
||||
{ MODKEY, BTN_RIGHT, moveresize, {.ui = CurResize} },
|
||||
};
|
||||
diff --git a/dwl.c b/dwl.c
|
||||
index dc0c861..dcc3ece 100644
|
||||
--- a/dwl.c
|
||||
+++ b/dwl.c
|
||||
@@ -112,6 +112,7 @@ typedef struct {
|
||||
Monitor *mon;
|
||||
struct wlr_scene_tree *scene;
|
||||
struct wlr_scene_rect *border[4]; /* top, bottom, left, right */
|
||||
+ struct wlr_scene_rect *dimmer;
|
||||
struct wlr_scene_tree *scene_surface;
|
||||
struct wl_list link;
|
||||
struct wl_list flink;
|
||||
@@ -141,7 +142,7 @@ typedef struct {
|
||||
#endif
|
||||
unsigned int bw;
|
||||
uint32_t tags;
|
||||
- int isfloating, isurgent, isfullscreen;
|
||||
+ int isfloating, isurgent, isfullscreen, neverdim;
|
||||
uint32_t resize; /* configure serial of a pending resize */
|
||||
} Client;
|
||||
|
||||
@@ -231,6 +232,7 @@ typedef struct {
|
||||
const char *title;
|
||||
uint32_t tags;
|
||||
int isfloating;
|
||||
+ int neverdim;
|
||||
int monitor;
|
||||
} Rule;
|
||||
|
||||
@@ -338,6 +340,8 @@ static void startdrag(struct wl_listener *listener, void *data);
|
||||
static void tag(const Arg *arg);
|
||||
static void tagmon(const Arg *arg);
|
||||
static void tile(Monitor *m);
|
||||
+static void toggledimming(const Arg *arg);
|
||||
+static void toggledimmingclient(const Arg *arg);
|
||||
static void togglefloating(const Arg *arg);
|
||||
static void togglefullscreen(const Arg *arg);
|
||||
static void toggletag(const Arg *arg);
|
||||
@@ -410,6 +414,7 @@ static struct wlr_output_layout *output_layout;
|
||||
static struct wlr_box sgeom;
|
||||
static struct wl_list mons;
|
||||
static Monitor *selmon;
|
||||
+static int DIMOPT = 1;
|
||||
|
||||
#ifdef XWAYLAND
|
||||
static void activatex11(struct wl_listener *listener, void *data);
|
||||
@@ -466,6 +471,7 @@ applyrules(Client *c)
|
||||
if ((!r->title || strstr(title, r->title))
|
||||
&& (!r->id || strstr(appid, r->id))) {
|
||||
c->isfloating = r->isfloating;
|
||||
+ c->neverdim = r-> neverdim;
|
||||
newtags |= r->tags;
|
||||
i = 0;
|
||||
wl_list_for_each(m, &mons, link) {
|
||||
@@ -1365,8 +1371,10 @@ focusclient(Client *c, int lift)
|
||||
|
||||
/* Don't change border color if there is an exclusive focus or we are
|
||||
* handling a drag operation */
|
||||
- if (!exclusive_focus && !seat->drag)
|
||||
+ if (!exclusive_focus && !seat->drag) {
|
||||
client_set_border_color(c, focuscolor);
|
||||
+ client_set_dimmer_state(c, 0);
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Deactivate old client if focus is changing */
|
||||
@@ -1384,7 +1392,7 @@ focusclient(Client *c, int lift)
|
||||
* and probably other clients */
|
||||
} else if (old_c && !client_is_unmanaged(old_c) && (!c || !client_wants_focus(c))) {
|
||||
client_set_border_color(old_c, bordercolor);
|
||||
-
|
||||
+ client_set_dimmer_state(old_c, 1);
|
||||
client_activate_surface(old, 0);
|
||||
}
|
||||
}
|
||||
@@ -1681,8 +1689,7 @@ void
|
||||
mapnotify(struct wl_listener *listener, void *data)
|
||||
{
|
||||
/* Called when the surface is mapped, or ready to display on-screen. */
|
||||
- Client *p = NULL;
|
||||
- Client *w, *c = wl_container_of(listener, c, map);
|
||||
+ Client *p, *w, *d, *c = wl_container_of(listener, c, map);
|
||||
Monitor *m;
|
||||
int i;
|
||||
|
||||
@@ -1716,6 +1723,10 @@ mapnotify(struct wl_listener *listener, void *data)
|
||||
c->border[i]->node.data = c;
|
||||
}
|
||||
|
||||
+ c->dimmer = wlr_scene_rect_create(c->scene, 0, 0, unfocuseddim);
|
||||
+ c->dimmer->node.data = c;
|
||||
+ client_set_dimmer_state(c, 1);
|
||||
+
|
||||
/* Initialize client geometry with room for border */
|
||||
client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT);
|
||||
c->geom.width += 2 * c->bw;
|
||||
@@ -1734,6 +1745,10 @@ mapnotify(struct wl_listener *listener, void *data)
|
||||
setmon(c, p->mon, p->tags);
|
||||
} else {
|
||||
applyrules(c);
|
||||
+ d = focustop(selmon);
|
||||
+ if (d) {
|
||||
+ client_set_dimmer_state(d, 0);
|
||||
+ }
|
||||
}
|
||||
printstatus();
|
||||
|
||||
@@ -2160,7 +2175,7 @@ resize(Client *c, struct wlr_box geo, int interact)
|
||||
c->geom = geo;
|
||||
applybounds(c, bbox);
|
||||
|
||||
- /* Update scene-graph, including borders */
|
||||
+ /* Update scene-graph, including borders and dimmer*/
|
||||
wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y);
|
||||
wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw);
|
||||
wlr_scene_rect_set_size(c->border[0], c->geom.width, c->bw);
|
||||
@@ -2170,6 +2185,8 @@ resize(Client *c, struct wlr_box geo, int interact)
|
||||
wlr_scene_node_set_position(&c->border[1]->node, 0, c->geom.height - c->bw);
|
||||
wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw);
|
||||
wlr_scene_node_set_position(&c->border[3]->node, c->geom.width - c->bw, c->bw);
|
||||
+ wlr_scene_rect_set_size(c->dimmer, c->geom.width - 2*c->bw, c-> geom.height - 2*c->bw);
|
||||
+ wlr_scene_node_set_position(&c->dimmer->node, c->bw, c->bw);
|
||||
|
||||
/* this is a no-op if size hasn't changed */
|
||||
c->resize = client_set_size(c, c->geom.width - 2 * c->bw,
|
||||
@@ -2681,6 +2698,27 @@ tile(Monitor *m)
|
||||
}
|
||||
}
|
||||
|
||||
+void toggledimming(const Arg *arg)
|
||||
+{
|
||||
+ Client *c;
|
||||
+ DIMOPT ^= 1;
|
||||
+ wl_list_for_each(c, &clients, link)
|
||||
+ {
|
||||
+ client_set_dimmer_state(c, 1);
|
||||
+ }
|
||||
+ c = focustop(selmon);
|
||||
+ if (c)
|
||||
+ client_set_dimmer_state(c, 0);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+toggledimmingclient(const Arg *arg)
|
||||
+{
|
||||
+ Client *sel = focustop(selmon);
|
||||
+ if (sel)
|
||||
+ sel -> neverdim ^= 1;
|
||||
+}
|
||||
+
|
||||
void
|
||||
togglefloating(const Arg *arg)
|
||||
{
|
||||
@ -1,216 +1 @@
|
||||
diff --git a/client.h b/client.h
|
||||
index dabea35..3a31c25 100644
|
||||
--- a/client.h
|
||||
+++ b/client.h
|
||||
@@ -319,6 +319,12 @@ client_set_border_color(Client *c, const float color[static 4])
|
||||
wlr_scene_rect_set_color(c->border[i], color);
|
||||
}
|
||||
|
||||
+static inline void
|
||||
+client_set_dimmer_state(Client *c, const int dim)
|
||||
+{
|
||||
+ wlr_scene_node_set_enabled(&c->dimmer->node, DIMOPT && !c->neverdim && dim);
|
||||
+}
|
||||
+
|
||||
static inline void
|
||||
client_set_fullscreen(Client *c, int fullscreen)
|
||||
{
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index 22d2171..4ca21c9 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -10,6 +10,7 @@ static const unsigned int borderpx = 1; /* border pixel of windows */
|
||||
static const float rootcolor[] = COLOR(0x222222ff);
|
||||
static const float bordercolor[] = COLOR(0x444444ff);
|
||||
static const float focuscolor[] = COLOR(0x005577ff);
|
||||
+static const float unfocuseddim[] = COLOR(0x00000088);
|
||||
static const float urgentcolor[] = COLOR(0xff0000ff);
|
||||
/* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */
|
||||
static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */
|
||||
@@ -22,10 +23,11 @@ static int log_level = WLR_ERROR;
|
||||
|
||||
/* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */
|
||||
static const Rule rules[] = {
|
||||
- /* app_id title tags mask isfloating monitor */
|
||||
- /* examples: */
|
||||
- { "Gimp_EXAMPLE", NULL, 0, 1, -1 }, /* Start on currently visible tags floating, not tiled */
|
||||
- { "firefox_EXAMPLE", NULL, 1 << 8, 0, -1 }, /* Start on ONLY tag "9" */
|
||||
+ /* app_id title tags mask isfloating neverdim monitor */
|
||||
+ /* examples:
|
||||
+ { "Gimp_example", NULL, 0, 1, 0, -1 },
|
||||
+ */
|
||||
+ { "firefox_example", NULL, 1 << 8, 0, 1, -1 },
|
||||
};
|
||||
|
||||
/* layout(s) */
|
||||
@@ -140,8 +142,9 @@ static const Key keys[] = {
|
||||
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
|
||||
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
|
||||
{ MODKEY, XKB_KEY_space, setlayout, {0} },
|
||||
+ { MODKEY, XKB_KEY_apostrophe, toggledimming, {0} },
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
|
||||
- { MODKEY, XKB_KEY_e, togglefullscreen, {0} },
|
||||
+ { MODKEY, XKB_KEY_e, togglefullscreen, {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} },
|
||||
@@ -172,5 +175,6 @@ static const Key keys[] = {
|
||||
static const Button buttons[] = {
|
||||
{ MODKEY, BTN_LEFT, moveresize, {.ui = CurMove} },
|
||||
{ MODKEY, BTN_MIDDLE, togglefloating, {0} },
|
||||
+ { MODKEY|ShiftMask, BTN_MIDDLE, toggledimmingclient, {0} },
|
||||
{ MODKEY, BTN_RIGHT, moveresize, {.ui = CurResize} },
|
||||
};
|
||||
diff --git a/dwl.c b/dwl.c
|
||||
index dc0c861..dcc3ece 100644
|
||||
--- a/dwl.c
|
||||
+++ b/dwl.c
|
||||
@@ -112,6 +112,7 @@ typedef struct {
|
||||
Monitor *mon;
|
||||
struct wlr_scene_tree *scene;
|
||||
struct wlr_scene_rect *border[4]; /* top, bottom, left, right */
|
||||
+ struct wlr_scene_rect *dimmer;
|
||||
struct wlr_scene_tree *scene_surface;
|
||||
struct wl_list link;
|
||||
struct wl_list flink;
|
||||
@@ -141,7 +142,7 @@ typedef struct {
|
||||
#endif
|
||||
unsigned int bw;
|
||||
uint32_t tags;
|
||||
- int isfloating, isurgent, isfullscreen;
|
||||
+ int isfloating, isurgent, isfullscreen, neverdim;
|
||||
uint32_t resize; /* configure serial of a pending resize */
|
||||
} Client;
|
||||
|
||||
@@ -231,6 +232,7 @@ typedef struct {
|
||||
const char *title;
|
||||
uint32_t tags;
|
||||
int isfloating;
|
||||
+ int neverdim;
|
||||
int monitor;
|
||||
} Rule;
|
||||
|
||||
@@ -338,6 +340,8 @@ static void startdrag(struct wl_listener *listener, void *data);
|
||||
static void tag(const Arg *arg);
|
||||
static void tagmon(const Arg *arg);
|
||||
static void tile(Monitor *m);
|
||||
+static void toggledimming(const Arg *arg);
|
||||
+static void toggledimmingclient(const Arg *arg);
|
||||
static void togglefloating(const Arg *arg);
|
||||
static void togglefullscreen(const Arg *arg);
|
||||
static void toggletag(const Arg *arg);
|
||||
@@ -410,6 +414,7 @@ static struct wlr_output_layout *output_layout;
|
||||
static struct wlr_box sgeom;
|
||||
static struct wl_list mons;
|
||||
static Monitor *selmon;
|
||||
+static int DIMOPT = 1;
|
||||
|
||||
#ifdef XWAYLAND
|
||||
static void activatex11(struct wl_listener *listener, void *data);
|
||||
@@ -466,6 +471,7 @@ applyrules(Client *c)
|
||||
if ((!r->title || strstr(title, r->title))
|
||||
&& (!r->id || strstr(appid, r->id))) {
|
||||
c->isfloating = r->isfloating;
|
||||
+ c->neverdim = r-> neverdim;
|
||||
newtags |= r->tags;
|
||||
i = 0;
|
||||
wl_list_for_each(m, &mons, link) {
|
||||
@@ -1365,8 +1371,10 @@ focusclient(Client *c, int lift)
|
||||
|
||||
/* Don't change border color if there is an exclusive focus or we are
|
||||
* handling a drag operation */
|
||||
- if (!exclusive_focus && !seat->drag)
|
||||
+ if (!exclusive_focus && !seat->drag) {
|
||||
client_set_border_color(c, focuscolor);
|
||||
+ client_set_dimmer_state(c, 0);
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Deactivate old client if focus is changing */
|
||||
@@ -1384,7 +1392,7 @@ focusclient(Client *c, int lift)
|
||||
* and probably other clients */
|
||||
} else if (old_c && !client_is_unmanaged(old_c) && (!c || !client_wants_focus(c))) {
|
||||
client_set_border_color(old_c, bordercolor);
|
||||
-
|
||||
+ client_set_dimmer_state(old_c, 1);
|
||||
client_activate_surface(old, 0);
|
||||
}
|
||||
}
|
||||
@@ -1681,8 +1689,7 @@ void
|
||||
mapnotify(struct wl_listener *listener, void *data)
|
||||
{
|
||||
/* Called when the surface is mapped, or ready to display on-screen. */
|
||||
- Client *p = NULL;
|
||||
- Client *w, *c = wl_container_of(listener, c, map);
|
||||
+ Client *p, *w, *d, *c = wl_container_of(listener, c, map);
|
||||
Monitor *m;
|
||||
int i;
|
||||
|
||||
@@ -1716,6 +1723,10 @@ mapnotify(struct wl_listener *listener, void *data)
|
||||
c->border[i]->node.data = c;
|
||||
}
|
||||
|
||||
+ c->dimmer = wlr_scene_rect_create(c->scene, 0, 0, unfocuseddim);
|
||||
+ c->dimmer->node.data = c;
|
||||
+ client_set_dimmer_state(c, 1);
|
||||
+
|
||||
/* Initialize client geometry with room for border */
|
||||
client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT);
|
||||
c->geom.width += 2 * c->bw;
|
||||
@@ -1734,6 +1745,10 @@ mapnotify(struct wl_listener *listener, void *data)
|
||||
setmon(c, p->mon, p->tags);
|
||||
} else {
|
||||
applyrules(c);
|
||||
+ d = focustop(selmon);
|
||||
+ if (d) {
|
||||
+ client_set_dimmer_state(d, 0);
|
||||
+ }
|
||||
}
|
||||
printstatus();
|
||||
|
||||
@@ -2160,7 +2175,7 @@ resize(Client *c, struct wlr_box geo, int interact)
|
||||
c->geom = geo;
|
||||
applybounds(c, bbox);
|
||||
|
||||
- /* Update scene-graph, including borders */
|
||||
+ /* Update scene-graph, including borders and dimmer*/
|
||||
wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y);
|
||||
wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw);
|
||||
wlr_scene_rect_set_size(c->border[0], c->geom.width, c->bw);
|
||||
@@ -2170,6 +2185,8 @@ resize(Client *c, struct wlr_box geo, int interact)
|
||||
wlr_scene_node_set_position(&c->border[1]->node, 0, c->geom.height - c->bw);
|
||||
wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw);
|
||||
wlr_scene_node_set_position(&c->border[3]->node, c->geom.width - c->bw, c->bw);
|
||||
+ wlr_scene_rect_set_size(c->dimmer, c->geom.width - 2*c->bw, c-> geom.height - 2*c->bw);
|
||||
+ wlr_scene_node_set_position(&c->dimmer->node, c->bw, c->bw);
|
||||
|
||||
/* this is a no-op if size hasn't changed */
|
||||
c->resize = client_set_size(c, c->geom.width - 2 * c->bw,
|
||||
@@ -2681,6 +2698,27 @@ tile(Monitor *m)
|
||||
}
|
||||
}
|
||||
|
||||
+void toggledimming(const Arg *arg)
|
||||
+{
|
||||
+ Client *c;
|
||||
+ DIMOPT ^= 1;
|
||||
+ wl_list_for_each(c, &clients, link)
|
||||
+ {
|
||||
+ client_set_dimmer_state(c, 1);
|
||||
+ }
|
||||
+ c = focustop(selmon);
|
||||
+ if (c)
|
||||
+ client_set_dimmer_state(c, 0);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+toggledimmingclient(const Arg *arg)
|
||||
+{
|
||||
+ Client *sel = focustop(selmon);
|
||||
+ if (sel)
|
||||
+ sel -> neverdim ^= 1;
|
||||
+}
|
||||
+
|
||||
void
|
||||
togglefloating(const Arg *arg)
|
||||
{
|
||||
09
|
||||
17
patches/extrabar/README.md
Normal file
17
patches/extrabar/README.md
Normal file
@ -0,0 +1,17 @@
|
||||
### extrabar
|
||||
|
||||
Add an extra bar on the other side of the primary bar, shows additional status sections.
|
||||
_Requires_ `bar` patch to be applied first. Heavily inspired by `dwm`'s extrabar patch.
|
||||
|
||||
### Status
|
||||
|
||||
The status text on the extra bar is set using the stdin as usual, with the text being split by `;`
|
||||
|
||||
For example, if `status1;status2;status3` was set,
|
||||
then `status1` is set as the status of the primary bar,
|
||||
`status2` is set as the left status of extrabar,
|
||||
`status3` is set as the right status of extrabar.
|
||||
|
||||
### Author
|
||||
|
||||
[dhruva_sambrani](/dhruva_sambrani)
|
||||
193
patches/extrabar/extrabar.patch
Normal file
193
patches/extrabar/extrabar.patch
Normal file
@ -0,0 +1,193 @@
|
||||
diff --git a/dwl.c b/dwl.c
|
||||
index 7fe9468..4e3272e 100644
|
||||
--- a/dwl.c
|
||||
+++ b/dwl.c
|
||||
@@ -205,6 +205,7 @@ struct Monitor {
|
||||
struct wlr_output *wlr_output;
|
||||
struct wlr_scene_output *scene_output;
|
||||
struct wlr_scene_buffer *scene_buffer; /* bar buffer */
|
||||
+ struct wlr_scene_buffer *extra_scene_buffer; /* bar buffer */
|
||||
struct wlr_scene_rect *fullscreen_bg; /* See createmon() for info */
|
||||
struct wl_listener frame;
|
||||
struct wl_listener destroy;
|
||||
@@ -230,6 +231,7 @@ struct Monitor {
|
||||
int asleep;
|
||||
Drwl *drw;
|
||||
Buffer *pool[2];
|
||||
+ Buffer *extra_pool[2];
|
||||
int lrpad;
|
||||
};
|
||||
|
||||
@@ -278,7 +280,7 @@ static void bufdestroy(struct wlr_buffer *buffer);
|
||||
static bool bufdatabegin(struct wlr_buffer *buffer, uint32_t flags,
|
||||
void **data, uint32_t *format, size_t *stride);
|
||||
static void bufdataend(struct wlr_buffer *buffer);
|
||||
-static Buffer *bufmon(Monitor *m);
|
||||
+static Buffer *bufmon(Monitor *m, Buffer **pool);
|
||||
static void bufrelease(struct wl_listener *listener, void *data);
|
||||
static void buttonpress(struct wl_listener *listener, void *data);
|
||||
static void chvt(const Arg *arg);
|
||||
@@ -444,6 +446,8 @@ static struct wl_list mons;
|
||||
static Monitor *selmon;
|
||||
|
||||
static char stext[256];
|
||||
+static char stext2[256];
|
||||
+static char stext3[256];
|
||||
static struct wl_event_source *status_event_source;
|
||||
|
||||
static const struct wlr_buffer_impl buffer_impl = {
|
||||
@@ -627,6 +631,11 @@ arrangelayers(Monitor *m)
|
||||
usable_area.y += topbar ? m->b.real_height : 0;
|
||||
}
|
||||
|
||||
+ if (m->extra_scene_buffer->node.enabled) {
|
||||
+ usable_area.height -= m->b.real_height;
|
||||
+ usable_area.y += topbar ? 0 : m->b.real_height;
|
||||
+ }
|
||||
+
|
||||
/* Arrange exclusive surfaces from top->bottom */
|
||||
for (i = 3; i >= 0; i--)
|
||||
arrangelayer(m, &m->layers[i], &usable_area, 1);
|
||||
@@ -706,23 +715,23 @@ bufdataend(struct wlr_buffer *wlr_buffer)
|
||||
}
|
||||
|
||||
Buffer *
|
||||
-bufmon(Monitor *m)
|
||||
+bufmon(Monitor *m, Buffer **pool)
|
||||
{
|
||||
size_t i;
|
||||
Buffer *buf = NULL;
|
||||
|
||||
for (i = 0; i < LENGTH(m->pool); i++) {
|
||||
- if (m->pool[i]) {
|
||||
- if (m->pool[i]->busy)
|
||||
+ if (pool[i]) {
|
||||
+ if (pool[i]->busy)
|
||||
continue;
|
||||
- buf = m->pool[i];
|
||||
+ buf = pool[i];
|
||||
break;
|
||||
}
|
||||
|
||||
buf = ecalloc(1, sizeof(Buffer) + (m->b.width * 4 * m->b.height));
|
||||
buf->image = drwl_image_create(NULL, m->b.width, m->b.height, buf->data);
|
||||
wlr_buffer_init(&buf->base, &buffer_impl, m->b.width, m->b.height);
|
||||
- m->pool[i] = buf;
|
||||
+ pool[i] = buf;
|
||||
break;
|
||||
}
|
||||
if (!buf)
|
||||
@@ -1255,6 +1264,8 @@ createmon(struct wl_listener *listener, void *data)
|
||||
|
||||
m->scene_buffer = wlr_scene_buffer_create(layers[LyrBottom], NULL);
|
||||
m->scene_buffer->point_accepts_input = baracceptsinput;
|
||||
+ m->extra_scene_buffer = wlr_scene_buffer_create(layers[LyrBottom], NULL);
|
||||
+ m->extra_scene_buffer->point_accepts_input = baracceptsinput;
|
||||
updatebar(m);
|
||||
|
||||
wl_list_insert(&mons, &m->link);
|
||||
@@ -1580,7 +1591,7 @@ drawbar(Monitor *m)
|
||||
|
||||
if (!m->scene_buffer->node.enabled)
|
||||
return;
|
||||
- if (!(buf = bufmon(m)))
|
||||
+ if (!(buf = bufmon(m, m->pool)))
|
||||
return;
|
||||
|
||||
/* draw status first so it can be overdrawn by tags later */
|
||||
@@ -1633,13 +1644,52 @@ drawbar(Monitor *m)
|
||||
wlr_buffer_unlock(&buf->base);
|
||||
}
|
||||
|
||||
+void
|
||||
+extrabar(Monitor *m)
|
||||
+{
|
||||
+ int tw = 0;
|
||||
+ Buffer *buf = NULL;
|
||||
+
|
||||
+ /* Skip if the extra bar scene buffer is not initialized/enabled */
|
||||
+ if (!m->extra_scene_buffer || !m->extra_scene_buffer->node.enabled)
|
||||
+ return;
|
||||
+
|
||||
+ /* Inline bufmon logic for the extra pool to keep changes contained */
|
||||
+ if (!(buf = bufmon(m, m->extra_pool)))
|
||||
+ return;
|
||||
+
|
||||
+ buf->busy = true;
|
||||
+ LISTEN(&buf->base.events.release, &buf->release, bufrelease);
|
||||
+ wlr_buffer_lock(&buf->base);
|
||||
+ drwl_setimage(m->drw, buf->image);
|
||||
+
|
||||
+ drwl_setscheme(m->drw, colors[SchemeNorm]);
|
||||
+ drwl_rect(m->drw, 0, 0, m->b.width, m->b.height, 1, 1);
|
||||
+
|
||||
+ drwl_setscheme(m->drw, colors[SchemeNorm]);
|
||||
+ tw = TEXTW(m, stext2) - m->lrpad + 2; /* 2px right padding */
|
||||
+ drwl_text(m->drw, 2, 0, tw, m->b.height, 0, stext2, 0);
|
||||
+
|
||||
+ tw = TEXTW(m, stext3) - m->lrpad + 2; /* 2px right padding */
|
||||
+ drwl_text(m->drw, m->b.width - tw - 4, 0, tw, m->b.height, 0, stext3, 0);
|
||||
+
|
||||
+ wlr_scene_buffer_set_dest_size(m->extra_scene_buffer, m->b.real_width, m->b.real_height);
|
||||
+ wlr_scene_node_set_position(&m->extra_scene_buffer->node, m->m.x,
|
||||
+ m->m.y + (topbar ? m->m.height - m->b.real_height : 0));
|
||||
+
|
||||
+ wlr_scene_buffer_set_buffer(m->extra_scene_buffer, &buf->base);
|
||||
+ wlr_buffer_unlock(&buf->base);
|
||||
+}
|
||||
+
|
||||
void
|
||||
drawbars(void)
|
||||
{
|
||||
Monitor *m = NULL;
|
||||
|
||||
- wl_list_for_each(m, &mons, link)
|
||||
+ wl_list_for_each(m, &mons, link) {
|
||||
drawbar(m);
|
||||
+ extrabar(m);
|
||||
+ }
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2896,7 +2946,7 @@ startdrag(struct wl_listener *listener, void *data)
|
||||
int
|
||||
statusin(int fd, unsigned int mask, void *data)
|
||||
{
|
||||
- char status[256];
|
||||
+ char status[3*256];
|
||||
ssize_t n;
|
||||
|
||||
if (mask & WL_EVENT_ERROR)
|
||||
@@ -2911,7 +2961,18 @@ statusin(int fd, unsigned int mask, void *data)
|
||||
status[n] = '\0';
|
||||
status[strcspn(status, "\n")] = '\0';
|
||||
|
||||
- strncpy(stext, status, sizeof(stext));
|
||||
+ char *l1 = strchr(status, ';');
|
||||
+ if (l1) {
|
||||
+ *l1 = '\0';
|
||||
+ char *l2 = strchr(++l1, ';');
|
||||
+ if (l2) {
|
||||
+ *l2 = '\0';
|
||||
+ strncpy(stext3, ++l2, sizeof(stext3));
|
||||
+ }
|
||||
+ strncpy(stext2, l1, sizeof(stext2));
|
||||
+ }
|
||||
+ strncpy(stext, status, sizeof(stext));
|
||||
+
|
||||
drawbars();
|
||||
|
||||
return 0;
|
||||
@@ -3206,6 +3267,12 @@ updatebar(Monitor *m)
|
||||
m->pool[i] = NULL;
|
||||
}
|
||||
|
||||
+ for (i = 0; i < LENGTH(m->extra_pool); i++)
|
||||
+ if (m->extra_pool[i]) {
|
||||
+ wlr_buffer_drop(&m->extra_pool[i]->base);
|
||||
+ m->extra_pool[i] = NULL;
|
||||
+ }
|
||||
+
|
||||
if (m->b.scale == m->wlr_output->scale && m->drw)
|
||||
return;
|
||||
|
||||
@ -4,7 +4,8 @@ Arranges windows in a grid. Except it adjusts the number of windows in the first
|
||||
On widescreens (w > 2*h), it splits to three columns before splitting rows.
|
||||
|
||||
### Download
|
||||
- [2025-10-31](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/gaplessgrid/gaplessgrid.patch)
|
||||
- [v0.8](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/gaplessgrid/gaplessgrid.patch)
|
||||
- [2025-10-31](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/gaplessgrid/gaplessgrid-20251031.patch)
|
||||
- [2024-09-18](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/gaplessgrid/gaplessgrid-20240918.patch)
|
||||
- [2024-07-14](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/gaplessgrid/gaplessgrid-20240714.patch)
|
||||
- [2023-08-01](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/gaplessgrid/gaplessgrid-20230801.patch)
|
||||
|
||||
102
patches/gaplessgrid/gaplessgrid-20251031.patch
Normal file
102
patches/gaplessgrid/gaplessgrid-20251031.patch
Normal file
@ -0,0 +1,102 @@
|
||||
From 38427b81367e8b4d2aad708a1d463bc793aac65e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Andr=C3=A9=20Desgualdo=20Pereira?= <desgua@gmail.com>
|
||||
Date: Fri, 31 Oct 2025 15:46:48 -0300
|
||||
Subject: [PATCH] take on gaplessgrid and fix minor indentation and typos
|
||||
|
||||
---
|
||||
config.def.h | 2 ++
|
||||
dwl.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 53 insertions(+)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index 95c2afa..2054107 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -34,6 +34,7 @@ static const Layout layouts[] = {
|
||||
{ "[]=", tile },
|
||||
{ "><>", NULL }, /* no layout function means floating behavior */
|
||||
{ "[M]", monocle },
|
||||
+ { "###", gaplessgrid },
|
||||
};
|
||||
|
||||
/* monitors */
|
||||
@@ -139,6 +140,7 @@ static const Key keys[] = {
|
||||
{ MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
|
||||
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
|
||||
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
|
||||
+ { MODKEY, XKB_KEY_g, setlayout, {.v = &layouts[3]} },
|
||||
{ MODKEY, XKB_KEY_space, setlayout, {0} },
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
|
||||
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
|
||||
diff --git a/dwl.c b/dwl.c
|
||||
index 12f441e..7ab5323 100644
|
||||
--- a/dwl.c
|
||||
+++ b/dwl.c
|
||||
@@ -288,6 +288,7 @@ static void focusstack(const Arg *arg);
|
||||
static Client *focustop(Monitor *m);
|
||||
static void fullscreennotify(struct wl_listener *listener, void *data);
|
||||
static void gpureset(struct wl_listener *listener, void *data);
|
||||
+static void gaplessgrid(Monitor *m);
|
||||
static void handlesig(int signo);
|
||||
static void incnmaster(const Arg *arg);
|
||||
static void inputdevice(struct wl_listener *listener, void *data);
|
||||
@@ -1566,6 +1567,56 @@ handlesig(int signo)
|
||||
quit(NULL);
|
||||
}
|
||||
|
||||
+void
|
||||
+gaplessgrid(Monitor *m)
|
||||
+{
|
||||
+ int n = 0, i = 0, ch, cw, cn, rn, rows, cols;
|
||||
+ Client *c;
|
||||
+
|
||||
+ wl_list_for_each(c, &clients, link)
|
||||
+ if (VISIBLEON(c, m) && !c->isfloating)
|
||||
+ n++;
|
||||
+ if (n == 0)
|
||||
+ return;
|
||||
+
|
||||
+ /* grid dimensions */
|
||||
+ for (cols = 0; cols <= (n / 2); cols++)
|
||||
+ if ((cols * cols) >= n)
|
||||
+ break;
|
||||
+
|
||||
+ if (n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */
|
||||
+ cols = 2;
|
||||
+
|
||||
+ /* widescreen is better if 3 columns */
|
||||
+ if (n >= 3 && n <= 6 && (m->w.width / m->w.height) > 1)
|
||||
+ cols = 3;
|
||||
+
|
||||
+ rows = n / cols;
|
||||
+
|
||||
+ /* window geometries */
|
||||
+ cw = cols ? m->w.width / cols : m->w.width;
|
||||
+ cn = 0; /* current column number */
|
||||
+ rn = 0; /* current row number */
|
||||
+ wl_list_for_each(c, &clients, link) {
|
||||
+ unsigned int cx, cy;
|
||||
+ if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
|
||||
+ continue;
|
||||
+
|
||||
+ if ((i / rows + 1) > (cols - n % cols))
|
||||
+ rows = n / cols + 1;
|
||||
+ ch = rows ? m->w.height / rows : m->w.height;
|
||||
+ cx = m->w.x + cn * cw;
|
||||
+ cy = m->w.y + rn * ch;
|
||||
+ resize(c, (struct wlr_box) { cx, cy, cw, ch}, 0);
|
||||
+ rn++;
|
||||
+ if (rn >= rows) {
|
||||
+ rn = 0;
|
||||
+ cn++;
|
||||
+ }
|
||||
+ i++;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void
|
||||
incnmaster(const Arg *arg)
|
||||
{
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
From 38427b81367e8b4d2aad708a1d463bc793aac65e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Andr=C3=A9=20Desgualdo=20Pereira?= <desgua@gmail.com>
|
||||
Date: Fri, 31 Oct 2025 15:46:48 -0300
|
||||
Subject: [PATCH] take on gaplessgrid and fix minor indentation and typos
|
||||
From 91d34b1c664fe273a82eb7ff01e92b828feab5a9 Mon Sep 17 00:00:00 2001
|
||||
From: nate zhou <gnuunixchad@outlook.com>
|
||||
Date: Sat, 28 Feb 2026 21:42:04 +0800
|
||||
Subject: [PATCH] Patch: gaplessgrid.patch
|
||||
|
||||
---
|
||||
config.def.h | 2 ++
|
||||
@ -9,10 +9,10 @@ Subject: [PATCH] take on gaplessgrid and fix minor indentation and typos
|
||||
2 files changed, 53 insertions(+)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index 95c2afa..2054107 100644
|
||||
index 8a6eda0..8cb1782 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -34,6 +34,7 @@ static const Layout layouts[] = {
|
||||
@@ -33,6 +33,7 @@ static const Layout layouts[] = {
|
||||
{ "[]=", tile },
|
||||
{ "><>", NULL }, /* no layout function means floating behavior */
|
||||
{ "[M]", monocle },
|
||||
@ -20,16 +20,16 @@ index 95c2afa..2054107 100644
|
||||
};
|
||||
|
||||
/* monitors */
|
||||
@@ -139,6 +140,7 @@ static const Key keys[] = {
|
||||
{ MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
|
||||
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
|
||||
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
|
||||
+ { MODKEY, XKB_KEY_g, setlayout, {.v = &layouts[3]} },
|
||||
{ MODKEY, XKB_KEY_space, setlayout, {0} },
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
|
||||
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
|
||||
@@ -135,6 +136,7 @@ static const Key keys[] = {
|
||||
{ MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
|
||||
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
|
||||
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
|
||||
+ { MODKEY, XKB_KEY_g, setlayout, {.v = &layouts[3]} },
|
||||
{ MODKEY, XKB_KEY_space, setlayout, {0} },
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
|
||||
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
|
||||
diff --git a/dwl.c b/dwl.c
|
||||
index 12f441e..7ab5323 100644
|
||||
index 44f3ad9..83c053f 100644
|
||||
--- a/dwl.c
|
||||
+++ b/dwl.c
|
||||
@@ -288,6 +288,7 @@ static void focusstack(const Arg *arg);
|
||||
@ -98,5 +98,5 @@ index 12f441e..7ab5323 100644
|
||||
incnmaster(const Arg *arg)
|
||||
{
|
||||
--
|
||||
2.51.0
|
||||
2.53.0
|
||||
|
||||
|
||||
15
patches/hide-cursor-when-typing/README.md
Normal file
15
patches/hide-cursor-when-typing/README.md
Normal file
@ -0,0 +1,15 @@
|
||||
### Description
|
||||
|
||||
Hide the mouse cursor when you start typing, and restore it again when the
|
||||
mouse cursor moves or a mouse button is pressed, just like
|
||||
[xbanish](https://github.com/jcs/xbanish).
|
||||
|
||||
### credits
|
||||
Some code is taken from the
|
||||
[unclutter](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/unclutter) patch.
|
||||
|
||||
### Download
|
||||
[v0.8](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/hide-cursor-when-typing/hide-cursor-when-typing.patch)
|
||||
|
||||
### Authors
|
||||
- [unixchad](https://codeberg.org/unixchad/)
|
||||
170
patches/hide-cursor-when-typing/hide-cursor-when-typing.patch
Normal file
170
patches/hide-cursor-when-typing/hide-cursor-when-typing.patch
Normal file
@ -0,0 +1,170 @@
|
||||
From c72de058e6635c5bb3d973995ccbdb6e028f354d Mon Sep 17 00:00:00 2001
|
||||
From: nate zhou <gnuunixchad@outlook.com>
|
||||
Date: Tue, 3 Mar 2026 16:48:46 +0800
|
||||
Subject: [PATCH] Patch: hide-cursor-when-typing-0.8.patch
|
||||
|
||||
Hide the cursor when start typing, and restore it when start moving
|
||||
cursor again, just like xbanish.
|
||||
---
|
||||
config.def.h | 2 ++
|
||||
dwl.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++------
|
||||
2 files changed, 63 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index 8a6eda0..6205c0a 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -102,6 +102,8 @@ LIBINPUT_CONFIG_TAP_MAP_LMR -- 1/2/3 finger tap maps to left/middle/right
|
||||
*/
|
||||
static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TAP_MAP_LRM;
|
||||
|
||||
+static const int hide_cursor_when_typing = 1;
|
||||
+
|
||||
/* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */
|
||||
#define MODKEY WLR_MODIFIER_ALT
|
||||
|
||||
diff --git a/dwl.c b/dwl.c
|
||||
index 44f3ad9..9a076b6 100644
|
||||
--- a/dwl.c
|
||||
+++ b/dwl.c
|
||||
@@ -289,6 +289,8 @@ static Client *focustop(Monitor *m);
|
||||
static void fullscreennotify(struct wl_listener *listener, void *data);
|
||||
static void gpureset(struct wl_listener *listener, void *data);
|
||||
static void handlesig(int signo);
|
||||
+static void handlecursoractivity(void);
|
||||
+static int hidecursor(void *data);
|
||||
static void incnmaster(const Arg *arg);
|
||||
static void inputdevice(struct wl_listener *listener, void *data);
|
||||
static int keybinding(uint32_t mods, xkb_keysym_t sym);
|
||||
@@ -389,6 +391,14 @@ static struct wlr_pointer_constraint_v1 *active_constraint;
|
||||
|
||||
static struct wlr_cursor *cursor;
|
||||
static struct wlr_xcursor_manager *cursor_mgr;
|
||||
+static struct wl_event_source *hide_source;
|
||||
+static bool cursor_hidden = false;
|
||||
+static struct {
|
||||
+ enum wp_cursor_shape_device_v1_shape shape;
|
||||
+ struct wlr_surface *surface;
|
||||
+ int hotspot_x;
|
||||
+ int hotspot_y;
|
||||
+} last_cursor;
|
||||
|
||||
static struct wlr_scene_rect *root_bg;
|
||||
static struct wlr_session_lock_manager_v1 *session_lock_mgr;
|
||||
@@ -610,6 +620,7 @@ axisnotify(struct wl_listener *listener, void *data)
|
||||
* for example when you move the scroll wheel. */
|
||||
struct wlr_pointer_axis_event *event = data;
|
||||
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||
+ handlecursoractivity();
|
||||
/* TODO: allow usage of scroll wheel for mousebindings, it can be implemented
|
||||
* by checking the event's orientation and the delta of the event */
|
||||
/* Notify the client with pointer focus of the axis event. */
|
||||
@@ -628,6 +639,7 @@ buttonpress(struct wl_listener *listener, void *data)
|
||||
const Button *b;
|
||||
|
||||
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||
+ handlecursoractivity();
|
||||
|
||||
switch (event->state) {
|
||||
case WL_POINTER_BUTTON_STATE_PRESSED:
|
||||
@@ -1566,6 +1578,30 @@ handlesig(int signo)
|
||||
quit(NULL);
|
||||
}
|
||||
|
||||
+void
|
||||
+handlecursoractivity(void)
|
||||
+{
|
||||
+ if (!cursor_hidden)
|
||||
+ return;
|
||||
+
|
||||
+ cursor_hidden = false;
|
||||
+
|
||||
+ if (last_cursor.shape)
|
||||
+ wlr_cursor_set_xcursor(cursor, cursor_mgr,
|
||||
+ wlr_cursor_shape_v1_name(last_cursor.shape));
|
||||
+ else
|
||||
+ wlr_cursor_set_surface(cursor, last_cursor.surface,
|
||||
+ last_cursor.hotspot_x, last_cursor.hotspot_y);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+hidecursor(void *data)
|
||||
+{
|
||||
+ wlr_cursor_unset_image(cursor);
|
||||
+ cursor_hidden = true;
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
void
|
||||
incnmaster(const Arg *arg)
|
||||
{
|
||||
@@ -1645,6 +1681,11 @@ keypress(struct wl_listener *listener, void *data)
|
||||
|
||||
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||
|
||||
+ /* hide cursor when typing starts */
|
||||
+ if (hide_cursor_when_typing && !cursor_hidden && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
+ hidecursor(NULL);
|
||||
+ }
|
||||
+
|
||||
/* On _press_ if there is no active screen locker,
|
||||
* attempt to process a compositor keybinding. */
|
||||
if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
@@ -1907,6 +1948,7 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d
|
||||
|
||||
wlr_cursor_move(cursor, device, dx, dy);
|
||||
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||
+ handlecursoractivity();
|
||||
|
||||
/* Update selmon (even while dragging a window) */
|
||||
if (sloppyfocus)
|
||||
@@ -1931,7 +1973,7 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d
|
||||
/* If there's no client surface under the cursor, set the cursor image to a
|
||||
* default. This is what makes the cursor image appear when you move it
|
||||
* off of a client or over its border. */
|
||||
- if (!surface && !seat->drag)
|
||||
+ if (!surface && !seat->drag && !cursor_hidden)
|
||||
wlr_cursor_set_xcursor(cursor, cursor_mgr, "default");
|
||||
|
||||
pointerfocus(c, surface, sx, sy, time);
|
||||
@@ -2311,9 +2353,16 @@ setcursor(struct wl_listener *listener, void *data)
|
||||
* use the provided surface as the cursor image. It will set the
|
||||
* hardware cursor on the output that it's currently on and continue to
|
||||
* do so as the cursor moves between outputs. */
|
||||
- if (event->seat_client == seat->pointer_state.focused_client)
|
||||
- wlr_cursor_set_surface(cursor, event->surface,
|
||||
- event->hotspot_x, event->hotspot_y);
|
||||
+ if (event->seat_client == seat->pointer_state.focused_client) {
|
||||
+ last_cursor.shape = 0;
|
||||
+ last_cursor.surface = event->surface;
|
||||
+ last_cursor.hotspot_x = event->hotspot_x;
|
||||
+ last_cursor.hotspot_y = event->hotspot_y;
|
||||
+
|
||||
+ if (!cursor_hidden)
|
||||
+ wlr_cursor_set_surface(cursor, event->surface,
|
||||
+ event->hotspot_x, event->hotspot_y);
|
||||
+ }
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2325,9 +2374,14 @@ setcursorshape(struct wl_listener *listener, void *data)
|
||||
/* This can be sent by any client, so we check to make sure this one
|
||||
* actually has pointer focus first. If so, we can tell the cursor to
|
||||
* use the provided cursor shape. */
|
||||
- if (event->seat_client == seat->pointer_state.focused_client)
|
||||
- wlr_cursor_set_xcursor(cursor, cursor_mgr,
|
||||
- wlr_cursor_shape_v1_name(event->shape));
|
||||
+ if (event->seat_client == seat->pointer_state.focused_client) {
|
||||
+ last_cursor.shape = event->shape;
|
||||
+ last_cursor.surface = NULL;
|
||||
+
|
||||
+ if (!cursor_hidden)
|
||||
+ wlr_cursor_set_xcursor(cursor, cursor_mgr,
|
||||
+ wlr_cursor_shape_v1_name(event->shape));
|
||||
+ }
|
||||
}
|
||||
|
||||
void
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -15,7 +15,7 @@ So in short:
|
||||
|
||||
#### Limitations
|
||||
Reloading the compositor will replace all functionality except for `main`, `setup`, `run` and the reload logic.
|
||||
Note that you're responsible yourself for reloading ressources like fonts, which may only get acquired once.
|
||||
Note that you're responsible yourself for reloading resources like fonts, which may only get acquired once.
|
||||
A lot of components of dwl will also only get run on a trigger (the tiling for example).
|
||||
So not every change will be immediate.
|
||||
Furthermore, any patch adding more global state to dwl cannot currently be reloaded properly since
|
||||
@ -47,13 +47,13 @@ From the cold part there are some newly available macros:
|
||||
* `CSYM(T, v)` dynamically accesses the value of the symbol `v` of type `T` from the shared object. Use this to query values from config.h for example.
|
||||
* `LISTEN_GLOBAL(E, L)` is similar to the `LISTEN` macro. `E` is an event and `L` the name of a global
|
||||
listener. Current implementation is a bit messy and I may fix it if someone bothers me about it.
|
||||
* `UNLISTEN(L)` takes a listener and unregisteres it. This is important for reloading.
|
||||
* `UNLISTEN(L)` takes a listener and unregisters it. This is important for reloading.
|
||||
|
||||
When adding new code there are some considerations to be made. Since dwl decorates all symbols with `static` by default, we cannot access them as-is.
|
||||
C's macro system is a bit too powerful though and we use this to our advantage. We will repeatedly define and
|
||||
undefine a macro called `static` in order to replace the `static` keyword inside some sections.
|
||||
This allows us to do less refactoring and preserve a lot of the original patch compatability since we're only
|
||||
strategically adding lines. We're tring to be as minimally invasive as we can.
|
||||
This allows us to do less refactoring and preserve a lot of the original patch compatibility since we're only
|
||||
strategically adding lines. We're trying to be as minimally invasive as we can.
|
||||
As a general guide:
|
||||
* global state should be global for the cold part and `extern` in the cold part meaning it should be inside a block like this:
|
||||
```C
|
||||
@ -87,7 +87,7 @@ Thus, we enclose them the same way we do functions:
|
||||
#ifdef HOT
|
||||
... // function definitions here
|
||||
#endif
|
||||
* enfore use of the `LISTEN_GLOBAL` and `UNLISTEN` macros (I know this sucks but what can I do, I need to get
|
||||
* enforce use of the `LISTEN_GLOBAL` and `UNLISTEN` macros (I know this sucks but what can I do, I need to get
|
||||
access to the callbacks somehow). So you want
|
||||
* `wl_list_remove(listener.link)` to become `UNLISTEN(listener)` and
|
||||
* `wl_signal_add(event, global_listener)` to become `LISTEN_GLOBAL(event, global_listener)`.
|
||||
|
||||
@ -509,7 +509,7 @@ index def2562..1c9ab67 100644
|
||||
+ wlr_log_init(CSYM(enum wlr_log_importance, 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. */
|
||||
@@ -2454,7 +2576,7 @@ setup(void)
|
||||
|
||||
/* Initialize the scene graph used to lay out windows */
|
||||
|
||||
@ -637,7 +637,7 @@ index 4816159..70e99be 100644
|
||||
+ wlr_log_init(CSYM(enum wlr_log_importance, 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. */
|
||||
@@ -2463,7 +2602,7 @@ setup(void)
|
||||
|
||||
/* Initialize the scene graph used to lay out windows */
|
||||
|
||||
@ -7,7 +7,7 @@ To enable Xwayland support, you will need to enable it in the wlroots subproject
|
||||
```sh
|
||||
meson setup -Dwlroots:xwayland=enabled build
|
||||
```
|
||||
It is also reccomended to see the wlroots meson project configuration logs for any
|
||||
It is also recommended to see the wlroots meson project configuration logs for any
|
||||
unusual checks, such as requiring `hwdata` for the DRM backend.
|
||||
|
||||
### Download
|
||||
|
||||
@ -28,8 +28,10 @@ static const Modekey modekeys[] = {
|
||||
```
|
||||
|
||||
### Download
|
||||
- [v0.8](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/modes/modes.patch)
|
||||
- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.5/modes)
|
||||
- [v0.5](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/modes/modes.patch)
|
||||
- [v0.5](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/modes/modes-0.5.patch)
|
||||
|
||||
### Authors
|
||||
- [unixchad](https://codeberg.org/unixchad)
|
||||
- [wochap](https://codeberg.org/wochap)
|
||||
|
||||
165
patches/modes/modes-0.5.patch
Normal file
165
patches/modes/modes-0.5.patch
Normal file
@ -0,0 +1,165 @@
|
||||
From a32b85018ff2cea0fc9f9137789860a4aadc3b3a Mon Sep 17 00:00:00 2001
|
||||
From: wochap <gean.marroquin@gmail.com>
|
||||
Date: Wed, 6 Mar 2024 07:31:17 -0500
|
||||
Subject: [PATCH] implement modes
|
||||
|
||||
like sway/river modes
|
||||
---
|
||||
config.def.h | 20 ++++++++++++++++++++
|
||||
dwl.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 66 insertions(+)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index db0babc..1616136 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -13,6 +13,13 @@ static const float urgentcolor[] = COLOR(0xff0000ff);
|
||||
/* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */
|
||||
static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0}; /* You can also use glsl colors */
|
||||
|
||||
+enum {
|
||||
+ BROWSER,
|
||||
+};
|
||||
+const char *modes_labels[] = {
|
||||
+ "browser",
|
||||
+};
|
||||
+
|
||||
/* tagging - TAGCOUNT must be no greater than 31 */
|
||||
#define TAGCOUNT (9)
|
||||
|
||||
@@ -152,6 +159,8 @@ static const Key keys[] = {
|
||||
TAGKEYS( XKB_KEY_9, XKB_KEY_parenleft, 8),
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, quit, {0} },
|
||||
|
||||
+ { MODKEY, XKB_KEY_b, entermode, {.i = BROWSER} },
|
||||
+
|
||||
/* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */
|
||||
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} },
|
||||
/* Ctrl-Alt-Fx is used to switch to another VT, if you don't know what a VT is
|
||||
@@ -162,6 +171,17 @@ static const Key keys[] = {
|
||||
CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
|
||||
};
|
||||
|
||||
+static const Modekey modekeys[] = {
|
||||
+ /* mode modifier key function argument */
|
||||
+ { BROWSER, { 0, XKB_KEY_f, spawn, SHCMD("firefox") } },
|
||||
+ { BROWSER, { 0, XKB_KEY_f, entermode, {.i = NORMAL} } },
|
||||
+ { BROWSER, { 0, XKB_KEY_b, spawn, SHCMD("brave") } },
|
||||
+ { BROWSER, { 0, XKB_KEY_b, entermode, {.i = NORMAL} } },
|
||||
+ { BROWSER, { 0, XKB_KEY_g, spawn, SHCMD("google-chrome-stable") } },
|
||||
+ { BROWSER, { 0, XKB_KEY_g, entermode, {.i = NORMAL} } },
|
||||
+ { BROWSER, { 0, XKB_KEY_Escape, entermode, {.i = NORMAL} } },
|
||||
+};
|
||||
+
|
||||
static const Button buttons[] = {
|
||||
{ MODKEY, BTN_LEFT, moveresize, {.ui = CurMove} },
|
||||
{ MODKEY, BTN_MIDDLE, togglefloating, {0} },
|
||||
diff --git a/dwl.c b/dwl.c
|
||||
index ef27a1d..1ada006 100644
|
||||
--- a/dwl.c
|
||||
+++ b/dwl.c
|
||||
@@ -139,6 +139,11 @@ typedef struct {
|
||||
const Arg arg;
|
||||
} Key;
|
||||
|
||||
+typedef struct {
|
||||
+ int mode_index;
|
||||
+ Key key;
|
||||
+} Modekey;
|
||||
+
|
||||
typedef struct {
|
||||
struct wl_list link;
|
||||
struct wlr_keyboard *wlr_keyboard;
|
||||
@@ -270,6 +275,7 @@ static void handlesig(int signo);
|
||||
static void incnmaster(const Arg *arg);
|
||||
static void inputdevice(struct wl_listener *listener, void *data);
|
||||
static int keybinding(uint32_t mods, xkb_keysym_t sym);
|
||||
+static int modekeybinding(uint32_t mods, xkb_keysym_t sym);
|
||||
static void keypress(struct wl_listener *listener, void *data);
|
||||
static void keypressmod(struct wl_listener *listener, void *data);
|
||||
static int keyrepeat(void *data);
|
||||
@@ -327,6 +333,7 @@ static Monitor *xytomon(double x, double y);
|
||||
static void xytonode(double x, double y, struct wlr_surface **psurface,
|
||||
Client **pc, LayerSurface **pl, double *nx, double *ny);
|
||||
static void zoom(const Arg *arg);
|
||||
+static void entermode(const Arg *arg);
|
||||
|
||||
/* variables */
|
||||
static const char broken[] = "broken";
|
||||
@@ -377,6 +384,9 @@ static struct wlr_box sgeom;
|
||||
static struct wl_list mons;
|
||||
static Monitor *selmon;
|
||||
|
||||
+static const int NORMAL = -1;
|
||||
+static int active_mode_index = NORMAL;
|
||||
+
|
||||
#ifdef XWAYLAND
|
||||
static void activatex11(struct wl_listener *listener, void *data);
|
||||
static void associatex11(struct wl_listener *listener, void *data);
|
||||
@@ -1372,6 +1382,11 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
|
||||
*/
|
||||
int handled = 0;
|
||||
const Key *k;
|
||||
+
|
||||
+ if (active_mode_index >= 0) {
|
||||
+ return modekeybinding(mods, sym);
|
||||
+ }
|
||||
+
|
||||
for (k = keys; k < END(keys); k++) {
|
||||
if (CLEANMASK(mods) == CLEANMASK(k->mod) &&
|
||||
sym == k->keysym && k->func) {
|
||||
@@ -1382,6 +1397,29 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
|
||||
return handled;
|
||||
}
|
||||
|
||||
+int
|
||||
+modekeybinding(uint32_t mods, xkb_keysym_t sym)
|
||||
+{
|
||||
+ int handled = 0;
|
||||
+ const Modekey *mk;
|
||||
+ const Key *k;
|
||||
+
|
||||
+ for (mk = modekeys; mk < END(modekeys); mk++) {
|
||||
+ if (active_mode_index != mk->mode_index) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ k = &mk->key;
|
||||
+ if (CLEANMASK(mods) == CLEANMASK(k->mod) &&
|
||||
+ sym == k->keysym && k->func) {
|
||||
+ k->func(&k->arg);
|
||||
+ handled = 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return handled;
|
||||
+}
|
||||
+
|
||||
void
|
||||
keypress(struct wl_listener *listener, void *data)
|
||||
{
|
||||
@@ -1851,6 +1889,7 @@ printstatus(void)
|
||||
printf("%s tags %u %u %u %u\n", m->wlr_output->name, occ, m->tagset[m->seltags],
|
||||
sel, urg);
|
||||
printf("%s layout %s\n", m->wlr_output->name, m->ltsymbol);
|
||||
+ printf("%s mode %s\n", m->wlr_output->name, modes_labels[active_mode_index] ? modes_labels[active_mode_index] : "");
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
@@ -2746,6 +2785,13 @@ zoom(const Arg *arg)
|
||||
arrange(selmon);
|
||||
}
|
||||
|
||||
+void
|
||||
+entermode(const Arg *arg)
|
||||
+{
|
||||
+ active_mode_index = arg->i;
|
||||
+ printstatus();
|
||||
+}
|
||||
+
|
||||
#ifdef XWAYLAND
|
||||
void
|
||||
activatex11(struct wl_listener *listener, void *data)
|
||||
--
|
||||
2.42.0
|
||||
|
||||
@ -1,21 +1,20 @@
|
||||
From a32b85018ff2cea0fc9f9137789860a4aadc3b3a Mon Sep 17 00:00:00 2001
|
||||
From: wochap <gean.marroquin@gmail.com>
|
||||
Date: Wed, 6 Mar 2024 07:31:17 -0500
|
||||
Subject: [PATCH] implement modes
|
||||
From 915115151a4429bab38dd8cff2268f34ee23984f Mon Sep 17 00:00:00 2001
|
||||
From: nate zhou <gnuunixchad@outlook.com>
|
||||
Date: Mon, 2 Mar 2026 19:23:59 +0800
|
||||
Subject: [PATCH] Patch: modes-0.8.patch
|
||||
|
||||
like sway/river modes
|
||||
---
|
||||
config.def.h | 20 ++++++++++++++++++++
|
||||
dwl.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 66 insertions(+)
|
||||
dwl.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 67 insertions(+)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index db0babc..1616136 100644
|
||||
index 8a6eda0..bc88ea5 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -13,6 +13,13 @@ static const float urgentcolor[] = COLOR(0xff0000ff);
|
||||
/* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */
|
||||
static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0}; /* You can also use glsl colors */
|
||||
@@ -14,6 +14,13 @@ static const float urgentcolor[] = COLOR(0xff0000ff);
|
||||
/* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */
|
||||
static const float fullscreen_bg[] = {0.0f, 0.0f, 0.0f, 1.0f}; /* You can also use glsl colors */
|
||||
|
||||
+enum {
|
||||
+ BROWSER,
|
||||
@ -27,16 +26,16 @@ index db0babc..1616136 100644
|
||||
/* tagging - TAGCOUNT must be no greater than 31 */
|
||||
#define TAGCOUNT (9)
|
||||
|
||||
@@ -152,6 +159,8 @@ static const Key keys[] = {
|
||||
TAGKEYS( XKB_KEY_9, XKB_KEY_parenleft, 8),
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, quit, {0} },
|
||||
@@ -155,6 +162,8 @@ static const Key keys[] = {
|
||||
TAGKEYS( XKB_KEY_9, XKB_KEY_parenleft, 8),
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_q, quit, {0} },
|
||||
|
||||
+ { MODKEY, XKB_KEY_b, entermode, {.i = BROWSER} },
|
||||
+
|
||||
/* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */
|
||||
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} },
|
||||
/* Ctrl-Alt-Fx is used to switch to another VT, if you don't know what a VT is
|
||||
@@ -162,6 +171,17 @@ static const Key keys[] = {
|
||||
@@ -165,6 +174,17 @@ static const Key keys[] = {
|
||||
CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
|
||||
};
|
||||
|
||||
@ -55,10 +54,10 @@ index db0babc..1616136 100644
|
||||
{ MODKEY, BTN_LEFT, moveresize, {.ui = CurMove} },
|
||||
{ MODKEY, BTN_MIDDLE, togglefloating, {0} },
|
||||
diff --git a/dwl.c b/dwl.c
|
||||
index ef27a1d..1ada006 100644
|
||||
index 44f3ad9..9247541 100644
|
||||
--- a/dwl.c
|
||||
+++ b/dwl.c
|
||||
@@ -139,6 +139,11 @@ typedef struct {
|
||||
@@ -148,6 +148,11 @@ typedef struct {
|
||||
const Arg arg;
|
||||
} Key;
|
||||
|
||||
@ -68,9 +67,9 @@ index ef27a1d..1ada006 100644
|
||||
+} Modekey;
|
||||
+
|
||||
typedef struct {
|
||||
struct wl_list link;
|
||||
struct wlr_keyboard *wlr_keyboard;
|
||||
@@ -270,6 +275,7 @@ static void handlesig(int signo);
|
||||
struct wlr_keyboard_group *wlr_group;
|
||||
|
||||
@@ -292,6 +297,7 @@ static void handlesig(int signo);
|
||||
static void incnmaster(const Arg *arg);
|
||||
static void inputdevice(struct wl_listener *listener, void *data);
|
||||
static int keybinding(uint32_t mods, xkb_keysym_t sym);
|
||||
@ -78,27 +77,27 @@ index ef27a1d..1ada006 100644
|
||||
static void keypress(struct wl_listener *listener, void *data);
|
||||
static void keypressmod(struct wl_listener *listener, void *data);
|
||||
static int keyrepeat(void *data);
|
||||
@@ -327,6 +333,7 @@ static Monitor *xytomon(double x, double y);
|
||||
@@ -351,6 +357,7 @@ static Monitor *xytomon(double x, double y);
|
||||
static void xytonode(double x, double y, struct wlr_surface **psurface,
|
||||
Client **pc, LayerSurface **pl, double *nx, double *ny);
|
||||
static void zoom(const Arg *arg);
|
||||
+static void entermode(const Arg *arg);
|
||||
|
||||
/* variables */
|
||||
static const char broken[] = "broken";
|
||||
@@ -377,6 +384,9 @@ static struct wlr_box sgeom;
|
||||
static pid_t child_pid = -1;
|
||||
@@ -406,6 +413,9 @@ static struct wlr_box sgeom;
|
||||
static struct wl_list mons;
|
||||
static Monitor *selmon;
|
||||
|
||||
+static const int NORMAL = -1;
|
||||
+static int active_mode_index = NORMAL;
|
||||
+
|
||||
#ifdef XWAYLAND
|
||||
static void activatex11(struct wl_listener *listener, void *data);
|
||||
static void associatex11(struct wl_listener *listener, void *data);
|
||||
@@ -1372,6 +1382,11 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
|
||||
/* global event handlers */
|
||||
static struct wl_listener cursor_axis = {.notify = axisnotify};
|
||||
static struct wl_listener cursor_button = {.notify = buttonpress};
|
||||
@@ -1614,6 +1624,11 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
|
||||
* processing.
|
||||
*/
|
||||
int handled = 0;
|
||||
const Key *k;
|
||||
+
|
||||
+ if (active_mode_index >= 0) {
|
||||
@ -106,10 +105,10 @@ index ef27a1d..1ada006 100644
|
||||
+ }
|
||||
+
|
||||
for (k = keys; k < END(keys); k++) {
|
||||
if (CLEANMASK(mods) == CLEANMASK(k->mod) &&
|
||||
sym == k->keysym && k->func) {
|
||||
@@ -1382,6 +1397,29 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
|
||||
return handled;
|
||||
if (CLEANMASK(mods) == CLEANMASK(k->mod)
|
||||
&& xkb_keysym_to_lower(sym) == xkb_keysym_to_lower(k->keysym)
|
||||
@@ -1625,6 +1640,30 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int
|
||||
@ -134,19 +133,20 @@ index ef27a1d..1ada006 100644
|
||||
+
|
||||
+ return handled;
|
||||
+}
|
||||
+
|
||||
+
|
||||
void
|
||||
keypress(struct wl_listener *listener, void *data)
|
||||
{
|
||||
@@ -1851,6 +1889,7 @@ printstatus(void)
|
||||
printf("%s tags %u %u %u %u\n", m->wlr_output->name, occ, m->tagset[m->seltags],
|
||||
sel, urg);
|
||||
@@ -2119,6 +2158,7 @@ printstatus(void)
|
||||
printf("%s tags %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32"\n",
|
||||
m->wlr_output->name, occ, m->tagset[m->seltags], sel, urg);
|
||||
printf("%s layout %s\n", m->wlr_output->name, m->ltsymbol);
|
||||
+ printf("%s mode %s\n", m->wlr_output->name, modes_labels[active_mode_index] ? modes_labels[active_mode_index] : "");
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
@@ -2746,6 +2785,13 @@ zoom(const Arg *arg)
|
||||
@@ -3075,6 +3115,13 @@ zoom(const Arg *arg)
|
||||
arrange(selmon);
|
||||
}
|
||||
|
||||
@ -161,5 +161,5 @@ index ef27a1d..1ada006 100644
|
||||
void
|
||||
activatex11(struct wl_listener *listener, void *data)
|
||||
--
|
||||
2.42.0
|
||||
2.53.0
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
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 montior for client when it is reattached
|
||||
Subject: [PATCH] Restore correct monitor for client when it is reattached
|
||||
|
||||
---
|
||||
dwl.c | 24 ++++++++++++++++++++++--
|
||||
|
||||
@ -7,7 +7,7 @@ Most of this patch is stored in river-control.h, It contains a list of functions
|
||||
|
||||
This patch's main intended use case is to have a startup script that calls dwlctl a bunch to add all the binds/rules you want, without the need of restarting dwl if you make any changes to the list of binds/rules.
|
||||
|
||||
This patch also adds keybind modes which allow switching between a diffrent sets of keybinds on the fly.
|
||||
This patch also adds keybind modes which allow switching between a different sets of keybinds on the fly.
|
||||
Also you can set a keybind mode as oneshot (meaning as soon as a keybind is activated the mode is switched) by using...
|
||||
`dwlctl oneshot-mode _layout_you_want_to_make_oneshot_here_ _layout_you_want_to_switch_to_after_keybind_pressed_`
|
||||
Just make sure to set a mode as oneshot after creating a bind under it otherwise it won't work.
|
||||
|
||||
@ -120,7 +120,7 @@ index 95c2afa..ccc3edb 100644
|
||||
-static const Key keys[] = {
|
||||
+/* note keys gets cleared with riverctl clear-binds but the keys_always are excluded from being cleared
|
||||
+ * this is to have a list of fallback keybinds if your riverctl script fails
|
||||
+ * if you won't like to have keys[] declared commented out the KEYS_USED macro bellow to disable the functionality*/
|
||||
+ * if you won't like to have keys[] declared commented out the KEYS_USED macro below to disable the functionality*/
|
||||
+#define KEYS_USED
|
||||
+static Key keys[] = {
|
||||
/* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
|
||||
@ -1267,7 +1267,7 @@ index 0000000..599cffe
|
||||
+ .add_argument = zriver_control_add_argument,
|
||||
+ .destroy = zriver_control_destroy,
|
||||
+};
|
||||
+static void zriver_control_handle_destory(struct wl_resource *resource) {
|
||||
+static void zriver_control_handle_destroy(struct wl_resource *resource) {
|
||||
+ struct zriver_arg_list_resource *zriver_arg_list_resource = wl_resource_get_user_data(resource);
|
||||
+ free(zriver_arg_list_resource);
|
||||
+ printf("handle destroy\n");
|
||||
@ -1281,7 +1281,7 @@ index 0000000..599cffe
|
||||
+
|
||||
+
|
||||
+ wl_resource_set_implementation(resource, &zriver_control_interface,
|
||||
+ zriver_arg_list_resource, zriver_control_handle_destory);
|
||||
+ zriver_arg_list_resource, zriver_control_handle_destroy);
|
||||
+}
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
### Description
|
||||
Makes sticky work as expected with singletagset. The sticky window will
|
||||
stay on original output until you explicitely put it to a different monitor.
|
||||
stay on original output until you explicitly put it to a different monitor.
|
||||
|
||||
This patch expects both [singletagset](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/singletagset) and [sticky](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/sticky) patches to be already in
|
||||
your tree committed. It applies onto them.
|
||||
|
||||
@ -13,7 +13,7 @@ tempdir="/tmp/screenshots"
|
||||
mkdir -p "$tempdir"
|
||||
file="$(mktemp -p "$tempdir" "XXXXXX.png")"
|
||||
|
||||
# Grab the screenshot! Very conviniently, GEOMETRY format matches the one
|
||||
# Grab the screenshot! Very conveniently, GEOMETRY format matches the one
|
||||
# expected by grim
|
||||
grim -g "$GEOMETRY" "$file" || exit
|
||||
|
||||
|
||||
@ -6,9 +6,11 @@ Swap the focused window with the window (no floating) to the left, right, above,
|
||||
**NOTE:** this patch uses the same algorithm that River uses to select the window in the given direction.
|
||||
|
||||
### Download
|
||||
- [v0.8](https://codeberg.org/dwl/dwl-patches/raw/commit/a5f66f3d9cdbfc1a3fd7ae9c0288c35c8ec19479/patches/swapandfocusdir/swapandfocusdir.patch)
|
||||
- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.5/swapandfocusdir)
|
||||
- [2024-07-09](https://codeberg.org/dwl/dwl-patches/raw/commit/13d96b51b54500dd24544cf3a73c61b7a1414bc6/patches/swapandfocusdir/swapandfocusdir.patch)
|
||||
- [v0.5](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/swapandfocusdir/swapandfocusdir.patch)
|
||||
|
||||
### Authors
|
||||
- [unixchad](https://codeberg.org/unixchad)
|
||||
- [wochap](https://codeberg.org/wochap)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
From 285470897406b653e77d732a77356aaf9a70b799 Mon Sep 17 00:00:00 2001
|
||||
From: wochap <gean.marroquin@gmail.com>
|
||||
Date: Fri, 5 Jul 2024 12:37:39 -0500
|
||||
Subject: [PATCH] implement swapandfocusdir
|
||||
From 6972f383921a892e30ac10b42a3d3ce47b2f93e5 Mon Sep 17 00:00:00 2001
|
||||
From: nate zhou <gnuunixchad@outlook.com>
|
||||
Date: Sat, 28 Feb 2026 20:48:27 +0800
|
||||
Subject: [PATCH] Patch: swapandfocusdir.patch
|
||||
|
||||
---
|
||||
config.def.h | 8 +++
|
||||
@ -9,29 +9,29 @@ Subject: [PATCH] implement swapandfocusdir
|
||||
2 files changed, 172 insertions(+)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index 22d2171..724e15e 100644
|
||||
index 8a6eda0..6e7fc39 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -129,6 +129,14 @@ static const Key keys[] = {
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} },
|
||||
{ MODKEY, XKB_KEY_j, focusstack, {.i = +1} },
|
||||
{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} },
|
||||
+ { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_Left, focusdir, {.ui = 0} },
|
||||
+ { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_Right, focusdir, {.ui = 1} },
|
||||
+ { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_Up, focusdir, {.ui = 2} },
|
||||
+ { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_Down, focusdir, {.ui = 3} },
|
||||
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Left, swapdir, {.ui = 0} },
|
||||
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Right, swapdir, {.ui = 1} },
|
||||
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Up, swapdir, {.ui = 2} },
|
||||
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Down, swapdir, {.ui = 3} },
|
||||
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
|
||||
{ MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
|
||||
{ MODKEY, XKB_KEY_h, setmfact, {.f = -0.05f} },
|
||||
@@ -125,6 +125,14 @@ static const Key keys[] = {
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} },
|
||||
{ MODKEY, XKB_KEY_j, focusstack, {.i = +1} },
|
||||
{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} },
|
||||
+ { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_Left, focusdir, {.ui = 0} },
|
||||
+ { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_Right, focusdir, {.ui = 1} },
|
||||
+ { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_Up, focusdir, {.ui = 2} },
|
||||
+ { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_Down, focusdir, {.ui = 3} },
|
||||
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Left, swapdir, {.ui = 0} },
|
||||
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Right, swapdir, {.ui = 1} },
|
||||
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Up, swapdir, {.ui = 2} },
|
||||
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Down, swapdir, {.ui = 3} },
|
||||
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
|
||||
{ MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
|
||||
{ MODKEY, XKB_KEY_h, setmfact, {.f = -0.05f} },
|
||||
diff --git a/dwl.c b/dwl.c
|
||||
index dc0437e..844c1f5 100644
|
||||
index 44f3ad9..1893fbd 100644
|
||||
--- a/dwl.c
|
||||
+++ b/dwl.c
|
||||
@@ -241,6 +241,11 @@ typedef struct {
|
||||
@@ -239,6 +239,11 @@ typedef struct {
|
||||
struct wl_listener destroy;
|
||||
} SessionLock;
|
||||
|
||||
@ -51,8 +51,8 @@ index dc0437e..844c1f5 100644
|
||||
+static void swapdir(const Arg *arg);
|
||||
static Client *focustop(Monitor *m);
|
||||
static void fullscreennotify(struct wl_listener *listener, void *data);
|
||||
static void handlesig(int signo);
|
||||
@@ -1425,6 +1432,163 @@ focusstack(const Arg *arg)
|
||||
static void gpureset(struct wl_listener *listener, void *data);
|
||||
@@ -1511,6 +1518,163 @@ focusstack(const Arg *arg)
|
||||
focusclient(c, 1);
|
||||
}
|
||||
|
||||
@ -213,9 +213,9 @@ index dc0437e..844c1f5 100644
|
||||
+ arrange(selmon);
|
||||
+}
|
||||
+
|
||||
/* We probably should change the name of this, it sounds like
|
||||
/* We probably should change the name of this: it sounds like it
|
||||
* will focus the topmost client of this mon, when actually will
|
||||
* only return that client */
|
||||
--
|
||||
2.45.1
|
||||
2.53.0
|
||||
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
### Description
|
||||
This combines
|
||||
[tablet-input](../tablet-input) and
|
||||
[touch-input](../touch-input)
|
||||
into a single appliable patch.
|
||||
The two patches modify similar code areas in `dwl.c` and will conflict if one attempts to direcly apply both.
|
||||
|
||||
|
||||
### Download
|
||||
- [tablet-and-touch-wlroots-next-f4249db.patch](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/tablet-and-touch/tablet-and-touch-wlroots-next-f4249db.patch)
|
||||
- [tablet-and-touch-0.8.patch](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/tablet-and-touch/tablet-and-touch-0.8.patch)
|
||||
### Authors
|
||||
- [fauxmight](https://codeberg.org/fauxmight)
|
||||
@ -1,584 +0,0 @@
|
||||
From f0f797f8abebc4624c7e6bdfbb1ec2a3122f3914 Mon Sep 17 00:00:00 2001
|
||||
From: A Frederick Christensen <dwl@ivories.org>
|
||||
Date: Thu, 26 Feb 2026 23:20:03 -0600
|
||||
Subject: [PATCH] Apply tablet-and-touch patch
|
||||
|
||||
---
|
||||
Makefile | 6 +-
|
||||
config.def.h | 1 +
|
||||
dwl.c | 398 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 404 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 578194f..e0d1835 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 8a6eda0..1f20dfd 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 44f3ad9..5ed467d 100644
|
||||
--- a/dwl.c
|
||||
+++ b/dwl.c
|
||||
@@ -51,6 +51,10 @@
|
||||
#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_pad.h>
|
||||
+#include <wlr/types/wlr_tablet_tool.h>
|
||||
+#include <wlr/types/wlr_tablet_v2.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 +165,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 */
|
||||
@@ -268,7 +278,10 @@ 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 createtouch(struct wlr_touch *touch);
|
||||
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);
|
||||
@@ -281,6 +294,9 @@ static void destroynotify(struct wl_listener *listener, void *data);
|
||||
static void destroypointerconstraint(struct wl_listener *listener, void *data);
|
||||
static void destroysessionlock(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);
|
||||
@@ -333,11 +349,20 @@ 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);
|
||||
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);
|
||||
@@ -390,6 +415,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;
|
||||
@@ -405,6 +437,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};
|
||||
@@ -412,6 +445,12 @@ static struct wl_listener cursor_button = {.notify = buttonpress};
|
||||
static struct wl_listener cursor_frame = {.notify = cursorframe};
|
||||
static struct wl_listener cursor_motion = {.notify = motionrelative};
|
||||
static struct wl_listener cursor_motion_absolute = {.notify = motionabsolute};
|
||||
+static struct wl_listener tablet_device_destroy = {.notify = destroytablet};
|
||||
+static struct wl_listener tablet_tool_axis = {.notify = tablettoolaxis};
|
||||
+static struct wl_listener tablet_tool_button = {.notify = tablettoolbutton};
|
||||
+static struct wl_listener tablet_tool_destroy = {.notify = destroytablettool};
|
||||
+static struct wl_listener tablet_tool_proximity = {.notify = tablettoolproximity};
|
||||
+static struct wl_listener tablet_tool_tip = {.notify = tablettooltip};
|
||||
static struct wl_listener gpu_reset = {.notify = gpureset};
|
||||
static struct wl_listener layout_change = {.notify = updatemons};
|
||||
static struct wl_listener new_idle_inhibitor = {.notify = createidleinhibitor};
|
||||
@@ -434,6 +473,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
|
||||
@@ -781,6 +824,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 +1246,38 @@ 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);
|
||||
+ wl_signal_add(&tablet->wlr_device->events.destroy, &tablet_device_destroy);
|
||||
+ 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
|
||||
+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)
|
||||
{
|
||||
@@ -1383,6 +1462,29 @@ destroykeyboardgroup(struct wl_listener *listener, void *data)
|
||||
free(group);
|
||||
}
|
||||
|
||||
+void
|
||||
+destroytablet(struct wl_listener *listener, void *data)
|
||||
+{
|
||||
+ wl_list_remove(&tablet_device_destroy.link);
|
||||
+ 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)
|
||||
{
|
||||
@@ -1590,6 +1692,15 @@ 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;
|
||||
+ case WLR_INPUT_DEVICE_TOUCH:
|
||||
+ createtouch(wlr_touch_from_input_device(device));
|
||||
+ break;
|
||||
default:
|
||||
/* TODO handle other input device types */
|
||||
break;
|
||||
@@ -1602,6 +1713,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);
|
||||
}
|
||||
|
||||
@@ -2585,6 +2698,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.
|
||||
@@ -2614,6 +2729,18 @@ setup(void)
|
||||
wl_signal_add(&cursor->events.button, &cursor_button);
|
||||
wl_signal_add(&cursor->events.axis, &cursor_axis);
|
||||
wl_signal_add(&cursor->events.frame, &cursor_frame);
|
||||
+ wl_signal_add(&cursor->events.tablet_tool_proximity, &tablet_tool_proximity);
|
||||
+ wl_signal_add(&cursor->events.tablet_tool_axis, &tablet_tool_axis);
|
||||
+ wl_signal_add(&cursor->events.tablet_tool_button, &tablet_tool_button);
|
||||
+ wl_signal_add(&cursor->events.tablet_tool_tip, &tablet_tool_tip);
|
||||
+
|
||||
+
|
||||
+ 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);
|
||||
@@ -2709,6 +2836,163 @@ 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(surface, tablet))
|
||||
+ 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);
|
||||
+ wl_signal_add(&tablet_tool->wlr_tool->events.destroy, &tablet_tool_destroy);
|
||||
+ wl_signal_add(&tablet_tool->events.set_cursor, &request_cursor);
|
||||
+ }
|
||||
+
|
||||
+ 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;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+double tilt_x = 0;
|
||||
+double tilt_y = 0;
|
||||
+
|
||||
+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)
|
||||
+ tilt_x = event->tilt_x;
|
||||
+ if (event->updated_axes & WLR_TABLET_TOOL_AXIS_TILT_Y)
|
||||
+ tilt_y = event->tilt_y;
|
||||
+ 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, tilt_x, 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)
|
||||
{
|
||||
@@ -2787,6 +3071,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);
|
||||
+ if (sloppyfocus)
|
||||
+ focusclient(c, 0);
|
||||
+
|
||||
+ 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;
|
||||
+ struct wlr_pointer_motion_absolute_event *motion_event = data;
|
||||
+ double dx, dy;
|
||||
+
|
||||
+ wlr_cursor_absolute_to_layout_coords(cursor, &motion_event->pointer->base, motion_event->x, motion_event->y, &lx, &ly);
|
||||
+ wlr_cursor_warp_closest(cursor, &motion_event->pointer->base, lx, ly);
|
||||
+ dx = lx - cursor->x;
|
||||
+ dy = ly - cursor->y;
|
||||
+ motionnotify(motion_event->time_msec, &motion_event->pointer->base, dx, dy, dx, dy);
|
||||
+
|
||||
+ button_event->button = BTN_LEFT;
|
||||
+ button_event->state = WL_POINTER_BUTTON_STATE_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 = WL_POINTER_BUTTON_STATE_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 && 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.52.0
|
||||
|
||||
@ -1,584 +0,0 @@
|
||||
From 78eda59b86ca01188fd645fe4062dda75d60acb1 Mon Sep 17 00:00:00 2001
|
||||
From: A Frederick Christensen <dwl@ivories.org>
|
||||
Date: Thu, 26 Feb 2026 23:23:49 -0600
|
||||
Subject: [PATCH] Apply tablet-and-touch patch
|
||||
|
||||
---
|
||||
Makefile | 6 +-
|
||||
config.def.h | 1 +
|
||||
dwl.c | 398 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 404 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 578194f..e0d1835 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 8a6eda0..1f20dfd 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 8a9715d..6dc462a 100644
|
||||
--- a/dwl.c
|
||||
+++ b/dwl.c
|
||||
@@ -52,6 +52,10 @@
|
||||
#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_pad.h>
|
||||
+#include <wlr/types/wlr_tablet_tool.h>
|
||||
+#include <wlr/types/wlr_tablet_v2.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>
|
||||
@@ -163,6 +167,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 */
|
||||
@@ -270,7 +280,10 @@ 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 createtouch(struct wlr_touch *touch);
|
||||
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);
|
||||
@@ -283,6 +296,9 @@ static void destroynotify(struct wl_listener *listener, void *data);
|
||||
static void destroypointerconstraint(struct wl_listener *listener, void *data);
|
||||
static void destroysessionlock(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);
|
||||
@@ -335,11 +351,20 @@ 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);
|
||||
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);
|
||||
@@ -392,6 +417,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;
|
||||
@@ -407,6 +439,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};
|
||||
@@ -414,6 +447,12 @@ static struct wl_listener cursor_button = {.notify = buttonpress};
|
||||
static struct wl_listener cursor_frame = {.notify = cursorframe};
|
||||
static struct wl_listener cursor_motion = {.notify = motionrelative};
|
||||
static struct wl_listener cursor_motion_absolute = {.notify = motionabsolute};
|
||||
+static struct wl_listener tablet_device_destroy = {.notify = destroytablet};
|
||||
+static struct wl_listener tablet_tool_axis = {.notify = tablettoolaxis};
|
||||
+static struct wl_listener tablet_tool_button = {.notify = tablettoolbutton};
|
||||
+static struct wl_listener tablet_tool_destroy = {.notify = destroytablettool};
|
||||
+static struct wl_listener tablet_tool_proximity = {.notify = tablettoolproximity};
|
||||
+static struct wl_listener tablet_tool_tip = {.notify = tablettooltip};
|
||||
static struct wl_listener gpu_reset = {.notify = gpureset};
|
||||
static struct wl_listener layout_change = {.notify = updatemons};
|
||||
static struct wl_listener new_idle_inhibitor = {.notify = createidleinhibitor};
|
||||
@@ -436,6 +475,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
|
||||
@@ -783,6 +826,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);
|
||||
@@ -1201,6 +1248,38 @@ 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);
|
||||
+ wl_signal_add(&tablet->wlr_device->events.destroy, &tablet_device_destroy);
|
||||
+ 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
|
||||
+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)
|
||||
{
|
||||
@@ -1385,6 +1464,29 @@ destroykeyboardgroup(struct wl_listener *listener, void *data)
|
||||
free(group);
|
||||
}
|
||||
|
||||
+void
|
||||
+destroytablet(struct wl_listener *listener, void *data)
|
||||
+{
|
||||
+ wl_list_remove(&tablet_device_destroy.link);
|
||||
+ 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)
|
||||
{
|
||||
@@ -1592,6 +1694,15 @@ 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;
|
||||
+ case WLR_INPUT_DEVICE_TOUCH:
|
||||
+ createtouch(wlr_touch_from_input_device(device));
|
||||
+ break;
|
||||
default:
|
||||
/* TODO handle other input device types */
|
||||
break;
|
||||
@@ -1604,6 +1715,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);
|
||||
}
|
||||
|
||||
@@ -2588,6 +2701,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.
|
||||
@@ -2617,6 +2732,18 @@ setup(void)
|
||||
wl_signal_add(&cursor->events.button, &cursor_button);
|
||||
wl_signal_add(&cursor->events.axis, &cursor_axis);
|
||||
wl_signal_add(&cursor->events.frame, &cursor_frame);
|
||||
+ wl_signal_add(&cursor->events.tablet_tool_proximity, &tablet_tool_proximity);
|
||||
+ wl_signal_add(&cursor->events.tablet_tool_axis, &tablet_tool_axis);
|
||||
+ wl_signal_add(&cursor->events.tablet_tool_button, &tablet_tool_button);
|
||||
+ wl_signal_add(&cursor->events.tablet_tool_tip, &tablet_tool_tip);
|
||||
+
|
||||
+
|
||||
+ 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);
|
||||
@@ -2712,6 +2839,163 @@ 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(surface, tablet))
|
||||
+ 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);
|
||||
+ wl_signal_add(&tablet_tool->wlr_tool->events.destroy, &tablet_tool_destroy);
|
||||
+ wl_signal_add(&tablet_tool->events.set_cursor, &request_cursor);
|
||||
+ }
|
||||
+
|
||||
+ 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;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+double tilt_x = 0;
|
||||
+double tilt_y = 0;
|
||||
+
|
||||
+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)
|
||||
+ tilt_x = event->tilt_x;
|
||||
+ if (event->updated_axes & WLR_TABLET_TOOL_AXIS_TILT_Y)
|
||||
+ tilt_y = event->tilt_y;
|
||||
+ 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, tilt_x, 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)
|
||||
{
|
||||
@@ -2790,6 +3074,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);
|
||||
+ if (sloppyfocus)
|
||||
+ focusclient(c, 0);
|
||||
+
|
||||
+ 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;
|
||||
+ struct wlr_pointer_motion_absolute_event *motion_event = data;
|
||||
+ double dx, dy;
|
||||
+
|
||||
+ wlr_cursor_absolute_to_layout_coords(cursor, &motion_event->pointer->base, motion_event->x, motion_event->y, &lx, &ly);
|
||||
+ wlr_cursor_warp_closest(cursor, &motion_event->pointer->base, lx, ly);
|
||||
+ dx = lx - cursor->x;
|
||||
+ dy = ly - cursor->y;
|
||||
+ motionnotify(motion_event->time_msec, &motion_event->pointer->base, dx, dy, dx, dy);
|
||||
+
|
||||
+ button_event->button = BTN_LEFT;
|
||||
+ button_event->state = WL_POINTER_BUTTON_STATE_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 = WL_POINTER_BUTTON_STATE_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 && 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.52.0
|
||||
|
||||
@ -60,7 +60,7 @@ index 775dadf..621779e 100644
|
||||
- /* TODO: allow usage of scroll wheel for mousebindings, it can be implemented
|
||||
- * by checking the event's orientation and the delta of the event */
|
||||
+ handlecursoractivity();
|
||||
+ /* TODO: allow usage of scroll whell for mousebindings, it can be implemented
|
||||
+ /* TODO: allow usage of scroll wheel for mousebindings, it can be implemented
|
||||
+ * checking the event's orientation and the delta of the event */
|
||||
/* Notify the client with pointer focus of the axis event. */
|
||||
wlr_seat_pointer_notify_axis(seat,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
### Description
|
||||
implement wlr_virtual_pointer_v1 for things like wayvnc server to work
|
||||
|
||||
**NOTE:** no longer neccessary if you are using a DWL version after https://codeberg.org/dwl/dwl/commit/ac6074f4fdb8cc263c877f08e16a5805d3bb22d2
|
||||
**NOTE:** no longer necessary if you are using a DWL version after https://codeberg.org/dwl/dwl/commit/ac6074f4fdb8cc263c877f08e16a5805d3bb22d2
|
||||
|
||||
### Download
|
||||
- [git branch](https://codeberg.org/wochap/dwl/src/v0.5/virtual-pointer)
|
||||
@ -9,4 +9,4 @@ implement wlr_virtual_pointer_v1 for things like wayvnc server to work
|
||||
|
||||
### Authors
|
||||
- [wochap](https://codeberg.org/wochap)
|
||||
- [youbitchoc](https://github.com/youbitchoc)
|
||||
- [youbitchoc](https://github.com/youbitchoc)
|
||||
|
||||
@ -3,7 +3,7 @@ Implements the function `winview` which switches the visible tags to the tags on
|
||||
|
||||
This patch is inspired from <https://dwm.suckless.org/patches/winview/>. Citing the description of the dwm patch:
|
||||
|
||||
> Dwm tags are a powerfull feature that allows organizing windows in workspaces. Sometime it can be difficult to remember the tag to activate to unhide a window. With the winview patch the window to unhide can be selected from the all-window view. The user switches to the all-window view (Mod1-0), selects the window (Mod1-j/k or using the mouse) and press Mod1-o. The key Mod1-o switches the view to the selected window tag.
|
||||
> Dwm tags are a powerful feature that allows organizing windows in workspaces. Sometime it can be difficult to remember the tag to activate to unhide a window. With the winview patch the window to unhide can be selected from the all-window view. The user switches to the all-window view (Mod1-0), selects the window (Mod1-j/k or using the mouse) and press Mod1-o. The key Mod1-o switches the view to the selected window tag.
|
||||
>
|
||||
> #### Recommend patches
|
||||
>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
### Description
|
||||
Implements `swaymsg create_output` command, it allows you to create virtual/headless outputs. But in combination with a VNC server (for example wayvnc), this allows you to essentially have additional monitors, by connecting to the VNC server with an appropiate client (for example on an tablet or laptop).
|
||||
Implements `swaymsg create_output` command, it allows you to create virtual/headless outputs. But in combination with a VNC server (for example wayvnc), this allows you to essentially have additional monitors, by connecting to the VNC server with an appropriate client (for example on an tablet or laptop).
|
||||
|
||||
If you plan to use wayvnc, you'll need [virtual-pointer](https://codeberg.org/dwl/dwl-patches/wiki/virtual-pointer.-) patch as well
|
||||
|
||||
@ -8,4 +8,4 @@ If you plan to use wayvnc, you'll need [virtual-pointer](https://codeberg.org/dw
|
||||
- [v0.5](https://codeberg.org/dwl/dwl-patches/raw/commit/0096e49402bc59b4050e12cdb9befb79d0011006/headless/headless.patch)
|
||||
|
||||
### Authors
|
||||
- [wochap](https://codeberg.org/wochap)
|
||||
- [wochap](https://codeberg.org/wochap)
|
||||
|
||||
@ -417,7 +417,7 @@ index 0000000..0a6e7e5
|
||||
+I would probably just submit raphi's patchset but I don't think that would be polite.
|
||||
+-->
|
||||
+<protocol name="dwl_ipc_unstable_v2">
|
||||
+ <description summary="inter-proccess-communication about dwl's state">
|
||||
+ <description summary="inter-process-communication about dwl's state">
|
||||
+ This protocol allows clients to update and get updates from dwl.
|
||||
+
|
||||
+ Warning! The protocol described in this file is experimental and
|
||||
@ -437,7 +437,7 @@ index 0000000..0a6e7e5
|
||||
+ This interface is exposed as a global in wl_registry.
|
||||
+
|
||||
+ Clients can use this interface to get a dwl_ipc_output.
|
||||
+ After binding the client will recieve the dwl_ipc_manager.tags and dwl_ipc_manager.layout events.
|
||||
+ After binding the client will receive the dwl_ipc_manager.tags and dwl_ipc_manager.layout events.
|
||||
+ The dwl_ipc_manager.tags and dwl_ipc_manager.layout events expose tags and layouts to the client.
|
||||
+ </description>
|
||||
+
|
||||
@ -449,8 +449,8 @@ index 0000000..0a6e7e5
|
||||
+ </request>
|
||||
+
|
||||
+ <request name="get_output">
|
||||
+ <description summary="get a dwl_ipc_outout for a wl_output">
|
||||
+ Get a dwl_ipc_outout for the specified wl_output.
|
||||
+ <description summary="get a dwl_ipc_output for a wl_output">
|
||||
+ Get a dwl_ipc_output for the specified wl_output.
|
||||
+ </description>
|
||||
+ <arg name="id" type="new_id" interface="zdwl_ipc_output_v2"/>
|
||||
+ <arg name="output" type="object" interface="wl_output"/>
|
||||
@ -459,7 +459,7 @@ index 0000000..0a6e7e5
|
||||
+ <event name="tags">
|
||||
+ <description summary="Announces tag amount">
|
||||
+ This event is sent after binding.
|
||||
+ A roundtrip after binding guarantees the client recieved all tags.
|
||||
+ A roundtrip after binding guarantees the client received all tags.
|
||||
+ </description>
|
||||
+ <arg name="amount" type="uint"/>
|
||||
+ </event>
|
||||
@ -467,7 +467,7 @@ index 0000000..0a6e7e5
|
||||
+ <event name="layout">
|
||||
+ <description summary="Announces a layout">
|
||||
+ This event is sent after binding.
|
||||
+ A roundtrip after binding guarantees the client recieved all layouts.
|
||||
+ A roundtrip after binding guarantees the client received all layouts.
|
||||
+ </description>
|
||||
+ <arg name="name" type="string"/>
|
||||
+ </event>
|
||||
@ -491,13 +491,13 @@ index 0000000..0a6e7e5
|
||||
+ </enum>
|
||||
+
|
||||
+ <request name="release" type="destructor">
|
||||
+ <description summary="release dwl_ipc_outout">
|
||||
+ <description summary="release dwl_ipc_output">
|
||||
+ Indicates to that the client no longer needs this dwl_ipc_output.
|
||||
+ </description>
|
||||
+ </request>
|
||||
+
|
||||
+ <event name="toggle_visibility">
|
||||
+ <description summary="Toggle client visibilty">
|
||||
+ <description summary="Toggle client visibility">
|
||||
+ Indicates the client should hide or show themselves.
|
||||
+ If the client is visible then hide, if hidden then show.
|
||||
+ </description>
|
||||
@ -544,7 +544,7 @@ index 0000000..0a6e7e5
|
||||
+ <event name="layout_symbol" since="1">
|
||||
+ <description summary="Update the current layout symbol">
|
||||
+ Indicates the layout has changed. Since layout symbols are dynamic.
|
||||
+ As opposed to the zdwl_ipc_manager.layout event, this should take precendence when displaying.
|
||||
+ As opposed to the zdwl_ipc_manager.layout event, this should take precedence when displaying.
|
||||
+ You can ignore the zdwl_ipc_output.layout event.
|
||||
+ </description>
|
||||
+ <arg name="layout" type="string" summary="The new layout"/>
|
||||
@ -573,7 +573,7 @@ index 0000000..0a6e7e5
|
||||
+
|
||||
+ <request name="set_layout">
|
||||
+ <description summary="Set the layout of this output"/>
|
||||
+ <arg name="index" type="uint" summary="index of a layout recieved by dwl_ipc_manager.layout"/>
|
||||
+ <arg name="index" type="uint" summary="index of a layout received by dwl_ipc_manager.layout"/>
|
||||
+ </request>
|
||||
+
|
||||
+ <!-- Version 2 -->
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user