dwl-patches overhaul

Eliminated wiki.
Individual patches have a README.md explanation in their own subdirectory.
Simplified submission of new patches and maintenance of existing patches.
Instructions page (README.md autodisplayed) is now at https://codeberg.org/dwl/dwl-patches/
This commit is contained in:
A Frederick Christensen
2024-04-24 20:20:07 -05:00
parent d6b051f5b8
commit 9c5d5d85f3
183 changed files with 1434 additions and 4 deletions
+9
View File
@@ -0,0 +1,9 @@
### Description
Automatically center floating windows.
### Download
- [git branch](https://codeberg.org/guidocella/dwl/src/branch/alwayscenter)
- [2024-02-06](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/alwayscenter/alwayscenter.patch)
### Authors
- [Guido Cella](https://codeberg.org/guidocella)
+25
View File
@@ -0,0 +1,25 @@
From 95ac2fd73af8cee3ce3e556c254e60a2ca985515 Mon Sep 17 00:00:00 2001
From: Guido Cella <guido@guidocella.xyz>
Date: Tue, 16 Jan 2024 18:14:50 +0100
Subject: [PATCH] center floating windows
---
dwl.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dwl.c b/dwl.c
index 95ebee8..ac077e3 100644
--- a/dwl.c
+++ b/dwl.c
@@ -453,6 +453,8 @@ applyrules(Client *c)
}
}
}
+ c->geom.x = (mon->w.width - c->geom.width) / 2 + mon->m.x;
+ c->geom.y = (mon->w.height - c->geom.height) / 2 + mon->m.y;
setmon(c, mon, newtags);
}
--
2.43.0
+13
View File
@@ -0,0 +1,13 @@
### Description
This is a port of attachtop patch for dwm: https://dwm.suckless.org/patches/attachtop
New client attaches below the last master/on top of the stack.
Behavior feels very intuitive as it doesn't disrupt existing masters no matter the amount of them, it only pushes the clients in stack down.
### Download
- [git branch](https://codeberg.org/nikitaivanov/dwl/src/branch/attachtop)
- [2024-04-23](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/attachtop/attachtop.patch)
### Authors
- [Nikita Ivanov](https://codeberg.org/nikitaivanov)
+36
View File
@@ -0,0 +1,36 @@
From 42a66d6e06c38e913766ce625f049fdbc3dd0d12 Mon Sep 17 00:00:00 2001
From: Nikita Ivanov <nikita.vyach.ivanov@gmail.com>
Date: Sun, 7 Apr 2024 21:10:17 +0200
Subject: [PATCH] New client are attached on top of the stack
---
dwl.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/dwl.c b/dwl.c
index bf763df..c0a3d74 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1605,7 +1605,18 @@ mapnotify(struct wl_listener *listener, void *data)
c->geom.height += 2 * c->bw;
/* Insert this client into client lists. */
- wl_list_insert(&clients, &c->link);
+ i = 0;
+ wl_list_for_each(w, &clients, link) {
+ if (!VISIBLEON(w, selmon) || c->isfloating)
+ continue;
+ p = w;
+ if (++i >= selmon->nmaster)
+ break;
+ }
+ if (i > 0)
+ wl_list_insert(&p->link, &c->link);
+ else
+ wl_list_insert(&clients, &c->link);
wl_list_insert(&fstack, &c->flink);
/* Set initial monitor, tags, floating status, and focus:
--
2.44.0
+13
View File
@@ -0,0 +1,13 @@
### Description
Allow dwl to execute commands from autostart array in your config.h file. And when you exit dwl all processes from autostart array will be killed.
Note: Commands from array are executed using execvp(). So if you need to execute shell command you need to prefix it with "sh", "-c" (change sh to any shell you like).
### Download
- [git branch](https://codeberg.org/sevz/dwl/src/branch/autostart)
- [2024-03-31](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/autostart/autostart.patch)
### Authors
- [sevz](https://codeberg.org/sevz)
- [Rayan Nakib](https://nakibrayan2.pages.dev/)
- [NFVblog](https://github.com/nf02)
+154
View File
@@ -0,0 +1,154 @@
From 51d56a433f23e13ac711b283a03c7903068febf6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
<leohdz172@proton.me>
Date: Sat, 8 Jul 2023 17:11:36 -0600
Subject: [PATCH] port autostart patch from dwm
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
https://dwm.suckless.org/patches/cool_autostart/
Signed-off-by: Leonardo Hernández Hernández <leohdz172@proton.me>
---
config.def.h | 7 +++++++
dwl.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 61 insertions(+), 5 deletions(-)
diff --git a/config.def.h b/config.def.h
index a8ed61d..3585711 100644
--- a/config.def.h
+++ b/config.def.h
@@ -20,6 +20,13 @@ static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0}; /* You can al
/* logging */
static int log_level = WLR_ERROR;
+/* Autostart */
+static const char *const autostart[] = {
+ "wbg", "/path/to/your/image", NULL,
+ NULL /* terminate */
+};
+
+
static const Rule rules[] = {
/* app_id title tags mask isfloating monitor */
/* examples:
diff --git a/dwl.c b/dwl.c
index 10d5a5b..bbbef2b 100644
--- a/dwl.c
+++ b/dwl.c
@@ -236,6 +236,7 @@ static void arrange(Monitor *m);
static void arrangelayer(Monitor *m, struct wl_list *list,
struct wlr_box *usable_area, int exclusive);
static void arrangelayers(Monitor *m);
+static void autostartexec(void);
static void axisnotify(struct wl_listener *listener, void *data);
static void buttonpress(struct wl_listener *listener, void *data);
static void chvt(const Arg *arg);
@@ -403,6 +404,9 @@ static xcb_atom_t netatom[NetLast];
/* attempt to encapsulate suck into one file */
#include "client.h"
+static pid_t *autostart_pids;
+static size_t autostart_len;
+
/* function implementations */
void
applybounds(Client *c, struct wlr_box *bbox)
@@ -533,6 +537,27 @@ arrangelayers(Monitor *m)
}
}
+void
+autostartexec(void) {
+ const char *const *p;
+ size_t i = 0;
+
+ /* count entries */
+ for (p = autostart; *p; autostart_len++, p++)
+ while (*++p);
+
+ autostart_pids = calloc(autostart_len, sizeof(pid_t));
+ for (p = autostart; *p; i++, p++) {
+ if ((autostart_pids[i] = fork()) == 0) {
+ setsid();
+ execvp(*p, (char *const *)p);
+ die("dwl: execvp %s:", *p);
+ }
+ /* skip arguments */
+ while (*++p);
+ }
+}
+
void
axisnotify(struct wl_listener *listener, void *data)
{
@@ -630,11 +655,21 @@ checkidleinhibitor(struct wlr_surface *exclude)
void
cleanup(void)
{
+ size_t i;
#ifdef XWAYLAND
wlr_xwayland_destroy(xwayland);
xwayland = NULL;
#endif
wl_display_destroy_clients(dpy);
+
+ /* kill child processes */
+ for (i = 0; i < autostart_len; i++) {
+ if (0 < autostart_pids[i]) {
+ kill(autostart_pids[i], SIGTERM);
+ waitpid(autostart_pids[i], NULL, 0);
+ }
+ }
+
if (child_pid > 0) {
kill(child_pid, SIGTERM);
waitpid(child_pid, NULL, 0);
@@ -1294,18 +1329,31 @@ void
handlesig(int signo)
{
if (signo == SIGCHLD) {
-#ifdef XWAYLAND
siginfo_t in;
/* wlroots expects to reap the XWayland process itself, so we
* use WNOWAIT to keep the child waitable until we know it's not
* XWayland.
*/
while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid
- && (!xwayland || in.si_pid != xwayland->server->pid))
- waitpid(in.si_pid, NULL, 0);
-#else
- while (waitpid(-1, NULL, WNOHANG) > 0);
+#ifdef XWAYLAND
+ && (!xwayland || in.si_pid != xwayland->server->pid)
#endif
+ ) {
+ pid_t *p, *lim;
+ waitpid(in.si_pid, NULL, 0);
+ if (in.si_pid == child_pid)
+ child_pid = -1;
+ if (!(p = autostart_pids))
+ continue;
+ lim = &p[autostart_len];
+
+ for (; p < lim; p++) {
+ if (*p == in.si_pid) {
+ *p = -1;
+ break;
+ }
+ }
+ }
} else if (signo == SIGINT || signo == SIGTERM) {
quit(NULL);
}
@@ -1965,6 +2013,7 @@ run(char *startup_cmd)
die("startup: backend_start");
/* Now that the socket exists and the backend is started, run the startup command */
+ autostartexec();
if (startup_cmd) {
int piperw[2];
if (pipe(piperw) < 0)
--
2.43.0
+31
View File
@@ -0,0 +1,31 @@
### Description
Add a bar identical to dwm's bar.
To use a status-bar, you can pass in status text via stdin:
```
slstatus -s | dwl
```
### Dependencies
* tllist (build dependency, required & pulled automatically by fcft)
* fcft
* pixman
### Download
- [git branch](https://codeberg.org/sewn/dwl/src/branch/bar)
- [2024-04-25](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/bar/bar.patch)
Below is a preview of the barpadding and barborder patches applied.
![bar, barpadding and border patch preview](bar-with-barpadding-and-border.png)
For colors, they are in `RRRR, GGGG, BBBB, AAAA` format due to inheriting the `pixman_color_t` type, an example for the color `0x282a36` would be `0x2828, 0x2a2a, 0x3636, 0xffff`
### Authors
- [sewn](https://codeberg.org/sewn)
### Credits
- [MadcowOG](https://github.com/MadcowOG)
- [kolumni](https://github.com/kolunmi/dwlb)
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

File diff suppressed because it is too large Load Diff
+10
View File
@@ -0,0 +1,10 @@
### Description
Add a border around the [bar](https://codeberg.org/dwl/dwl-patches/wiki/bar) similar to how a client is given a border.
### Download
- [2024-04-14](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/barborder/barborder.patch) (bar 2024-04-14)
### Authors
- [sewn](https://codeberg.org/sewn)
+128
View File
@@ -0,0 +1,128 @@
From 38dd71e51784ab68261d9c0479a4579d419315f1 Mon Sep 17 00:00:00 2001
From: sewn <sewn@disroot.org>
Date: Sun, 14 Apr 2024 08:47:04 +0300
Subject: [PATCH] add border to bar
---
config.def.h | 3 ++-
dwl.c | 27 ++++++++++++++++-----------
2 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/config.def.h b/config.def.h
index 0be3ad0..e5e595a 100644
--- a/config.def.h
+++ b/config.def.h
@@ -6,7 +6,7 @@
/* appearance */
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 */
+static const unsigned int borderpx = 1; /* border pixel of windows & bar */
static const float rootcolor[] = COLOR(0x000000ff);
static const float bordercolor[] = COLOR(0x444444ff);
static const float focuscolor[] = COLOR(0x005577ff);
@@ -19,6 +19,7 @@ static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */
static const char *fonts[] = {"monospace:size=10"};
static const char *fontattrs = "dpi=96";
+static pixman_color_t borderbar = { 0x5555, 0x7777, 0x0000, 0xffff };
static pixman_color_t normbarfg = { 0xbbbb, 0xbbbb, 0xbbbb, 0xffff };
static pixman_color_t normbarbg = { 0x2222, 0x2222, 0x2222, 0xffff };
static pixman_color_t selbarfg = { 0xeeee, 0xeeee, 0xeeee, 0xffff };
diff --git a/dwl.c b/dwl.c
index 54273ae..3153bfd 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1344,7 +1344,8 @@ dirtomon(enum wlr_direction dir)
void
drawbar(Monitor *mon)
{
- int x, w, tw = 0;
+ int x, y = borderpx, w, tw = 0;
+ int mh, mw;
int sel;
int boxs = font->height / 9;
int boxw = font->height / 6 + 2;
@@ -1357,6 +1358,8 @@ drawbar(Monitor *mon)
if (!mon || !mon->showbar)
return;
+ mh = mon->b.height - borderpx * 2;
+ mw = mon->b.width - borderpx * 2;
stride = mon->b.width * 4;
size = stride * mon->b.height;
@@ -1367,12 +1370,14 @@ drawbar(Monitor *mon)
pix = pixman_image_create_bits(
PIXMAN_a8r8g8b8, mon->b.width, mon->b.height, buf->data, stride);
+ drwl_rect(pix, 0, 0, mon->b.width, mon->b.height, 1, &borderbar);
+
/* draw status first so it can be overdrawn by tags later */
if (mon == selmon) {
if (stext[0] == '\0')
strncpy(stext, "dwl-"VERSION, sizeof(stext));
tw = TEXTW(stext) - lrpad;
- drwl_text(pix, font, mon->b.width - tw, 0, tw, mon->b.height, 0,
+ drwl_text(pix, font, borderpx + mw - tw, y, tw, mh, 0,
stext, &normbarfg, &normbarbg);
}
@@ -1384,37 +1389,37 @@ drawbar(Monitor *mon)
urg |= c->tags;
}
c = focustop(mon);
- x = 0;
+ x = borderpx;
for (i = 0; i < LENGTH(tags); i++) {
w = TEXTW(tags[i]);
sel = mon->tagset[mon->seltags] & 1 << i;
- drwl_text(pix, font, x, 0, w, mon->b.height, lrpad / 2, tags[i],
+ drwl_text(pix, font, x, y, w, mh, lrpad / 2, tags[i],
urg & 1 << i ? &selbarbg : (sel ? &selbarfg : &normbarfg),
urg & 1 << i ? &selbarfg : (sel ? &selbarbg : &normbarbg));
if (occ & 1 << i)
- drwl_rect(pix, x + boxs, boxs, boxw, boxw, sel,
+ drwl_rect(pix, x + boxs, y + boxs, boxw, boxw, sel,
urg & 1 << i ? &selbarbg : (sel ? &selbarfg : &normbarfg));
x += w;
}
w = TEXTW(mon->ltsymbol);
- x = drwl_text(pix, font, x, 0, w, mon->b.height, lrpad / 2,
+ x = drwl_text(pix, font, x, y, w, mh, lrpad / 2,
mon->ltsymbol, &normbarfg, &normbarbg);
- if ((w = mon->b.width - tw - x) > mon->b.height) {
+ if ((w = mw - tw - x + borderpx) > mh) {
if (c != NULL) {
- drwl_text(pix, font, x, 0, w, mon->b.height, lrpad / 2,
+ drwl_text(pix, font, x, y, w, mh, lrpad / 2,
c ? client_get_title(c) : NULL,
mon == selmon ? &selbarfg : &normbarfg,
(mon == selmon && c) ? &selbarbg : &normbarbg);
if (c && c->isfloating)
- drwl_rect(pix, x + boxs, boxs, boxw, boxw, 0,
+ drwl_rect(pix, x + boxs, y + boxs, boxw, boxw, 0,
mon == selmon ? &selbarfg : &normbarfg);
} else {
- drwl_rect(pix, x, 0, w, mon->b.height, 1, &normbarbg);
+ drwl_rect(pix, x, y, w, mh, 1, &normbarbg);
}
}
@@ -2664,7 +2669,7 @@ setup(void)
die("Could not load font");
lrpad = font->height;
- bh = font->height + 2;
+ bh = font->height + 2 + borderpx * 2;
status_event_source = wl_event_loop_add_fd(wl_display_get_event_loop(dpy),
STDIN_FILENO, WL_EVENT_READABLE, status_in, NULL);
--
2.44.0
+10
View File
@@ -0,0 +1,10 @@
### Description
Adds the ability to change the [bar's](https://codeberg.org/dwl/dwl-patches/wiki/bar) height.
### Download
- [2024-04-5](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/barheight/barheight.patch)
- [git branch](https://codeberg.org/Oak/dwl/src/branch/barheight)
### Authors
- [Oak](https://codeberg.org/oak)
+35
View File
@@ -0,0 +1,35 @@
From 225ce9045d0d2f101a33a61d741b466a240f30b8 Mon Sep 17 00:00:00 2001
From: oak <oak@petrifiedoak.com>
Date: Fri, 5 Apr 2024 14:29:10 +0200
Subject: [PATCH] port barheight patch from dwm
---
config.def.h | 1 +
dwl.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/config.def.h b/config.def.h
index 8fb2d68..2a90092 100644
--- a/config.def.h
+++ b/config.def.h
@@ -17,6 +17,7 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
/* bar */
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */
+static const int user_bh = 0; /* 0 means that dwl will calculate bar height, >= 1 means dwl will use user_bh as bar height */
static const char *fonts[] = {"monospace:size=10"};
static const char *fontattrs = "dpi=96";
static pixman_color_t normbarfg = { 0xbbbb, 0xbbbb, 0xbbbb, 0xffff };
diff --git a/dwl.c b/dwl.c
index 056718d..4247f4c 100644
--- a/dwl.c
+++ b/dwl.c
@@ -2745,7 +2745,7 @@ setup(void)
die("Could not load font");
lrpad = font->height;
- bh = font->height + 2;
+ bh = user_bh ? user_bh : font->height + 2;
status_event_source = wl_event_loop_add_fd(wl_display_get_event_loop(dpy),
STDIN_FILENO, WL_EVENT_READABLE, status_in, NULL);
+10
View File
@@ -0,0 +1,10 @@
### Description
Add vertical and horizontal space between the [bar](https://codeberg.org/dwl/dwl-patches/wiki/bar) and the edge of the screen.
### Download
- [2024-04-14](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/barpadding/barpadding.patch) (bar 2024-04-14)
### Authors
- [sewn](https://codeberg.org/sewn)
+78
View File
@@ -0,0 +1,78 @@
From 7fe1a19287e1f40d90efd0c3b314c178cb27a571 Mon Sep 17 00:00:00 2001
From: sewn <sewn@disroot.org>
Date: Sun, 14 Apr 2024 08:02:56 +0300
Subject: [PATCH] port barpadding patch to bar for dwl
---
config.def.h | 2 ++
dwl.c | 13 ++++++++-----
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/config.def.h b/config.def.h
index 0be3ad0..423330b 100644
--- a/config.def.h
+++ b/config.def.h
@@ -17,6 +17,8 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
/* bar */
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */
+static const int vertpad = 10; /* vertical padding of bar */
+static const int sidepad = 10; /* horizontal padding of bar */
static const char *fonts[] = {"monospace:size=10"};
static const char *fontattrs = "dpi=96";
static pixman_color_t normbarfg = { 0xbbbb, 0xbbbb, 0xbbbb, 0xffff };
diff --git a/dwl.c b/dwl.c
index 54273ae..b19d1a3 100644
--- a/dwl.c
+++ b/dwl.c
@@ -431,6 +431,7 @@ static struct wl_list mons;
static Monitor *selmon;
static struct fcft_font *font;
+static int vp, sp;
static int bh;
static int lrpad;
static char stext[256];
@@ -569,8 +570,8 @@ arrangelayers(Monitor *m)
return;
if (m->showbar) {
- usable_area.height -= m->b.height;
- usable_area.y += topbar ? m->b.height : 0;
+ usable_area.height = usable_area.height - vertpad - m->b.height;
+ usable_area.y = topbar ? usable_area.y + m->b.height + vp : usable_area.y;
}
/* Arrange exclusive surfaces from top->bottom */
@@ -1419,8 +1420,8 @@ drawbar(Monitor *mon)
}
pixman_image_unref(pix);
- wlr_scene_node_set_position(&mon->scene_buffer->node, mon->m.x,
- mon->m.y + (topbar ? 0 : mon->m.height - mon->b.height));
+ wlr_scene_node_set_position(&mon->scene_buffer->node, mon->m.x + sp,
+ mon->m.y + vp + (topbar ? 0 : mon->m.height - mon->b.height));
wlr_scene_buffer_set_buffer(mon->scene_buffer, &buf->base);
wlr_buffer_drop(&buf->base);
}
@@ -2665,6 +2666,8 @@ setup(void)
lrpad = font->height;
bh = font->height + 2;
+ sp = sidepad;
+ vp = (topbar == 1) ? vertpad : - vertpad;
status_event_source = wl_event_loop_add_fd(wl_display_get_event_loop(dpy),
STDIN_FILENO, WL_EVENT_READABLE, status_in, NULL);
@@ -3004,7 +3007,7 @@ updatebardims(Monitor *m)
{
int rw, rh;
wlr_output_effective_resolution(m->wlr_output, &rw, &rh);
- m->b.width = rw;
+ m->b.width = rw - 2 * sp;
m->b.height = bh;
}
--
2.44.0
+36
View File
@@ -0,0 +1,36 @@
### Description
Adds 2 more borders to each side (top, bottom, left, right) of every window.
<details>
<summary>Preview</summary>
<pre>
With the following config:
```c
static const unsigned int borderpx = 9; /* border pixel of windows */
static const unsigned int borderspx = 3; /* width of the border that start from outside the windows */
static const unsigned int borderepx = 3; /* width of the border that start from inside the windows */
```
and `border_color_type` set to `BrdOriginal`:
<img src="https://i.imgur.com/msead2K.png"/>
and `border_color_type` set to `BrdStart`:
<img src="https://i.imgur.com/ssgPG36.png"/>
and `border_color_type` set to `BrdEnd`:
<img src="https://i.imgur.com/i2Xtjy6.png"/>
and `border_color_type` set to `BrdStartEnd`:
<img src="https://i.imgur.com/fnkitdR.png"/>
</pre>
</details>
### Download
- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.5/borders)
- [v0.5](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/borders/borders.patch)
### Authors
- [wochap](https://codeberg.org/wochap)
+184
View File
@@ -0,0 +1,184 @@
From 18abc170273690fd3fbbdcbe88b348a0b802ba91 Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Wed, 6 Mar 2024 11:45:30 -0500
Subject: [PATCH] add 2 more borders for each side
---
client.h | 16 +++++++++++++---
config.def.h | 7 +++++++
dwl.c | 41 +++++++++++++++++++++++++++++++++++++----
3 files changed, 57 insertions(+), 7 deletions(-)
diff --git a/client.h b/client.h
index 71c7d76..c65f3ec 100644
--- a/client.h
+++ b/client.h
@@ -309,11 +309,21 @@ client_send_close(Client *c)
}
static inline void
-client_set_border_color(Client *c, const float color[static 4])
+client_set_border_color(Client *c, const float color[static 4], const float colors[static 4], const float colore[static 4])
{
int i;
- for (i = 0; i < 4; i++)
- wlr_scene_rect_set_color(c->border[i], color);
+ for (i = 0; i < 4; i++) {
+ if (border_color_type == BrdOriginal) {
+ wlr_scene_rect_set_color(c->border[i], color);
+ } else if (border_color_type == BrdStart) {
+ wlr_scene_rect_set_color(c->borders[i], colors);
+ } else if (border_color_type == BrdEnd) {
+ wlr_scene_rect_set_color(c->bordere[i], colore);
+ } else if (border_color_type == BrdStartEnd) {
+ wlr_scene_rect_set_color(c->borders[i], colors);
+ wlr_scene_rect_set_color(c->bordere[i], colore);
+ }
+ }
}
static inline void
diff --git a/config.def.h b/config.def.h
index db0babc..bc03d24 100644
--- a/config.def.h
+++ b/config.def.h
@@ -7,7 +7,14 @@
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 */
+static const unsigned int borderspx = 0; /* width of the border that start from outside the windows */
+static const unsigned int borderepx = 0; /* width of the border that start from inside the windows */
+static const unsigned int borderspx_offset = 0; /* offset of the border that start from outside the windows */
+static const unsigned int borderepx_negative_offset = 0; /* offset of the border that start from inside the windows */
static const float bordercolor[] = COLOR(0x444444ff);
+static const float borderscolor[] = COLOR(0x444444ff); /* color of the border that start from outside the windows */
+static const float borderecolor[] = COLOR(0x444444ff); /* color of the border that start from inside the windows */
+static const int border_color_type = BrdOriginal; /* borders to be colored (focuscolor, urgentcolor) */
static const float focuscolor[] = COLOR(0x005577ff);
static const float urgentcolor[] = COLOR(0xff0000ff);
/* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */
diff --git a/dwl.c b/dwl.c
index ef27a1d..e11b185 100644
--- a/dwl.c
+++ b/dwl.c
@@ -80,6 +80,7 @@ enum { LyrBg, LyrBottom, LyrTile, LyrFloat, LyrFS, LyrTop, LyrOverlay, LyrBlock,
enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar,
NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */
#endif
+enum { BrdOriginal, BrdStart, BrdEnd, BrdStartEnd };
typedef union {
int i;
@@ -103,6 +104,8 @@ typedef struct {
Monitor *mon;
struct wlr_scene_tree *scene;
struct wlr_scene_rect *border[4]; /* top, bottom, left, right */
+ struct wlr_scene_rect *borders[4]; /* top, bottom, left, right */
+ struct wlr_scene_rect *bordere[4]; /* top, bottom, left, right */
struct wlr_scene_tree *scene_surface;
struct wl_list link;
struct wl_list flink;
@@ -127,6 +130,8 @@ typedef struct {
struct wl_listener set_hints;
#endif
unsigned int bw;
+ unsigned int bws;
+ unsigned int bwe;
uint32_t tags;
int isfloating, isurgent, isfullscreen;
uint32_t resize; /* configure serial of a pending resize */
@@ -971,6 +976,8 @@ createnotify(struct wl_listener *listener, void *data)
c = xdg_surface->data = ecalloc(1, sizeof(*c));
c->surface.xdg = xdg_surface;
c->bw = borderpx;
+ c->bws = borderspx;
+ c->bwe = borderepx;
wlr_xdg_toplevel_set_wm_capabilities(xdg_surface->toplevel,
WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
@@ -1205,7 +1212,7 @@ 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)
- client_set_border_color(c, focuscolor);
+ client_set_border_color(c, focuscolor, focuscolor, focuscolor);
}
/* Deactivate old client if focus is changing */
@@ -1222,7 +1229,7 @@ focusclient(Client *c, int lift)
/* Don't deactivate old client if the new one wants focus, as this causes issues with winecfg
* 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_border_color(old_c, bordercolor, borderscolor, borderecolor);
client_activate_surface(old, 0);
}
@@ -1535,6 +1542,12 @@ mapnotify(struct wl_listener *listener, void *data)
for (i = 0; i < 4; i++) {
c->border[i] = wlr_scene_rect_create(c->scene, 0, 0, bordercolor);
c->border[i]->node.data = c;
+
+ c->borders[i] = wlr_scene_rect_create(c->scene, 0, 0, borderscolor);
+ c->borders[i]->node.data = c;
+
+ c->bordere[i] = wlr_scene_rect_create(c->scene, 0, 0, borderecolor);
+ c->bordere[i]->node.data = c;
}
/* Initialize client geometry with room for border */
@@ -1951,6 +1964,24 @@ resize(Client *c, struct wlr_box geo, int interact)
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->borders[0], c->geom.width - 2 * borderspx_offset, c->bws);
+ wlr_scene_rect_set_size(c->borders[1], c->geom.width - 2 * borderspx_offset, c->bws);
+ wlr_scene_rect_set_size(c->borders[2], c->bws, c->geom.height - 2 * c->bws - 2 * borderspx_offset);
+ wlr_scene_rect_set_size(c->borders[3], c->bws, c->geom.height - 2 * c->bws - 2 * borderspx_offset);
+ wlr_scene_node_set_position(&c->borders[0]->node, borderspx_offset, borderspx_offset);
+ wlr_scene_node_set_position(&c->borders[1]->node, borderspx_offset, c->geom.height - c->bws - borderspx_offset);
+ wlr_scene_node_set_position(&c->borders[2]->node, borderspx_offset, c->bws + borderspx_offset);
+ wlr_scene_node_set_position(&c->borders[3]->node, c->geom.width - c->bws - borderspx_offset, c->bws + borderspx_offset);
+
+ wlr_scene_rect_set_size(c->bordere[0], c->geom.width - (c->bw - c->bwe) * 2 + borderepx_negative_offset * 2, c->bwe);
+ wlr_scene_rect_set_size(c->bordere[1], c->geom.width - (c->bw - c->bwe) * 2 + borderepx_negative_offset * 2, c->bwe);
+ wlr_scene_rect_set_size(c->bordere[2], c->bwe, c->geom.height - 2 * c->bw + 2 * borderepx_negative_offset);
+ wlr_scene_rect_set_size(c->bordere[3], c->bwe, c->geom.height - 2 * c->bw + 2 * borderepx_negative_offset);
+ wlr_scene_node_set_position(&c->bordere[0]->node, c->bw - c->bwe - borderepx_negative_offset, c->bw - c->bwe - borderepx_negative_offset);
+ wlr_scene_node_set_position(&c->bordere[1]->node, c->bw - c->bwe - borderepx_negative_offset, c->geom.height - c->bw + borderepx_negative_offset);
+ wlr_scene_node_set_position(&c->bordere[2]->node, c->bw - c->bwe - borderepx_negative_offset, c->bw - borderepx_negative_offset);
+ wlr_scene_node_set_position(&c->bordere[3]->node, c->geom.width - c->bw + borderepx_negative_offset, c->bw - borderepx_negative_offset);
+
/* this is a no-op if size hasn't changed */
c->resize = client_set_size(c, c->geom.width - 2 * c->bw,
c->geom.height - 2 * c->bw);
@@ -2063,6 +2094,8 @@ setfullscreen(Client *c, int fullscreen)
if (!c->mon)
return;
c->bw = fullscreen ? 0 : borderpx;
+ c->bws = fullscreen ? 0 : borderspx;
+ c->bwe = fullscreen ? 0 : borderepx;
client_set_fullscreen(c, fullscreen);
wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen
? LyrFS : c->isfloating ? LyrFloat : LyrTile]);
@@ -2651,7 +2684,7 @@ urgent(struct wl_listener *listener, void *data)
return;
if (client_surface(c)->mapped)
- client_set_border_color(c, urgentcolor);
+ client_set_border_color(c, urgentcolor, urgentcolor, urgentcolor);
c->isurgent = 1;
printstatus();
}
@@ -2835,7 +2868,7 @@ sethints(struct wl_listener *listener, void *data)
c->isurgent = xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints);
if (c->isurgent && surface && surface->mapped)
- client_set_border_color(c, urgentcolor);
+ client_set_border_color(c, urgentcolor, urgentcolor, urgentcolor);
printstatus();
}
--
2.42.0
+26
View File
@@ -0,0 +1,26 @@
### Description
bstack and bstackhoriz are two stack layouts for dwl.
### Scheme
```
bstack (TTT) bstackhoriz (===)
+-----------------+ +-----------------+
| | | |
| | | |
| | | |
+-----+-----+-----+ +-----------------+
| | | | +-----------------+
| | | | +-----------------+
+-----+-----+-----+ +-----------------+
```
### Download
- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.5/bottomstack)
- [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
- [wochap](https://codeberg.org/wochap)
- [DanielMowitz](https://github.com/DanielMowitz)
- [Abanoub8](https://github.com/Abanoub8)
+141
View File
@@ -0,0 +1,141 @@
From 589c964e47965d84ffd3a2b036e75feddd619eed Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Thu, 11 Apr 2024 16:50:20 -0500
Subject: [PATCH] add bstack and bstackhoriz layouts
---
config.def.h | 4 +++
dwl.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 88 insertions(+)
diff --git a/config.def.h b/config.def.h
index 8847e58..68b62db 100644
--- a/config.def.h
+++ b/config.def.h
@@ -33,6 +33,8 @@ static const Layout layouts[] = {
{ "[]=", tile },
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
+ { "TTT", bstack },
+ { "===", bstackhoriz },
};
/* monitors */
@@ -134,6 +136,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 bf763df..dc3d000 100644
--- a/dwl.c
+++ b/dwl.c
@@ -55,6 +55,7 @@
#include <wlr/types/wlr_xdg_decoration_v1.h>
#include <wlr/types/wlr_xdg_output_v1.h>
#include <wlr/types/wlr_xdg_shell.h>
+#include <wlr/util/box.h>
#include <wlr/util/log.h>
#include <wlr/util/region.h>
#include <xkbcommon/xkbcommon.h>
@@ -347,6 +348,8 @@ 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 bstack(Monitor *m);
+static void bstackhoriz(Monitor *m);
/* variables */
static const char broken[] = "broken";
@@ -3088,3 +3091,84 @@ main(int argc, char *argv[])
usage:
die("Usage: %s [-v] [-d] [-s startup command]", argv[0]);
}
+
+static void
+bstack(Monitor *m)
+{
+ int w, h, mh, mx, tx, ty, tw;
+ int i, n = 0;
+ Client *c;
+
+ wl_list_for_each(c, &clients, link)
+ if (VISIBLEON(c, m) && !c->isfloating)
+ n++;
+ if (n == 0)
+ return;
+
+ if (n > m->nmaster) {
+ mh = ROUND(m->nmaster ? m->mfact * m->w.height : 0);
+ tw = m->w.width / (n - m->nmaster);
+ ty = m->w.y + mh;
+ } else {
+ mh = m->w.height;
+ tw = m->w.width;
+ ty = m->w.y;
+ }
+
+ i = mx = 0;
+ tx = m-> w.x;
+ wl_list_for_each(c, &clients, link) {
+ if (!VISIBLEON(c, m) || c->isfloating)
+ continue;
+ if (i < m->nmaster) {
+ w = (m->w.width - mx) / (MIN(n, m->nmaster) - i);
+ resize(c, (struct wlr_box) { .x = m->w.x + mx, .y = m->w.y, .width = w, .height = mh }, 0);
+ mx += c->geom.width;
+ } else {
+ h = m->w.height - mh;
+ resize(c, (struct wlr_box) { .x = tx, .y = ty, .width = tw, .height = h }, 0);
+ if (tw != m->w.width)
+ tx += c->geom.width;
+ }
+ i++;
+ }
+}
+
+static void
+bstackhoriz(Monitor *m) {
+ int w, mh, mx, tx, ty, th;
+ int i, n = 0;
+ Client *c;
+
+ wl_list_for_each(c, &clients, link)
+ if (VISIBLEON(c, m) && !c->isfloating)
+ n ++;
+ if (n == 0)
+ return;
+
+ if (n > m->nmaster) {
+ mh = ROUND(m->nmaster ? m->mfact * m->w.height : 0);
+ th = (m->w.height - mh) / (n - m->nmaster);
+ ty = m->w.y + mh;
+ } else {
+ th = mh = m->w.height;
+ ty = m->w.y;
+ }
+
+ i = mx = 0;
+ tx = m-> w.x;
+ wl_list_for_each(c, &clients, link) {
+ if (!VISIBLEON(c,m) || c->isfloating)
+ continue;
+ if (i < m->nmaster) {
+ w = (m->w.width - mx) / (MIN(n, m->nmaster) - i);
+ resize(c, (struct wlr_box) { .x = m->w.x + mx, .y = m->w.y, .width = w, .height = mh }, 0);
+ mx += c->geom.width;
+ } else {
+ resize(c, (struct wlr_box) { .x = tx, .y = ty, .width = m->w.width, .height = th }, 0);
+ if (th != m->w.height)
+ ty += c->geom.height;
+ }
+ i++;
+ }
+}
--
2.43.2
+10
View File
@@ -0,0 +1,10 @@
### Description
Adds "state" (`enum wlr_button_state`) to configure a button action on either press or release.
This basically enables release to be used for button actions.
### Download
- [git branch](https://codeberg.org/nullsystem/dwl/src/branch/main_buttonbystate)
- [2024-04-06](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/buttonbystate/buttonbystate.patch)
### Authors
- [nullsystem](https://codeberg.org/nullsystem)
+78
View File
@@ -0,0 +1,78 @@
From 4141aa9455e4b4a5b4a235475c70e8c100ec663e Mon Sep 17 00:00:00 2001
From: nullsystem <nullsystem.aongp@slmail.me>
Date: Sat, 6 Apr 2024 02:03:49 +0100
Subject: [PATCH] buttonbystate - allow config for release (and press)
- Adds "state" (enum wlr_button_state) to configure a button action on
either press or release. This basically enables release to be used
for button actions.
---
config.def.h | 6 +++---
dwl.c | 22 ++++++++++++----------
2 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/config.def.h b/config.def.h
index 8847e58..cc989cf 100644
--- a/config.def.h
+++ b/config.def.h
@@ -165,7 +165,7 @@ static const Key keys[] = {
};
static const Button buttons[] = {
- { MODKEY, BTN_LEFT, moveresize, {.ui = CurMove} },
- { MODKEY, BTN_MIDDLE, togglefloating, {0} },
- { MODKEY, BTN_RIGHT, moveresize, {.ui = CurResize} },
+ { MODKEY, BTN_LEFT, moveresize, {.ui = CurMove}, WLR_BUTTON_PRESSED },
+ { MODKEY, BTN_MIDDLE, togglefloating, {0}, WLR_BUTTON_PRESSED },
+ { MODKEY, BTN_RIGHT, moveresize, {.ui = CurResize}, WLR_BUTTON_PRESSED },
};
diff --git a/dwl.c b/dwl.c
index bf763df..6b60ccf 100644
--- a/dwl.c
+++ b/dwl.c
@@ -99,6 +99,7 @@ typedef struct {
unsigned int button;
void (*func)(const Arg *);
const Arg arg;
+ enum wlr_button_state state;
} Button;
typedef struct Monitor Monitor;
@@ -595,16 +596,6 @@ buttonpress(struct wl_listener *listener, void *data)
xytonode(cursor->x, cursor->y, NULL, &c, NULL, NULL, NULL);
if (c && (!client_is_unmanaged(c) || client_wants_focus(c)))
focusclient(c, 1);
-
- keyboard = wlr_seat_get_keyboard(seat);
- mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
- for (b = buttons; b < END(buttons); b++) {
- if (CLEANMASK(mods) == CLEANMASK(b->mod) &&
- event->button == b->button && b->func) {
- b->func(&b->arg);
- return;
- }
- }
break;
case WLR_BUTTON_RELEASED:
held_grab = NULL;
@@ -622,6 +613,17 @@ buttonpress(struct wl_listener *listener, void *data)
}
break;
}
+
+ keyboard = wlr_seat_get_keyboard(seat);
+ mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
+ for (b = buttons; b < END(buttons); b++) {
+ if (b->state == event->state && CLEANMASK(mods) == CLEANMASK(b->mod) &&
+ event->button == b->button && b->func) {
+ b->func(&b->arg);
+ return;
+ }
+ }
+
/* If the event wasn't handled by the compositor, notify the client with
* pointer focus that a button press has occurred */
wlr_seat_pointer_notify_button(seat,
--
2.44.0
+13
View File
@@ -0,0 +1,13 @@
### Description
Add a keybinding that toggles centering the terminally horizontally when
it's the only window, while still tiling multiple windows.
This limits the width of long text making it easier to read, and avoids
covering the wallpaper more than necessary.
### Download
- [git branch](https://codeberg.org/guidocella/dwl/src/branch/center-terminal)
- [2024-02-06](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/center-terminal/center-terminal.patch)
### Authors
- [Guido Cella](https://codeberg.org/guidocella)
@@ -0,0 +1,102 @@
From 5646d7e7d933a2e7a667767c3fde89c91697c4ea Mon Sep 17 00:00:00 2001
From: Guido Cella <guido@guidocella.xyz>
Date: Tue, 6 Feb 2024 09:20:48 +0100
Subject: [PATCH] add a keybinding to center the terminal
Add a keybinding that toggles centering the terminally horizontally when
it's the only window, while still tiling multiple windows.
This limits the width of long text making it easier to read, and avoids
covering the wallpaper more than necessary.
---
config.def.h | 1 +
dwl.c | 19 +++++++++++++++++++
2 files changed, 20 insertions(+)
diff --git a/config.def.h b/config.def.h
index a85ca27..2055df9 100644
--- a/config.def.h
+++ b/config.def.h
@@ -139,6 +139,7 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_space, setlayout, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
+ { MODKEY, XKB_KEY_v, togglecenter, {0} },
{ MODKEY, XKB_KEY_0, view, {.ui = ~0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} },
{ MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} },
diff --git a/dwl.c b/dwl.c
index 002349a..4582413 100644
--- a/dwl.c
+++ b/dwl.c
@@ -7,6 +7,7 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
+#include <strings.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
@@ -135,6 +136,7 @@ typedef struct {
unsigned int bw;
uint32_t tags;
int isfloating, isurgent, isfullscreen;
+ bool centered;
uint32_t resize; /* configure serial of a pending resize */
} Client;
@@ -319,6 +321,7 @@ 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 togglecenter(const Arg *arg);
static void togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg);
static void toggletag(const Arg *arg);
@@ -392,6 +395,8 @@ static struct wlr_box sgeom;
static struct wl_list mons;
static Monitor *selmon;
+static bool center;
+
#ifdef XWAYLAND
static void activatex11(struct wl_listener *listener, void *data);
static void associatex11(struct wl_listener *listener, void *data);
@@ -457,6 +462,8 @@ applyrules(Client *c)
}
}
}
+ if (!strcasecmp(appid, termcmd[0]))
+ c->centered = true;
setmon(c, mon, newtags);
}
@@ -2519,6 +2526,11 @@ tile(Monitor *m)
if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
continue;
if (i < m->nmaster) {
+ if (n == 1 && center && c->centered) {
+ resize(c, (struct wlr_box){.x = m->w.width / 4, .y = m->w.y,
+ .width = m->w.width / 2, .height = m->w.height - 2 * c->bw}, 0);
+ return;
+ }
resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw,
.height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0);
my += c->geom.height;
@@ -2531,6 +2543,13 @@ tile(Monitor *m)
}
}
+void
+togglecenter(const Arg *arg)
+{
+ center = !center;
+ tile(selmon);
+}
+
void
togglefloating(const Arg *arg)
{
--
2.43.0
+33
View File
@@ -0,0 +1,33 @@
### Description
This is a port of centeredmaster patch for dwm: <https://dwm.suckless.org/patches/centeredmaster>
centeredmaster centers the nmaster area on screen, using mfact * monitor
width & height, with the stacked windows distributed to the left and
right. It can be selected with `Alt+c`.
With one and two clients in master respectively this results in:
```
+------------------------------+ +------------------------------+
|+--------++--------++--------+| |+--------++--------++--------+|
|| || || || || || || ||
|| || || || || || M1 || ||
|| || || || || || || ||
|| S2 || M || S1 || || |+--------+| ||
|| || || || || |+--------+| ||
|| || || || || || || ||
|| || || || || || M2 || ||
|| || || || || || || ||
|+--------++--------++--------+| |+--------++--------++--------+|
+------------------------------+ +------------------------------+
```
### Download
- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.5/centeredmaster)
- [2024-04-11](https://codeberg.org/dwl/dwl-patches/raw/commit/b104a580a80ebaf9f7e8917fe574e3e97ddd019a/centeredmaster/centeredmaster.patch)
- [v0.5](https://codeberg.org/dwl/dwl-patches/raw/commit/0f4e40fee49d1b8b430778e241b29496ae3b3b70/centeredmaster/centeredmaster.patch)
### Authors
- [wochap](https://codeberg.org/wochap)
- [Nikita Ivanov](https://github.com/NikitaIvanovV)
+116
View File
@@ -0,0 +1,116 @@
From a9d47325283a55fd299de5bbbab5ab195840c7ca Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Thu, 11 Apr 2024 16:42:25 -0500
Subject: [PATCH] implement centeredmaster layout
inspiration: https://github.com/djpohly/dwl/wiki/centeredmaster
---
config.def.h | 2 ++
dwl.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 66 insertions(+)
diff --git a/config.def.h b/config.def.h
index 8847e58..cfc6e62 100644
--- a/config.def.h
+++ b/config.def.h
@@ -33,6 +33,7 @@ static const Layout layouts[] = {
{ "[]=", tile },
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
+ { "|M|", centeredmaster },
};
/* monitors */
@@ -134,6 +135,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_c, 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 bf763df..0e84ccf 100644
--- a/dwl.c
+++ b/dwl.c
@@ -248,6 +248,7 @@ static void arrangelayer(Monitor *m, struct wl_list *list,
static void arrangelayers(Monitor *m);
static void axisnotify(struct wl_listener *listener, void *data);
static void buttonpress(struct wl_listener *listener, void *data);
+static void centeredmaster(Monitor *m);
static void chvt(const Arg *arg);
static void checkidleinhibitor(struct wlr_surface *exclude);
static void cleanup(void);
@@ -628,6 +629,69 @@ buttonpress(struct wl_listener *listener, void *data)
event->time_msec, event->button, event->state);
}
+void
+centeredmaster(Monitor *m)
+{
+ unsigned int h, mw, mx, my, oty, ety, tw;
+ int i, n;
+ Client *c;
+
+ n = 0;
+ wl_list_for_each(c, &clients, link)
+ if (VISIBLEON(c, m) && !c->isfloating && !c->isfullscreen)
+ n++;
+ if (n == 0)
+ return;
+
+ /* initialize areas */
+ mw = m->w.width;
+ mx = 0;
+ my = 0;
+ tw = mw;
+
+ if (n > m->nmaster) {
+ /* go mfact box in the center if more than nmaster clients */
+ mw = ROUND(m->nmaster ? m->w.width * m->mfact : 0);
+ tw = m->w.width - mw;
+
+ if (n - m->nmaster > 1) {
+ /* only one client */
+ mx = (m->w.width - mw) / 2;
+ tw = (m->w.width - mw) / 2;
+ }
+ }
+
+ i = 0;
+ oty = 0;
+ ety = 0;
+ wl_list_for_each(c, &clients, link) {
+ if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
+ continue;
+ if (i < m->nmaster) {
+ /* nmaster clients are stacked vertically, in the center
+ * of the screen */
+ h = (m->w.height - my) / (MIN(n, m->nmaster) - i);
+ resize(c, (struct wlr_box){.x = m->w.x + mx, .y = m->w.y + my, .width = mw,
+ .height = h}, 0);
+ my += c->geom.height;
+ } else {
+ /* stack clients are stacked vertically */
+ if ((i - m->nmaster) % 2) {
+ h = (m->w.height - ety) / ( (1 + n - i) / 2);
+ resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + ety, .width = tw,
+ .height = h}, 0);
+ ety += c->geom.height;
+ } else {
+ h = (m->w.height - oty) / ((1 + n - i) / 2);
+ resize(c, (struct wlr_box){.x = m->w.x + mx + mw, .y = m->w.y + oty, .width = tw,
+ .height = h}, 0);
+ oty += c->geom.height;
+ }
+ }
+ i++;
+ }
+}
+
void
chvt(const Arg *arg)
{
--
2.43.2
+21
View File
@@ -0,0 +1,21 @@
### Description
A port of the [dwm cfacts patch](https://dwm.suckless.org/patches/cfacts/) (with the limits removed)
Clients with higher weight are allocated more space!
```
+---------------------+
| | 0.5 |
| 1.0 +----------+
+----------+ |
| | 1.0 |
| +----------+
| 2.0 | |
| | 1.0 |
+----------+----------+`
```
### Download
- [git branch](https://codeberg.org/Palanix/dwl/src/branch/cfact)
- [2024-02-15](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/cfact/cfact.patch)
### Authors
- [Palanix](https://codeberg.org/Palanix)
+121
View File
@@ -0,0 +1,121 @@
From 98fe302cd240b519c28c886250273854844ab2c7 Mon Sep 17 00:00:00 2001
From: Palanix <palanixyt@gmail.com>
Date: Fri, 24 Nov 2023 21:16:56 +0100
Subject: [PATCH] cweights to allow different size clients in normal layouts
---
config.def.h | 3 +++
dwl.c | 32 ++++++++++++++++++++++++++++++--
2 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/config.def.h b/config.def.h
index 9009517..27ff521 100644
--- a/config.def.h
+++ b/config.def.h
@@ -128,6 +128,9 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
{ MODKEY, XKB_KEY_h, setmfact, {.f = -0.05f} },
{ MODKEY, XKB_KEY_l, setmfact, {.f = +0.05f} },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_H, setcfact, {.f = +0.25f} },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_L, setcfact, {.f = -0.25f} },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_K, setcfact, {.f = 0.0f} },
{ MODKEY, XKB_KEY_Return, zoom, {0} },
{ MODKEY, XKB_KEY_Tab, view, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} },
diff --git a/dwl.c b/dwl.c
index fa76db2..9bdb438 100644
--- a/dwl.c
+++ b/dwl.c
@@ -136,6 +136,7 @@ typedef struct {
uint32_t tags;
int isfloating, isurgent, isfullscreen;
uint32_t resize; /* configure serial of a pending resize */
+ float cweight;
} Client;
typedef struct {
@@ -301,6 +302,7 @@ static void requeststartdrag(struct wl_listener *listener, void *data);
static void requestmonstate(struct wl_listener *listener, void *data);
static void resize(Client *c, struct wlr_box geo, int interact);
static void run(char *startup_cmd);
+static void setcfact(const Arg *arg);
static void setcursor(struct wl_listener *listener, void *data);
static void setcursorshape(struct wl_listener *listener, void *data);
static void setfloating(Client *c, int floating);
@@ -956,6 +958,7 @@ createnotify(struct wl_listener *listener, void *data)
c = xdg_surface->data = ecalloc(1, sizeof(*c));
c->surface.xdg = xdg_surface;
c->bw = borderpx;
+ c->cweight = 1.0;
wlr_xdg_toplevel_set_wm_capabilities(xdg_surface->toplevel,
WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
@@ -2009,6 +2012,19 @@ run(char *startup_cmd)
wl_display_run(dpy);
}
+void
+setcfact(const Arg *arg)
+{
+ Client *sel = focustop(selmon);
+
+ if(!arg || !sel || !selmon->lt[selmon->sellt]->arrange)
+ return;
+ sel->cweight = (float) (arg->f ? sel->cweight + arg->f : 1.0);
+ if (sel->cweight < 0)
+ sel->cweight = 0;
+ arrange(selmon);
+}
+
void
setcursor(struct wl_listener *listener, void *data)
{
@@ -2468,6 +2484,7 @@ tile(Monitor *m)
{
unsigned int mw, my, ty;
int i, n = 0;
+ float mweight = 0, tweight = 0;
Client *c;
wl_list_for_each(c, &clients, link)
@@ -2480,17 +2497,27 @@ tile(Monitor *m)
mw = m->nmaster ? ROUND(m->w.width * m->mfact) : 0;
else
mw = m->w.width;
+ i = 0;
+ wl_list_for_each(c, &clients, link){
+ if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
+ continue;
+ if (i < m->nmaster)
+ mweight += c->cweight;
+ else
+ tweight += c->cweight;
+ i++;
+ }
i = my = ty = 0;
wl_list_for_each(c, &clients, link) {
if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
continue;
if (i < m->nmaster) {
resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw,
- .height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0);
+ .height = (int) ((c->cweight / mweight) * m->w.height)}, 0);
my += c->geom.height;
} else {
resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y + ty,
- .width = m->w.width - mw, .height = (m->w.height - ty) / (n - i)}, 0);
+ .width = m->w.width - mw, .height = (int) ((c->cweight / tweight) * m->w.height) }, 0);
ty += c->geom.height;
}
i++;
@@ -2872,6 +2899,7 @@ createnotifyx11(struct wl_listener *listener, void *data)
c->surface.xwayland = xsurface;
c->type = X11;
c->bw = borderpx;
+ c->cweight = 1.0;
/* Listen to the various events it can emit */
LISTEN(&xsurface->events.associate, &c->associate, associatex11);
--
2.43.1
+12
View File
@@ -0,0 +1,12 @@
### Description
Implements chained keybindings (like the dwm [keychain](https://dwm.suckless.org/patches/keychain/) patch).
Bindings can share a leading chain key. This chain key will be triggered when Mod+chain is pressed. A subsequent keypress will be matched against bindings for that chain key. If it is configured the action will be triggered, otherwise the keypress will be ignored.
### Download
- [git branch](https://codeberg.org/bencc/dwl/src/branch/chainkeys)
- [2024-01-17](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/chainkeys/chainkeys.patch)
### Authors
- [Ben Collerson](https://codeberg.org/bencc)
+215
View File
@@ -0,0 +1,215 @@
From 8cad102fd59463e8a2238845399dcaa1f759508c Mon Sep 17 00:00:00 2001
From: Ben Collerson <benc@benc.cc>
Date: Tue, 2 Jan 2024 10:33:59 +1000
Subject: [PATCH 1/2] chainkeys
---
config.def.h | 62 ++++++++++++++++++++++++++--------------------------
dwl.c | 22 ++++++++++++++++++-
2 files changed, 52 insertions(+), 32 deletions(-)
diff --git a/config.def.h b/config.def.h
index 9009517..f4b7b2a 100644
--- a/config.def.h
+++ b/config.def.h
@@ -105,10 +105,10 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
#define MODKEY WLR_MODIFIER_ALT
#define TAGKEYS(KEY,SKEY,TAG) \
- { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
- { MODKEY|WLR_MODIFIER_CTRL, KEY, toggleview, {.ui = 1 << TAG} }, \
- { MODKEY|WLR_MODIFIER_SHIFT, SKEY, tag, {.ui = 1 << TAG} }, \
- { MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,SKEY,toggletag, {.ui = 1 << TAG} }
+ { MODKEY, -1, KEY, view, {.ui = 1 << TAG} }, \
+ { MODKEY|WLR_MODIFIER_CTRL, -1, KEY, toggleview, {.ui = 1 << TAG} }, \
+ { MODKEY|WLR_MODIFIER_SHIFT, -1, SKEY, tag, {.ui = 1 << TAG} }, \
+ { MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,-1,SKEY,toggletag, {.ui = 1 << TAG} }
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
@@ -119,30 +119,30 @@ static const char *menucmd[] = { "bemenu-run", NULL };
static const Key keys[] = {
/* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
- /* modifier key function argument */
- { MODKEY, XKB_KEY_p, spawn, {.v = menucmd} },
- { 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, XKB_KEY_i, incnmaster, {.i = +1} },
- { MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
- { MODKEY, XKB_KEY_h, setmfact, {.f = -0.05f} },
- { MODKEY, XKB_KEY_l, setmfact, {.f = +0.05f} },
- { MODKEY, XKB_KEY_Return, zoom, {0} },
- { MODKEY, XKB_KEY_Tab, view, {0} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} },
- { 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_space, setlayout, {0} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {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} },
- { MODKEY, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_LEFT} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater, tagmon, {.i = WLR_DIRECTION_RIGHT} },
+ /* modifier chain, key function argument */
+ { MODKEY, -1, XKB_KEY_p, spawn, {.v = menucmd} },
+ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_Return, spawn, {.v = termcmd} },
+ { MODKEY, -1, XKB_KEY_j, focusstack, {.i = +1} },
+ { MODKEY, -1, XKB_KEY_k, focusstack, {.i = -1} },
+ { MODKEY, -1, XKB_KEY_i, incnmaster, {.i = +1} },
+ { MODKEY, -1, XKB_KEY_d, incnmaster, {.i = -1} },
+ { MODKEY, -1, XKB_KEY_h, setmfact, {.f = -0.05} },
+ { MODKEY, -1, XKB_KEY_l, setmfact, {.f = +0.05} },
+ { MODKEY, -1, XKB_KEY_Return, zoom, {0} },
+ { MODKEY, -1, XKB_KEY_Tab, view, {0} },
+ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_C, killclient, {0} },
+ { MODKEY, -1, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
+ { MODKEY, -1, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
+ { MODKEY, -1, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
+ { MODKEY, -1, XKB_KEY_space, setlayout, {0} },
+ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_space, togglefloating, {0} },
+ { MODKEY, -1, XKB_KEY_e, togglefullscreen, {0} },
+ { MODKEY, -1, XKB_KEY_0, view, {.ui = ~0} },
+ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_parenright, tag, {.ui = ~0} },
+ { MODKEY, -1, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} },
+ { MODKEY, -1, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT} },
+ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_LEFT} },
+ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_greater, tagmon, {.i = WLR_DIRECTION_RIGHT} },
TAGKEYS( XKB_KEY_1, XKB_KEY_exclam, 0),
TAGKEYS( XKB_KEY_2, XKB_KEY_at, 1),
TAGKEYS( XKB_KEY_3, XKB_KEY_numbersign, 2),
@@ -152,14 +152,14 @@ static const Key keys[] = {
TAGKEYS( XKB_KEY_7, XKB_KEY_ampersand, 6),
TAGKEYS( XKB_KEY_8, XKB_KEY_asterisk, 7),
TAGKEYS( XKB_KEY_9, XKB_KEY_parenleft, 8),
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, quit, {0} },
+ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_Q, quit, {0} },
/* 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} },
+ { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,-1,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
* do not remove them.
*/
-#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} }
+#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,-1,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} }
CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6),
CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
};
diff --git a/dwl.c b/dwl.c
index f25ac2f..8ffad73 100644
--- a/dwl.c
+++ b/dwl.c
@@ -139,6 +139,7 @@ typedef struct {
typedef struct {
uint32_t mod;
+ xkb_keysym_t chain;
xkb_keysym_t keysym;
void (*func)(const Arg *);
const Arg arg;
@@ -338,6 +339,7 @@ static const char broken[] = "broken";
static pid_t child_pid = -1;
static int locked;
static void *exclusive_focus;
+static xkb_keysym_t chainkey = -1;
static struct wl_display *dpy;
static struct wlr_backend *backend;
static struct wlr_scene *scene;
@@ -1363,10 +1365,28 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
const Key *k;
for (k = keys; k < END(keys); k++) {
if (CLEANMASK(mods) == CLEANMASK(k->mod)
- && sym == k->keysym && k->func) {
+ && sym == k->keysym
+ && chainkey == -1
+ && k->chain == -1
+ && k->func) {
k->func(&k->arg);
return 1;
}
+ else if (sym == k->keysym
+ && chainkey != -1
+ && k->chain == chainkey
+ && k->func) {
+ k->func(&k->arg);
+ chainkey = -1;
+ return 1;
+ }
+ else if (CLEANMASK(mods) == CLEANMASK(k->mod)
+ && k->chain == sym
+ && chainkey == -1
+ && k->func) {
+ chainkey = sym;
+ return 1;
+ }
}
return 0;
}
--
2.43.0
From 0b11cce166dc0daabe305622d593532407a178ed Mon Sep 17 00:00:00 2001
From: Ben Collerson <benc@benc.cc>
Date: Tue, 2 Jan 2024 10:33:59 +1000
Subject: [PATCH 2/2] fix types - signed ints should be signed.
---
config.def.h | 4 ++--
dwl.c | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/config.def.h b/config.def.h
index f4b7b2a..ac70906 100644
--- a/config.def.h
+++ b/config.def.h
@@ -126,8 +126,8 @@ static const Key keys[] = {
{ MODKEY, -1, XKB_KEY_k, focusstack, {.i = -1} },
{ MODKEY, -1, XKB_KEY_i, incnmaster, {.i = +1} },
{ MODKEY, -1, XKB_KEY_d, incnmaster, {.i = -1} },
- { MODKEY, -1, XKB_KEY_h, setmfact, {.f = -0.05} },
- { MODKEY, -1, XKB_KEY_l, setmfact, {.f = +0.05} },
+ { MODKEY, -1, XKB_KEY_h, setmfact, {.f = -0.05f} },
+ { MODKEY, -1, XKB_KEY_l, setmfact, {.f = +0.05f} },
{ MODKEY, -1, XKB_KEY_Return, zoom, {0} },
{ MODKEY, -1, XKB_KEY_Tab, view, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_C, killclient, {0} },
diff --git a/dwl.c b/dwl.c
index 8ffad73..cbb9cbf 100644
--- a/dwl.c
+++ b/dwl.c
@@ -139,7 +139,7 @@ typedef struct {
typedef struct {
uint32_t mod;
- xkb_keysym_t chain;
+ int chain;
xkb_keysym_t keysym;
void (*func)(const Arg *);
const Arg arg;
@@ -339,7 +339,7 @@ static const char broken[] = "broken";
static pid_t child_pid = -1;
static int locked;
static void *exclusive_focus;
-static xkb_keysym_t chainkey = -1;
+static int chainkey = -1;
static struct wl_display *dpy;
static struct wlr_backend *backend;
static struct wlr_scene *scene;
@@ -1381,7 +1381,7 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
return 1;
}
else if (CLEANMASK(mods) == CLEANMASK(k->mod)
- && k->chain == sym
+ && k->chain == (int)sym
&& chainkey == -1
&& k->func) {
chainkey = sym;
--
2.43.0
+18
View File
@@ -0,0 +1,18 @@
### Description
This patch adds default transparency parameters to config.h which specify the starting transparencies of all windows.
It also adds opacities to the ruleset, enabling override of the opacities on a per client basis.
Additionally, it adds some shortcuts:
```
[MODKEY]+[o] -> increase focus opacity of currently focused window
[MODKEY]+[Shift]+[o] -> decrease focus opacity of currently focused window
```
### Download
- [git branch](https://codeberg.org/sevz/dwl/src/branch/client-opacity)
- [2024-03-31](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/client-opacity/client-opacity.patch)
### Authors
- [sevz](https://codeberg.org/sevz)
+182
View File
@@ -0,0 +1,182 @@
From adbc47f25aadfa55d2e042c52f81ba4db08dd57f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
<leohdz172@proton.me>
Date: Tue, 25 Jul 2023 12:48:22 -0600
Subject: [PATCH] add default transparency for windows and rules for override
the transparency
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Leonardo Hernández Hernández <leohdz172@proton.me>
---
config.def.h | 10 +++++++---
dwl.c | 38 ++++++++++++++++++++++++++++++++++++++
2 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/config.def.h b/config.def.h
index a8ed61d..3c79817 100644
--- a/config.def.h
+++ b/config.def.h
@@ -13,6 +13,7 @@ static const float focuscolor[] = COLOR(0x005577ff);
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 */
+static const float default_opacity = 0.75;
/* tagging - TAGCOUNT must be no greater than 31 */
#define TAGCOUNT (9)
@@ -21,11 +22,12 @@ static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0}; /* You can al
static int log_level = WLR_ERROR;
static const Rule rules[] = {
- /* app_id title tags mask isfloating monitor */
+ /* app_id title tags mask isfloating alpha monitor */
/* examples:
- { "Gimp", NULL, 0, 1, -1 },
+ { "Gimp", NULL, 0, 1, default_alpha, -1 },
+ { "Alacritty",NULL, 1 << 2, 0, 1.0, -1 },
*/
- { "firefox", NULL, 1 << 8, 0, -1 },
+ { "firefox", NULL, 1 << 8, 0, default_opacity, -1 },
};
/* layout(s) */
@@ -128,6 +130,8 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
{ MODKEY, XKB_KEY_h, setmfact, {.f = -0.05} },
{ MODKEY, XKB_KEY_l, setmfact, {.f = +0.05} },
+ { MODKEY, XKB_KEY_o, setopacity, {.f = +0.1} },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_O, setopacity, {.f = -0.1} },
{ MODKEY, XKB_KEY_Return, zoom, {0} },
{ MODKEY, XKB_KEY_Tab, view, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} },
diff --git a/dwl.c b/dwl.c
index 4d19357..1b905ed 100644
--- a/dwl.c
+++ b/dwl.c
@@ -133,6 +133,7 @@ typedef struct {
unsigned int bw;
uint32_t tags;
int isfloating, isurgent, isfullscreen;
+ float opacity;
uint32_t resize; /* configure serial of a pending resize */
} Client;
@@ -217,6 +218,7 @@ typedef struct {
const char *title;
uint32_t tags;
int isfloating;
+ float opacity;
int monitor;
} Rule;
@@ -299,6 +301,7 @@ static void requeststartdrag(struct wl_listener *listener, void *data);
static void requestmonstate(struct wl_listener *listener, void *data);
static void resize(Client *c, struct wlr_box geo, int interact);
static void run(char *startup_cmd);
+static void scenebuffersetopacity(struct wlr_scene_buffer *buffer, int sx, int sy, void *user_data);
static void setcursor(struct wl_listener *listener, void *data);
static void setcursorshape(struct wl_listener *listener, void *data);
static void setfloating(Client *c, int floating);
@@ -307,6 +310,7 @@ static void setgamma(struct wl_listener *listener, void *data);
static void setlayout(const Arg *arg);
static void setmfact(const Arg *arg);
static void setmon(Client *c, Monitor *m, uint32_t newtags);
+static void setopacity(const Arg *arg);
static void setpsel(struct wl_listener *listener, void *data);
static void setsel(struct wl_listener *listener, void *data);
static void setup(void);
@@ -440,6 +444,7 @@ applyrules(Client *c)
if ((!r->title || strstr(title, r->title))
&& (!r->id || strstr(appid, r->id))) {
c->isfloating = r->isfloating;
+ c->opacity = r->opacity;
newtags |= r->tags;
i = 0;
wl_list_for_each(m, &mons, link) {
@@ -448,6 +453,7 @@ applyrules(Client *c)
}
}
}
+ wlr_scene_node_for_each_buffer(&c->scene_surface->node, scenebuffersetopacity, c);
wlr_scene_node_reparent(&c->scene->node, layers[c->isfloating ? LyrFloat : LyrTile]);
setmon(c, mon, newtags);
}
@@ -734,6 +740,9 @@ commitnotify(struct wl_listener *listener, void *data)
if (client_surface(c)->mapped && c->mon)
resize(c, c->geom, (c->isfloating && !c->isfullscreen));
+ if (c->scene_surface)
+ wlr_scene_node_for_each_buffer(&c->scene_surface->node, scenebuffersetopacity, c);
+
/* mark a pending resize as completed */
if (c->resize && c->resize <= c->surface.xdg->current.configure_serial)
c->resize = 0;
@@ -947,6 +956,7 @@ createnotify(struct wl_listener *listener, void *data)
c = xdg_surface->data = ecalloc(1, sizeof(*c));
c->surface.xdg = xdg_surface;
c->bw = borderpx;
+ c->opacity = default_opacity;
wlr_xdg_toplevel_set_wm_capabilities(xdg_surface->toplevel,
WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
@@ -2002,6 +2012,15 @@ run(char *startup_cmd)
wl_display_run(dpy);
}
+void
+scenebuffersetopacity(struct wlr_scene_buffer *buffer, int sx, int sy, void *data)
+{
+ Client *c = data;
+ /* xdg-popups are children of Client.scene, we do not have to worry about
+ messing with them. */
+ wlr_scene_buffer_set_opacity(buffer, c->isfullscreen ? 1 : c->opacity);
+}
+
void
setcursor(struct wl_listener *listener, void *data)
{
@@ -2067,6 +2086,7 @@ setfullscreen(Client *c, int fullscreen)
* client positions are set by the user and cannot be recalculated */
resize(c, c->prev, 0);
}
+ wlr_scene_node_for_each_buffer(&c->scene_surface->node, scenebuffersetopacity, c);
arrange(c->mon);
printstatus();
}
@@ -2132,6 +2152,23 @@ setmon(Client *c, Monitor *m, uint32_t newtags)
focusclient(focustop(selmon), 1);
}
+void
+setopacity(const Arg *arg)
+{
+ Client *sel = focustop(selmon);
+ if (!sel)
+ return;
+
+ sel->opacity += arg->f;
+ if (sel->opacity > 1.0)
+ sel->opacity = 1.0;
+
+ if (sel->opacity < 0.1)
+ sel->opacity = 0.1;
+
+ wlr_scene_node_for_each_buffer(&sel->scene_surface->node, scenebuffersetopacity, sel);
+}
+
void
setpsel(struct wl_listener *listener, void *data)
{
@@ -2842,6 +2879,7 @@ createnotifyx11(struct wl_listener *listener, void *data)
c->surface.xwayland = xsurface;
c->type = X11;
c->bw = borderpx;
+ c->opacity = default_opacity;
/* Listen to the various events it can emit */
LISTEN(&xsurface->events.associate, &c->associate, associatex11);
--
2.43.0
+9
View File
@@ -0,0 +1,9 @@
### Description
A column layout patch. This patch just puts the visible clients into equal-width columns on the screen.
### Download
- [git branch](https://codeberg.org/bencc/dwl/src/branch/column)
- [2024-01-02](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/column/column.patch)
### Authors
- [Ben Collerson](https://codeberg.org/bencc)
+79
View File
@@ -0,0 +1,79 @@
From d1eb2061c619d0bbd7a0ecda0fe77409f3a6c399 Mon Sep 17 00:00:00 2001
From: Ben Collerson <benc@benc.cc>
Date: Fri, 29 Dec 2023 19:02:11 +1000
Subject: [PATCH] column layout
---
config.def.h | 2 ++
dwl.c | 28 ++++++++++++++++++++++++++++
2 files changed, 30 insertions(+)
diff --git a/config.def.h b/config.def.h
index a8ed61d9..edb30cae 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 },
+ { "||", col },
};
/* monitors */
@@ -134,6 +135,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_c, 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 4d19357f..63d80da7 100644
--- a/dwl.c
+++ b/dwl.c
@@ -243,6 +243,7 @@ static void checkidleinhibitor(struct wlr_surface *exclude);
static void cleanup(void);
static void cleanupmon(struct wl_listener *listener, void *data);
static void closemon(Monitor *m);
+static void col(Monitor *m);
static void commitlayersurfacenotify(struct wl_listener *listener, void *data);
static void commitnotify(struct wl_listener *listener, void *data);
static void createdecoration(struct wl_listener *listener, void *data);
@@ -704,6 +705,33 @@ closemon(Monitor *m)
printstatus();
}
+void
+col(Monitor *m)
+{
+ Client *c;
+ unsigned int n = 0, i = 0;
+
+ wl_list_for_each(c, &clients, link)
+ if (VISIBLEON(c, m) && !c->isfloating && !c->isfullscreen)
+ n++;
+
+ wl_list_for_each(c, &clients, link) {
+ if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
+ continue;
+ resize(
+ c,
+ (struct wlr_box){
+ .x = m->w.x + i * m->w.width / n,
+ .y = m->w.y,
+ .width = m->w.width / n,
+ .height = m->w.height
+ },
+ 0
+ );
+ i++;
+ }
+}
+
void
commitlayersurfacenotify(struct wl_listener *listener, void *data)
{
--
2.43.0
+9
View File
@@ -0,0 +1,9 @@
### Description
Generate a coredump if dwl exited abnormally (to be more usefull you need to compile dwl and wlroots with debug symbols)
### Download
- [git branch](https://codeberg.org/sevz/dwl/src/branch/coredump)
- [2023-11-30](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/coredump/coredump.patch)
### Authors
- [sevz](https://codeberg.org/sevz)
+65
View File
@@ -0,0 +1,65 @@
From 38bf34759e5eb3aed9fd14429eee8a1e509c014e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
<leohdz172@protonmail.com>
Date: Wed, 5 Oct 2022 23:07:13 -0500
Subject: [PATCH] increase RLIMIT_CORE (generate a coredump)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Leonardo Hernández Hernández <leohdz172@proton.me>
---
dwl.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/dwl.c b/dwl.c
index 10d5a5b..62cdb5a 100644
--- a/dwl.c
+++ b/dwl.c
@@ -7,6 +7,7 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
+#include <sys/resource.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
@@ -334,6 +335,8 @@ static void zoom(const Arg *arg);
/* variables */
static const char broken[] = "broken";
+static struct rlimit oldrlimit;
+static struct rlimit newrlimit;
static pid_t child_pid = -1;
static int locked;
static void *exclusive_focus;
@@ -1972,6 +1975,7 @@ run(char *startup_cmd)
if ((child_pid = fork()) < 0)
die("startup: fork:");
if (child_pid == 0) {
+ setrlimit(RLIMIT_CORE, &oldrlimit);
dup2(piperw[0], STDIN_FILENO);
close(piperw[0]);
close(piperw[1]);
@@ -2410,6 +2414,7 @@ void
spawn(const Arg *arg)
{
if (fork() == 0) {
+ setrlimit(RLIMIT_CORE, &oldrlimit);
dup2(STDERR_FILENO, STDOUT_FILENO);
setsid();
execvp(((char **)arg->v)[0], (char **)arg->v);
@@ -2928,6 +2933,10 @@ main(int argc, char *argv[])
char *startup_cmd = NULL;
int c;
+ getrlimit(RLIMIT_CORE, &oldrlimit);
+ newrlimit.rlim_cur = newrlimit.rlim_max = oldrlimit.rlim_max;
+ setrlimit(RLIMIT_CORE, &newrlimit);
+
while ((c = getopt(argc, argv, "s:hdv")) != -1) {
if (c == 's')
startup_cmd = optarg;
--
2.43.0
+11
View File
@@ -0,0 +1,11 @@
### Description
Adds ability to change cursor's theme and size.
### Download
- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.5/cursortheme)
- [2024-04-11](https://codeberg.org/dwl/dwl-patches/raw/commit/b828e21717fa584affeb3245359c3ab615759fa4/cursortheme/cursortheme.patch)
- [v0.5](https://codeberg.org/dwl/dwl-patches/raw/commit/c676de59d51e613bd52ac46c77a24b1cac9a61a1/cursortheme/cursortheme.patch)
### Authors
- [wochap](https://codeberg.org/wochap)
- [egorguslyan](https://github.com/egorguslyan)
+51
View File
@@ -0,0 +1,51 @@
From 55c22683c88c9816ceba6351a716fbe005555abd Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Thu, 11 Apr 2024 12:43:29 -0500
Subject: [PATCH] add ability to change cursor's theme and size
---
config.def.h | 2 ++
dwl.c | 6 ++++--
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/config.def.h b/config.def.h
index 8847e58..3189d48 100644
--- a/config.def.h
+++ b/config.def.h
@@ -13,6 +13,8 @@ static const float focuscolor[] = COLOR(0x005577ff);
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 char cursortheme[] = ""; /* theme from /usr/share/cursors/xorg-x11 */
+static const unsigned int cursorsize = 24;
/* tagging - TAGCOUNT must be no greater than 31 */
#define TAGCOUNT (9)
diff --git a/dwl.c b/dwl.c
index bf763df..961e2f1 100644
--- a/dwl.c
+++ b/dwl.c
@@ -2274,7 +2274,9 @@ setup(void)
int i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE};
struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig};
+ char cursorsize_str[3];
sigemptyset(&sa.sa_mask);
+ sprintf(cursorsize_str, "%d", cursorsize);
for (i = 0; i < (int)LENGTH(sig); i++)
sigaction(sig[i], &sa, NULL);
@@ -2412,8 +2414,8 @@ setup(void)
* Xcursor themes to source cursor images from and makes sure that cursor
* images are available at all scale factors on the screen (necessary for
* HiDPI support). Scaled cursors will be loaded with each output. */
- cursor_mgr = wlr_xcursor_manager_create(NULL, 24);
- setenv("XCURSOR_SIZE", "24", 1);
+ cursor_mgr = wlr_xcursor_manager_create(cursortheme, cursorsize);
+ setenv("XCURSOR_SIZE", cursorsize_str, 1);
/*
* wlr_cursor *only* displays an image on screen. It does not move around
--
2.43.2
+23
View File
@@ -0,0 +1,23 @@
### Description
Rules for floating windows support default x, y, width, height. Defaults to the center of the screen and the client size.
If the width or height is less than or equal to 1, then the value will be interpreted as a percentage. For example, 0.5 represents 50%, 0.25 represents 25%, and 1 represents 100%. **NOTE**: Some clients, like Thunar, have minimum width/height
The variable `center_relative_to_monitor` allows the user to choose whether to center relative to the monitor or relative to the window area.
<details>
<summary>Explanation of center_relative_to_monitor:</summary>
<pre>
The "Monitor area" refers to the space enclosed by the green rectangle, while the "Window area" refers to the space enclosed by the red rectangle.
<img src="https://i.imgur.com/xhejzPh.png"/>
</pre>
</details>
### Download
- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.5/customfloat)
- [2024-04-11](https://codeberg.org/dwl/dwl-patches/raw/commit/98cba933c9f4099202e54f39acbf17e05bde828a/customfloat/customfloat.patch)
- [v0.5](https://codeberg.org/dwl/dwl-patches/raw/commit/bf098459219e7a473d8edb4c0435aeb6a4b82e38/customfloat/customfloat.patch)
### Authors
- [wochap](https://codeberg.org/wochap)
- [Stivvo](https://github.com/Stivvo)
+77
View File
@@ -0,0 +1,77 @@
From ff29aba2f45d5acdee66efaf7cf94ab66145c0ed Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Thu, 11 Apr 2024 14:19:24 -0500
Subject: [PATCH] rules for floating windows support default x, y, width,
height If the width or height is less than or equal to 1, then the value will
be interpreted as a percentage. For example, 0.5 represents 50%, 0.25
represents 25%, and 1 represents 100%. NOTE: Some clients, like Thunar, have
minimum width/height
`floating_relative_to_monitor` allows the user to choose whether to position relative to the monitor or relative to the window area.
---
config.def.h | 7 ++++---
dwl.c | 16 ++++++++++++++++
2 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/config.def.h b/config.def.h
index 8847e58..ebaf1ab 100644
--- a/config.def.h
+++ b/config.def.h
@@ -13,6 +13,7 @@ static const float focuscolor[] = COLOR(0x005577ff);
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 int floating_relative_to_monitor = 0; /* 0 means center floating relative to the window area */
/* tagging - TAGCOUNT must be no greater than 31 */
#define TAGCOUNT (9)
@@ -21,10 +22,10 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
static int log_level = WLR_ERROR;
static const Rule rules[] = {
- /* app_id title tags mask isfloating monitor */
+ /* app_id title tags mask isfloating monitor x y width height */
/* 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" */
+ { "Gimp_EXAMPLE", NULL, 0, 1, -1, 0, 0, 1000, 0.75 }, /* Start on currently visible tags floating, not tiled */
+ { "firefox_EXAMPLE", NULL, 1 << 8, 0, -1, 0, 0, 0, 0 },/* Start on ONLY tag "9" */
};
/* layout(s) */
diff --git a/dwl.c b/dwl.c
index bf763df..94e4d7d 100644
--- a/dwl.c
+++ b/dwl.c
@@ -228,6 +228,10 @@ typedef struct {
uint32_t tags;
int isfloating;
int monitor;
+ int x;
+ int y;
+ float w;
+ float h;
} Rule;
typedef struct {
@@ -468,6 +472,18 @@ applyrules(Client *c)
if (r->monitor == i++)
mon = m;
}
+ if (c->isfloating) {
+ struct wlr_box b = floating_relative_to_monitor ? mon->m : mon->w;
+ int newwidth = ROUND(r->w ? (r->w <= 1 ? b.width * r->w : r->w) : c->geom.width);
+ int newheight = ROUND(r->h ? (r->h <= 1 ? b.height * r->h : r->h) : c->geom.height);
+
+ resize(c, (struct wlr_box){
+ .x = r->x ? r->x + b.x : (b.width - newwidth) / 2 + b.x,
+ .y = r->y ? r->y + b.y : (b.height - newheight) / 2 + b.y,
+ .width = newwidth,
+ .height = newheight,
+ }, 1);
+ }
}
}
setmon(c, mon, newtags);
--
2.43.2
@@ -0,0 +1,18 @@
### Description
This patch adds the ability to define the modkey with a make argument like so:
```
make MODKEY=WLR_MODIFIER_ALT
make MODKEY=WLR_MODIFIER_LOGO
make MODKEY=WLR_MODIFIER_CTRL
make MODKEY=WLR_MODIFIER_SHIFT
```
It can be used to compile multiple times quickly, you can also have a main session and sub session with different modkeys.
### Download
- [git branch](https://codeberg.org/Abanoub/dwl/src/branch/define-modkey-patch)
- [2024-02-14](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/define-modkey-with-make-argument/define-modkey-with-make-argument.patch)
### Authors
- [Abanoub](https://codeberg.org/Abanoub)
@@ -0,0 +1,49 @@
From ec6a6a4fe56ef5bdf45633966345f0d0338776d5 Mon Sep 17 00:00:00 2001
From: Abanoub <abanoubsameh@protonmail.com>
Date: Fri, 19 Jan 2024 21:42:42 +0200
Subject: [PATCH] Add the ability to define a MODKEY as a make argument
---
Makefile | 6 +++++-
config.def.h | 4 +++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index 0822ddc..d169a97 100644
--- a/Makefile
+++ b/Makefile
@@ -13,6 +13,10 @@ PKGS = wlroots wayland-server xkbcommon libinput $(XLIBS)
DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS)
LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS)
+ifneq ($(MODKEY),)
+MODKEYVAL = -DMODKEY=$(MODKEY)
+endif
+
all: dwl
dwl: dwl.o util.o
$(CC) dwl.o util.o $(LDLIBS) $(LDFLAGS) $(DWLCFLAGS) -o $@
@@ -63,4 +67,4 @@ uninstall:
.SUFFIXES: .c .o
.c.o:
- $(CC) $(CPPFLAGS) $(DWLCFLAGS) -c $<
+ $(CC) $(CPPFLAGS) $(DWLCFLAGS) $(MODKEYVAL) -c $<
diff --git a/config.def.h b/config.def.h
index 9009517..b1e53cd 100644
--- a/config.def.h
+++ b/config.def.h
@@ -102,7 +102,9 @@ 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;
/* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */
-#define MODKEY WLR_MODIFIER_ALT
+#ifndef MODKEY
+# define MODKEY WLR_MODIFIER_ALT
+#endif
#define TAGKEYS(KEY,SKEY,TAG) \
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
--
2.43.0
+11
View File
@@ -0,0 +1,11 @@
### Description
Implements dimming of clients which are unfocused.
The code also allows you to "dim" focused windows if you wish to, and as such allows any color dimming. There is also an additional option in Rule, which allows you to keep the client `alwaysbright`, that is, as if it is focused.
### Download
- [2024-04-16](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/dim-unfocused/dim-unfocused.patch)
- [git branch](https://codeberg.org/dhruva_sambrani/dwl/src/branch/dim-unfocused)
### Authors
- [Dhruva Sambrani](https://codeberg.org/dhruva_sambrani)
+177
View File
@@ -0,0 +1,177 @@
diff --git a/client.h b/client.h
index 800b867..4d83248 100644
--- a/client.h
+++ b/client.h
@@ -332,6 +332,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 8847e58..36ac2a1 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 */
@@ -21,10 +22,11 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
static int log_level = WLR_ERROR;
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) */
@@ -135,8 +137,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} },
diff --git a/dwl.c b/dwl.c
index bf763df..abd7112 100644
--- a/dwl.c
+++ b/dwl.c
@@ -109,6 +109,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;
@@ -137,7 +138,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;
@@ -227,6 +228,7 @@ typedef struct {
const char *title;
uint32_t tags;
int isfloating;
+ int neverdim;
int monitor;
} Rule;
@@ -330,6 +332,7 @@ 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 togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg);
static void toggletag(const Arg *arg);
@@ -404,6 +407,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);
@@ -462,6 +466,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) {
@@ -1267,8 +1272,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 */
@@ -1286,7 +1293,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);
}
}
@@ -1599,6 +1606,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;
@@ -2040,7 +2051,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);
@@ -2050,6 +2061,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, c-> geom.height);
+ wlr_scene_node_set_position(&c->dimmer->node, 0, 0);
/* this is a no-op if size hasn't changed */
c->resize = client_set_size(c, c->geom.width - 2 * c->bw,
@@ -2603,6 +2616,17 @@ 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);
+ }
+ client_set_dimmer_state(focustop(selmon), 0);
+}
+
void
togglefloating(const Arg *arg)
{
+9
View File
@@ -0,0 +1,9 @@
### Description
Change mfact by dragging the mouse.
### Download
- [git branch](https://codeberg.org/Palanix/dwl/src/branch/dragmfact)
- [2024-02-16](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/dragmfact/dragmfact.patch)
### Authors
- [Palanix](https://codeberg.org/Palanix)
+59
View File
@@ -0,0 +1,59 @@
From 435cdf673e5a8080123109dbf874aac2ccef1498 Mon Sep 17 00:00:00 2001
From: Palanix <palanixyt@gmail.com>
Date: Fri, 25 Mar 2022 23:45:10 +0100
Subject: [PATCH] Change mfact using Middle mouse
---
config.def.h | 2 +-
dwl.c | 9 ++++++++-
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/config.def.h b/config.def.h
index 9009517..3c26522 100644
--- a/config.def.h
+++ b/config.def.h
@@ -166,6 +166,6 @@ static const Key keys[] = {
static const Button buttons[] = {
{ MODKEY, BTN_LEFT, moveresize, {.ui = CurMove} },
- { MODKEY, BTN_MIDDLE, togglefloating, {0} },
+ { MODKEY, BTN_MIDDLE, moveresize, {.ui = Curmfact} },
{ MODKEY, BTN_RIGHT, moveresize, {.ui = CurResize} },
};
diff --git a/dwl.c b/dwl.c
index fa76db2..528e102 100644
--- a/dwl.c
+++ b/dwl.c
@@ -76,7 +76,7 @@
#define LISTEN_STATIC(E, H) do { static struct wl_listener _l = {.notify = (H)}; wl_signal_add((E), &_l); } while (0)
/* enums */
-enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */
+enum { CurNormal, CurPressed, CurMove, CurResize, Curmfact }; /* cursor */
enum { XDGShell, LayerShell, X11 }; /* client types */
enum { LyrBg, LyrBottom, LyrTile, LyrFloat, LyrFS, LyrTop, LyrOverlay, LyrBlock, NUM_LAYERS }; /* scene layers */
#ifdef XWAYLAND
@@ -1639,6 +1639,9 @@ motionnotify(uint32_t time)
resize(grabc, (struct wlr_box){.x = grabc->geom.x, .y = grabc->geom.y,
.width = ROUND(cursor->x) - grabc->geom.x, .height = ROUND(cursor->y) - grabc->geom.y}, 1);
return;
+ } else if (cursor_mode == Curmfact && time) {
+ selmon->mfact = (float) (cursor->x / selmon->m.width);
+ arrange(selmon);
}
/* Find the client under the pointer and send the event along. */
@@ -1701,6 +1704,10 @@ moveresize(const Arg *arg)
grabc->geom.y + grabc->geom.height);
wlr_cursor_set_xcursor(cursor, cursor_mgr, "se-resize");
break;
+ case Curmfact:
+ setfloating(grabc, 0);
+ selmon->mfact = (float) (cursor->x / selmon->m.width);
+ arrange(selmon);
}
}
--
2.43.2
+11
View File
@@ -0,0 +1,11 @@
### Description
Always use the English keymap to get keycodes, so key bindings work even when using a non-English keyboard layout.
### Download
- [git branch](https://codeberg.org/ForzCross/dwl/src/branch/en-keycodes.patch)
- [2024-01-11](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/en-keycodes/en-keycodes.patch)
### Authors
- [ForzCross](https://codeberg.org/ForzCross)
- [Nikita Ivanov](https://github.com/NikitaIvanovV)
- [dimkr](https://codeberg.org/dimkr) (<dima@dimakrasner.com>)
+66
View File
@@ -0,0 +1,66 @@
From 19d52ef3f9814dd205e71c3ef31e41fd52cef515 Mon Sep 17 00:00:00 2001
From: ForzCross <forzcross@gmail.com>
Date: Wed, 10 Jan 2024 00:42:39 +0300
Subject: [PATCH] Always use the English keymap to get keycodes
---
dwl.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/dwl.c b/dwl.c
index 632dabf..858318a 100644
--- a/dwl.c
+++ b/dwl.c
@@ -384,6 +384,12 @@ static struct wlr_box sgeom;
static struct wl_list mons;
static Monitor *selmon;
+static const struct xkb_rule_names en_rules = {.layout = "us"};
+static struct xkb_context *en_context;
+static struct xkb_keymap *en_keymap;
+static struct xkb_state *en_state, *en_state_shift;
+static xkb_mod_index_t en_shift;
+
#ifdef XWAYLAND
static void activatex11(struct wl_listener *listener, void *data);
static void associatex11(struct wl_listener *listener, void *data);
@@ -647,6 +653,10 @@ cleanup(void)
wl_event_source_remove(vkb_group.key_repeat_source);
wl_display_destroy(dpy);
+ xkb_state_unref(en_state);
+ xkb_state_unref(en_state_shift);
+ xkb_keymap_unref(en_keymap);
+ xkb_context_unref(en_context);
/* Destroy after the wayland display (when the monitors are already destroyed)
to avoid destroying them with an invalid scene output. */
wlr_scene_node_destroy(&scene->tree.node);
@@ -1381,8 +1391,10 @@ keypress(struct wl_listener *listener, void *data)
uint32_t keycode = event->keycode + 8;
/* Get a list of keysyms based on the keymap for this keyboard */
const xkb_keysym_t *syms;
+ int shift = xkb_state_mod_index_is_active(
+ group->wlr_group->keyboard.xkb_state, en_shift, XKB_STATE_MODS_EFFECTIVE);
int nsyms = xkb_state_key_get_syms(
- group->wlr_group->keyboard.xkb_state, keycode, &syms);
+ shift ? en_state_shift : en_state, keycode, &syms);
int handled = 0;
uint32_t mods = wlr_keyboard_get_modifiers(&group->wlr_group->keyboard);
@@ -2323,6 +2335,13 @@ setup(void)
* pointer, touch, and drawing tablet device. We also rig up a listener to
* let us know when new input devices are available on the backend.
*/
+ en_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
+ en_keymap = xkb_keymap_new_from_names(en_context, &en_rules,
+ XKB_KEYMAP_COMPILE_NO_FLAGS);
+ en_state = xkb_state_new(en_keymap);
+ en_state_shift = xkb_state_new(en_keymap);
+ en_shift = xkb_keymap_mod_get_index(en_keymap, XKB_MOD_NAME_SHIFT);
+ xkb_state_update_mask(en_state_shift, 1 << en_shift, 0, 0, 0, 0, 0);
LISTEN_STATIC(&backend->events.new_input, inputdevice);
virtual_keyboard_mgr = wlr_virtual_keyboard_manager_v1_create(dpy);
LISTEN_STATIC(&virtual_keyboard_mgr->events.new_virtual_keyboard, virtualkeyboard);
--
2.43.0
+8
View File
@@ -0,0 +1,8 @@
### Description
Input device configuration (click method, tap-and-drag, acceleration, etc), border size and colors via environment variables.
### Download
- [2024-02-11](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/env/env.patch)
### Authors
- [Dima Krasner](https://codeberg.org/dimkr) (<dima@dimakrasner.com>)
+302
View File
@@ -0,0 +1,302 @@
From a822ac65306ca331b95b17ffe08147110c03c60d Mon Sep 17 00:00:00 2001
From: Dima Krasner <dima@dimakrasner.com>
Date: Sat, 30 Dec 2023 10:49:48 +0200
Subject: [PATCH] allow environment variables to override config.h
---
Makefile | 1 +
config.def.h | 10 +--
dwl.c | 5 ++
env.c | 217 +++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 228 insertions(+), 5 deletions(-)
create mode 100644 env.c
diff --git a/Makefile b/Makefile
index 0822ddc..fbdfdca 100644
--- a/Makefile
+++ b/Makefile
@@ -17,6 +17,7 @@ all: dwl
dwl: dwl.o util.o
$(CC) dwl.o util.o $(LDLIBS) $(LDFLAGS) $(DWLCFLAGS) -o $@
dwl.o: dwl.c config.mk config.h client.h cursor-shape-v1-protocol.h xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h
+dwl.o: env.c
util.o: util.c util.h
# wayland-scanner is a tool which generates C headers and rigging for Wayland
diff --git a/config.def.h b/config.def.h
index 9009517..c6b9ae0 100644
--- a/config.def.h
+++ b/config.def.h
@@ -6,11 +6,11 @@
/* appearance */
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 */
-static const float rootcolor[] = COLOR(0x222222ff);
-static const float bordercolor[] = COLOR(0x444444ff);
-static const float focuscolor[] = COLOR(0x005577ff);
-static const float urgentcolor[] = COLOR(0xff0000ff);
+static unsigned int borderpx = 1; /* border pixel of windows */
+static float rootcolor[] = COLOR(0x222222ff);
+static float bordercolor[] = COLOR(0x444444ff);
+static float focuscolor[] = COLOR(0x005577ff);
+static 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.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */
diff --git a/dwl.c b/dwl.c
index fa76db2..6dd4524 100644
--- a/dwl.c
+++ b/dwl.c
@@ -407,6 +407,8 @@ static xcb_atom_t netatom[NetLast];
/* attempt to encapsulate suck into one file */
#include "client.h"
+#include "env.c"
+
/* function implementations */
void
applybounds(Client *c, struct wlr_box *bbox)
@@ -1010,6 +1012,8 @@ createpointer(struct wlr_pointer *pointer)
libinput_device_config_accel_set_profile(device, accel_profile);
libinput_device_config_accel_set_speed(device, accel_speed);
}
+
+ inputconfig(device);
}
wlr_cursor_attach_input_device(cursor, &pointer->base);
@@ -2974,6 +2978,7 @@ main(int argc, char *argv[])
/* Wayland requires XDG_RUNTIME_DIR for creating its communications socket */
if (!getenv("XDG_RUNTIME_DIR"))
die("XDG_RUNTIME_DIR must be set");
+ loadtheme();
setup();
run(startup_cmd);
cleanup();
diff --git a/env.c b/env.c
new file mode 100644
index 0000000..618f81e
--- /dev/null
+++ b/env.c
@@ -0,0 +1,217 @@
+static int
+isenabled(const char *val, int def)
+{
+ return ((def && (!val || !val[0] || (val[0] != '0'))) || (!def && (val && val[0] && (val[0] != '0'))));
+}
+
+static void
+setclickmethod(struct libinput_device *libinput_device)
+{
+ const char *val;
+ long l;
+ char *end = NULL;
+
+ val = getenv("LIBINPUT_DEFAULT_CLICK_METHOD");
+ if (!val || !val[0])
+ return;
+
+ errno = 0;
+ l = strtol(val, &end, 10);
+ if (errno || (end && *end))
+ return;
+
+ libinput_device_config_click_set_method(libinput_device,
+ (enum libinput_config_click_method)l);
+}
+
+static void
+settap(struct libinput_device *libinput_device)
+{
+ const char *val;
+
+ val = getenv("LIBINPUT_DEFAULT_TAP");
+ if (val) {
+ if (!val[0])
+ return;
+
+ libinput_device_config_tap_set_enabled(libinput_device,
+ isenabled(val, 1) ? LIBINPUT_CONFIG_TAP_ENABLED :
+ LIBINPUT_CONFIG_TAP_DISABLED);
+ } else if (tap_to_click && libinput_device_config_tap_get_finger_count(libinput_device))
+ libinput_device_config_tap_set_enabled(libinput_device,
+ LIBINPUT_CONFIG_TAP_ENABLED);
+}
+
+static void
+settapanddrag(struct libinput_device *libinput_device)
+{
+ const char *val;
+
+ val = getenv("LIBINPUT_DEFAULT_DRAG");
+ if (val && val[0])
+ libinput_device_config_tap_set_drag_enabled(libinput_device,
+ isenabled(val, 1) ? LIBINPUT_CONFIG_DRAG_ENABLED :
+ LIBINPUT_CONFIG_DRAG_DISABLED);
+}
+
+static void
+setnaturalscroll(struct libinput_device *libinput_device)
+{
+ const char *val;
+
+ val = getenv("LIBINPUT_DEFAULT_NATURAL_SCROLL");
+ if (val && val[0])
+ libinput_device_config_scroll_set_natural_scroll_enabled(
+ libinput_device, isenabled(val, 0));
+ else if (!val && libinput_device_config_scroll_has_natural_scroll(libinput_device))
+ libinput_device_config_scroll_set_natural_scroll_enabled(
+ libinput_device, natural_scrolling);
+}
+
+static void
+setaccelprofile(struct libinput_device *libinput_device)
+{
+ const char *val;
+ double profile;
+ char *end = NULL;
+
+ val = getenv("LIBINPUT_DEFAULT_ACCELERATION_PROFILE");
+ if (!val || !val[0])
+ return;
+
+ errno = 0;
+ profile = strtod(val, &end);
+ if (errno || (end && *end))
+ return;
+
+ libinput_device_config_accel_set_profile(libinput_device,
+ (enum libinput_config_accel_profile)profile);
+}
+
+static void
+setaccelspeed(struct libinput_device *libinput_device)
+{
+ const char *val;
+ double accel = 0;
+ char *end = NULL;
+
+ val = getenv("LIBINPUT_DEFAULT_ACCELERATION");
+ if (!val || !val[0])
+ return;
+
+ errno = 0;
+ accel = strtod(val, &end);
+ if (errno || (end && *end) || (accel < -1) || (accel > 1))
+ return;
+
+ libinput_device_config_accel_set_speed(libinput_device, accel);
+}
+
+static void
+setscrollmethod(struct libinput_device *libinput_device)
+{
+ const char *val;
+ long l;
+ char *end = NULL;
+
+ val = getenv("LIBINPUT_DEFAULT_SCROLL_METHOD");
+ if (!val || !val[0])
+ return;
+
+ errno = 0;
+ l = strtol(val, &end, 10);
+ if (errno || (end && *end))
+ return;
+
+ libinput_device_config_scroll_set_method(libinput_device,
+ (enum libinput_config_scroll_method)l);
+}
+
+static void
+setdwt(struct libinput_device *libinput_device)
+{
+ const char *val;
+
+ val = getenv("LIBINPUT_DEFAULT_DISABLE_WHILE_TYPING");
+ if (val && val[0])
+ libinput_device_config_dwt_set_enabled(libinput_device,
+ isenabled(val, false) ? LIBINPUT_CONFIG_DWT_ENABLED :
+ LIBINPUT_CONFIG_DWT_DISABLED);
+}
+
+static void
+setmiddleemul(struct libinput_device *libinput_device)
+{
+ const char *val;
+
+ val = getenv("LIBINPUT_DEFAULT_MIDDLE_EMULATION");
+ if (val && val[0])
+ libinput_device_config_middle_emulation_set_enabled(libinput_device,
+ isenabled(val, false) ? LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED :
+ LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
+}
+
+static void
+setlefthanded(struct libinput_device *libinput_device)
+{
+ const char *val;
+
+ val = getenv("LIBINPUT_DEFAULT_LEFT_HANDED");
+ if (val && val[0])
+ libinput_device_config_left_handed_set(libinput_device,
+ isenabled(val, 0));
+}
+
+static void
+inputconfig(struct libinput_device *libinput_device)
+{
+ setclickmethod(libinput_device);
+ settap(libinput_device);
+ settapanddrag(libinput_device);
+ setnaturalscroll(libinput_device);
+ setaccelprofile(libinput_device);
+ setaccelspeed(libinput_device);
+ setscrollmethod(libinput_device);
+ setdwt(libinput_device);
+ setmiddleemul(libinput_device);
+ setlefthanded(libinput_device);
+}
+
+static void
+parsecolor(const char *val, float color[4])
+{
+ uint8_t r, g, b;
+ if (sscanf(val, "#%02hhx%02hhx%02hhx", &r, &g, &b) == 3) {
+ color[0] = (float)r / 0xFF;
+ color[1] = (float)g / 0xFF;
+ color[2] = (float)b / 0xFF;
+ color[3] = 1.0;
+ }
+}
+
+static void
+loadtheme(void)
+{
+ const char *val;
+ unsigned int tmp;
+
+ val = getenv("DWL_ROOT_COLOR");
+ if (val)
+ parsecolor(val, rootcolor);
+
+ val = getenv("DWL_BORDER_COLOR");
+ if (val)
+ parsecolor(val, bordercolor);
+
+ val = getenv("DWL_FOCUS_COLOR");
+ if (val)
+ parsecolor(val, focuscolor);
+
+ val = getenv("DWL_URGENT_COLOR");
+ if (val)
+ parsecolor(val, urgentcolor);
+
+ val = getenv("DWL_BORDER");
+ if (val && sscanf(val, "%u", &tmp) == 1)
+ borderpx = tmp;
+}
--
2.43.0
+8
View File
@@ -0,0 +1,8 @@
### Description
Allow setting fake fullscreen per client
### Download
- [git branch](https://codeberg.org/notchoc/dwl/src/branch/fakefullscreenclient)
- [2024-03-29](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/fakefullscreenclient/fakefullscreenclient.patch)
### Authors
- [notchoc](https://codeberg.org/notchoc)
@@ -0,0 +1,87 @@
From 2ec6d0c668b4daee601337f8da45ccfa3a7d5fc6 Mon Sep 17 00:00:00 2001
From: choc <notchoc@proton.me>
Date: Fri, 29 Mar 2024 22:50:00 +0800
Subject: [PATCH] implement fakefullscreenclient
---
config.def.h | 1 +
dwl.c | 23 ++++++++++++++++++++++-
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/config.def.h b/config.def.h
index 9009517..8c220eb 100644
--- a/config.def.h
+++ b/config.def.h
@@ -137,6 +137,7 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_space, setlayout, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_E, togglefakefullscreen, {0} },
{ MODKEY, XKB_KEY_0, view, {.ui = ~0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} },
{ MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} },
diff --git a/dwl.c b/dwl.c
index 5867b0c..1e78491 100644
--- a/dwl.c
+++ b/dwl.c
@@ -137,7 +137,7 @@ typedef struct {
#endif
unsigned int bw;
uint32_t tags;
- int isfloating, isurgent, isfullscreen;
+ int isfloating, isurgent, isfullscreen, isfakefullscreen;
uint32_t resize; /* configure serial of a pending resize */
} Client;
@@ -318,6 +318,7 @@ static void setcursor(struct wl_listener *listener, void *data);
static void setcursorshape(struct wl_listener *listener, void *data);
static void setfloating(Client *c, int floating);
static void setfullscreen(Client *c, int fullscreen);
+static void setfakefullscreen(Client *c, int fullscreen);
static void setgamma(struct wl_listener *listener, void *data);
static void setlayout(const Arg *arg);
static void setmfact(const Arg *arg);
@@ -332,6 +333,7 @@ static void tagmon(const Arg *arg);
static void tile(Monitor *m);
static void togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg);
+static void togglefakefullscreen(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unlocksession(struct wl_listener *listener, void *data);
@@ -2181,6 +2183,17 @@ setfullscreen(Client *c, int fullscreen)
printstatus();
}
+void
+setfakefullscreen(Client *c, int fullscreen)
+{
+ c->isfakefullscreen = fullscreen;
+ if (!c->mon)
+ return;
+ if (c->isfullscreen)
+ setfullscreen(c, 0);
+ client_set_fullscreen(c, fullscreen);
+}
+
void
setgamma(struct wl_listener *listener, void *data)
{
@@ -2620,6 +2633,14 @@ togglefullscreen(const Arg *arg)
setfullscreen(sel, !sel->isfullscreen);
}
+void
+togglefakefullscreen(const Arg *arg)
+{
+ Client *sel = focustop(selmon);
+ if (sel)
+ setfakefullscreen(sel, !sel->isfakefullscreen);
+}
+
void
toggletag(const Arg *arg)
{
--
2.44.0
+8
View File
@@ -0,0 +1,8 @@
### Description
Tries a different display mode if the preferred mode doesn't work.
### Download
- [2024-02-11](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/fallback/fallback.patch)
### Authors
- [Dima Krasner](https://codeberg.org/dimkr) (<dima@dimakrasner.com>)
+44
View File
@@ -0,0 +1,44 @@
From 830f6ed5352d32a66c62f49b28439b2bcd904417 Mon Sep 17 00:00:00 2001
From: Dima Krasner <dima@dimakrasner.com>
Date: Sat, 2 Dec 2023 10:36:35 +0200
Subject: [PATCH] fall back to a lower output mode if needed
(swaywm/sway@4cdc4ac)
---
dwl.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/dwl.c b/dwl.c
index fa76db2..88cabeb 100644
--- a/dwl.c
+++ b/dwl.c
@@ -848,6 +848,7 @@ createmon(struct wl_listener *listener, void *data)
/* This event is raised by the backend when a new output (aka a display or
* monitor) becomes available. */
struct wlr_output *wlr_output = data;
+ struct wlr_output_mode *preferred_mode, *mode;
const MonitorRule *r;
size_t i;
struct wlr_output_state state;
@@ -884,7 +885,17 @@ createmon(struct wl_listener *listener, void *data)
* monitor supports only a specific set of modes. We just pick the
* monitor's preferred mode; a more sophisticated compositor would let
* the user configure it. */
- wlr_output_state_set_mode(&state, wlr_output_preferred_mode(wlr_output));
+ preferred_mode = wlr_output_preferred_mode(wlr_output);
+ wlr_output_state_set_mode(&state, preferred_mode);
+ if (!wlr_output_test_state(wlr_output, &state) && !wl_list_empty(&wlr_output->modes)) {
+ wl_list_for_each(mode, &wlr_output->modes, link) {
+ if (mode != preferred_mode) {
+ wlr_output_state_set_mode(&state, mode);
+ if (wlr_output_test_state(wlr_output, &state))
+ break;
+ }
+ }
+ }
/* Set up event listeners */
LISTEN(&wlr_output->events.frame, &m->frame, rendermon);
--
2.43.0
+9
View File
@@ -0,0 +1,9 @@
### Description
Focus the window to the left, right, above or below the current focused window
### Download
- [git branch](https://codeberg.org/ldev105/dwl/src/branch/focusdir)
- [2023-01-22](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/focusdir/focusdir.patch)
### Authors
- [ldev105](https://codeberg.org/ldev105)
+98
View File
@@ -0,0 +1,98 @@
From a0e71a687b7fcaebdaf1da80c09bf5563bff46b1 Mon Sep 17 00:00:00 2001
From: ldev <ldev@ldev.eu.org>
Date: Mon, 12 Feb 2024 21:50:24 +0100
Subject: [PATCH] focusdir
---
config.def.h | 4 ++++
dwl.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 49 insertions(+)
diff --git a/config.def.h b/config.def.h
index 9009517..2a1a82e 100644
--- a/config.def.h
+++ b/config.def.h
@@ -124,6 +124,10 @@ 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_h, focusdir, {.ui = 0} },
+ { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_l, focusdir, {.ui = 1} },
+ { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_k, focusdir, {.ui = 2} },
+ { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_j, focusdir, {.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 bf02a6d..64d5de7 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1,6 +1,7 @@
/*
* See LICENSE file for copyright and license details.
*/
+#include <limits.h>
#include <getopt.h>
#include <libinput.h>
#include <linux/input-event-codes.h>
@@ -268,6 +269,7 @@ static Monitor *dirtomon(enum wlr_direction dir);
static void focusclient(Client *c, int lift);
static void focusmon(const Arg *arg);
static void focusstack(const Arg *arg);
+static void focusdir(const Arg *arg);
static Client *focustop(Monitor *m);
static void fullscreennotify(struct wl_listener *listener, void *data);
static void handlesig(int signo);
@@ -1271,6 +1273,49 @@ focusstack(const Arg *arg)
focusclient(c, 1);
}
+void focusdir(const Arg *arg)
+{
+ /* Focus the left, right, up, down client relative to the current focused client on selmon */
+ Client *c, *sel = focustop(selmon);
+ if (!sel || sel->isfullscreen)
+ return;
+
+ int dist=INT_MAX;
+ Client *newsel = NULL;
+ int newdist=INT_MAX;
+ wl_list_for_each(c, &clients, link) {
+ if (!VISIBLEON(c, selmon))
+ continue; /* skip non visible windows */
+
+ if (arg->ui == 0 && sel->geom.x <= c->geom.x) {
+ /* Client isn't on our left */
+ continue;
+ }
+ if (arg->ui == 1 && sel->geom.x >= c->geom.x) {
+ /* Client isn't on our right */
+ continue;
+ }
+ if (arg->ui == 2 && sel->geom.y <= c->geom.y) {
+ /* Client isn't above us */
+ continue;
+ }
+ if (arg->ui == 3 && sel->geom.y >= c->geom.y) {
+ /* Client isn't below us */
+ continue;
+ }
+
+ dist=abs(sel->geom.x-c->geom.x)+abs(sel->geom.y-c->geom.y);
+ if (dist < newdist){
+ newdist = dist;
+ newsel=c;
+ }
+ }
+ if (newsel != NULL){
+ focusclient(newsel, 1);
+ }
+}
+
+
/* We probably should change the name of this, it sounds like
* will focus the topmost client of this mon, when actually will
* only return that client */
--
2.43.0
@@ -0,0 +1,9 @@
### Description
Implement `foreign-toplevel-management`, it add handlers for activate, close, fullscreen and destroy request events, it's missing minimize and maximize request handlers.
### Download
- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.6-a/foreign-toplevel-management)
- [2024-05-02](https://codeberg.org/dwl/dwl-patches/raw/commit/e58c3ec41a39df934d2998161d7187ac965ea77a/foreign-toplevel-management/foreign-toplevel-management.patch)
### Authors
- [wochap](https://codeberg.org/wochap)
@@ -0,0 +1,507 @@
From dc63d64cd69f515013464b3feb8acb411f5a348f Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Thu, 2 May 2024 17:25:45 -0500
Subject: [PATCH] implement foreign toplevel management
---
Makefile | 5 +-
dwl.c | 93 +++++-
...oreign-toplevel-management-unstable-v1.xml | 270 ++++++++++++++++++
3 files changed, 366 insertions(+), 2 deletions(-)
create mode 100644 protocols/wlr-foreign-toplevel-management-unstable-v1.xml
diff --git a/Makefile b/Makefile
index a67fdd3..e0e1260 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@ LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS)
all: dwl
dwl: dwl.o util.o
$(CC) dwl.o util.o $(LDLIBS) $(LDFLAGS) $(DWLCFLAGS) -o $@
-dwl.o: dwl.c config.mk config.h client.h cursor-shape-v1-protocol.h pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h xdg-shell-protocol.h
+dwl.o: dwl.c config.mk config.h client.h cursor-shape-v1-protocol.h pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h xdg-shell-protocol.h wlr-foreign-toplevel-management-unstable-v1-protocol.h
util.o: util.c util.h
# wayland-scanner is a tool which generates C headers and rigging for Wayland
@@ -37,6 +37,9 @@ wlr-layer-shell-unstable-v1-protocol.h:
xdg-shell-protocol.h:
$(WAYLAND_SCANNER) server-header \
$(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@
+wlr-foreign-toplevel-management-unstable-v1-protocol.h:
+ $(WAYLAND_SCANNER) server-header \
+ protocols/wlr-foreign-toplevel-management-unstable-v1.xml $@
config.h:
cp config.def.h $@
diff --git a/dwl.c b/dwl.c
index bf763df..648616d 100644
--- a/dwl.c
+++ b/dwl.c
@@ -22,6 +22,7 @@
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_drm.h>
#include <wlr/types/wlr_export_dmabuf_v1.h>
+#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
#include <wlr/types/wlr_fractional_scale_v1.h>
#include <wlr/types/wlr_gamma_control_v1.h>
#include <wlr/types/wlr_idle_inhibit_v1.h>
@@ -126,6 +127,11 @@ typedef struct {
struct wl_listener fullscreen;
struct wl_listener set_decoration_mode;
struct wl_listener destroy_decoration;
+ struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel;
+ struct wl_listener factivate;
+ struct wl_listener fclose;
+ struct wl_listener ffullscreen;
+ struct wl_listener fdestroy;
struct wlr_box prev; /* layout-relative, includes border */
struct wlr_box bounds;
#ifdef XWAYLAND
@@ -347,6 +353,11 @@ 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 createforeigntoplevel(Client *c);
+static void factivatenotify(struct wl_listener *listener, void *data);
+static void fclosenotify(struct wl_listener *listener, void *data);
+static void fdestroynotify(struct wl_listener *listener, void *data);
+static void ffullscreennotify(struct wl_listener *listener, void *data);
/* variables */
static const char broken[] = "broken";
@@ -392,6 +403,8 @@ static struct wlr_scene_rect *locked_bg;
static struct wlr_session_lock_v1 *cur_lock;
static struct wl_listener lock_listener = {.notify = locksession};
+static struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_mgr;
+
static struct wlr_seat *seat;
static KeyboardGroup kb_group = {0};
static KeyboardGroup vkb_group = {0};
@@ -458,6 +471,11 @@ applyrules(Client *c)
if (!(title = client_get_title(c)))
title = broken;
+ if (c->foreign_toplevel) {
+ wlr_foreign_toplevel_handle_v1_set_app_id(c->foreign_toplevel, appid);
+ wlr_foreign_toplevel_handle_v1_set_title(c->foreign_toplevel, title);
+ }
+
for (r = rules; r < END(rules); r++) {
if ((!r->title || strstr(title, r->title))
&& (!r->id || strstr(appid, r->id))) {
@@ -1288,6 +1306,8 @@ focusclient(Client *c, int lift)
client_set_border_color(old_c, bordercolor);
client_activate_surface(old, 0);
+ if (old_c->foreign_toplevel)
+ wlr_foreign_toplevel_handle_v1_set_activated(old_c->foreign_toplevel, 0);
}
}
printstatus();
@@ -1306,6 +1326,8 @@ focusclient(Client *c, int lift)
/* Activate the new client */
client_activate_surface(client_surface(c), 1);
+ if (c->foreign_toplevel)
+ wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, 1);
}
void
@@ -1599,6 +1621,8 @@ mapnotify(struct wl_listener *listener, void *data)
c->border[i]->node.data = c;
}
+ createforeigntoplevel(c);
+
/* 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;
@@ -2232,12 +2256,17 @@ setmon(Client *c, Monitor *m, uint32_t newtags)
c->prev = c->geom;
/* Scene graph sends surface leave/enter events on move and resize */
- if (oldmon)
+ if (oldmon) {
+ if (c->foreign_toplevel)
+ wlr_foreign_toplevel_handle_v1_output_leave(c->foreign_toplevel, oldmon->wlr_output);
arrange(oldmon);
+ }
if (m) {
/* Make sure window actually overlaps with the monitor */
resize(c, c->geom, 0);
c->tags = newtags ? newtags : m->tagset[m->seltags]; /* assign tags of target monitor */
+ if (c->foreign_toplevel)
+ wlr_foreign_toplevel_handle_v1_output_enter(c->foreign_toplevel, m->wlr_output);
setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */
setfloating(c, c->isfloating);
}
@@ -2351,6 +2380,9 @@ setup(void)
gamma_control_mgr = wlr_gamma_control_manager_v1_create(dpy);
LISTEN_STATIC(&gamma_control_mgr->events.set_gamma, setgamma);
+ /* Initializes foreign toplevel management */
+ foreign_toplevel_mgr = wlr_foreign_toplevel_manager_v1_create(dpy);
+
/* Creates an output layout, which a wlroots utility for working with an
* arrangement of screens in a physical layout. */
output_layout = wlr_output_layout_create();
@@ -2691,6 +2723,11 @@ unmapnotify(struct wl_listener *listener, void *data)
wl_list_remove(&c->flink);
}
+ if (c->foreign_toplevel) {
+ wlr_foreign_toplevel_handle_v1_destroy(c->foreign_toplevel);
+ c->foreign_toplevel = NULL;
+ }
+
wlr_scene_node_destroy(&c->scene->node);
printstatus();
motionnotify(0, NULL, 0, 0, 0, 0);
@@ -2802,6 +2839,12 @@ void
updatetitle(struct wl_listener *listener, void *data)
{
Client *c = wl_container_of(listener, c, set_title);
+ if (c->foreign_toplevel) {
+ const char *title;
+ if (!(title = client_get_title(c)))
+ title = broken;
+ wlr_foreign_toplevel_handle_v1_set_title(c->foreign_toplevel, title);
+ }
if (c == focustop(c->mon))
printstatus();
}
@@ -2929,6 +2972,54 @@ zoom(const Arg *arg)
arrange(selmon);
}
+void
+createforeigntoplevel(Client *c)
+{
+ c->foreign_toplevel = wlr_foreign_toplevel_handle_v1_create(foreign_toplevel_mgr);
+
+ LISTEN(&c->foreign_toplevel->events.request_activate, &c->factivate, factivatenotify);
+ LISTEN(&c->foreign_toplevel->events.request_close, &c->fclose, fclosenotify);
+ LISTEN(&c->foreign_toplevel->events.request_fullscreen, &c->ffullscreen, ffullscreennotify);
+ LISTEN(&c->foreign_toplevel->events.destroy, &c->fdestroy, fdestroynotify);
+}
+
+void
+factivatenotify(struct wl_listener *listener, void *data)
+{
+ Client *c = wl_container_of(listener, c, factivate);
+ if (c->mon == selmon) {
+ c->tags = c->mon->tagset[c->mon->seltags];
+ } else {
+ setmon(c, selmon, 0);
+ }
+ focusclient(c, 1);
+ arrange(c->mon);
+}
+
+void
+fclosenotify(struct wl_listener *listener, void *data)
+{
+ Client *c = wl_container_of(listener, c, fclose);
+ client_send_close(c);
+}
+
+void
+ffullscreennotify(struct wl_listener *listener, void *data) {
+ Client *c = wl_container_of(listener, c, ffullscreen);
+ struct wlr_foreign_toplevel_handle_v1_fullscreen_event *event = data;
+ setfullscreen(c, event->fullscreen);
+}
+
+void
+fdestroynotify(struct wl_listener *listener, void *data)
+{
+ Client *c = wl_container_of(listener, c, fdestroy);
+ wl_list_remove(&c->factivate.link);
+ wl_list_remove(&c->fclose.link);
+ wl_list_remove(&c->ffullscreen.link);
+ wl_list_remove(&c->fdestroy.link);
+}
+
#ifdef XWAYLAND
void
activatex11(struct wl_listener *listener, void *data)
diff --git a/protocols/wlr-foreign-toplevel-management-unstable-v1.xml b/protocols/wlr-foreign-toplevel-management-unstable-v1.xml
new file mode 100644
index 0000000..44505bb
--- /dev/null
+++ b/protocols/wlr-foreign-toplevel-management-unstable-v1.xml
@@ -0,0 +1,270 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="wlr_foreign_toplevel_management_unstable_v1">
+ <copyright>
+ Copyright © 2018 Ilia Bozhinov
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that copyright notice and this permission
+ notice appear in supporting documentation, and that the name of
+ the copyright holders not be used in advertising or publicity
+ pertaining to distribution of the software without specific,
+ written prior permission. The copyright holders make no
+ representations about the suitability of this software for any
+ purpose. It is provided "as is" without express or implied
+ warranty.
+
+ THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ THIS SOFTWARE.
+ </copyright>
+
+ <interface name="zwlr_foreign_toplevel_manager_v1" version="3">
+ <description summary="list and control opened apps">
+ The purpose of this protocol is to enable the creation of taskbars
+ and docks by providing them with a list of opened applications and
+ letting them request certain actions on them, like maximizing, etc.
+
+ After a client binds the zwlr_foreign_toplevel_manager_v1, each opened
+ toplevel window will be sent via the toplevel event
+ </description>
+
+ <event name="toplevel">
+ <description summary="a toplevel has been created">
+ This event is emitted whenever a new toplevel window is created. It
+ is emitted for all toplevels, regardless of the app that has created
+ them.
+
+ All initial details of the toplevel(title, app_id, states, etc.) will
+ be sent immediately after this event via the corresponding events in
+ zwlr_foreign_toplevel_handle_v1.
+ </description>
+ <arg name="toplevel" type="new_id" interface="zwlr_foreign_toplevel_handle_v1"/>
+ </event>
+
+ <request name="stop">
+ <description summary="stop sending events">
+ Indicates the client no longer wishes to receive events for new toplevels.
+ However the compositor may emit further toplevel_created events, until
+ the finished event is emitted.
+
+ The client must not send any more requests after this one.
+ </description>
+ </request>
+
+ <event name="finished" type="destructor">
+ <description summary="the compositor has finished with the toplevel manager">
+ This event indicates that the compositor is done sending events to the
+ zwlr_foreign_toplevel_manager_v1. The server will destroy the object
+ immediately after sending this request, so it will become invalid and
+ the client should free any resources associated with it.
+ </description>
+ </event>
+ </interface>
+
+ <interface name="zwlr_foreign_toplevel_handle_v1" version="3">
+ <description summary="an opened toplevel">
+ A zwlr_foreign_toplevel_handle_v1 object represents an opened toplevel
+ window. Each app may have multiple opened toplevels.
+
+ Each toplevel has a list of outputs it is visible on, conveyed to the
+ client with the output_enter and output_leave events.
+ </description>
+
+ <event name="title">
+ <description summary="title change">
+ This event is emitted whenever the title of the toplevel changes.
+ </description>
+ <arg name="title" type="string"/>
+ </event>
+
+ <event name="app_id">
+ <description summary="app-id change">
+ This event is emitted whenever the app-id of the toplevel changes.
+ </description>
+ <arg name="app_id" type="string"/>
+ </event>
+
+ <event name="output_enter">
+ <description summary="toplevel entered an output">
+ This event is emitted whenever the toplevel becomes visible on
+ the given output. A toplevel may be visible on multiple outputs.
+ </description>
+ <arg name="output" type="object" interface="wl_output"/>
+ </event>
+
+ <event name="output_leave">
+ <description summary="toplevel left an output">
+ This event is emitted whenever the toplevel stops being visible on
+ the given output. It is guaranteed that an entered-output event
+ with the same output has been emitted before this event.
+ </description>
+ <arg name="output" type="object" interface="wl_output"/>
+ </event>
+
+ <request name="set_maximized">
+ <description summary="requests that the toplevel be maximized">
+ Requests that the toplevel be maximized. If the maximized state actually
+ changes, this will be indicated by the state event.
+ </description>
+ </request>
+
+ <request name="unset_maximized">
+ <description summary="requests that the toplevel be unmaximized">
+ Requests that the toplevel be unmaximized. If the maximized state actually
+ changes, this will be indicated by the state event.
+ </description>
+ </request>
+
+ <request name="set_minimized">
+ <description summary="requests that the toplevel be minimized">
+ Requests that the toplevel be minimized. If the minimized state actually
+ changes, this will be indicated by the state event.
+ </description>
+ </request>
+
+ <request name="unset_minimized">
+ <description summary="requests that the toplevel be unminimized">
+ Requests that the toplevel be unminimized. If the minimized state actually
+ changes, this will be indicated by the state event.
+ </description>
+ </request>
+
+ <request name="activate">
+ <description summary="activate the toplevel">
+ Request that this toplevel be activated on the given seat.
+ There is no guarantee the toplevel will be actually activated.
+ </description>
+ <arg name="seat" type="object" interface="wl_seat"/>
+ </request>
+
+ <enum name="state">
+ <description summary="types of states on the toplevel">
+ The different states that a toplevel can have. These have the same meaning
+ as the states with the same names defined in xdg-toplevel
+ </description>
+
+ <entry name="maximized" value="0" summary="the toplevel is maximized"/>
+ <entry name="minimized" value="1" summary="the toplevel is minimized"/>
+ <entry name="activated" value="2" summary="the toplevel is active"/>
+ <entry name="fullscreen" value="3" summary="the toplevel is fullscreen" since="2"/>
+ </enum>
+
+ <event name="state">
+ <description summary="the toplevel state changed">
+ This event is emitted immediately after the zlw_foreign_toplevel_handle_v1
+ is created and each time the toplevel state changes, either because of a
+ compositor action or because of a request in this protocol.
+ </description>
+
+ <arg name="state" type="array"/>
+ </event>
+
+ <event name="done">
+ <description summary="all information about the toplevel has been sent">
+ This event is sent after all changes in the toplevel state have been
+ sent.
+
+ This allows changes to the zwlr_foreign_toplevel_handle_v1 properties
+ to be seen as atomic, even if they happen via multiple events.
+ </description>
+ </event>
+
+ <request name="close">
+ <description summary="request that the toplevel be closed">
+ Send a request to the toplevel to close itself. The compositor would
+ typically use a shell-specific method to carry out this request, for
+ example by sending the xdg_toplevel.close event. However, this gives
+ no guarantees the toplevel will actually be destroyed. If and when
+ this happens, the zwlr_foreign_toplevel_handle_v1.closed event will
+ be emitted.
+ </description>
+ </request>
+
+ <request name="set_rectangle">
+ <description summary="the rectangle which represents the toplevel">
+ The rectangle of the surface specified in this request corresponds to
+ the place where the app using this protocol represents the given toplevel.
+ It can be used by the compositor as a hint for some operations, e.g
+ minimizing. The client is however not required to set this, in which
+ case the compositor is free to decide some default value.
+
+ If the client specifies more than one rectangle, only the last one is
+ considered.
+
+ The dimensions are given in surface-local coordinates.
+ Setting width=height=0 removes the already-set rectangle.
+ </description>
+
+ <arg name="surface" type="object" interface="wl_surface"/>
+ <arg name="x" type="int"/>
+ <arg name="y" type="int"/>
+ <arg name="width" type="int"/>
+ <arg name="height" type="int"/>
+ </request>
+
+ <enum name="error">
+ <entry name="invalid_rectangle" value="0"
+ summary="the provided rectangle is invalid"/>
+ </enum>
+
+ <event name="closed">
+ <description summary="this toplevel has been destroyed">
+ This event means the toplevel has been destroyed. It is guaranteed there
+ won't be any more events for this zwlr_foreign_toplevel_handle_v1. The
+ toplevel itself becomes inert so any requests will be ignored except the
+ destroy request.
+ </description>
+ </event>
+
+ <request name="destroy" type="destructor">
+ <description summary="destroy the zwlr_foreign_toplevel_handle_v1 object">
+ Destroys the zwlr_foreign_toplevel_handle_v1 object.
+
+ This request should be called either when the client does not want to
+ use the toplevel anymore or after the closed event to finalize the
+ destruction of the object.
+ </description>
+ </request>
+
+ <!-- Version 2 additions -->
+
+ <request name="set_fullscreen" since="2">
+ <description summary="request that the toplevel be fullscreened">
+ Requests that the toplevel be fullscreened on the given output. If the
+ fullscreen state and/or the outputs the toplevel is visible on actually
+ change, this will be indicated by the state and output_enter/leave
+ events.
+
+ The output parameter is only a hint to the compositor. Also, if output
+ is NULL, the compositor should decide which output the toplevel will be
+ fullscreened on, if at all.
+ </description>
+ <arg name="output" type="object" interface="wl_output" allow-null="true"/>
+ </request>
+
+ <request name="unset_fullscreen" since="2">
+ <description summary="request that the toplevel be unfullscreened">
+ Requests that the toplevel be unfullscreened. If the fullscreen state
+ actually changes, this will be indicated by the state event.
+ </description>
+ </request>
+
+ <!-- Version 3 additions -->
+
+ <event name="parent" since="3">
+ <description summary="parent change">
+ This event is emitted whenever the parent of the toplevel changes.
+
+ No event is emitted when the parent handle is destroyed by the client.
+ </description>
+ <arg name="parent" type="object" interface="zwlr_foreign_toplevel_handle_v1" allow-null="true"/>
+ </event>
+ </interface>
+</protocol>
--
2.43.2
+15
View File
@@ -0,0 +1,15 @@
### Description
Arranges windows in a grid. Except it adjusts the number of windows in the first few columns to avoid empty cells.
### Download
- [2024-08-01](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/gaplessgrid/gaplessgrid.patch)
- [git branch](https://codeberg.org/dhruva_sambrani/dwl/src/branch/gaplessgrid)
## Pre-codeberg
- [2023-11-14](https://github.com/djpohly/dwl/compare/main...Sneethe:gaplessgrid.patch)
- [2021-07-27](https://github.com/djpohly/dwl/compare/main...vnepogodin:gaplessgrid.patch)
### Authors
- [Sneethe](https://github.com/Sneethe/)
- [Vladislav Nepogodin](https://github.com/vnepogodin)
- [Dhruva Sambrani](https://codeberg.org/dhruva_sambrani/) (Revived to codeberg)
+97
View File
@@ -0,0 +1,97 @@
From 958cf2c2415927e2f7b471da9ada7c6e7d169a63 Mon Sep 17 00:00:00 2001
From: Dhruva Sambrani <44899822+DhruvaSambrani@users.noreply.github.com>
Date: Mon, 8 Jan 2024 16:11:30 +0100
Subject: [PATCH] revive gaplessgrid
---
config.def.h | 2 ++
dwl.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+)
diff --git a/config.def.h b/config.def.h
index a8ed61d..7400b7f 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 */
@@ -134,6 +135,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 632dabf..4d810f7 100644
--- a/dwl.c
+++ b/dwl.c
@@ -268,6 +268,7 @@ static void focusclient(Client *c, int lift);
static void focusmon(const Arg *arg);
static void focusstack(const Arg *arg);
static Client *focustop(Monitor *m);
+static void gaplessgrid(Monitor *m);
static void fullscreennotify(struct wl_listener *listener, void *data);
static void handlesig(int signo);
static void incnmaster(const Arg *arg);
@@ -1311,6 +1312,51 @@ handlesig(int signo)
}
}
+void
+gaplessgrid(Monitor *m)
+{
+ unsigned 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;
+ 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.43.0
+13
View File
@@ -0,0 +1,13 @@
### Description
Adds gaps between clients, providing the ability to disable them at run-time.
`smartgaps` can also be changed to remove gaps when there is only one client present.
### Download
- [git branch](https://codeberg.org/sewn/dwl/src/branch/gaps)
- [2024-04-01](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/gaps/gaps.patch)
### Authors
- [sewn](https://codeberg.org/sewn)
- [Serene Void](https://github.com/serenevoid)
- [Rayan Nakib](https://nakibrayan2.pages.dev)
+128
View File
@@ -0,0 +1,128 @@
From c814a3f16995a2fe8542c5bbdb28e38e7de5ef7e Mon Sep 17 00:00:00 2001
From: sewn <sewn@disroot.org>
Date: Sun, 15 Oct 2023 09:38:16 +0100
Subject: [PATCH] introduce gaps with functionality of useless gaps from dwm
Co-authored-by: serenevoid <ajuph9224@gmail.com>
---
config.def.h | 4 ++++
dwl.c | 38 ++++++++++++++++++++++++++++----------
2 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/config.def.h b/config.def.h
index 8847e58..dca0a46 100644
--- a/config.def.h
+++ b/config.def.h
@@ -6,6 +6,9 @@
/* appearance */
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 int smartgaps = 0; /* 1 means no outer gap when there is only one window */
+static int gaps = 1; /* 1 means gaps between windows are added */
+static const unsigned int gappx = 10; /* gap pixel between windows */
static const unsigned int borderpx = 1; /* border pixel of windows */
static const float rootcolor[] = COLOR(0x222222ff);
static const float bordercolor[] = COLOR(0x444444ff);
@@ -130,6 +133,7 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_l, setmfact, {.f = +0.05f} },
{ MODKEY, XKB_KEY_Return, zoom, {0} },
{ MODKEY, XKB_KEY_Tab, view, {0} },
+ { MODKEY, XKB_KEY_g, togglegaps, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} },
{ MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
diff --git a/dwl.c b/dwl.c
index 39ce68c..2d317c5 100644
--- a/dwl.c
+++ b/dwl.c
@@ -198,6 +198,7 @@ struct Monitor {
struct wlr_box w; /* window area, layout-relative */
struct wl_list layers[4]; /* LayerSurface.link */
const Layout *lt[2];
+ int gaps;
unsigned int seltags;
unsigned int sellt;
uint32_t tagset[2];
@@ -332,6 +333,7 @@ static void tagmon(const Arg *arg);
static void tile(Monitor *m);
static void togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg);
+static void togglegaps(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unlocksession(struct wl_listener *listener, void *data);
@@ -881,6 +883,8 @@ createmon(struct wl_listener *listener, void *data)
wlr_output_state_init(&state);
/* Initialize monitor state using configured rules */
+ m->gaps = gaps;
+
m->tagset[0] = m->tagset[1] = 1;
for (r = monrules; r < END(monrules); r++) {
if (!r->name || strstr(wlr_output->name, r->name)) {
@@ -2572,7 +2576,7 @@ tagmon(const Arg *arg)
void
tile(Monitor *m)
{
- unsigned int mw, my, ty;
+ unsigned int h, r, e = m->gaps, mw, my, ty;
int i, n = 0;
Client *c;
@@ -2581,23 +2585,30 @@ tile(Monitor *m)
n++;
if (n == 0)
return;
+ if (smartgaps == n)
+ e = 0;
if (n > m->nmaster)
- mw = m->nmaster ? ROUND(m->w.width * m->mfact) : 0;
+ mw = m->nmaster ? ROUND((m->w.width + gappx*e) * m->mfact) : 0;
else
- mw = m->w.width;
- i = my = ty = 0;
+ mw = m->w.width - 2*gappx*e + gappx*e;
+ i = 0;
+ my = ty = gappx*e;
wl_list_for_each(c, &clients, link) {
if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
continue;
if (i < m->nmaster) {
- resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw,
- .height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0);
- my += c->geom.height;
+ r = MIN(n, m->nmaster) - i;
+ h = (m->w.height - my - gappx*e - gappx*e * (r - 1)) / r;
+ resize(c, (struct wlr_box){.x = m->w.x + gappx*e, .y = m->w.y + my,
+ .width = mw - gappx*e, .height = h}, 0);
+ my += c->geom.height + gappx*e;
} else {
- resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y + ty,
- .width = m->w.width - mw, .height = (m->w.height - ty) / (n - i)}, 0);
- ty += c->geom.height;
+ r = n - i;
+ h = (m->w.height - ty - gappx*e - gappx*e * (r - 1)) / r;
+ resize(c, (struct wlr_box){.x = m->w.x + mw + gappx*e, .y = m->w.y + ty,
+ .width = m->w.width - mw - 2*gappx*e, .height = h}, 0);
+ ty += c->geom.height + gappx*e;
}
i++;
}
@@ -2620,6 +2631,13 @@ togglefullscreen(const Arg *arg)
setfullscreen(sel, !sel->isfullscreen);
}
+void
+togglegaps(const Arg *arg)
+{
+ selmon->gaps = !selmon->gaps;
+ arrange(selmon);
+}
+
void
toggletag(const Arg *arg)
{
--
2.44.0
+20
View File
@@ -0,0 +1,20 @@
### Description
Add swipe gestures to trigger functions, similar to [libinput-gestures](https://github.com/bulletmark/libinput-gestures/tree/master). It supports the following gestures: `SWIPE_UP`, `SWIPE_DOWN`, `SWIPE_LEFT` and `SWIPE_RIGHT`
```c
static const Gesture gestures[] = {
/* modifier gesture fingers_count function argument */
{ MODKEY, SWIPE_LEFT, 4, shiftview, { .i = 1 } },
{ 0, SWIPE_RIGHT, 4, shiftview, { .i = -1 } },
};
```
**NOTE:** the example above requires the following patch [shiftview](https://codeberg.org/dwl/dwl-patches/wiki/shiftview)
### Download
- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.5/gestures)
- [2024-04-11](https://codeberg.org/dwl/dwl-patches/raw/commit/be3735bc6a5c64ff76c200a8679453bd179be456/gestures/gestures.patch)
- [v0.5](https://codeberg.org/dwl/dwl-patches/raw/commit/655fd2916c1bcaa022ce6dcdfb370051cf64df66/gestures/gestures.patch)
### Authors
- [wochap](https://codeberg.org/wochap)
+170
View File
@@ -0,0 +1,170 @@
From 6b9c8f96a2f1ed3c36d260df1e1dcba24cb98550 Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Thu, 11 Apr 2024 14:46:48 -0500
Subject: [PATCH] add swipe gestures to trigger functions
like libinput-gestures, it supports the following gestures: SWIPE_UP, SWIPE_DOWN, SWIPE_LEFT and SWIPE_RIGHTsupport multiple fingers count in gestures[]support mods in gestures[]
---
config.def.h | 9 +++++++
dwl.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 77 insertions(+)
diff --git a/config.def.h b/config.def.h
index 8847e58..53a8437 100644
--- a/config.def.h
+++ b/config.def.h
@@ -14,6 +14,8 @@ 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 unsigned int swipe_min_threshold = 0;
+
/* tagging - TAGCOUNT must be no greater than 31 */
#define TAGCOUNT (9)
@@ -169,3 +171,10 @@ static const Button buttons[] = {
{ MODKEY, BTN_MIDDLE, togglefloating, {0} },
{ MODKEY, BTN_RIGHT, moveresize, {.ui = CurResize} },
};
+
+static const Gesture gestures[] = {
+ // { MODKEY, SWIPE_LEFT, 4, shiftview, { .i = 1 } },
+ // { MODKEY, SWIPE_RIGHT, 4, shiftview, { .i = -1 } },
+ { MODKEY, SWIPE_UP, 3, focusstack, {.i = 1} },
+ { MODKEY, SWIPE_DOWN, 3, focusstack, {.i = -1} },
+};
diff --git a/dwl.c b/dwl.c
index e96ea09..7e8a684 100644
--- a/dwl.c
+++ b/dwl.c
@@ -87,6 +87,7 @@ enum { LyrBg, LyrBottom, LyrTile, LyrFloat, LyrTop, LyrFS, LyrOverlay, LyrBlock,
enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar,
NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */
#endif
+enum { SWIPE_LEFT, SWIPE_RIGHT, SWIPE_DOWN, SWIPE_UP };
typedef union {
int i;
@@ -102,6 +103,14 @@ typedef struct {
const Arg arg;
} Button;
+typedef struct {
+ unsigned int mod;
+ unsigned int motion;
+ unsigned int fingers_count;
+ void (*func)(const Arg *);
+ const Arg arg;
+} Gesture;
+
typedef struct Monitor Monitor;
typedef struct {
/* Must keep these three elements in this order */
@@ -249,6 +258,7 @@ static void arrangelayer(Monitor *m, struct wl_list *list,
static void arrangelayers(Monitor *m);
static void axisnotify(struct wl_listener *listener, void *data);
static void buttonpress(struct wl_listener *listener, void *data);
+static int ongesture(struct wlr_pointer_swipe_end_event *event);
static void swipe_begin(struct wl_listener *listener, void *data);
static void swipe_update(struct wl_listener *listener, void *data);
static void swipe_end(struct wl_listener *listener, void *data);
@@ -413,6 +423,10 @@ static struct wlr_box sgeom;
static struct wl_list mons;
static Monitor *selmon;
+static uint32_t swipe_fingers = 0;
+static double swipe_dx = 0;
+static double swipe_dy = 0;
+
#ifdef XWAYLAND
static void activatex11(struct wl_listener *listener, void *data);
static void associatex11(struct wl_listener *listener, void *data);
@@ -432,6 +446,8 @@ static xcb_atom_t netatom[NetLast];
/* attempt to encapsulate suck into one file */
#include "client.h"
+static const unsigned int abzsquare = swipe_min_threshold * swipe_min_threshold;
+
/* function implementations */
void
applybounds(Client *c, struct wlr_box *bbox)
@@ -641,6 +657,11 @@ swipe_begin(struct wl_listener *listener, void *data)
{
struct wlr_pointer_swipe_begin_event *event = data;
+ swipe_fingers = event->fingers;
+ // Reset swipe distance at the beginning of a swipe
+ swipe_dx = 0;
+ swipe_dy = 0;
+
// Forward swipe begin event to client
wlr_pointer_gestures_v1_send_swipe_begin(
pointer_gestures,
@@ -655,6 +676,11 @@ swipe_update(struct wl_listener *listener, void *data)
{
struct wlr_pointer_swipe_update_event *event = data;
+ swipe_fingers = event->fingers;
+ // Accumulate swipe distance
+ swipe_dx += event->dx;
+ swipe_dy += event->dy;
+
// Forward swipe update event to client
wlr_pointer_gestures_v1_send_swipe_update(
pointer_gestures,
@@ -665,11 +691,53 @@ swipe_update(struct wl_listener *listener, void *data)
);
}
+int
+ongesture(struct wlr_pointer_swipe_end_event *event)
+{
+ struct wlr_keyboard *keyboard;
+ uint32_t mods;
+ const Gesture *g;
+ unsigned int motion;
+ unsigned int adx = ROUND(fabs(swipe_dx));
+ unsigned int ady = ROUND(fabs(swipe_dy));
+ int handled = 0;
+
+ if (event->cancelled) {
+ return handled;
+ }
+
+ // Require absolute distance movement beyond a small thresh-hold
+ if (adx * adx + ady * ady < abzsquare) {
+ return handled;
+ }
+
+ if (adx > ady) {
+ motion = swipe_dx < 0 ? SWIPE_LEFT : SWIPE_RIGHT;
+ } else {
+ motion = swipe_dy < 0 ? SWIPE_UP : SWIPE_DOWN;
+ }
+
+ keyboard = wlr_seat_get_keyboard(seat);
+ mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
+ for (g = gestures; g < END(gestures); g++) {
+ if (CLEANMASK(mods) == CLEANMASK(g->mod) &&
+ swipe_fingers == g->fingers_count &&
+ motion == g->motion && g->func) {
+ g->func(&g->arg);
+ handled = 1;
+ }
+ }
+ return handled;
+}
+
void
swipe_end(struct wl_listener *listener, void *data)
{
struct wlr_pointer_swipe_end_event *event = data;
+ // TODO: should we stop here if the event has been handled?
+ ongesture(event);
+
// Forward swipe end event to client
wlr_pointer_gestures_v1_send_swipe_end(
pointer_gestures,
--
2.43.2
+11
View File
@@ -0,0 +1,11 @@
### 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).
If you plan to use wayvnc, you'll need [virtual-pointer](https://codeberg.org/dwl/dwl-patches/wiki/virtual-pointer.-) patch as well
### Download
- [git branch](https://codeberg.org/wochap/dwl/src/v0.5/headless)
- [v0.5](https://codeberg.org/dwl/dwl-patches/raw/commit/0096e49402bc59b4050e12cdb9befb79d0011006/headless/headless.patch)
### Authors
- [wochap](https://codeberg.org/wochap)
+130
View File
@@ -0,0 +1,130 @@
From 2e1123af5c7ae4354ec997d59cb36143fb2fdd27 Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Mon, 8 Apr 2024 10:23:40 -0500
Subject: [PATCH] feat: implement headless backend
---
config.def.h | 1 +
dwl.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 59 insertions(+)
diff --git a/config.def.h b/config.def.h
index db0babc..f0a2080 100644
--- a/config.def.h
+++ b/config.def.h
@@ -141,6 +141,7 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_LEFT} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater, tagmon, {.i = WLR_DIRECTION_RIGHT} },
+ { MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT, XKB_KEY_M, create_output, {0} },
TAGKEYS( XKB_KEY_1, XKB_KEY_exclam, 0),
TAGKEYS( XKB_KEY_2, XKB_KEY_at, 1),
TAGKEYS( XKB_KEY_3, XKB_KEY_numbersign, 2),
diff --git a/dwl.c b/dwl.c
index ef27a1d..79a63b0 100644
--- a/dwl.c
+++ b/dwl.c
@@ -12,7 +12,10 @@
#include <unistd.h>
#include <wayland-server-core.h>
#include <wlr/backend.h>
+#include <wlr/backend/headless.h>
#include <wlr/backend/libinput.h>
+#include <wlr/backend/multi.h>
+#include <wlr/backend/wayland.h>
#include <wlr/render/allocator.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_compositor.h>
@@ -58,6 +61,9 @@
#include <xcb/xcb.h>
#include <xcb/xcb_icccm.h>
#endif
+#if WLR_HAS_X11_BACKEND
+#include <wlr/backend/x11.h>
+#endif
#include "util.h"
@@ -327,6 +333,8 @@ 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 _create_output(struct wlr_backend *backend, void *data);
+static void create_output(const Arg *arg);
/* variables */
static const char broken[] = "broken";
@@ -335,6 +343,7 @@ static int locked;
static void *exclusive_focus;
static struct wl_display *dpy;
static struct wlr_backend *backend;
+static struct wlr_backend *headless_backend;
static struct wlr_scene *scene;
static struct wlr_scene_tree *layers[NUM_LAYERS];
static struct wlr_scene_tree *drag_icon;
@@ -2321,6 +2330,16 @@ setup(void)
cursor_shape_mgr = wlr_cursor_shape_manager_v1_create(dpy, 1);
LISTEN_STATIC(&cursor_shape_mgr->events.request_set_shape, setcursorshape);
+ /**
+ * Initialize headless backend
+ */
+ headless_backend = wlr_headless_backend_create(dpy);
+ if (!headless_backend) {
+ die("Failed to create secondary headless backend");
+ } else {
+ wlr_multi_backend_add(backend, headless_backend);
+ }
+
/*
* Configures a seat, which is a single "seat" at which a user sits and
* operates the computer. This conceptually includes up to one keyboard,
@@ -2746,6 +2765,45 @@ zoom(const Arg *arg)
arrange(selmon);
}
+void
+_create_output(struct wlr_backend *_backend, void *data)
+{
+ bool *done = data;
+ if (*done) {
+ return;
+ }
+
+ if (wlr_backend_is_wl(_backend)) {
+ wlr_wl_output_create(_backend);
+ *done = true;
+ } else if (wlr_backend_is_headless(_backend)) {
+ wlr_headless_add_output(_backend, 1920, 1080);
+ *done = true;
+ }
+#if WLR_HAS_X11_BACKEND
+ else if (wlr_backend_is_x11(backend)) {
+ wlr_x11_output_create(backend);
+ *done = true;
+ }
+#endif
+}
+
+void
+create_output(const Arg *arg)
+{
+ bool done = false;
+
+ if (!wlr_backend_is_multi(backend)) {
+ die("Expected a multi backend");
+ }
+
+ wlr_multi_for_each_backend(backend, _create_output, &done);
+
+ if (!done) {
+ die("Can only create outputs for Wayland, X11 or headless backends");
+ }
+}
+
#ifdef XWAYLAND
void
activatex11(struct wl_listener *listener, void *data)
--
2.43.2
+9
View File
@@ -0,0 +1,9 @@
### Description
Hide all clients (and layer surfaces) behind the current client if it is fullscreen, only the background (layer surfaces at the background layer) will be shown
### Download
- [git branch](https://codeberg.org/sevz/dwl/src/branch/hide-behind-fullscreen)
- [2023-11-25](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/hide-behind-fullscreen/hide-behind-fullscreen.patch)
### Authors
- [sevz](https://codeberg.org/sevz)
@@ -0,0 +1,67 @@
From da92f84aa261051b410a0ffcfc80b4d6c8c7dfae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
<leohdz172@protonmail.com>
Date: Sun, 10 Apr 2022 22:38:53 -0500
Subject: [PATCH] hide-behind-fullscreen
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Leonardo Hernández Hernández <leohdz172@proton.me>
---
config.def.h | 2 +-
dwl.c | 18 +++++++++++++++++-
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/config.def.h b/config.def.h
index a8ed61d..b219c0d 100644
--- a/config.def.h
+++ b/config.def.h
@@ -12,7 +12,7 @@ static const float bordercolor[] = COLOR(0x444444ff);
static const float focuscolor[] = COLOR(0x005577ff);
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 */
+static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 0.0}; /* You can also use glsl colors */
/* tagging - TAGCOUNT must be no greater than 31 */
#define TAGCOUNT (9)
diff --git a/dwl.c b/dwl.c
index 10d5a5b..0b8d03a 100644
--- a/dwl.c
+++ b/dwl.c
@@ -455,7 +455,9 @@ applyrules(Client *c)
void
arrange(Monitor *m)
{
- Client *c;
+ LayerSurface *l;
+ Client *c, *sel = focustop(selmon);
+ int i;
wl_list_for_each(c, &clients, link) {
if (c->mon == m) {
wlr_scene_node_set_enabled(&c->scene->node, VISIBLEON(c, m));
@@ -468,6 +470,20 @@ arrange(Monitor *m)
strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol));
+ if (sel && sel->isfullscreen && VISIBLEON(sel, m)) {
+ for (i = 3; i > ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; i--)
+ wl_list_for_each(l, &sel->mon->layers[i], link)
+ wlr_scene_node_set_enabled(&l->scene->node, 0);
+
+ wl_list_for_each(c, &clients, link)
+ wlr_scene_node_set_enabled(&c->scene->node, (sel->isfullscreen && c == sel)
+ || !sel->isfullscreen);
+ }
+ if (!sel || (!sel->isfullscreen && VISIBLEON(sel, m)))
+ for (i = 3; i > ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; i--)
+ wl_list_for_each(l, &m->layers[i], link)
+ wlr_scene_node_set_enabled(&l->scene->node, 1);
+
if (m->lt[m->sellt]->arrange)
m->lt[m->sellt]->arrange(m);
motionnotify(0);
--
2.43.0
+9
View File
@@ -0,0 +1,9 @@
### Description
Hide all clients behind the focused one in the monocle layout
### Download
- [git branch](https://codeberg.org/sevz/dwl/src/branch/hide-behind-monocle)
- [2023-11-25](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/hide-behind-monocle/hide-behind-monocle.patch)
### Authors
- [sevz](https://codeberg.org/sevz)
@@ -0,0 +1,328 @@
From 1ba8580b2596c14b9305f1e7cb8d88f54367af59 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
<leohdz172@proton.me>
Date: Sat, 8 Jul 2023 17:25:16 -0600
Subject: [PATCH] hide behind monocle
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Leonardo Hernández Hernández <leohdz172@proton.me>
---
dwl.c | 84 ++++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 52 insertions(+), 32 deletions(-)
diff --git a/dwl.c b/dwl.c
index 10d5a5b..07659ea 100644
--- a/dwl.c
+++ b/dwl.c
@@ -267,9 +267,10 @@ static Monitor *dirtomon(enum wlr_direction dir);
static void focusclient(Client *c, int lift);
static void focusmon(const Arg *arg);
static void focusstack(const Arg *arg);
-static Client *focustop(Monitor *m);
+static Client *focustop(Monitor *m, int onlytiled);
static void fullscreennotify(struct wl_listener *listener, void *data);
static void handlesig(int signo);
+static void hidebehindmonocle(Monitor *m);
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);
@@ -464,7 +465,7 @@ arrange(Monitor *m)
}
wlr_scene_node_set_enabled(&m->fullscreen_bg->node,
- (c = focustop(m)) && c->isfullscreen);
+ (c = focustop(m, 0)) && c->isfullscreen);
strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol));
@@ -700,7 +701,7 @@ closemon(Monitor *m)
if (c->mon == m)
setmon(c, selmon, c->tags);
}
- focusclient(focustop(selmon), 1);
+ focusclient(focustop(selmon, 0), 1);
printstatus();
}
@@ -1030,7 +1031,7 @@ void
destroydragicon(struct wl_listener *listener, void *data)
{
/* Focus enter isn't sent during drag, so refocus the focused node. */
- focusclient(focustop(selmon), 1);
+ focusclient(focustop(selmon, 0), 1);
motionnotify(0);
}
@@ -1066,7 +1067,7 @@ destroylock(SessionLock *lock, int unlock)
wlr_scene_node_set_enabled(&locked_bg->node, 0);
- focusclient(focustop(selmon), 0);
+ focusclient(focustop(selmon, 0), 0);
motionnotify(0);
destroy:
@@ -1095,7 +1096,7 @@ destroylocksurface(struct wl_listener *listener, void *data)
surface = wl_container_of(cur_lock->surfaces.next, surface, link);
client_notify_enter(surface->surface, wlr_seat_get_keyboard(seat));
} else if (!locked) {
- focusclient(focustop(selmon), 1);
+ focusclient(focustop(selmon, 0), 1);
} else {
wlr_seat_keyboard_clear_focus(seat);
}
@@ -1186,6 +1187,7 @@ focusclient(Client *c, int lift)
wl_list_insert(&fstack, &c->flink);
selmon = c->mon;
c->isurgent = 0;
+ hidebehindmonocle(c->mon);
client_restack_surface(c);
/* Don't change border color if there is an exclusive focus or we are
@@ -1240,14 +1242,14 @@ focusmon(const Arg *arg)
selmon = dirtomon(arg->i);
while (!selmon->wlr_output->enabled && i++ < nmons);
}
- focusclient(focustop(selmon), 1);
+ focusclient(focustop(selmon, 0), 1);
}
void
focusstack(const Arg *arg)
{
/* Focus the next or previous client (in tiling order) on selmon */
- Client *c, *sel = focustop(selmon);
+ Client *c, *sel = focustop(selmon, 0);
if (!sel || sel->isfullscreen)
return;
if (arg->i > 0) {
@@ -1273,12 +1275,15 @@ focusstack(const Arg *arg)
* will focus the topmost client of this mon, when actually will
* only return that client */
Client *
-focustop(Monitor *m)
+focustop(Monitor *m, int onlytiled)
{
Client *c;
wl_list_for_each(c, &fstack, flink) {
- if (VISIBLEON(c, m))
+ if (VISIBLEON(c, m)) {
+ if (onlytiled && c->isfloating)
+ continue;
return c;
+ }
}
return NULL;
}
@@ -1311,6 +1316,22 @@ handlesig(int signo)
}
}
+void
+hidebehindmonocle(Monitor *m)
+{
+ Client *c;
+ if (m && m->lt[m->sellt]->arrange == monocle) {
+ wl_list_for_each(c, &clients, link)
+ wlr_scene_node_set_enabled(&c->scene->node, VISIBLEON(c, m) && c->isfloating);
+
+ c = NULL;
+
+ /* Enable top tiled client, fullscreen is considered tiled */
+ if ((c = focustop(m, 1)))
+ wlr_scene_node_set_enabled(&c->scene->node, 1);
+ }
+}
+
void
incnmaster(const Arg *arg)
{
@@ -1449,7 +1470,7 @@ keyrepeat(void *data)
void
killclient(const Arg *arg)
{
- Client *sel = focustop(selmon);
+ Client *sel = focustop(selmon, 0);
if (sel)
client_send_close(sel);
}
@@ -1584,8 +1605,7 @@ monocle(Monitor *m)
}
if (n)
snprintf(m->ltsymbol, LENGTH(m->ltsymbol), "[%d]", n);
- if ((c = focustop(m)))
- wlr_scene_node_raise_to_top(&c->scene->node);
+ hidebehindmonocle(m);
}
void
@@ -1813,7 +1833,7 @@ printstatus(void)
if (c->isurgent)
urg |= c->tags;
}
- if ((c = focustop(m))) {
+ if ((c = focustop(m, 0))) {
title = client_get_title(c);
appid = client_get_appid(c);
printf("%s title %s\n", m->wlr_output->name, title ? title : broken);
@@ -2129,7 +2149,7 @@ setmon(Client *c, Monitor *m, uint32_t newtags)
setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */
setfloating(c, c->isfloating);
}
- focusclient(focustop(selmon), 1);
+ focusclient(focustop(selmon, 0), 1);
}
void
@@ -2431,12 +2451,12 @@ startdrag(struct wl_listener *listener, void *data)
void
tag(const Arg *arg)
{
- Client *sel = focustop(selmon);
+ Client *sel = focustop(selmon, 0);
if (!sel || (arg->ui & TAGMASK) == 0)
return;
sel->tags = arg->ui & TAGMASK;
- focusclient(focustop(selmon), 1);
+ focusclient(focustop(selmon, 0), 1);
arrange(selmon);
printstatus();
}
@@ -2444,7 +2464,7 @@ tag(const Arg *arg)
void
tagmon(const Arg *arg)
{
- Client *sel = focustop(selmon);
+ Client *sel = focustop(selmon, 0);
if (sel)
setmon(sel, dirtomon(arg->i), 0);
}
@@ -2485,7 +2505,7 @@ tile(Monitor *m)
void
togglefloating(const Arg *arg)
{
- Client *sel = focustop(selmon);
+ Client *sel = focustop(selmon, 0);
/* return if fullscreen */
if (sel && !sel->isfullscreen)
setfloating(sel, !sel->isfloating);
@@ -2494,7 +2514,7 @@ togglefloating(const Arg *arg)
void
togglefullscreen(const Arg *arg)
{
- Client *sel = focustop(selmon);
+ Client *sel = focustop(selmon, 0);
if (sel)
setfullscreen(sel, !sel->isfullscreen);
}
@@ -2503,12 +2523,12 @@ void
toggletag(const Arg *arg)
{
uint32_t newtags;
- Client *sel = focustop(selmon);
+ Client *sel = focustop(selmon, 0);
if (!sel || !(newtags = sel->tags ^ (arg->ui & TAGMASK)))
return;
sel->tags = newtags;
- focusclient(focustop(selmon), 1);
+ focusclient(focustop(selmon, 0), 1);
arrange(selmon);
printstatus();
}
@@ -2521,7 +2541,7 @@ toggleview(const Arg *arg)
return;
selmon->tagset[selmon->seltags] = newtagset;
- focusclient(focustop(selmon), 1);
+ focusclient(focustop(selmon, 0), 1);
arrange(selmon);
printstatus();
}
@@ -2545,7 +2565,7 @@ unmaplayersurfacenotify(struct wl_listener *listener, void *data)
if (l->layer_surface->output && (l->mon = l->layer_surface->output->data))
arrangelayers(l->mon);
if (l->layer_surface->surface == seat->keyboard_state.focused_surface)
- focusclient(focustop(selmon), 1);
+ focusclient(focustop(selmon, 0), 1);
motionnotify(0);
}
@@ -2562,7 +2582,7 @@ unmapnotify(struct wl_listener *listener, void *data)
if (client_is_unmanaged(c)) {
if (c == exclusive_focus) {
exclusive_focus = NULL;
- focusclient(focustop(selmon), 1);
+ focusclient(focustop(selmon, 0), 1);
}
} else {
wl_list_remove(&c->link);
@@ -2643,7 +2663,7 @@ updatemons(struct wl_listener *listener, void *data)
/* Don't move clients to the left output when plugging monitors */
arrange(m);
/* make sure fullscreen clients have the right size */
- if ((c = focustop(m)) && c->isfullscreen)
+ if ((c = focustop(m, 0)) && c->isfullscreen)
resize(c, m->m, 0);
/* Try to re-set the gamma LUT when updating monitors,
@@ -2659,7 +2679,7 @@ updatemons(struct wl_listener *listener, void *data)
if (!c->mon && client_surface(c)->mapped)
setmon(c, selmon, c->tags);
}
- focusclient(focustop(selmon), 1);
+ focusclient(focustop(selmon, 0), 1);
if (selmon->lock_surface) {
client_notify_enter(selmon->lock_surface->surface,
wlr_seat_get_keyboard(seat));
@@ -2681,7 +2701,7 @@ void
updatetitle(struct wl_listener *listener, void *data)
{
Client *c = wl_container_of(listener, c, set_title);
- if (c == focustop(c->mon))
+ if (c == focustop(c->mon, 0))
printstatus();
}
@@ -2691,7 +2711,7 @@ urgent(struct wl_listener *listener, void *data)
struct wlr_xdg_activation_v1_request_activate_event *event = data;
Client *c = NULL;
toplevel_from_wlr_surface(event->surface, &c, NULL);
- if (!c || c == focustop(selmon))
+ if (!c || c == focustop(selmon, 0))
return;
c->isurgent = 1;
@@ -2709,7 +2729,7 @@ view(const Arg *arg)
selmon->seltags ^= 1; /* toggle sel tagset */
if (arg->ui & TAGMASK)
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
- focusclient(focustop(selmon), 1);
+ focusclient(focustop(selmon, 0), 1);
arrange(selmon);
printstatus();
}
@@ -2767,7 +2787,7 @@ xytonode(double x, double y, struct wlr_surface **psurface,
void
zoom(const Arg *arg)
{
- Client *c, *sel = focustop(selmon);
+ Client *c, *sel = focustop(selmon, 0);
if (!sel || !selmon || !selmon->lt[selmon->sellt]->arrange || sel->isfloating)
return;
@@ -2880,7 +2900,7 @@ sethints(struct wl_listener *listener, void *data)
{
Client *c = wl_container_of(listener, c, set_hints);
struct wlr_surface *surface = client_surface(c);
- if (c == focustop(selmon))
+ if (c == focustop(selmon, 0))
return;
c->isurgent = xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints);
--
2.43.0
+11
View File
@@ -0,0 +1,11 @@
### Description
Prevent [bar](https://codeberg.org/dwl/dwl-patches/wiki/bar) from drawing tags with no clients (i.e. vacant).
It also stops drawing empty rectangles on the bar for non-vacant tags as there is no need anymore to distinguish vacant tags and it offers a more visible contrast than if there were filled/empty rectangles.
### Download
- [2024-04-14](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/hide_vacant_tags/hide_vacant_tags.patch) (bar 2024-04-14)
### Authors
- [sewn](https://codeberg.org/sewn)
@@ -0,0 +1,75 @@
From 6337cf36554eda98f3d160ef4fdd12eb042f4120 Mon Sep 17 00:00:00 2001
From: sewn <sewn@disroot.org>
Date: Sun, 14 Apr 2024 07:58:53 +0300
Subject: [PATCH] port hide vacant tags patch
---
dwl.c | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/dwl.c b/dwl.c
index 54273ae..7db6273 100644
--- a/dwl.c
+++ b/dwl.c
@@ -651,7 +651,7 @@ void buffer_end_data_ptr_access(struct wlr_buffer *buffer) {
void
buttonpress(struct wl_listener *listener, void *data)
{
- unsigned int i = 0, x = 0;
+ unsigned int i = 0, x = 0, occ = 0;
unsigned int click;
struct wlr_pointer_button_event *event = data;
struct wlr_keyboard *keyboard;
@@ -672,9 +672,17 @@ buttonpress(struct wl_listener *listener, void *data)
if ((node = wlr_scene_node_at(&layers[LyrBottom]->node, cursor->x, cursor->y, NULL, NULL)) &&
(buffer = wlr_scene_buffer_from_node(node)) && buffer == selmon->scene_buffer) {
x = selmon->m.x;
- do
- x += TEXTW(tags[i]);
- while (cursor->x >= x && ++i < LENGTH(tags));
+ wl_list_for_each(c, &clients, link) {
+ if (c->mon != selmon)
+ continue;
+ occ |= c->tags == TAGMASK ? 0 : c->tags;
+ }
+ do {
+ /* Do not reserve space for vacant tags */
+ if (!(occ & 1 << i || selmon->tagset[selmon->seltags] & 1 << i))
+ continue;
+ x += TEXTW(tags[i]);
+ } while (cursor->x >= x && ++i < LENGTH(tags));
if (i < LENGTH(tags)) {
click = ClkTagBar;
arg.ui = 1 << i;
@@ -1379,13 +1387,16 @@ drawbar(Monitor *mon)
wl_list_for_each(c, &clients, link) {
if (c->mon != mon)
continue;
- occ |= c->tags;
+ occ |= c->tags == TAGMASK ? 0 : c->tags;
if (c->isurgent)
urg |= c->tags;
}
c = focustop(mon);
x = 0;
for (i = 0; i < LENGTH(tags); i++) {
+ /* Do not draw vacant tags */
+ if(!(occ & 1 << i || mon->tagset[mon->seltags] & 1 << i))
+ continue;
w = TEXTW(tags[i]);
sel = mon->tagset[mon->seltags] & 1 << i;
@@ -1393,10 +1404,6 @@ drawbar(Monitor *mon)
urg & 1 << i ? &selbarbg : (sel ? &selbarfg : &normbarfg),
urg & 1 << i ? &selbarfg : (sel ? &selbarbg : &normbarbg));
- if (occ & 1 << i)
- drwl_rect(pix, x + boxs, boxs, boxw, boxw, sel,
- urg & 1 << i ? &selbarbg : (sel ? &selbarfg : &normbarfg));
-
x += w;
}
--
2.44.0
+9
View File
@@ -0,0 +1,9 @@
### Description
Adds a `ishidden` option to client rules, that allows hiding any matching clients entirely.
### Download
- [git branch](https://codeberg.org/minego/dwl/src/branch/hiderule)
- [yyyy-mm-dd](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/hiderule/hiderule.patch)
### Authors
- [minego](https://codeberg.org/minego)
+57
View File
@@ -0,0 +1,57 @@
From fb48ec754d63b3d8e40fff2d047050675887d7f4 Mon Sep 17 00:00:00 2001
From: Micah N Gorrell <m@minego.net>
Date: Wed, 27 Mar 2024 12:53:18 -0600
Subject: [PATCH] hiderule
---
config.def.h | 9 ++++++---
dwl.c | 4 ++++
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/config.def.h b/config.def.h
index 9009517..c476057 100644
--- a/config.def.h
+++ b/config.def.h
@@ -21,11 +21,14 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
static int log_level = WLR_ERROR;
static const Rule rules[] = {
- /* app_id title tags mask isfloating monitor */
+ /* app_id title tags mask isfloating monitor ishidden */
/* examples:
- { "Gimp", NULL, 0, 1, -1 },
+ { "Gimp", NULL, 0, 1, -1, 0 },
*/
- { "firefox", NULL, 1 << 8, 0, -1 },
+ { "firefox", NULL, 1 << 8, 0, -1, 0 },
+
+ { "firefox", "Sharing Indicator",
+ 0, 1, -1, 1 },
};
/* layout(s) */
diff --git a/dwl.c b/dwl.c
index 5867b0c..799fd89 100644
--- a/dwl.c
+++ b/dwl.c
@@ -228,6 +228,7 @@ typedef struct {
uint32_t tags;
int isfloating;
int monitor;
+ int ishidden;
} Rule;
typedef struct {
@@ -464,6 +465,9 @@ applyrules(Client *c)
c->isfloating = r->isfloating;
newtags |= r->tags;
i = 0;
+ if (r->ishidden) {
+ mon = NULL;
+ }
wl_list_for_each(m, &mons, link) {
if (r->monitor == i++)
mon = m;
--
2.44.0
+19
View File
@@ -0,0 +1,19 @@
### Description
Largely based on [raphi](https://sr.ht/~raphi/)'s [somebar](https://sr.ht/~raphi/somebar/), this patch provides an ipc for wayland clients to get and set dwl state. The ipc is intended for status bars, but can also be scripted with tools like [dwlmsg](https://codeberg.org/notchoc/dwlmsg).
Status information to stdout is currently disabled as dwl tends to freeze. For now, `dwlmsg -w` should act as a drop-in replacement.
### Download
- [git branch](https://codeberg.org/notchoc/dwl/src/branch/ipc)
- [2024-03-13](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/ipc/ipc.patch)
- [2024-02-20](https://codeberg.org/dwl/dwl-patches/raw/commit/0c5ae06e4bc1d7f641376e8fcb86b43bd48ce2ee/ipc/ipc.patch)
- [2023-10-28](https://gist.githubusercontent.com/fbushstone/b116c44340eb7a7878de1119dd931ca5/raw/ee66ac9e2a5dddd9b528df553e21080c2811e974/ipc-v2-fixed.patch) Updated version of 2023-04-29, prevents ipc from freezing the compositor in printstatus.
- [2023-04-29](https://github.com/djpohly/dwl/compare/main...madcowog:ipc-v2.patch) Use this for dwl-ipc-unstable-v2. If you are using commit [9d68554](https://github.com/djpohly/dwl/commit/9d68554c59a886b641d27a364884fb461af2d4f1) or later, use this. For status bars this protocol is supported by dwlb, Waybar and dwl-bar.
- [2023-04-29](https://github.com/djpohly/dwl/compare/main...madcowog:ipc-bbdf2.patch) Use this for dwl-ipc-unstable-v1. If you are using commit [bbdaf2a9](https://github.com/djpohly/dwl/commit/bbdf2a913b72e7a308ee0dfde6518a4285d4a775), [release 0.4](https://github.com/djpohly/dwl/releases/tag/v0.4) or earlier, use this. For status bars, this protocol is supported by dwl-bar.
- [2023-02-20](https://lists.sr.ht/~raphi/public-inbox/patches/39166) Use this for net-tapesoftware-dwl-wm-unstable-v1. If you are using commit [c69a2bec](https://github.com/djpohly/dwl/commit/c69a2bec3ff417fbc4ea8fec0a49096773e01e7d) or later, use this. For status bars this protocol is supported by somebar.
### Authors
- [MadcowOG](https://github.com/MadcowOG)
- [fbushstone](https://github.com/fbushstone)
- [notchoc](https://codeberg.org/notchoc)
- [snuk](https://codeberg.org/snuk)
+594
View File
@@ -0,0 +1,594 @@
From 5bbb9d70ab0a8322d1556ac0983eb3140b1c5dcd Mon Sep 17 00:00:00 2001
From: choc <notchoc@proton.me>
Date: Mon, 23 Oct 2023 10:35:17 +0800
Subject: [PATCH] implement dwl-ipc-unstable-v2
https://codeberg.org/dwl/dwl-patches/wiki/ipc
---
Makefile | 13 +-
config.def.h | 1 +
dwl.c | 257 ++++++++++++++++++++++++++----
protocols/dwl-ipc-unstable-v2.xml | 181 +++++++++++++++++++++
4 files changed, 415 insertions(+), 37 deletions(-)
create mode 100644 protocols/dwl-ipc-unstable-v2.xml
diff --git a/Makefile b/Makefile
index a67fdd3..2b45b2c 100644
--- a/Makefile
+++ b/Makefile
@@ -14,10 +14,11 @@ DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CF
LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS)
all: dwl
-dwl: dwl.o util.o
- $(CC) dwl.o util.o $(LDLIBS) $(LDFLAGS) $(DWLCFLAGS) -o $@
-dwl.o: dwl.c config.mk config.h client.h cursor-shape-v1-protocol.h pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h xdg-shell-protocol.h
+dwl: dwl.o util.o dwl-ipc-unstable-v2-protocol.o
+ $(CC) dwl.o util.o dwl-ipc-unstable-v2-protocol.o $(LDLIBS) $(LDFLAGS) $(DWLCFLAGS) -o $@
+dwl.o: dwl.c config.mk config.h client.h cursor-shape-v1-protocol.h pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h xdg-shell-protocol.h dwl-ipc-unstable-v2-protocol.h
util.o: util.c util.h
+dwl-ipc-unstable-v2-protocol.o: dwl-ipc-unstable-v2-protocol.c dwl-ipc-unstable-v2-protocol.h
# wayland-scanner is a tool which generates C headers and rigging for Wayland
# protocols, which are specified in XML. wlroots requires you to rig these up
@@ -37,6 +38,12 @@ wlr-layer-shell-unstable-v1-protocol.h:
xdg-shell-protocol.h:
$(WAYLAND_SCANNER) server-header \
$(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@
+dwl-ipc-unstable-v2-protocol.h:
+ $(WAYLAND_SCANNER) server-header \
+ protocols/dwl-ipc-unstable-v2.xml $@
+dwl-ipc-unstable-v2-protocol.c:
+ $(WAYLAND_SCANNER) private-code \
+ protocols/dwl-ipc-unstable-v2.xml $@
config.h:
cp config.def.h $@
diff --git a/config.def.h b/config.def.h
index 9009517..3467fed 100644
--- a/config.def.h
+++ b/config.def.h
@@ -122,6 +122,7 @@ static const Key keys[] = {
/* modifier key function argument */
{ MODKEY, XKB_KEY_p, spawn, {.v = menucmd} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} },
+ { MODKEY, XKB_KEY_b, togglebar, {0} },
{ MODKEY, XKB_KEY_j, focusstack, {.i = +1} },
{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} },
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
diff --git a/dwl.c b/dwl.c
index d508d79..5f8af37 100644
--- a/dwl.c
+++ b/dwl.c
@@ -64,6 +64,7 @@
#include <xcb/xcb_icccm.h>
#endif
+#include "dwl-ipc-unstable-v2-protocol.h"
#include "util.h"
/* macros */
@@ -141,6 +142,12 @@ typedef struct {
uint32_t resize; /* configure serial of a pending resize */
} Client;
+typedef struct {
+ struct wl_list link;
+ struct wl_resource *resource;
+ Monitor *mon;
+} DwlIpcOutput;
+
typedef struct {
uint32_t mod;
xkb_keysym_t keysym;
@@ -186,6 +193,7 @@ typedef struct {
struct Monitor {
struct wl_list link;
+ struct wl_list dwl_ipc_outputs;
struct wlr_output *wlr_output;
struct wlr_scene_output *scene_output;
struct wlr_scene_rect *fullscreen_bg; /* See createmon() for info */
@@ -278,6 +286,17 @@ static void destroypointerconstraint(struct wl_listener *listener, void *data);
static void destroysessionlock(struct wl_listener *listener, void *data);
static void destroysessionmgr(struct wl_listener *listener, void *data);
static Monitor *dirtomon(enum wlr_direction dir);
+static void dwl_ipc_manager_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id);
+static void dwl_ipc_manager_destroy(struct wl_resource *resource);
+static void dwl_ipc_manager_get_output(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *output);
+static void dwl_ipc_manager_release(struct wl_client *client, struct wl_resource *resource);
+static void dwl_ipc_output_destroy(struct wl_resource *resource);
+static void dwl_ipc_output_printstatus(Monitor *monitor);
+static void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output);
+static void dwl_ipc_output_set_client_tags(struct wl_client *client, struct wl_resource *resource, uint32_t and_tags, uint32_t xor_tags);
+static void dwl_ipc_output_set_layout(struct wl_client *client, struct wl_resource *resource, uint32_t index);
+static void dwl_ipc_output_set_tags(struct wl_client *client, struct wl_resource *resource, uint32_t tagmask, uint32_t toggle_tagset);
+static void dwl_ipc_output_release(struct wl_client *client, struct wl_resource *resource);
static void focusclient(Client *c, int lift);
static void focusmon(const Arg *arg);
static void focusstack(const Arg *arg);
@@ -330,6 +349,7 @@ 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 togglebar(const Arg *arg);
static void togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg);
static void toggletag(const Arg *arg);
@@ -405,6 +425,9 @@ static struct wlr_box sgeom;
static struct wl_list mons;
static Monitor *selmon;
+static struct zdwl_ipc_manager_v2_interface dwl_manager_implementation = {.release = dwl_ipc_manager_release, .get_output = dwl_ipc_manager_get_output};
+static struct zdwl_ipc_output_v2_interface dwl_output_implementation = {.release = dwl_ipc_output_release, .set_tags = dwl_ipc_output_set_tags, .set_layout = dwl_ipc_output_set_layout, .set_client_tags = dwl_ipc_output_set_client_tags};
+
#ifdef XWAYLAND
static void activatex11(struct wl_listener *listener, void *data);
static void associatex11(struct wl_listener *listener, void *data);
@@ -684,6 +707,10 @@ cleanupmon(struct wl_listener *listener, void *data)
LayerSurface *l, *tmp;
size_t i;
+ DwlIpcOutput *ipc_output, *ipc_output_tmp;
+ wl_list_for_each_safe(ipc_output, ipc_output_tmp, &m->dwl_ipc_outputs, link)
+ wl_resource_destroy(ipc_output->resource);
+
/* m->layers[i] are intentionally not unlinked */
for (i = 0; i < LENGTH(m->layers); i++) {
wl_list_for_each_safe(l, tmp, &m->layers[i], link)
@@ -876,6 +903,8 @@ createmon(struct wl_listener *listener, void *data)
m = wlr_output->data = ecalloc(1, sizeof(*m));
m->wlr_output = wlr_output;
+ wl_list_init(&m->dwl_ipc_outputs);
+
for (i = 0; i < LENGTH(m->layers); i++)
wl_list_init(&m->layers[i]);
@@ -1233,6 +1262,190 @@ dirtomon(enum wlr_direction dir)
return selmon;
}
+void
+dwl_ipc_manager_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+{
+ struct wl_resource *manager_resource = wl_resource_create(client, &zdwl_ipc_manager_v2_interface, version, id);
+ if (!manager_resource) {
+ wl_client_post_no_memory(client);
+ return;
+ }
+ wl_resource_set_implementation(manager_resource, &dwl_manager_implementation, NULL, dwl_ipc_manager_destroy);
+
+ zdwl_ipc_manager_v2_send_tags(manager_resource, TAGCOUNT);
+
+ for (unsigned int i = 0; i < LENGTH(layouts); i++)
+ zdwl_ipc_manager_v2_send_layout(manager_resource, layouts[i].symbol);
+}
+
+void
+dwl_ipc_manager_destroy(struct wl_resource *resource)
+{
+ /* No state to destroy */
+}
+
+void
+dwl_ipc_manager_get_output(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *output)
+{
+ DwlIpcOutput *ipc_output;
+ Monitor *monitor = wlr_output_from_resource(output)->data;
+ struct wl_resource *output_resource = wl_resource_create(client, &zdwl_ipc_output_v2_interface, wl_resource_get_version(resource), id);
+ if (!output_resource)
+ return;
+
+ ipc_output = ecalloc(1, sizeof(*ipc_output));
+ ipc_output->resource = output_resource;
+ ipc_output->mon = monitor;
+ wl_resource_set_implementation(output_resource, &dwl_output_implementation, ipc_output, dwl_ipc_output_destroy);
+ wl_list_insert(&monitor->dwl_ipc_outputs, &ipc_output->link);
+ dwl_ipc_output_printstatus_to(ipc_output);
+}
+
+void
+dwl_ipc_manager_release(struct wl_client *client, struct wl_resource *resource)
+{
+ wl_resource_destroy(resource);
+}
+
+static void
+dwl_ipc_output_destroy(struct wl_resource *resource)
+{
+ DwlIpcOutput *ipc_output = wl_resource_get_user_data(resource);
+ wl_list_remove(&ipc_output->link);
+ free(ipc_output);
+}
+
+void
+dwl_ipc_output_printstatus(Monitor *monitor)
+{
+ DwlIpcOutput *ipc_output;
+ wl_list_for_each(ipc_output, &monitor->dwl_ipc_outputs, link)
+ dwl_ipc_output_printstatus_to(ipc_output);
+}
+
+void
+dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output)
+{
+ Monitor *monitor = ipc_output->mon;
+ Client *c, *focused;
+ int tagmask, state, numclients, focused_client, tag;
+ const char *title, *appid;
+ focused = focustop(monitor);
+ zdwl_ipc_output_v2_send_active(ipc_output->resource, monitor == selmon);
+
+ for (tag = 0 ; tag < TAGCOUNT; tag++) {
+ numclients = state = focused_client = 0;
+ tagmask = 1 << tag;
+ if ((tagmask & monitor->tagset[monitor->seltags]) != 0)
+ state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE;
+
+ wl_list_for_each(c, &clients, link) {
+ if (c->mon != monitor)
+ continue;
+ if (!(c->tags & tagmask))
+ continue;
+ if (c == focused)
+ focused_client = 1;
+ if (c->isurgent)
+ state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_URGENT;
+
+ numclients++;
+ }
+ zdwl_ipc_output_v2_send_tag(ipc_output->resource, tag, state, numclients, focused_client);
+ }
+ title = focused ? client_get_title(focused) : "";
+ appid = focused ? client_get_appid(focused) : "";
+
+ zdwl_ipc_output_v2_send_layout(ipc_output->resource, monitor->lt[monitor->sellt] - layouts);
+ zdwl_ipc_output_v2_send_title(ipc_output->resource, title ? title : broken);
+ zdwl_ipc_output_v2_send_appid(ipc_output->resource, appid ? appid : broken);
+ zdwl_ipc_output_v2_send_layout_symbol(ipc_output->resource, monitor->ltsymbol);
+ if (wl_resource_get_version(ipc_output->resource) >= ZDWL_IPC_OUTPUT_V2_FULLSCREEN_SINCE_VERSION) {
+ zdwl_ipc_output_v2_send_fullscreen(ipc_output->resource, focused ? focused->isfullscreen : 0);
+ }
+ if (wl_resource_get_version(ipc_output->resource) >= ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) {
+ zdwl_ipc_output_v2_send_floating(ipc_output->resource, focused ? focused->isfloating : 0);
+ }
+ zdwl_ipc_output_v2_send_frame(ipc_output->resource);
+}
+
+void
+dwl_ipc_output_set_client_tags(struct wl_client *client, struct wl_resource *resource, uint32_t and_tags, uint32_t xor_tags)
+{
+ DwlIpcOutput *ipc_output;
+ Monitor *monitor;
+ Client *selected_client;
+ unsigned int newtags = 0;
+
+ ipc_output = wl_resource_get_user_data(resource);
+ if (!ipc_output)
+ return;
+
+ monitor = ipc_output->mon;
+ selected_client = focustop(monitor);
+ if (!selected_client)
+ return;
+
+ newtags = (selected_client->tags & and_tags) ^ xor_tags;
+ if (!newtags)
+ return;
+
+ selected_client->tags = newtags;
+ focusclient(focustop(selmon), 1);
+ arrange(selmon);
+ printstatus();
+}
+
+void
+dwl_ipc_output_set_layout(struct wl_client *client, struct wl_resource *resource, uint32_t index)
+{
+ DwlIpcOutput *ipc_output;
+ Monitor *monitor;
+
+ ipc_output = wl_resource_get_user_data(resource);
+ if (!ipc_output)
+ return;
+
+ monitor = ipc_output->mon;
+ if (index >= LENGTH(layouts))
+ return;
+ if (index != monitor->lt[monitor->sellt] - layouts)
+ monitor->sellt ^= 1;
+
+ monitor->lt[monitor->sellt] = &layouts[index];
+ arrange(monitor);
+ printstatus();
+}
+
+void
+dwl_ipc_output_set_tags(struct wl_client *client, struct wl_resource *resource, uint32_t tagmask, uint32_t toggle_tagset)
+{
+ DwlIpcOutput *ipc_output;
+ Monitor *monitor;
+ unsigned int newtags = tagmask & TAGMASK;
+
+ ipc_output = wl_resource_get_user_data(resource);
+ if (!ipc_output)
+ return;
+ monitor = ipc_output->mon;
+
+ if (!newtags || newtags == monitor->tagset[monitor->seltags])
+ return;
+ if (toggle_tagset)
+ monitor->seltags ^= 1;
+
+ monitor->tagset[monitor->seltags] = newtags;
+ focusclient(focustop(monitor), 1);
+ arrange(monitor);
+ printstatus();
+}
+
+void
+dwl_ipc_output_release(struct wl_client *client, struct wl_resource *resource)
+{
+ wl_resource_destroy(resource);
+}
+
void
focusclient(Client *c, int lift)
{
@@ -1905,41 +2118,9 @@ void
printstatus(void)
{
Monitor *m = NULL;
- Client *c;
- uint32_t occ, urg, sel;
- const char *appid, *title;
- wl_list_for_each(m, &mons, link) {
- occ = urg = 0;
- wl_list_for_each(c, &clients, link) {
- if (c->mon != m)
- continue;
- occ |= c->tags;
- if (c->isurgent)
- urg |= c->tags;
- }
- if ((c = focustop(m))) {
- title = client_get_title(c);
- appid = client_get_appid(c);
- printf("%s title %s\n", m->wlr_output->name, title ? title : broken);
- printf("%s appid %s\n", m->wlr_output->name, appid ? appid : broken);
- printf("%s fullscreen %d\n", m->wlr_output->name, c->isfullscreen);
- printf("%s floating %d\n", m->wlr_output->name, c->isfloating);
- sel = c->tags;
- } else {
- printf("%s title \n", m->wlr_output->name);
- printf("%s appid \n", m->wlr_output->name);
- printf("%s fullscreen \n", m->wlr_output->name);
- printf("%s floating \n", m->wlr_output->name);
- sel = 0;
- }
-
- printf("%s selmon %u\n", m->wlr_output->name, m == selmon);
- 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);
- }
- fflush(stdout);
+ wl_list_for_each(m, &mons, link)
+ dwl_ipc_output_printstatus(m);
}
void
@@ -2502,6 +2683,7 @@ setup(void)
LISTEN_STATIC(&output_mgr->events.test, outputmgrtest);
wlr_scene_set_presentation(scene, wlr_presentation_create(dpy, backend));
+ wl_global_create(dpy, &zdwl_ipc_manager_v2_interface, 2, NULL, dwl_ipc_manager_bind);
/* Make sure XWayland clients don't connect to the parent X server,
* e.g when running in the x11 backend or the wayland backend and the
@@ -2600,6 +2782,13 @@ tile(Monitor *m)
}
}
+void
+togglebar(const Arg *arg) {
+ DwlIpcOutput *ipc_output;
+ wl_list_for_each(ipc_output, &selmon->dwl_ipc_outputs, link)
+ zdwl_ipc_output_v2_send_toggle_visibility(ipc_output->resource);
+}
+
void
togglefloating(const Arg *arg)
{
diff --git a/protocols/dwl-ipc-unstable-v2.xml b/protocols/dwl-ipc-unstable-v2.xml
new file mode 100644
index 0000000..0a6e7e5
--- /dev/null
+++ b/protocols/dwl-ipc-unstable-v2.xml
@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+This is largely ripped from somebar's ipc patchset; just with some personal modifications.
+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">
+ This protocol allows clients to update and get updates from dwl.
+
+ Warning! The protocol described in this file is experimental and
+ backward incompatible changes may be made. Backward compatible
+ changes may be added together with the corresponding interface
+ version bump.
+ Backward incompatible changes are done by bumping the version
+ number in the protocol and interface names and resetting the
+ interface version. Once the protocol is to be declared stable,
+ the 'z' prefix and the version number in the protocol and
+ interface names are removed and the interface version number is
+ reset.
+ </description>
+
+ <interface name="zdwl_ipc_manager_v2" version="2">
+ <description summary="manage dwl state">
+ 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.
+ The dwl_ipc_manager.tags and dwl_ipc_manager.layout events expose tags and layouts to the client.
+ </description>
+
+ <request name="release" type="destructor">
+ <description summary="release dwl_ipc_manager">
+ Indicates that the client will not the dwl_ipc_manager object anymore.
+ Objects created through this instance are not affected.
+ </description>
+ </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>
+ <arg name="id" type="new_id" interface="zdwl_ipc_output_v2"/>
+ <arg name="output" type="object" interface="wl_output"/>
+ </request>
+
+ <event name="tags">
+ <description summary="Announces tag amount">
+ This event is sent after binding.
+ A roundtrip after binding guarantees the client recieved all tags.
+ </description>
+ <arg name="amount" type="uint"/>
+ </event>
+
+ <event name="layout">
+ <description summary="Announces a layout">
+ This event is sent after binding.
+ A roundtrip after binding guarantees the client recieved all layouts.
+ </description>
+ <arg name="name" type="string"/>
+ </event>
+ </interface>
+
+ <interface name="zdwl_ipc_output_v2" version="2">
+ <description summary="control dwl output">
+ Observe and control a dwl output.
+
+ Events are double-buffered:
+ Clients should cache events and redraw when a dwl_ipc_output.frame event is sent.
+
+ Request are not double-buffered:
+ The compositor will update immediately upon request.
+ </description>
+
+ <enum name="tag_state">
+ <entry name="none" value="0" summary="no state"/>
+ <entry name="active" value="1" summary="tag is active"/>
+ <entry name="urgent" value="2" summary="tag has at least one urgent client"/>
+ </enum>
+
+ <request name="release" type="destructor">
+ <description summary="release dwl_ipc_outout">
+ Indicates to that the client no longer needs this dwl_ipc_output.
+ </description>
+ </request>
+
+ <event name="toggle_visibility">
+ <description summary="Toggle client visibilty">
+ Indicates the client should hide or show themselves.
+ If the client is visible then hide, if hidden then show.
+ </description>
+ </event>
+
+ <event name="active">
+ <description summary="Update the selected output.">
+ Indicates if the output is active. Zero is invalid, nonzero is valid.
+ </description>
+ <arg name="active" type="uint"/>
+ </event>
+
+ <event name="tag">
+ <description summary="Update the state of a tag.">
+ Indicates that a tag has been updated.
+ </description>
+ <arg name="tag" type="uint" summary="Index of the tag"/>
+ <arg name="state" type="uint" enum="tag_state" summary="The state of the tag."/>
+ <arg name="clients" type="uint" summary="The number of clients in the tag."/>
+ <arg name="focused" type="uint" summary="If there is a focused client. Nonzero being valid, zero being invalid."/>
+ </event>
+
+ <event name="layout">
+ <description summary="Update the layout.">
+ Indicates a new layout is selected.
+ </description>
+ <arg name="layout" type="uint" summary="Index of the layout."/>
+ </event>
+
+ <event name="title">
+ <description summary="Update the title.">
+ Indicates the title has changed.
+ </description>
+ <arg name="title" type="string" summary="The new title name."/>
+ </event>
+
+ <event name="appid" since="1">
+ <description summary="Update the appid.">
+ Indicates the appid has changed.
+ </description>
+ <arg name="appid" type="string" summary="The new appid."/>
+ </event>
+
+ <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.
+ You can ignore the zdwl_ipc_output.layout event.
+ </description>
+ <arg name="layout" type="string" summary="The new layout"/>
+ </event>
+
+ <event name="frame">
+ <description summary="The update sequence is done.">
+ Indicates that a sequence of status updates have finished and the client should redraw.
+ </description>
+ </event>
+
+ <request name="set_tags">
+ <description summary="Set the active tags of this output"/>
+ <arg name="tagmask" type="uint" summary="bitmask of the tags that should be set."/>
+ <arg name="toggle_tagset" type="uint" summary="toggle the selected tagset, zero for invalid, nonzero for valid."/>
+ </request>
+
+ <request name="set_client_tags">
+ <description summary="Set the tags of the focused client.">
+ The tags are updated as follows:
+ new_tags = (current_tags AND and_tags) XOR xor_tags
+ </description>
+ <arg name="and_tags" type="uint"/>
+ <arg name="xor_tags" type="uint"/>
+ </request>
+
+ <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"/>
+ </request>
+
+ <!-- Version 2 -->
+ <event name="fullscreen" since="2">
+ <description summary="Update fullscreen status">
+ Indicates if the selected client on this output is fullscreen.
+ </description>
+ <arg name="is_fullscreen" type="uint" summary="If the selected client is fullscreen. Nonzero is valid, zero invalid"/>
+ </event>
+
+ <event name="floating" since="2">
+ <description summary="Update the floating status">
+ Indicates if the selected client on this output is floating.
+ </description>
+ <arg name="is_floating" type="uint" summary="If the selected client is floating. Nonzero is valid, zero invalid"/>
+ </event>
+ </interface>
+</protocol>
--
2.44.0
+29
View File
@@ -0,0 +1,29 @@
### Description
This patch adds per-client keyboard layout and ability to send current
keyboard layout information to a status bar.
Only per-client feature is enabled by default. You can edit
`kblayout_file` and `kblayout_cmd` variables to notify a status bar
about keyboard layout.
[Someblocks](https://sr.ht/~raphi/someblocks) config that works
with the example settings in `config.h`:
```c
static const Block blocks[] = {
/*Icon*/ /*Command*/ /*Update Interval*/ /*Update Signal*/
{"", "cat /tmp/dwl-keymap", 0, 1},
};
```
Both of these features are included in one patch because their
implementation happens to share some code. If you don't need
any of these features, just disable it in `config.h`.
### Download
- [git branch](https://codeberg.org/ForzCross/dwl/src/branch/kblayout.patch)
- [2024-01-21](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/kblayout/kblayout.patch)
### Authors
- [ForzCross](https://codeberg.org/ForzCross)
- [Nikita Ivanov](https://github.com/NikitaIvanovV)
+187
View File
@@ -0,0 +1,187 @@
From a0c758953fe0cbb20ea74d0acfa3e44b8173d12d Mon Sep 17 00:00:00 2001
From: ForzCross <forzcross@gmail.com>
Date: Sun, 21 Jan 2024 15:52:31 +0300
Subject: [PATCH] Add per client keyboard layout and status bar info
---
config.def.h | 3 +++
dwl.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/config.def.h b/config.def.h
index 9009517..81bb10d 100644
--- a/config.def.h
+++ b/config.def.h
@@ -13,6 +13,9 @@ static const float focuscolor[] = COLOR(0x005577ff);
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.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */
+/* keyboard layout change notification for status bar */
+static const char kblayout_file[] = "/tmp/dwl-keymap";
+static const char *kblayout_cmd[] = {"pkill", "-RTMIN+3", "someblocks", NULL};
/* tagging - TAGCOUNT must be no greater than 31 */
#define TAGCOUNT (9)
diff --git a/dwl.c b/dwl.c
index bf02a6d..17c8fa4 100644
--- a/dwl.c
+++ b/dwl.c
@@ -135,6 +135,7 @@ typedef struct {
uint32_t tags;
int isfloating, isurgent, isfullscreen;
uint32_t resize; /* configure serial of a pending resize */
+ xkb_layout_index_t layout_idx;
} Client;
typedef struct {
@@ -155,6 +156,7 @@ typedef struct {
struct wl_listener modifiers;
struct wl_listener key;
+ xkb_layout_index_t layout_idx;
} KeyboardGroup;
typedef struct {
@@ -273,6 +275,7 @@ static void fullscreennotify(struct wl_listener *listener, void *data);
static void handlesig(int signo);
static void incnmaster(const Arg *arg);
static void inputdevice(struct wl_listener *listener, void *data);
+static void kblayoutnotify(KeyboardGroup *kb, int update);
static int keybinding(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);
@@ -385,6 +388,8 @@ static struct wlr_box sgeom;
static struct wl_list mons;
static Monitor *selmon;
+xkb_layout_index_t status_layout_idx = -1;
+
#ifdef XWAYLAND
static void activatex11(struct wl_listener *listener, void *data);
static void associatex11(struct wl_listener *listener, void *data);
@@ -772,6 +777,7 @@ createkeyboard(struct wlr_keyboard *keyboard)
/* Add the new keyboard to the group */
wlr_keyboard_group_add_keyboard(kb_group.wlr_group, keyboard);
+ kblayoutnotify(&kb_group, 1);
}
void
@@ -927,6 +933,7 @@ createnotify(struct wl_listener *listener, void *data)
struct wlr_xdg_surface *xdg_surface = data;
Client *c = NULL;
LayerSurface *l = NULL;
+ struct wlr_keyboard *kb = wlr_seat_get_keyboard(seat);
if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
struct wlr_xdg_popup *popup = xdg_surface->popup;
@@ -949,6 +956,9 @@ createnotify(struct wl_listener *listener, void *data)
c = xdg_surface->data = ecalloc(1, sizeof(*c));
c->surface.xdg = xdg_surface;
c->bw = borderpx;
+ c->layout_idx = kb
+ ? xkb_state_serialize_layout(kb->xkb_state, XKB_STATE_LAYOUT_EFFECTIVE)
+ : 0;
wlr_xdg_toplevel_set_wm_capabilities(xdg_surface->toplevel,
WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
@@ -1165,6 +1175,9 @@ focusclient(Client *c, int lift)
int unused_lx, unused_ly, old_client_type;
Client *old_c = NULL;
LayerSurface *old_l = NULL;
+ xkb_mod_mask_t mdepr, mlatc, mlock;
+ xkb_layout_index_t ldepr, llatc, llock;
+ struct wlr_keyboard *kb = wlr_seat_get_keyboard(seat);
if (locked)
return;
@@ -1217,6 +1230,17 @@ focusclient(Client *c, int lift)
}
printstatus();
+ /* Update keyboard layout */
+ if (kb) {
+ mdepr = xkb_state_serialize_mods(kb->xkb_state, XKB_STATE_MODS_DEPRESSED);
+ mlatc = xkb_state_serialize_mods(kb->xkb_state, XKB_STATE_MODS_LATCHED);
+ mlock = xkb_state_serialize_mods(kb->xkb_state, XKB_STATE_MODS_LOCKED);
+ ldepr = xkb_state_serialize_layout(kb->xkb_state, XKB_STATE_LAYOUT_DEPRESSED);
+ llatc = xkb_state_serialize_layout(kb->xkb_state, XKB_STATE_LAYOUT_LATCHED);
+ llock = c ? c->layout_idx : 0;
+ xkb_state_update_mask(kb->xkb_state, mdepr, mlatc, mlock, ldepr, llatc, llock);
+ }
+
if (!c) {
/* With no client, all we have left is to clear focus */
wlr_seat_keyboard_notify_clear_focus(seat);
@@ -1227,7 +1251,7 @@ focusclient(Client *c, int lift)
motionnotify(0);
/* Have a client, so focus its top-level wlr_surface */
- client_notify_enter(client_surface(c), wlr_seat_get_keyboard(seat));
+ client_notify_enter(client_surface(c), kb);
/* Activate the new client */
client_activate_surface(client_surface(c), 1);
@@ -1352,6 +1376,41 @@ inputdevice(struct wl_listener *listener, void *data)
wlr_seat_set_capabilities(seat, caps);
}
+void
+kblayoutnotify(KeyboardGroup *kb, int update)
+{
+ FILE *f;
+ Client *c;
+ xkb_layout_index_t old = kb->layout_idx;
+
+ if (update) {
+ kb->layout_idx = xkb_state_serialize_layout(kb->wlr_group->keyboard.xkb_state,
+ XKB_STATE_LAYOUT_EFFECTIVE);
+
+ // Update client layout
+ if (kb->layout_idx != old && (c = focustop(selmon)))
+ c->layout_idx = kb->layout_idx;
+ }
+
+ // If layout did not change, do nothing
+ if (status_layout_idx == kb->layout_idx)
+ return;
+ status_layout_idx = kb->layout_idx;
+
+ // Save current layout to kblayout_file
+ if (*kblayout_file && (f = fopen(kblayout_file, "w"))) {
+ fputs(xkb_keymap_layout_get_name(kb->wlr_group->keyboard.keymap,
+ kb->layout_idx), f);
+ fclose(f);
+ }
+
+ // Run kblayout_cmd
+ if (kblayout_cmd[0] && fork() == 0) {
+ execvp(kblayout_cmd[0], (char *const *)kblayout_cmd);
+ die("dwl: execvp %s failed:", kblayout_cmd[0]);
+ }
+}
+
int
keybinding(uint32_t mods, xkb_keysym_t sym)
{
@@ -1391,6 +1450,8 @@ keypress(struct wl_listener *listener, void *data)
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
+ kblayoutnotify(group, 0);
+
/* On _press_ if there is no active screen locker,
* attempt to process a compositor keybinding. */
if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
@@ -1429,6 +1490,8 @@ keypressmod(struct wl_listener *listener, void *data)
/* Send modifiers to the client. */
wlr_seat_keyboard_notify_modifiers(seat,
&group->wlr_group->keyboard.modifiers);
+
+ kblayoutnotify(group, 1);
}
int
--
2.43.0
+18
View File
@@ -0,0 +1,18 @@
### Description
Use keycodes instead of keysyms. This way, input is independent from keyboard layout (you can use the keys.h file to customize, or get the keycodes with `wev` or `xkbcli interactive-wayland` (x11-libs/libxkbcommon[tools] in gentoo)).
### Download
- [git branch](https://codeberg.org/sevz/dwl/src/branch/keycodes)
- [2023-11-25](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/keycodes/keycodes.patch)
### Config after patching
(run in DWL source directory)
```
export XKB_DEFAULT_VARIANT=yourbestkeyboardlayout
cc -lxkbcommon -o generate-keys generate-keys.c
./generate-keys
sudo make install
```
### Authors
- [sevz](https://codeberg.org/sevz)
+598
View File
@@ -0,0 +1,598 @@
From 8e58ce22afe6a7cca34ff69d8862c89497156f40 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
<leohdz172@proton.me>
Date: Fri, 4 Jun 2021 16:51:01 -0500
Subject: [PATCH 1/2] allow use keycodes instead keysyms
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Leonardo Hernández Hernández <leohdz172@proton.me>
---
config.def.h | 85 +++++++++---------
dwl.c | 35 +++-----
keys.h | 242 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 297 insertions(+), 65 deletions(-)
create mode 100644 keys.h
diff --git a/config.def.h b/config.def.h
index a8ed61d..40e13af 100644
--- a/config.def.h
+++ b/config.def.h
@@ -104,11 +104,11 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
/* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */
#define MODKEY WLR_MODIFIER_ALT
-#define TAGKEYS(KEY,SKEY,TAG) \
+#define TAGKEYS(KEY,TAG) \
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
{ MODKEY|WLR_MODIFIER_CTRL, KEY, toggleview, {.ui = 1 << TAG} }, \
- { MODKEY|WLR_MODIFIER_SHIFT, SKEY, tag, {.ui = 1 << TAG} }, \
- { MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,SKEY,toggletag, {.ui = 1 << TAG} }
+ { MODKEY|WLR_MODIFIER_SHIFT, KEY, tag, {.ui = 1 << TAG} }, \
+ { MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,KEY,toggletag, {.ui = 1 << TAG} }
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
@@ -117,51 +117,52 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
static const char *termcmd[] = { "foot", NULL };
static const char *menucmd[] = { "bemenu-run", NULL };
+#include "keys.h"
static const Key keys[] = {
- /* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
- /* modifier key function argument */
- { MODKEY, XKB_KEY_p, spawn, {.v = menucmd} },
- { 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, XKB_KEY_i, incnmaster, {.i = +1} },
- { MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
- { MODKEY, XKB_KEY_h, setmfact, {.f = -0.05} },
- { MODKEY, XKB_KEY_l, setmfact, {.f = +0.05} },
- { MODKEY, XKB_KEY_Return, zoom, {0} },
- { MODKEY, XKB_KEY_Tab, view, {0} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} },
- { 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_space, setlayout, {0} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {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} },
- { MODKEY, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_LEFT} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater, tagmon, {.i = WLR_DIRECTION_RIGHT} },
- TAGKEYS( XKB_KEY_1, XKB_KEY_exclam, 0),
- TAGKEYS( XKB_KEY_2, XKB_KEY_at, 1),
- TAGKEYS( XKB_KEY_3, XKB_KEY_numbersign, 2),
- TAGKEYS( XKB_KEY_4, XKB_KEY_dollar, 3),
- TAGKEYS( XKB_KEY_5, XKB_KEY_percent, 4),
- TAGKEYS( XKB_KEY_6, XKB_KEY_asciicircum, 5),
- TAGKEYS( XKB_KEY_7, XKB_KEY_ampersand, 6),
- TAGKEYS( XKB_KEY_8, XKB_KEY_asterisk, 7),
- TAGKEYS( XKB_KEY_9, XKB_KEY_parenleft, 8),
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, quit, {0} },
+ /* modifier key function argument */
+ { MODKEY, Key_p, spawn, {.v = menucmd} },
+ { MODKEY|WLR_MODIFIER_SHIFT, Key_Return, spawn, {.v = termcmd} },
+ { MODKEY, Key_j, focusstack, {.i = +1} },
+ { MODKEY, Key_k, focusstack, {.i = -1} },
+ { MODKEY, Key_i, incnmaster, {.i = +1} },
+ { MODKEY, Key_d, incnmaster, {.i = -1} },
+ { MODKEY, Key_h, setmfact, {.f = -0.05} },
+ { MODKEY, Key_l, setmfact, {.f = +0.05} },
+ { MODKEY, Key_Return, zoom, {0} },
+ { MODKEY, Key_Tab, view, {0} },
+ { MODKEY|WLR_MODIFIER_SHIFT, Key_c, killclient, {0} },
+ { MODKEY, Key_t, setlayout, {.v = &layouts[0]} },
+ { MODKEY, Key_f, setlayout, {.v = &layouts[1]} },
+ { MODKEY, Key_m, setlayout, {.v = &layouts[2]} },
+ { MODKEY, Key_space, setlayout, {0} },
+ { MODKEY|WLR_MODIFIER_SHIFT, Key_space, togglefloating, {0} },
+ { MODKEY, Key_e, togglefullscreen, {0} },
+ { MODKEY, Key_0, view, {.ui = ~0} },
+ { MODKEY|WLR_MODIFIER_SHIFT, Key_0, tag, {.ui = ~0} },
+ { MODKEY, Key_comma, focusmon, {.i = WLR_DIRECTION_LEFT} },
+ { MODKEY, Key_period, focusmon, {.i = WLR_DIRECTION_RIGHT} },
+ { MODKEY|WLR_MODIFIER_SHIFT, Key_comma, tagmon, {.i = WLR_DIRECTION_LEFT} },
+ { MODKEY|WLR_MODIFIER_SHIFT, Key_period, tagmon, {.i = WLR_DIRECTION_RIGHT} },
+ TAGKEYS( Key_1, 0),
+ TAGKEYS( Key_2, 1),
+ TAGKEYS( Key_3, 2),
+ TAGKEYS( Key_4, 3),
+ TAGKEYS( Key_5, 4),
+ TAGKEYS( Key_6, 5),
+ TAGKEYS( Key_7, 6),
+ TAGKEYS( Key_8, 7),
+ TAGKEYS( Key_9, 8),
+ { MODKEY|WLR_MODIFIER_SHIFT, Key_q, quit, {0} },
/* 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} },
+ { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,Key_BackSpace, quit, {0} },
+#define CHVT(KEY,n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT, KEY, chvt, {.ui = (n)} }
/* Ctrl-Alt-Fx is used to switch to another VT, if you don't know what a VT is
* do not remove them.
*/
-#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} }
- CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6),
- CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
+ CHVT(Key_F1, 1), CHVT(Key_F2, 2), CHVT(Key_F3, 3), CHVT(Key_F4, 4),
+ CHVT(Key_F5, 5), CHVT(Key_F6, 6), CHVT(Key_F7, 7), CHVT(Key_F8, 8),
+ CHVT(Key_F9, 9), CHVT(Key_F10, 10), CHVT(Key_F11, 11), CHVT(Key_F12, 12),
};
static const Button buttons[] = {
diff --git a/dwl.c b/dwl.c
index 10d5a5b..33fb251 100644
--- a/dwl.c
+++ b/dwl.c
@@ -138,7 +138,7 @@ typedef struct {
typedef struct {
uint32_t mod;
- xkb_keysym_t keysym;
+ xkb_keycode_t keycode;
void (*func)(const Arg *);
const Arg arg;
} Key;
@@ -147,9 +147,8 @@ typedef struct {
struct wl_list link;
struct wlr_keyboard_group *wlr_group;
- int nsyms;
- const xkb_keysym_t *keysyms; /* invalid if nsyms == 0 */
- uint32_t mods; /* invalid if nsyms == 0 */
+ xkb_keycode_t keycode;
+ uint32_t mods; /* invalid if keycode == 0 */
struct wl_event_source *key_repeat_source;
struct wl_listener modifiers;
@@ -272,7 +271,7 @@ static void fullscreennotify(struct wl_listener *listener, void *data);
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 keybinding(uint32_t mods, xkb_keycode_t keycode);
static void keypress(struct wl_listener *listener, void *data);
static void keypressmod(struct wl_listener *listener, void *data);
static int keyrepeat(void *data);
@@ -1351,7 +1350,7 @@ inputdevice(struct wl_listener *listener, void *data)
}
int
-keybinding(uint32_t mods, xkb_keysym_t sym)
+keybinding(uint32_t mods, xkb_keycode_t keycode)
{
/*
* Here we handle compositor keybindings. This is when the compositor is
@@ -1361,7 +1360,7 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
const Key *k;
for (k = keys; k < END(keys); k++) {
if (CLEANMASK(mods) == CLEANMASK(k->mod)
- && sym == k->keysym && k->func) {
+ && keycode == k->keycode && k->func) {
k->func(&k->arg);
return 1;
}
@@ -1372,17 +1371,12 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
void
keypress(struct wl_listener *listener, void *data)
{
- int i;
/* This event is raised when a key is pressed or released. */
KeyboardGroup *group = wl_container_of(listener, group, key);
struct wlr_keyboard_key_event *event = data;
/* Translate libinput keycode -> xkbcommon */
uint32_t keycode = event->keycode + 8;
- /* Get a list of keysyms based on the keymap for this keyboard */
- const xkb_keysym_t *syms;
- int nsyms = xkb_state_key_get_syms(
- group->wlr_group->keyboard.xkb_state, keycode, &syms);
int handled = 0;
uint32_t mods = wlr_keyboard_get_modifiers(&group->wlr_group->keyboard);
@@ -1391,19 +1385,16 @@ keypress(struct wl_listener *listener, void *data)
/* On _press_ if there is no active screen locker,
* attempt to process a compositor keybinding. */
- if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
- for (i = 0; i < nsyms; i++)
- handled = keybinding(mods, syms[i]) || handled;
- }
+ if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED)
+ handled = keybinding(mods, keycode);
if (handled && group->wlr_group->keyboard.repeat_info.delay > 0) {
group->mods = mods;
- group->keysyms = syms;
- group->nsyms = nsyms;
+ group->keycode = keycode;
wl_event_source_timer_update(group->key_repeat_source,
group->wlr_group->keyboard.repeat_info.delay);
} else {
- group->nsyms = 0;
+ group->keycode = 0;
wl_event_source_timer_update(group->key_repeat_source, 0);
}
@@ -1433,15 +1424,13 @@ int
keyrepeat(void *data)
{
KeyboardGroup *group = data;
- int i;
- if (!group->nsyms || group->wlr_group->keyboard.repeat_info.rate <= 0)
+ if (!group->keycode || group->wlr_group->keyboard.repeat_info.rate <= 0)
return 0;
wl_event_source_timer_update(group->key_repeat_source,
1000 / group->wlr_group->keyboard.repeat_info.rate);
- for (i = 0; i < group->nsyms; i++)
- keybinding(group->mods, group->keysyms[i]);
+ keybinding(group->mods, group->keycode);
return 0;
}
diff --git a/keys.h b/keys.h
new file mode 100644
index 0000000..e732f80
--- /dev/null
+++ b/keys.h
@@ -0,0 +1,242 @@
+/* You can use the macros within this file
+ * instead of search the keycodes yourself
+ * with wev or something like that
+ * Also probably you search this:
+ * Key_XF86AudioMute
+ * Key_XF86AudioLowerVolume
+ * Key_XF86AudioRaiseVolume
+ * Key_XF86MonBrightnessDown
+ * Key_XF86MonBrightnessUp
+*/
+
+#define Key_Escape 9
+#define Key_1 10
+#define Key_2 11
+#define Key_3 12
+#define Key_4 13
+#define Key_5 14
+#define Key_6 15
+#define Key_7 16
+#define Key_8 17
+#define Key_9 18
+#define Key_0 19
+#define Key_minus 20
+#define Key_equal 21
+#define Key_BackSpace 22
+#define Key_Tab 23
+#define Key_q 24
+#define Key_w 25
+#define Key_e 26
+#define Key_r 27
+#define Key_t 28
+#define Key_y 29
+#define Key_u 30
+#define Key_i 31
+#define Key_o 32
+#define Key_p 33
+#define Key_bracketleft 34
+#define Key_bracketright 35
+#define Key_Return 36
+#define Key_Control_L 37
+#define Key_a 38
+#define Key_s 39
+#define Key_d 40
+#define Key_f 41
+#define Key_g 42
+#define Key_h 43
+#define Key_j 44
+#define Key_k 45
+#define Key_l 46
+#define Key_semicolon 47
+#define Key_apostrophe 48
+#define Key_grave 49
+#define Key_Shift_L 50
+#define Key_backslash 51
+#define Key_z 52
+#define Key_x 53
+#define Key_c 54
+#define Key_v 55
+#define Key_b 56
+#define Key_n 57
+#define Key_m 58
+#define Key_comma 59
+#define Key_period 60
+#define Key_slash 61
+#define Key_Shift_R 62
+#define Key_KP_Multiply 63
+#define Key_Alt_L 64
+#define Key_space 65
+#define Key_Caps_Lock 66
+#define Key_F1 67
+#define Key_F2 68
+#define Key_F3 69
+#define Key_F4 70
+#define Key_F5 71
+#define Key_F6 72
+#define Key_F7 73
+#define Key_F8 74
+#define Key_F9 75
+#define Key_F10 76
+#define Key_Num_Lock 77
+#define Key_Scroll_Lock 78
+#define Key_KP_Home 79
+#define Key_KP_7 Key_KP_Home
+#define Key_KP_Up 80
+#define Key_KP_8 Key_KP_Up
+#define Key_KP_Prior 81
+#define Key_KP_9 Key_KP_Prior
+#define Key_KP_Subtract 82
+#define Key_KP_Left 83
+#define Key_KP_4 Key_KP_Left
+#define Key_KP_Begin 84
+#define Key_KP_5 Key_KP_Begin
+#define Key_KP_Right 85
+#define Key_KP_6 Key_KP_Right
+#define Key_KP_Add 86
+#define Key_KP_End 87
+#define Key_KP_1 Key_KP_End
+#define Key_KP_Down 88
+#define Key_KP_2 Key_KP_Down
+#define Key_KP_Next 89
+#define Key_KP_3 Key_KP_Next
+#define Key_KP_Insert 90
+#define Key_KP_0 Key_KP_Insert
+#define Key_KP_Delete 91
+#define Key_KP_Period Key_KP_Insert
+#define Key_ISO_Level3_Shift 92
+#define Key_less 94
+#define Key_F11 95
+#define Key_F12 96
+#define Key_Katakana 98
+#define Key_Hiragana 99
+#define Key_Henkan_Mode 100
+#define Key_Hiragana_Katakana 101
+#define Key_Muhenkan 102
+#define Key_KP_Enter 104
+#define Key_Control_R 105
+#define Key_KP_Divide 106
+#define Key_Print 107
+#define Key_Alt_R 108
+#define Key_Linefeed 109
+#define Key_Home 110
+#define Key_Up 111
+#define Key_Prior 112
+#define Key_Left 113
+#define Key_Right 114
+#define Key_End 115
+#define Key_Down 116
+#define Key_Next 117
+#define Key_Insert 118
+#define Key_Delete 119
+#define Key_XF86AudioMute 121
+#define Key_XF86AudioLowerVolume 122
+#define Key_XF86AudioRaiseVolume 123
+#define Key_XF86PowerOff 124
+#define Key_KP_Equal 125
+#define Key_plusminus 126
+#define Key_Pause 127
+#define Key_XF86LaunchA 128
+#define Key_KP_Decimal 129
+#define Key_Hangul 130
+#define Key_Hangul_Hanja 131
+#define Key_Super_L 133
+#define Key_Super_R 134
+#define Key_Menu 135
+#define Key_Cancel 136
+#define Key_Redo 137
+#define Key_SunProps 138
+#define Key_Undo 139
+#define Key_SunFront 140
+#define Key_XF86Copy 141
+#define Key_XF86Open 142
+#define Key_XF86Paste 143
+#define Key_Find 144
+#define Key_XF86Cut 145
+#define Key_Help 146
+#define Key_XF86MenuKB 147
+#define Key_XF86Calculator 148
+#define Key_XF86Sleep 150
+#define Key_XF86WakeUp 151
+#define Key_XF86Explorer 152
+#define Key_XF86Send 153
+#define Key_XF86Xfer 155
+#define Key_XF86Launch1 156
+#define Key_XF86Launch2 157
+#define Key_XF86WWW 158
+#define Key_XF86DOS 159
+#define Key_XF86ScreenSaver 160
+#define Key_XF86RotateWindows 161
+#define Key_XF86TaskPane 162
+#define Key_XF86Mail 163
+#define Key_XF86Favorites 164
+#define Key_XF86MyComputer 165
+#define Key_XF86Back 166
+#define Key_XF86Forward 167
+#define Key_XF86Eject1 169
+#define Key_XF86Eject2 170
+#define Key_XF86AudioNext 171
+#define Key_XF86AudioPlay 172
+#define Key_XF86AudioPrev 173
+#define Key_XF86AudioStop 174
+#define Key_XF86AudioRecord 175
+#define Key_XF86AudioRewind 176
+#define Key_XF86Phone 177
+#define Key_XF86Tools 179
+#define Key_XF86HomePage 180
+#define Key_XF86Reload 181
+#define Key_XF86Close 182
+#define Key_XF86ScrollUp 185
+#define Key_XF86ScrollDown 186
+#define Key_parenleft 187
+#define Key_parenright 188
+#define Key_XF86New 189
+#define Key_Redo2 190
+#define Key_XF86Tools2 191
+#define Key_XF86Launch5 192
+#define Key_XF86Launch6 193
+#define Key_XF86Launch7 194
+#define Key_XF86Launch8 195
+#define Key_XF86Launch9 196
+#define Key_XF86AudioMicMute 198
+#define Key_XF86TouchpadToggle 199
+#define Key_XF86TouchpadOn 200
+#define Key_XF86TouchpadOff 201
+#define Key_Mode_switch 203
+#define Key_XF86AudioPlay2 208
+#define Key_XF86AudioPause 209
+#define Key_XF86Launch3 210
+#define Key_XF86Launch4 211
+#define Key_XF86LaunchB 212
+#define Key_XF86Suspend 213
+#define Key_XF86Close2 214
+#define Key_XF86AudioPlay3 215
+#define Key_XF86AudioForward 216
+#define Key_Print2 218
+#define Key_XF86WebCam 220
+#define Key_XF86AudioPreset 221
+#define Key_XF86Mail2 223
+#define Key_XF86Messenger 224
+#define Key_XF86Search 225
+#define Key_XF86Go 226
+#define Key_XF86Finance 227
+#define Key_XF86Game 228
+#define Key_XF86Shop 229
+#define Key_Cancel2 231
+#define Key_XF86MonBrightnessDown 232
+#define Key_XF86MonBrightnessUp 233
+#define Key_XF86AudioMedia 234
+#define Key_XF86Display 235
+#define Key_XF86KbdLightOnOff 236
+#define Key_XF86KbdBrightnessDown 237
+#define Key_XF86KbdBrightnessUp 238
+#define Key_XF86Send2 239
+#define Key_XF86Reply 240
+#define Key_XF86MailForward 241
+#define Key_XF86Save 242
+#define Key_XF86Documents 243
+#define Key_XF86Battery 244
+#define Key_XF86Bluetooth 245
+#define Key_XF86WLAN 246
+#define Key_XF86MonBrightnessCycle 251
+#define Key_XF86WWAN 254
+#define Key_XF86RFKill 255
--
2.43.0
From 9d24eaa9b2bd2c87c975882cd0b2adba978db564 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
<leohdz172@proton.me>
Date: Sun, 19 Mar 2023 15:50:07 -0600
Subject: [PATCH 2/2] add program to generate keys.h
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Leonardo Hernández Hernández <leohdz172@proton.me>
---
generate-keys.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 82 insertions(+)
create mode 100644 generate-keys.c
diff --git a/generate-keys.c b/generate-keys.c
new file mode 100644
index 0000000..83458fb
--- /dev/null
+++ b/generate-keys.c
@@ -0,0 +1,82 @@
+/******************************************************************
+ * Copyright 2023 Leonardo Hernández Hernández
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the “Software”), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ ******************************************************************/
+
+/* cc -lxkbcommon -o generate-keys generate-keys.c */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <xkbcommon/xkbcommon.h>
+
+int
+main(void)
+{
+ struct xkb_context *context;
+ /* Allow generate keys with a different layout and variant.
+ * You can also use XKB_DEFAULT_* environmental variables and let this as is */
+ struct xkb_rule_names rules = {
+ 0
+ };
+ struct xkb_keymap *keymap;
+ struct xkb_state *state;
+ xkb_keycode_t keycode, min_keycode, max_keycode;
+ int i, nsyms;
+ const xkb_keysym_t *syms;
+ char keyname[64];
+ FILE *f = fopen("keys.h", "w");
+ if (!f) {
+ perror("Couldn't open keys.h");
+ return EXIT_FAILURE;
+ }
+
+ if (!(context = xkb_context_new(XKB_CONTEXT_NO_FLAGS))) {
+ fputs("Couldn't create xkbcommon context\n", stderr);
+ return EXIT_FAILURE;
+ }
+
+ if (!(keymap = xkb_keymap_new_from_names(context, &rules,
+ XKB_KEYMAP_COMPILE_NO_FLAGS))) {
+ fputs("Couldn't create xkbcommon keymap\n", stderr);
+ return EXIT_FAILURE;
+ }
+
+ if (!(state = xkb_state_new(keymap))) {
+ fputs("Couldn't create xkbcommon state\n", stderr);
+ return EXIT_FAILURE;
+ }
+
+ min_keycode = xkb_keymap_min_keycode(keymap);
+ max_keycode = xkb_keymap_max_keycode(keymap);
+
+ for (keycode = min_keycode; keycode <= max_keycode; keycode++) {
+ nsyms = xkb_state_key_get_syms(state, keycode, &syms);
+ for (i = 0; i < nsyms; i++) {
+ xkb_keysym_get_name(syms[i], keyname, sizeof(keyname) / sizeof(keyname[0]));
+ fprintf(f, "#define Key_%-24s %d\n", keyname, keycode);
+ }
+ }
+
+ xkb_state_unref(state);
+ xkb_keymap_unref(keymap);
+ xkb_context_unref(context);
+}
--
2.43.0
+21
View File
@@ -0,0 +1,21 @@
### Description
Adds touchscreen functionality.
This patch was based on the [simple-touch-input](https://codeberg.org/dwl/dwl-patches/wiki/simple-touch-input) but instead of emulating mouse movement, this now forwards the appropriate event notifications to clients.
KNOWN BUGS:
- Sometimes, the pointer moves to where the screen is pressed, but the button press doesn't occur until the screen is touched AGAIN. This means that if you touch to click button 'Q' on the screen (for instance), nothing happens; then you touch elsewhere on the screen and THEN button 'Q' registers a click. This is annoying, doesn't always happen, and I don't yet know how to fix it.
### Download
- [git branch](https://codeberg.org/minego/dwl/src/branch/touch)
- [2024-03-26](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/less-simple-touch-input/less-simple-touch-input.patch)
### Authors
- [minego](https://codeberg.org/minego)
- [fauxmight](https://codeberg.org/fauxmight)
- [Unprex](https://github.com/Unprex)
### Changelog
- 2024-02-11 Corrected issue where motion events where not sending notifications for unfocused clients such as an on screen keyboard
- 2024-03-26 Rebased, and removed #ifdef's for the pointer constraints patch which has been merged into upstream
- 2024-03-28 Removed debug
@@ -0,0 +1,263 @@
From adc8734017644f44443db30e976cf03147c7c3c4 Mon Sep 17 00:00:00 2001
From: Micah N Gorrell <m@minego.net>
Date: Fri, 9 Feb 2024 17:08:20 -0700
Subject: [PATCH 1/2] Add support for touch screen input devices, and send the
appropriate events to clients
Send notification of touch motition events even if there is no client to focus. This is important for swiping on an OSK.
Add support for touch screen input devices, and send the appropriate events to clients
Removed #ifdef around code that needs pointer constraints now that that is merged to upstream
---
dwl.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 145 insertions(+)
diff --git a/dwl.c b/dwl.c
index 5867b0c..fe447fb 100644
--- a/dwl.c
+++ b/dwl.c
@@ -47,6 +47,7 @@
#include <wlr/types/wlr_session_lock_v1.h>
#include <wlr/types/wlr_single_pixel_buffer_v1.h>
#include <wlr/types/wlr_subcompositor.h>
+#include <wlr/types/wlr_touch.h>
#include <wlr/types/wlr_viewporter.h>
#include <wlr/types/wlr_virtual_keyboard_v1.h>
#include <wlr/types/wlr_virtual_pointer_v1.h>
@@ -161,6 +162,12 @@ typedef struct {
struct wl_listener key;
} KeyboardGroup;
+typedef struct TouchGroup {
+ struct wl_list link;
+ struct wlr_touch *touch;
+ Monitor *m;
+} TouchGroup;
+
typedef struct {
/* Must keep these three elements in this order */
unsigned int type; /* LayerShell */
@@ -264,7 +271,9 @@ static void createmon(struct wl_listener *listener, void *data);
static void createnotify(struct wl_listener *listener, void *data);
static void createpointer(struct wlr_pointer *pointer);
static void createpointerconstraint(struct wl_listener *listener, void *data);
+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);
@@ -334,6 +343,10 @@ static void togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
+static void touchdown(struct wl_listener *listener, void *data);
+static void touchup(struct wl_listener *listener, void *data);
+static void touchframe(struct wl_listener *listener, void *data);
+static void touchmotion(struct wl_listener *listener, void *data);
static void unlocksession(struct wl_listener *listener, void *data);
static void unmaplayersurfacenotify(struct wl_listener *listener, void *data);
static void unmapnotify(struct wl_listener *listener, void *data);
@@ -404,6 +417,7 @@ static struct wlr_output_layout *output_layout;
static struct wlr_box sgeom;
static struct wl_list mons;
static Monitor *selmon;
+static struct wl_list touches;
#ifdef XWAYLAND
static void activatex11(struct wl_listener *listener, void *data);
@@ -1041,6 +1055,16 @@ createpointerconstraint(struct wl_listener *listener, void *data)
&pointer_constraint->destroy, destroypointerconstraint);
}
+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)
{
@@ -1412,6 +1436,9 @@ inputdevice(struct wl_listener *listener, void *data)
case WLR_INPUT_DEVICE_POINTER:
createpointer(wlr_pointer_from_input_device(device));
break;
+ case WLR_INPUT_DEVICE_TOUCH:
+ createtouch(wlr_touch_from_input_device(device));
+ break;
default:
/* TODO handle other input device types */
break;
@@ -1424,6 +1451,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);
}
@@ -2431,6 +2460,13 @@ setup(void)
LISTEN_STATIC(&cursor->events.axis, axisnotify);
LISTEN_STATIC(&cursor->events.frame, cursorframe);
+ wl_list_init(&touches);
+
+ LISTEN_STATIC(&cursor->events.touch_down, touchdown);
+ LISTEN_STATIC(&cursor->events.touch_frame, touchframe);
+ LISTEN_STATIC(&cursor->events.touch_motion, touchmotion);
+ LISTEN_STATIC(&cursor->events.touch_up, touchup);
+
cursor_shape_mgr = wlr_cursor_shape_manager_v1_create(dpy, 1);
LISTEN_STATIC(&cursor_shape_mgr->events.request_set_shape, setcursorshape);
@@ -2647,6 +2683,115 @@ toggleview(const Arg *arg)
printstatus();
}
+void
+touchdown(struct wl_listener *listener, void *data)
+{
+ struct wlr_touch_down_event *event = data;
+ double lx, ly;
+ double sx, sy;
+ struct wlr_surface *surface;
+ Client *c = NULL;
+ uint32_t serial = 0;
+ Monitor *m;
+
+ wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
+
+ // Map the input to the appropriate output, to ensure that rotation is
+ // handled.
+ wl_list_for_each(m, &mons, link) {
+ if (m == NULL || m->wlr_output == NULL) {
+ continue;
+ }
+ if (event->touch->output_name != NULL && 0 != strcmp(event->touch->output_name, m->wlr_output->name)) {
+ continue;
+ }
+
+ wlr_cursor_map_input_to_output(cursor, &event->touch->base, m->wlr_output);
+ }
+
+ wlr_cursor_absolute_to_layout_coords(cursor, &event->touch->base, event->x, event->y, &lx, &ly);
+
+ /* Find the client under the pointer and send the event along. */
+ xytonode(lx, ly, &surface, &c, NULL, &sx, &sy);
+ // fprintf(stderr, "touch_down at %lf, %lf\n", lx, ly);
+
+ if (surface != NULL) {
+ serial = wlr_seat_touch_notify_down(seat, surface, event->time_msec, event->touch_id, sx, sy);
+ }
+
+ if (serial && wlr_seat_touch_num_points(seat) == 1) {
+ /* Emulate a mouse click if the touch event wasn't handled */
+ struct wlr_pointer_button_event *button_event = data;
+ 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 = WLR_BUTTON_PRESSED;
+ buttonpress(listener, button_event);
+ }
+}
+
+void
+touchup(struct wl_listener *listener, void *data)
+{
+ struct wlr_touch_up_event *event = data;
+
+ if (!wlr_seat_touch_get_point(seat, event->touch_id)) {
+ return;
+ }
+
+ if (wlr_seat_touch_num_points(seat) == 1) {
+ struct wlr_pointer_button_event *button_event = data;
+
+ button_event->button = BTN_LEFT;
+ button_event->state = WLR_BUTTON_RELEASED;
+ buttonpress(listener, button_event);
+ }
+
+ wlr_seat_touch_notify_up(seat, event->time_msec, event->touch_id);
+ wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
+}
+
+void
+touchframe(struct wl_listener *listener, void *data)
+{
+ wlr_seat_touch_notify_frame(seat);
+ wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
+}
+
+void
+touchmotion(struct wl_listener *listener, void *data)
+{
+ struct wlr_touch_motion_event *event = data;
+ double lx, ly;
+ double sx, sy;
+ struct wlr_surface *surface;
+ Client *c = NULL;
+
+ if (!wlr_seat_touch_get_point(seat, event->touch_id)) {
+ return;
+ }
+
+ wlr_cursor_absolute_to_layout_coords(cursor, &event->touch->base, event->x, event->y, &lx, &ly);
+ xytonode(lx, ly, &surface, &c, NULL, &sx, &sy);
+
+ if (c != NULL) {
+ wlr_seat_touch_point_focus(seat, surface, event->time_msec, event->touch_id, sx, sy);
+ } else {
+ 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.44.0
From c2e4ff7253f33c80552abe9126e3c57d0aa23560 Mon Sep 17 00:00:00 2001
From: Micah N Gorrell <m@minego.net>
Date: Thu, 28 Mar 2024 11:25:59 -0600
Subject: [PATCH 2/2] Removed debug
---
dwl.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/dwl.c b/dwl.c
index fe447fb..c26c581 100644
--- a/dwl.c
+++ b/dwl.c
@@ -2713,7 +2713,6 @@ touchdown(struct wl_listener *listener, void *data)
/* Find the client under the pointer and send the event along. */
xytonode(lx, ly, &surface, &c, NULL, &sx, &sy);
- // fprintf(stderr, "touch_down at %lf, %lf\n", lx, ly);
if (surface != NULL) {
serial = wlr_seat_touch_notify_down(seat, surface, event->time_msec, event->touch_id, sx, sy);
--
2.44.0
+9
View File
@@ -0,0 +1,9 @@
### Description
Limits nmaster to within the range of currently-opened windows (nmaster will not change past the full horizontal split layout)
### Download
- [git branch](https://codeberg.org/dev-gm/dwl/src/branch/limitnmaster)
- [2024-03-15](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/limitnmaster/limitnmaster.patch)
### Authors
- [dev-gm](https://codeberg.org/dev-gm)
+33
View File
@@ -0,0 +1,33 @@
From 20c948398af900564a59007fc08d15eaa0b65da3 Mon Sep 17 00:00:00 2001
From: Gavin M <github@gavinm.us>
Date: Fri, 15 Mar 2024 17:33:27 -0500
Subject: [PATCH] Added limitnmaster
---
dwl.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/dwl.c b/dwl.c
index 5867b0c..210c41d 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1391,9 +1391,15 @@ handlesig(int signo)
void
incnmaster(const Arg *arg)
{
+ unsigned int n = 0;
+ Client *c;
+
if (!arg || !selmon)
return;
- selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
+ wl_list_for_each(c, &clients, link)
+ if (VISIBLEON(c, selmon) && !c->isfloating && !c->isfullscreen)
+ n++;
+ selmon->nmaster = MIN(MAX(selmon->nmaster + arg->i, 0), n);
arrange(selmon);
}
--
2.44.0
+23
View File
@@ -0,0 +1,23 @@
### Description
This patch allows you to add keybindings to the lockscreen.
```c
static const Key lockedkeys[] = {
/* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
/* modifier key function argument */
/* 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} },
#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} }
CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6),
CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
};
```
### Download
- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.5/lockedkeys)
- [2024-04-11](https://codeberg.org/dwl/dwl-patches/raw/commit/fc4146f3068dcd46035a2a11fe9d6109a97ae6d6/lockedkeys/lockedkeys.patch)
- [v0.5](https://codeberg.org/dwl/dwl-patches/raw/commit/2a6560c167e5c9afc5598ac5431d23d90de8846c/lockedkeys/lockedkeys.patch)
### Authors
- [wochap](https://codeberg.org/wochap)
+79
View File
@@ -0,0 +1,79 @@
From 70dc03a3817b8fd933244c2db1bb849d9626b12b Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Thu, 11 Apr 2024 13:16:40 -0500
Subject: [PATCH] allow to add keybindings in lockscreen
---
config.def.h | 11 +++++++++++
dwl.c | 20 ++++++++++++++++++++
2 files changed, 31 insertions(+)
diff --git a/config.def.h b/config.def.h
index 8847e58..0d4a4f8 100644
--- a/config.def.h
+++ b/config.def.h
@@ -164,6 +164,17 @@ static const Key keys[] = {
CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
};
+static const Key lockedkeys[] = {
+ /* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
+ /* modifier key function argument */
+
+ /* 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} },
+#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} }
+ CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6),
+ CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
+};
+
static const Button buttons[] = {
{ MODKEY, BTN_LEFT, moveresize, {.ui = CurMove} },
{ MODKEY, BTN_MIDDLE, togglefloating, {0} },
diff --git a/dwl.c b/dwl.c
index bf763df..db4bb2b 100644
--- a/dwl.c
+++ b/dwl.c
@@ -287,6 +287,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 lockedkeybinding(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);
@@ -1446,6 +1447,21 @@ keybinding(uint32_t mods, xkb_keysym_t sym)
return 0;
}
+int
+lockedkeybinding(uint32_t mods, xkb_keysym_t sym)
+{
+ int handled = 0;
+ const Key *k;
+ for (k = lockedkeys; k < END(lockedkeys); k++) {
+ 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)
{
@@ -1473,6 +1489,10 @@ keypress(struct wl_listener *listener, void *data)
handled = keybinding(mods, syms[i]) || handled;
}
+ if (locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED)
+ for (i = 0; i < nsyms; i++)
+ handled = lockedkeybinding(mods, syms[i]) || handled;
+
if (handled && group->wlr_group->keyboard.repeat_info.delay > 0) {
group->mods = mods;
group->keysyms = syms;
--
2.43.2
+9
View File
@@ -0,0 +1,9 @@
### Description
Show the master area to the right.
### Download
- [git branch](https://codeberg.org/sevz/dwl/src/branch/master-right)
- [2023-11-25](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/master-right/master-right.patch)
### Authors
- [sevz](https://codeberg.org/sevz)
+35
View File
@@ -0,0 +1,35 @@
From 4693a27d3c435883743f60dbe3c0c523bdc1a0cc Mon Sep 17 00:00:00 2001
From: Sevz17 <leohdz172@outlook.com>
Date: Fri, 25 Jun 2021 19:50:56 -0500
Subject: [PATCH] show master area to the right
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Leonardo Hernández Hernández <leohdz172@proton.me>
---
dwl.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dwl.c b/dwl.c
index 10d5a5b..5ae2605 100644
--- a/dwl.c
+++ b/dwl.c
@@ -2470,11 +2470,12 @@ tile(Monitor *m)
if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
continue;
if (i < m->nmaster) {
- resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw,
+ resize(c, (struct wlr_box){.x = m->w.x + m->w.width - mw,
+ .y = m->w.y + my, .width = mw,
.height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0);
my += c->geom.height;
} else {
- resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y + ty,
+ resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + ty,
.width = m->w.width - mw, .height = (m->w.height - ty) / (n - i)}, 0);
ty += c->geom.height;
}
--
2.43.0
+33
View File
@@ -0,0 +1,33 @@
### Description
Dynamically adjusts the borders between adjacent windows to make them visually merge
**NOTE:** to disable minimalborders after applying this patch, set `draw_minimal_borders` to `0`
```c
static const int draw_minimal_borders = 0; /* disable minimalborders */
```
<details>
<summary>Preview:</summary>
<pre>
with:
```c
static const unsigned int borderpx = 10; /* border pixel of windows */
```
Before applying the patch
<img src="https://i.imgur.com/VQfXCjp.png"/>
After applying the patch
<img src="https://i.imgur.com/I7s0Xkv.png"/>
</pre>
</details>
### Download
- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.5/minimalborders)
- [2024-04-11](https://codeberg.org/dwl/dwl-patches/raw/commit/7a5c3420822074c544fa102e030b7c30aa6b6be8/minimalborders/minimalborders.patch)
- [v0.5](https://codeberg.org/dwl/dwl-patches/raw/commit/be3735bc6a5c64ff76c200a8679453bd179be456/minimalborders/minimalborders.patch)
### Authors
- [wochap](https://codeberg.org/wochap)
+162
View File
@@ -0,0 +1,162 @@
From 225fcc26d1b0fd696a90817c996b670ced8964f2 Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Thu, 11 Apr 2024 14:34:45 -0500
Subject: [PATCH] apply minimal borders
dynamically adjusts the borders between adjacent clients to make them visually merge
---
config.def.h | 1 +
dwl.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 72 insertions(+), 6 deletions(-)
diff --git a/config.def.h b/config.def.h
index 8847e58..55d8796 100644
--- a/config.def.h
+++ b/config.def.h
@@ -7,6 +7,7 @@
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 */
+static const int draw_minimal_borders = 1; /* merge adjacent borders */
static const float rootcolor[] = COLOR(0x222222ff);
static const float bordercolor[] = COLOR(0x444444ff);
static const float focuscolor[] = COLOR(0x005577ff);
diff --git a/dwl.c b/dwl.c
index bf763df..d581f31 100644
--- a/dwl.c
+++ b/dwl.c
@@ -105,6 +105,7 @@ typedef struct Monitor Monitor;
typedef struct {
/* Must keep these three elements in this order */
unsigned int type; /* XDGShell or X11* */
+ int interact;
struct wlr_box geom; /* layout-relative, includes border */
Monitor *mon;
struct wlr_scene_tree *scene;
@@ -312,7 +313,8 @@ static void rendermon(struct wl_listener *listener, void *data);
static void requestdecorationmode(struct wl_listener *listener, void *data);
static void requeststartdrag(struct wl_listener *listener, void *data);
static void requestmonstate(struct wl_listener *listener, void *data);
-static void resize(Client *c, struct wlr_box geo, int interact);
+static void resizeapply(Client *c, struct wlr_box geo, int interact);
+static void resizenoapply(Client *c, struct wlr_box geo, int interact);
static void run(char *startup_cmd);
static void setcursor(struct wl_listener *listener, void *data);
static void setcursorshape(struct wl_listener *listener, void *data);
@@ -405,6 +407,8 @@ static struct wlr_box sgeom;
static struct wl_list mons;
static Monitor *selmon;
+static void (*resize)(Client *c, struct wlr_box geo, int interact) = resizeapply;
+
#ifdef XWAYLAND
static void activatex11(struct wl_listener *listener, void *data);
static void associatex11(struct wl_listener *listener, void *data);
@@ -473,6 +477,35 @@ applyrules(Client *c)
setmon(c, mon, newtags);
}
+void
+applyminimalborders(Client *c, Monitor *m)
+{
+ struct wlr_box geom = c->geom;
+
+ geom.x -= borderpx;
+ geom.width += borderpx;
+ geom.y -= borderpx;
+ geom.height += borderpx;
+
+ if (geom.x < m->w.x) {
+ geom.x += borderpx;
+ geom.width -= borderpx;
+ }
+ if (geom.x + geom.width > m->w.width - (int)borderpx) {
+ geom.width -= borderpx;
+ }
+
+ if (geom.y < m->w.y) {
+ geom.y += borderpx;
+ geom.height -= borderpx;
+ }
+ if (geom.y + geom.height > m->w.height - (int)borderpx) {
+ geom.height -= borderpx;
+ }
+
+ resize(c, geom, 0);
+}
+
void
arrange(Monitor *m)
{
@@ -493,8 +526,28 @@ arrange(Monitor *m)
strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol));
- if (m->lt[m->sellt]->arrange)
- m->lt[m->sellt]->arrange(m);
+ if (m->lt[m->sellt]->arrange) {
+ if (draw_minimal_borders) {
+ int save_width = m->w.width;
+ int save_height = m->w.height;
+ m->w.width += borderpx;
+ m->w.height += borderpx;
+ resize = resizenoapply;
+ m->lt[m->sellt]->arrange(m);
+ wl_list_for_each(c, &clients, link) {
+ if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
+ continue;
+ if (draw_minimal_borders)
+ applyminimalborders(c, m);
+ resizeapply(c, c->geom, c->interact);
+ }
+ m->w.width = save_width;
+ m->w.height = save_height;
+ resize = resizeapply;
+ } else {
+ m->lt[m->sellt]->arrange(m);
+ }
+ }
motionnotify(0, NULL, 0, 0, 0, 0);
checkidleinhibitor(NULL);
}
@@ -1883,8 +1936,13 @@ pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy,
struct timespec now;
if ((!active_constraint || active_constraint->surface != surface) &&
- sloppyfocus && time && c && !client_is_unmanaged(c))
- focusclient(c, 0);
+ sloppyfocus && time && c && !client_is_unmanaged(c)) {
+ if (c->isfloating || c->isfullscreen) {
+ focusclient(c, 0);
+ } else {
+ focusclient(c, 1);
+ }
+ }
/* If surface is NULL, clear pointer focus */
if (!surface) {
@@ -2032,7 +2090,7 @@ requestmonstate(struct wl_listener *listener, void *data)
}
void
-resize(Client *c, struct wlr_box geo, int interact)
+resizeapply(Client *c, struct wlr_box geo, int interact)
{
struct wlr_box *bbox = interact ? &sgeom : &c->mon->w;
struct wlr_box clip;
@@ -2058,6 +2116,13 @@ resize(Client *c, struct wlr_box geo, int interact)
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip);
}
+void
+resizenoapply(Client *c, struct wlr_box geo, int interact)
+{
+ c->geom = geo;
+ c->interact = interact;
+}
+
void
run(char *startup_cmd)
{
--
2.43.2
+35
View File
@@ -0,0 +1,35 @@
### Description
Implement modes, that way each mapping is associated with a mode and is only active while in that mode, default mode is `NORMAL`
### Example
In the example below, you declare a mode: `BROWSER`, which is activated when you press <kbd>modkey</kbd> + <kbd>b</kbd>. Then, you can press <kbd>f</kbd> to launch `Firefox` and return to the default `NORMAL` mode.
```c
enum {
BROWSER,
};
const char *modes_labels[] = {
"browser",
};
static const Key keys[] = {
// ...
{ MODKEY, XKB_KEY_b, entermode, {.i = BROWSER} },
// ...
};
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_Escape, entermode, {.i = NORMAL} } },
};
```
### Download
- [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)
### Authors
- [wochap](https://codeberg.org/wochap)
+165
View 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
+9
View File
@@ -0,0 +1,9 @@
### Description
Allows more monitor configuration in config.h
### Download
- [git branch](https://codeberg.org/Palanix/dwl/src/branch/monfig)
- [2024-02-15](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/monfig/monfig.patch)
### Authors
- [Palanix](https://codeberg.org/Palanix)
+95
View File
@@ -0,0 +1,95 @@
From e7a8ee402ba7f03c621eab9df839aabd8aa5eb4c Mon Sep 17 00:00:00 2001
From: Palanix <palanixyt@gmail.com>
Date: Mon, 4 Apr 2022 16:08:29 +0200
Subject: [PATCH] Updated patch now allowing setting x and y
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Leonardo Hernández Hernández <leohdz172@proton.me
---
config.def.h | 11 +++++++----
dwl.c | 25 +++++++++++++++++++------
2 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/config.def.h b/config.def.h
index 8847e58..a8860c4 100644
--- a/config.def.h
+++ b/config.def.h
@@ -38,12 +38,15 @@ static const Layout layouts[] = {
/* monitors */
/* NOTE: ALWAYS add a fallback rule, even if you are completely sure it won't be used */
static const MonitorRule monrules[] = {
- /* name mfact nmaster scale layout rotate/reflect x y */
- /* example of a HiDPI laptop monitor:
- { "eDP-1", 0.5f, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
+ /* name mfact nmaster scale layout rotate/reflect x y resx resy rate mode adaptive*/
+ /* example of a HiDPI laptop monitor at 120Hz:
+ { "eDP-1", 0.5f, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, 0, 0, 0, 0, 120.000f, 1, 1},
*/
/* defaults */
- { NULL, 0.55f, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
+ { NULL, 0.55f, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, 0, 0, 0, 0, 0.0f, 0 ,1},
+ // mode let's the user decide on how dwl should implement the modes:
+ // -1 Sets a custom mode following the users choice
+ // All other number's set the mode at the index n, 0 is the standard mode; see wlr-randr
};
/* keyboard */
diff --git a/dwl.c b/dwl.c
index bf763df..fdd603b 100644
--- a/dwl.c
+++ b/dwl.c
@@ -215,6 +215,11 @@ typedef struct {
const Layout *lt;
enum wl_output_transform rr;
int x, y;
+ int resx;
+ int resy;
+ float rate;
+ int mode;
+ int adaptive;
} MonitorRule;
typedef struct {
@@ -865,6 +870,7 @@ createmon(struct wl_listener *listener, void *data)
/* This event is raised by the backend when a new output (aka a display or
* monitor) becomes available. */
struct wlr_output *wlr_output = data;
+ struct wlr_output_mode *mode = wl_container_of(wlr_output->modes.next, mode, link);
const MonitorRule *r;
size_t i;
struct wlr_output_state state;
@@ -893,16 +899,23 @@ createmon(struct wl_listener *listener, void *data)
strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol));
wlr_output_state_set_scale(&state, r->scale);
wlr_output_state_set_transform(&state, r->rr);
+
+ wlr_output_state_set_adaptive_sync_enabled(&state, r->adaptive);
+
+ if(r->mode == -1)
+ wlr_output_state_set_custom_mode(&state, r->resx, r->resy,
+ (int) (r->rate > 0 ? r->rate * 1000 : 0));
+ else if (!wl_list_empty(&wlr_output->modes)) {
+ for (int j = 0; j < r->mode; j++) {
+ mode = wl_container_of(mode->link.next, mode, link);
+ }
+ wlr_output_state_set_mode(&state, mode);
+ }
+
break;
}
}
- /* The mode is a tuple of (width, height, refresh rate), and each
- * monitor supports only a specific set of modes. We just pick the
- * monitor's preferred mode; a more sophisticated compositor would let
- * the user configure it. */
- wlr_output_state_set_mode(&state, wlr_output_preferred_mode(wlr_output));
-
/* Set up event listeners */
LISTEN(&wlr_output->events.frame, &m->frame, rendermon);
LISTEN(&wlr_output->events.destroy, &m->destroy, cleanupmon);
--
2.45.0
+24
View File
@@ -0,0 +1,24 @@
### Description
This patch provides a keybinding to center the focused floating window.
Press <kbd>MODKEY</kbd> + <kbd>x</kbd> to center the focused floating window.
It does NOT center windows that are not floating.
The variable `center_relative_to_monitor` allows the user to choose whether to center relative to the monitor or relative to the window area.
<details>
<summary>Explanation of center_relative_to_monitor:</summary>
<pre>
The "Monitor area" refers to the space enclosed by the green rectangle, while the "Window area" refers to the space enclosed by the red rectangle.
<img src="https://i.imgur.com/xhejzPh.png"/>
</pre>
</details>
### Download
- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.5/movecenter)
- [v0.5](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/movecenter/movecenter.patch)
### Authors
- [wochap](https://codeberg.org/wochap)
+73
View File
@@ -0,0 +1,73 @@
From f0d50d609a04cbcc1ae4d3cf27b68024f256207c Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Tue, 5 Mar 2024 23:39:01 -0500
Subject: [PATCH] implement keybinding to center focused windows
---
config.def.h | 2 ++
dwl.c | 23 +++++++++++++++++++++++
2 files changed, 25 insertions(+)
diff --git a/config.def.h b/config.def.h
index db0babc..71b01ab 100644
--- a/config.def.h
+++ b/config.def.h
@@ -12,6 +12,7 @@ static const float focuscolor[] = COLOR(0x005577ff);
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 */
+static const int center_relative_to_monitor = 0; /* 0 means center floating relative to the window area */
/* tagging - TAGCOUNT must be no greater than 31 */
#define TAGCOUNT (9)
@@ -135,6 +136,7 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_space, setlayout, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
+ { MODKEY, XKB_KEY_x, movecenter, {0} },
{ MODKEY, XKB_KEY_0, view, {.ui = ~0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} },
{ MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} },
diff --git a/dwl.c b/dwl.c
index ef27a1d..fb39d13 100644
--- a/dwl.c
+++ b/dwl.c
@@ -313,6 +313,7 @@ static void tagmon(const Arg *arg);
static void tile(Monitor *m);
static void togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg);
+static void movecenter(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unlocksession(struct wl_listener *listener, void *data);
@@ -2454,6 +2455,28 @@ togglefullscreen(const Arg *arg)
setfullscreen(sel, !sel->isfullscreen);
}
+void
+movecenter(const Arg *arg)
+{
+ Client *c = focustop(selmon);
+ Monitor *m = selmon;
+
+ if (!m) {
+ return;
+ }
+
+ if (c) {
+ // const int center_relative_to_monitor = arg->i;
+ struct wlr_box b = center_relative_to_monitor ? m->m : m->w;
+ resize(c, (struct wlr_box){
+ .x = (b.width - c->geom.width) / 2 + b.x,
+ .y = (b.height - c->geom.height) / 2 + b.y,
+ .width = c->geom.width,
+ .height = c->geom.height,
+ }, 1);
+ }
+}
+
void
toggletag(const Arg *arg)
{
--
2.42.0
+20
View File
@@ -0,0 +1,20 @@
### Description
This allows the user to change size and placement of floating windows using only the keyboard, default keybindings:
| Keybinding | Action |
| :--- | :--- |
| <kbd>MODKEY</kbd> + <kbd>Up</kbd> | move 40px up |
| <kbd>MODKEY</kbd> + <kbd>Down</kbd> | move 40px down |
| <kbd>MODKEY</kbd> + <kbd>Left</kbd> | move 40px left |
| <kbd>MODKEY</kbd> + <kbd>Right</kbd> | move 40px right |
| <kbd>MODKEY</kbd> + <kbd>Shift</kbd> + <kbd>Up</kbd> | shrink height 40px |
| <kbd>MODKEY</kbd> + <kbd>Shift</kbd> + <kbd>Down</kbd> | grow height 40px |
| <kbd>MODKEY</kbd> + <kbd>Shift</kbd> + <kbd>Left</kbd> | shrink width 40px |
| <kbd>MODKEY</kbd> + <kbd>Shift</kbd> + <kbd>Right</kbd> | grow width 40px |
### Download
- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.5/moveresizekb)
- [v0.5](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/moveresizekb/moveresizekb.patch)
### Authors
- [wochap](https://codeberg.org/wochap)
+70
View File
@@ -0,0 +1,70 @@
From c8af428f964679089599e4ffbe7d28d08a4e875f Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Tue, 5 Mar 2024 23:42:55 -0500
Subject: [PATCH] implement keybindings to move and resize focused floating
window
---
config.def.h | 8 ++++++++
dwl.c | 19 +++++++++++++++++++
2 files changed, 27 insertions(+)
diff --git a/config.def.h b/config.def.h
index db0babc..d0570b8 100644
--- a/config.def.h
+++ b/config.def.h
@@ -135,6 +135,14 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_space, setlayout, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
+ { MODKEY, XKB_KEY_Down, moveresizekb, {.v = (int []){ 0, 40, 0, 0 }}},
+ { MODKEY, XKB_KEY_Up, moveresizekb, {.v = (int []){ 0, -40, 0, 0 }}},
+ { MODKEY, XKB_KEY_Right, moveresizekb, {.v = (int []){ 40, 0, 0, 0 }}},
+ { MODKEY, XKB_KEY_Left, moveresizekb, {.v = (int []){ -40, 0, 0, 0 }}},
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Down, moveresizekb, {.v = (int []){ 0, 0, 0, 40 }}},
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Up, moveresizekb, {.v = (int []){ 0, 0, 0, -40 }}},
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Right, moveresizekb, {.v = (int []){ 0, 0, 40, 0 }}},
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Left, moveresizekb, {.v = (int []){ 0, 0, -40, 0 }}},
{ MODKEY, XKB_KEY_0, view, {.ui = ~0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} },
{ MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} },
diff --git a/dwl.c b/dwl.c
index ef27a1d..251472b 100644
--- a/dwl.c
+++ b/dwl.c
@@ -313,6 +313,7 @@ static void tagmon(const Arg *arg);
static void tile(Monitor *m);
static void togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg);
+static void moveresizekb(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unlocksession(struct wl_listener *listener, void *data);
@@ -2454,6 +2455,24 @@ togglefullscreen(const Arg *arg)
setfullscreen(sel, !sel->isfullscreen);
}
+void
+moveresizekb(const Arg *arg)
+{
+ Client *c = focustop(selmon);
+ Monitor *m = selmon;
+
+ if(!(m && arg && arg->v && c && c->isfloating)) {
+ return;
+ }
+
+ resize(c, (struct wlr_box){
+ .x = c->geom.x + ((int *)arg->v)[0],
+ .y = c->geom.y + ((int *)arg->v)[1],
+ .width = c->geom.width + ((int *)arg->v)[2],
+ .height = c->geom.height + ((int *)arg->v)[3],
+ }, 1);
+}
+
void
toggletag(const Arg *arg)
{
--
2.42.0
+13
View File
@@ -0,0 +1,13 @@
### Description
Allows you to move a window up and down the stack.
### Download
- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.5/movestack)
- [v0.5](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/movestack/movestack.patch)
### Authors
- [wochap](https://codeberg.org/wochap)
- [sam-barr](https://github.com/ss7m)
- [Dmitry Zakharchenko](https://github.com/dm1tz)
- [Abanoub8](https://github.com/Abanoub8)
- [Nikita Ivanov](https://github.com/NikitaIvanovV)
+79
View File
@@ -0,0 +1,79 @@
From b051f50233033b399db324b29ab24227257ac141 Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Tue, 5 Mar 2024 23:31:51 -0500
Subject: [PATCH] apply NikitaIvanovV movestack patch
source: https://github.com/djpohly/dwl/wiki/movestack
---
config.def.h | 2 ++
dwl.c | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 37 insertions(+)
diff --git a/config.def.h b/config.def.h
index db0babc..778a0dc 100644
--- a/config.def.h
+++ b/config.def.h
@@ -122,6 +122,8 @@ 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_SHIFT, XKB_KEY_J, movestack, {.i = +1} },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_K, movestack, {.i = -1} },
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
{ MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
{ MODKEY, XKB_KEY_h, setmfact, {.f = -0.05} },
diff --git a/dwl.c b/dwl.c
index ef27a1d..69b9756 100644
--- a/dwl.c
+++ b/dwl.c
@@ -279,6 +279,7 @@ static void maplayersurfacenotify(struct wl_listener *listener, void *data);
static void mapnotify(struct wl_listener *listener, void *data);
static void maximizenotify(struct wl_listener *listener, void *data);
static void monocle(Monitor *m);
+static void movestack(const Arg *arg);
static void motionabsolute(struct wl_listener *listener, void *data);
static void motionnotify(uint32_t time);
static void motionrelative(struct wl_listener *listener, void *data);
@@ -1603,6 +1604,40 @@ monocle(Monitor *m)
wlr_scene_node_raise_to_top(&c->scene->node);
}
+void
+movestack(const Arg *arg)
+{
+ Client *c, *sel = focustop(selmon);
+
+ if (!sel) {
+ return;
+ }
+
+ if (wl_list_length(&clients) <= 1) {
+ return;
+ }
+
+ if (arg->i > 0) {
+ wl_list_for_each(c, &sel->link, link) {
+ if (VISIBLEON(c, selmon) || &c->link == &clients) {
+ break; /* found it */
+ }
+ }
+ } else {
+ wl_list_for_each_reverse(c, &sel->link, link) {
+ if (VISIBLEON(c, selmon) || &c->link == &clients) {
+ break; /* found it */
+ }
+ }
+ /* backup one client */
+ c = wl_container_of(c->link.prev, c, link);
+ }
+
+ wl_list_remove(&sel->link);
+ wl_list_insert(&c->link, &sel->link);
+ arrange(selmon);
+}
+
void
motionabsolute(struct wl_listener *listener, void *data)
{
--
2.42.0
+15
View File
@@ -0,0 +1,15 @@
### Description
Allows for the creation of multiple scratchpad windows, each assigned to a different keybinding. In simple terms, it enables 'run or raise' functionality
This patch adds the following functions:
* `togglescratch`: simply toggles the scratchpad window
* `focusortogglescratch`: change the focus to the scratchpad window if it is visible and toggles it if it is already in focus
* `focusortogglematchingscratch`: similar to `focusortogglescratch` but also closes all other scratchpad windows
### Download
- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.5/namedscratchpads)
- [v0.5](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/namedscratchpads/namedscratchpads.patch)
### Authors
- [wochap](https://codeberg.org/wochap)
- [Louis-Michel Raynauld](https://github.com/loumray)

Some files were not shown because too many files have changed in this diff Show More