Compare commits

...
11 Commits
27 changed files with 901 additions and 120 deletions
+3 -2
View File
@@ -5,8 +5,9 @@ Note: Commands from array are executed using execvp(). So if you need to execute
### Download ### Download
- [git branch](https://codeberg.org/sevz/dwl/src/branch/autostart) - [git branch](https://codeberg.org/sevz/dwl/src/branch/autostart)
- [autostart-wlroots-next-f4249db.patch](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/autostart/autostart-wlroots-next-f4249db.patch) - [autostart_main-5fd19fe](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/autostart/autostart_main-5fd19fe.patch)
- [autostart-0.8.patch](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/autostart/autostart-0.8.patch) - [autostart_wlroots-next-f4249db.patch](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/autostart/autostart_wlroots-next-f4249db.patch)
- [autostart_0.8.patch](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/autostart/autostart_0.8.patch)
### Authors ### Authors
- [fauxmight](https://codeberg.org/fauxmight) - [fauxmight](https://codeberg.org/fauxmight)
@@ -0,0 +1,128 @@
diff --git a/config.def.h b/config.def.h
index 572984b..0697b66 100644
--- a/config.def.h
+++ b/config.def.h
@@ -20,6 +20,12 @@ static const float fullscreen_bg[] = {0.0f, 0.0f, 0.0f, 1.0f}; /* You ca
/* 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 */
{ "Gimp_EXAMPLE", NULL, 0, 1, -1 }, /* Start on currently visible tags floating, not tiled */
diff --git a/dwl.c b/dwl.c
index f902ace..36496b3 100644
--- a/dwl.c
+++ b/dwl.c
@@ -263,6 +263,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 capturerequest(struct wl_listener *listener, void *data);
@@ -471,6 +472,9 @@ static struct wl_listener xwayland_ready = {.notify = xwaylandready};
static struct wlr_xwayland *xwayland;
#endif
+static pid_t *autostart_pids;
+static size_t autostart_len;
+
/* configuration, allows nested code to access above variables */
#include "config.h"
@@ -630,6 +634,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)
{
@@ -767,12 +792,23 @@ checkidleinhibitor(struct wlr_surface *exclude)
void
cleanup(void)
{
+ size_t i;
+
cleanuplisteners();
#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);
@@ -1646,10 +1682,25 @@ gpureset(struct wl_listener *listener, void *data)
void
handlesig(int signo)
{
- if (signo == SIGCHLD)
- while (waitpid(-1, NULL, WNOHANG) > 0);
- else if (signo == SIGINT || signo == SIGTERM)
+ if (signo == SIGCHLD) {
+ pid_t pid, *p, *lim;
+ while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
+ if (pid == child_pid)
+ child_pid = -1;
+ if (!(p = autostart_pids))
+ continue;
+ lim = &p[autostart_len];
+
+ for (; p < lim; p++) {
+ if (*p == pid) {
+ *p = -1;
+ break;
+ }
+ }
+ }
+ } else if (signo == SIGINT || signo == SIGTERM) {
quit(NULL);
+ }
}
void
@@ -2365,6 +2416,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)
+1 -1
View File
@@ -7,7 +7,7 @@ covering the wallpaper more than necessary.
### Download ### Download
- [git branch](https://codeberg.org/guidocella/dwl/src/branch/center-terminal) - [git branch](https://codeberg.org/guidocella/dwl/src/branch/center-terminal)
- [2026-02-09](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/center-terminal/center-terminal.patch) - [2026-09-16](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/center-terminal/center-terminal.patch)
### Authors ### Authors
- [Guido Cella](https://codeberg.org/guidocella) - [Guido Cella](https://codeberg.org/guidocella)
+14 -14
View File
@@ -1,4 +1,4 @@
From 897765216ac8567a40654b813379a4e074ca6298 Mon Sep 17 00:00:00 2001 From 974db1c4a01a38e2c2af9460e4d9c5f48e7974f7 Mon Sep 17 00:00:00 2001
From: Guido Cella <guido@guidocella.xyz> From: Guido Cella <guido@guidocella.xyz>
Date: Mon, 9 Feb 2026 10:21:33 +0100 Date: Mon, 9 Feb 2026 10:21:33 +0100
Subject: [PATCH] add a keybinding to center the terminal Subject: [PATCH] add a keybinding to center the terminal
@@ -14,7 +14,7 @@ covering the wallpaper more than necessary.
2 files changed, 21 insertions(+) 2 files changed, 21 insertions(+)
diff --git a/config.def.h b/config.def.h diff --git a/config.def.h b/config.def.h
index 8a6eda0..8c35c40 100644 index 13c5322..aef03cb 100644
--- a/config.def.h --- a/config.def.h
+++ b/config.def.h +++ b/config.def.h
@@ -138,6 +138,7 @@ static const Key keys[] = { @@ -138,6 +138,7 @@ static const Key keys[] = {
@@ -23,13 +23,13 @@ index 8a6eda0..8c35c40 100644
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} }, { MODKEY, XKB_KEY_e, togglefullscreen, {0} },
+ { MODKEY, XKB_KEY_v, togglecenter, {0} }, + { MODKEY, XKB_KEY_v, togglecenter, {0} },
{ MODKEY, XKB_KEY_0, view, {.ui = ~0} }, { MODKEY, XKB_KEY_0, view, {.ui = ~0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_0, tag, {.ui = ~0} },
{ MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} }, { MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} },
diff --git a/dwl.c b/dwl.c diff --git a/dwl.c b/dwl.c
index 44f3ad9..9ee397a 100644 index f7bda0b..cfdd4d1 100644
--- a/dwl.c --- a/dwl.c
+++ b/dwl.c +++ b/dwl.c
@@ -8,6 +8,7 @@ @@ -9,6 +9,7 @@
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -37,15 +37,15 @@ index 44f3ad9..9ee397a 100644
#include <sys/wait.h> #include <sys/wait.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
@@ -138,6 +139,7 @@ typedef struct { @@ -158,6 +159,7 @@ typedef struct {
unsigned int bw; unsigned int bw;
uint32_t tags; uint32_t tags;
int isfloating, isurgent, isfullscreen; int isfloating, isurgent, isfullscreen;
+ bool centered; + bool centered;
uint32_t resize; /* configure serial of a pending resize */
} Client; } Client;
@@ -334,6 +336,7 @@ static void startdrag(struct wl_listener *listener, void *data); typedef struct {
@@ -354,6 +356,7 @@ static void startdrag(struct wl_listener *listener, void *data);
static void tag(const Arg *arg); static void tag(const Arg *arg);
static void tagmon(const Arg *arg); static void tagmon(const Arg *arg);
static void tile(Monitor *m); static void tile(Monitor *m);
@@ -53,16 +53,16 @@ index 44f3ad9..9ee397a 100644
static void togglefloating(const Arg *arg); static void togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg); static void togglefullscreen(const Arg *arg);
static void toggletag(const Arg *arg); static void toggletag(const Arg *arg);
@@ -436,6 +439,8 @@ static struct wl_listener request_start_drag = {.notify = requeststartdrag}; @@ -460,6 +463,8 @@ static struct wl_listener start_drag = {.notify = startdrag};
static struct wl_listener start_drag = {.notify = startdrag};
static struct wl_listener new_session_lock = {.notify = locksession}; static struct wl_listener new_session_lock = {.notify = locksession};
static struct wl_listener new_foreign_toplevel_capture_request = {.notify = capturerequest};
+static bool center; +static bool center;
+ +
#ifdef XWAYLAND #ifdef XWAYLAND
static void activatex11(struct wl_listener *listener, void *data); static void activatex11(struct wl_listener *listener, void *data);
static void associatex11(struct wl_listener *listener, void *data); static void associatex11(struct wl_listener *listener, void *data);
@@ -499,6 +504,9 @@ applyrules(Client *c) @@ -534,6 +539,9 @@ applyrules(Client *c)
} }
} }
@@ -72,7 +72,7 @@ index 44f3ad9..9ee397a 100644
c->isfloating |= client_is_float_type(c); c->isfloating |= client_is_float_type(c);
setmon(c, mon, newtags); setmon(c, mon, newtags);
} }
@@ -2731,6 +2739,11 @@ tile(Monitor *m) @@ -2886,6 +2894,11 @@ tile(Monitor *m)
if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
continue; continue;
if (i < m->nmaster) { if (i < m->nmaster) {
@@ -84,7 +84,7 @@ index 44f3ad9..9ee397a 100644
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, .y = m->w.y + my, .width = mw,
.height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0); .height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0);
my += c->geom.height; my += c->geom.height;
@@ -2743,6 +2756,13 @@ tile(Monitor *m) @@ -2898,6 +2911,13 @@ tile(Monitor *m)
} }
} }
@@ -99,5 +99,5 @@ index 44f3ad9..9ee397a 100644
togglefloating(const Arg *arg) togglefloating(const Arg *arg)
{ {
-- --
2.52.0 2.55.0
+4 -4
View File
@@ -9,14 +9,14 @@ The variable `center_relative_to_monitor` allows the user to choose whether to c
<summary>Explanation of center_relative_to_monitor:</summary> <summary>Explanation of center_relative_to_monitor:</summary>
<pre> <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. 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"/> <img src="customfloat-monitor-vs-window.png"/>
</pre> </pre>
</details> </details>
### Download ### Download
- [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.5/customfloat) - [customfloat_main-5fd19fe](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/customfloat/customfloat_main-5fd19fe.patch)
- [wlroots-next-f4249db](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/customfloat/customfloat-wlroots-next-f4249db.patch) - [customfloat_wlroots-next-f4249db](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/customfloat/customfloat_wlroots-next-f4249db.patch)
- [0.8](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/customfloat/customfloat-0.8.patch) - [customfloat_0.8](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/customfloat/customfloat_0.8.patch)
### Authors ### Authors
- [fauxmight](https://codeberg.org/fauxmight) - [fauxmight](https://codeberg.org/fauxmight)
Binary file not shown.

After

Width:  |  Height:  |  Size: 286 KiB

@@ -0,0 +1,82 @@
diff --git a/config.def.h b/config.def.h
index 572984b..708d87a 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.0f, 0.0f, 0.0f, 1.0f}; /* You can also use glsl colors */
+static const int respect_monitor_reserved_area = 0; /* 1 to monitor center while respecting the monitor's reserved area, 0 to monitor center */
/* tagging - TAGCOUNT must be no greater than 31 */
#define TAGCOUNT (9)
@@ -21,9 +22,9 @@ static const float fullscreen_bg[] = {0.0f, 0.0f, 0.0f, 1.0f}; /* You ca
static int log_level = WLR_ERROR;
static const Rule rules[] = {
- /* app_id title tags mask isfloating monitor */
- { "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 monitor x y width height */
+ { "Gimp_EXAMPLE", NULL, 0, 1, -1, -1, -1, 1000, 0.75 }, /* Start on currently visible tags floating, not tiled */
+ { "firefox_EXAMPLE", NULL, 1 << 8, 0, -1, -1, -1, -1, -1 }, /* Start on ONLY tag "9" */
/* default/example rule: can be changed but cannot be eliminated; at least one rule must exist */
};
diff --git a/dwl.c b/dwl.c
index f902ace..97e09e6 100644
--- a/dwl.c
+++ b/dwl.c
@@ -245,6 +245,10 @@ typedef struct {
uint32_t tags;
int isfloating;
int monitor;
+ int x;
+ int y;
+ float w;
+ float h;
} Rule;
typedef struct {
@@ -506,6 +510,11 @@ applyrules(Client *c)
int i;
const Rule *r;
Monitor *mon = selmon, *m;
+ int newwidth;
+ int newheight;
+ int newx;
+ int newy;
+ int apply_resize = 0;
appid = client_get_appid(c);
title = client_get_title(c);
@@ -519,12 +528,29 @@ applyrules(Client *c)
wl_list_for_each(m, &mons, link) {
if (r->monitor == i++)
mon = m;
+ if (c->isfloating || !mon->lt[mon->sellt]->arrange) {
+ /* client is floating or in floating layout */
+ struct wlr_box b = respect_monitor_reserved_area ? mon->w : mon->m;
+ newwidth = (int)round((r->w >= 0) ? (r->w <= 1 ? b.width * r->w : r->w) : c->geom.width);
+ newheight = (int)round((r->h >= 0) ? (r->h <= 1 ? b.height * r->h : r->h) : c->geom.height);
+ newx = (int)round((r->x >= 0) ? (r->x <= 1 ? b.width * r->x + b.x : r->x + b.x) : c->geom.x);
+ newy = (int)round((r->y >= 0) ? (r->y <= 1 ? b.height * r->y + b.y : r->y + b.y) : c->geom.y);
+ apply_resize = 1;
+ }
}
}
}
c->isfloating |= client_is_float_type(c);
setmon(c, mon, newtags);
+ if (apply_resize) {
+ resize(c, (struct wlr_box){
+ .x = newx,
+ .y = newy,
+ .width = newwidth,
+ .height = newheight,
+ }, 1);
+ }
}
void
+12
View File
@@ -0,0 +1,12 @@
### Description
Hides all slave clients behind last focused slave in deck layout.
### Dependencies
This patch depends on [decklayout](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/decklayout/) and [hide-behind-monocle](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/hide-behind-monocle/) patches (suggest installing it in metioned sequence).
### Download
- [0.8](/dwl/dwl-patches/raw/branch/main/patches/hide-behind-deck/hide-behind-deck.patch)
### Authors
- [tvtur](https://codeberg.org/tvtur)
@@ -0,0 +1,132 @@
From 295945a45db881627501eb4dbca151aaa6b8b8ed Mon Sep 17 00:00:00 2001
From: tvtur <tur.timothy@gmail.com>
Date: Mon, 13 Apr 2026 13:21:13 +0300
Subject: [PATCH] hide-behind-deck
---
dwl.c | 54 +++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 37 insertions(+), 17 deletions(-)
diff --git a/dwl.c b/dwl.c
index 5d6db1a..090d44d 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, ismaster;
uint32_t resize; /* configure serial of a pending resize */
} Client;
@@ -290,7 +290,7 @@ static Client *focustop(Monitor *m, int onlytiled);
static void fullscreennotify(struct wl_listener *listener, void *data);
static void gpureset(struct wl_listener *listener, void *data);
static void handlesig(int signo);
-static void hidebehindmonocle(Monitor *m);
+static void hidebehind(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);
@@ -1431,7 +1431,7 @@ focusclient(Client *c, int lift)
wl_list_insert(&fstack, &c->flink);
selmon = c->mon;
c->isurgent = 0;
- hidebehindmonocle(c->mon);
+ hidebehind(c->mon);
/* Don't change border color if there is an exclusive focus or we are
* handling a drag operation */
@@ -1573,21 +1573,38 @@ handlesig(int signo)
}
void
-hidebehindmonocle(Monitor *m)
+hidebehind(Monitor *m)
{
Client *c;
- if (m && m->lt[m->sellt]->arrange == monocle) {
- wl_list_for_each(c, &clients, link) {
- if (c->mon != m)
- continue;
- wlr_scene_node_set_enabled(&c->scene->node, VISIBLEON(c, m) && c->isfloating);
- }
+ int check1 = 0;
- c = NULL;
-
- /* Enable top tiled client, fullscreen is considered tiled */
- if ((c = focustop(m, 1)))
- wlr_scene_node_set_enabled(&c->scene->node, 1);
+ if (m) {
+ if (m && m->lt[m->sellt]->arrange == monocle) {
+ wl_list_for_each(c, &clients, link) {
+ if (c->mon != m)
+ continue;
+ 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);
+ } else if (m && m->lt[m->sellt]->arrange == deck) {
+ wl_list_for_each(c, &fstack, flink) {
+ if (!VISIBLEON(c, m))
+ continue;
+ if (c->isfloating || c->ismaster) {
+ wlr_scene_node_set_enabled(&c->scene->node, 1);
+ continue;
+ }
+ if (!check1 && !c->ismaster) {
+ wlr_scene_node_set_enabled(&c->scene->node, 1);
+ check1 = 1;
+ continue;
+ }
+ wlr_scene_node_set_enabled(&c->scene->node, 0);
+ }
+ }
}
}
@@ -1859,7 +1876,7 @@ monocle(Monitor *m)
}
if (n)
snprintf(m->ltsymbol, LENGTH(m->ltsymbol), "[%d]", n);
- hidebehindmonocle(m);
+ hidebehind(m);
}
void
@@ -1871,7 +1888,6 @@ deck(Monitor *m)
/* count tiled clients */
wl_list_for_each(c, &clients, link)
-
/* if (VISIBLEON(c, m) && !c->isfloating && !c->isfullscreen) */
if (VISIBLEON(c, m) && !c->isfloating)
n++;
@@ -1909,6 +1925,7 @@ deck(Monitor *m)
.height = (m->w.height - my) / (MIN(n, m->nmaster) - i)
}, 0);
my += c->geom.height;
+ c->ismaster = 1;
} else {
/* deck clients: overlap in stack area */
resize(c, (struct wlr_box){
@@ -1917,9 +1934,12 @@ deck(Monitor *m)
.width = m->w.width - mw,
.height = m->w.height
}, 0);
+ c->ismaster = 0;
}
i++;
}
+
+ hidebehind(m);
}
void
--
2.53.0
+2
View File
@@ -5,6 +5,8 @@ Hide all clients behind the focused one in the monocle layout
- [git branch](https://codeberg.org/sevz/dwl/src/branch/hide-behind-monocle) - [git branch](https://codeberg.org/sevz/dwl/src/branch/hide-behind-monocle)
- [main 2025-01-20](/dwl/dwl-patches/raw/branch/main/patches/hide-behind-monocle/hide-behind-monocle.patch) - [main 2025-01-20](/dwl/dwl-patches/raw/branch/main/patches/hide-behind-monocle/hide-behind-monocle.patch)
- [hide-behind-monocle-0.7.patch](/dwl/dwl-patches/raw/branch/main/patches/hide-behind-monocle/hide-behind-monocle-0.7.patch) - [hide-behind-monocle-0.7.patch](/dwl/dwl-patches/raw/branch/main/patches/hide-behind-monocle/hide-behind-monocle-0.7.patch)
- [hide-behind-monocle-0.8.patch](/dwl/dwl-patches/raw/branch/main/patches/hide-behind-monocle/hide-behind-monocle-0.8.patch)
### Authors ### Authors
- [tvtur](https://codeberg.org/tvtur)
- [sevz](https://codeberg.org/sevz) - [sevz](https://codeberg.org/sevz)
@@ -0,0 +1,327 @@
From de87e122a354fde6f22610c1a15d6cc0b17f465a Mon Sep 17 00:00:00 2001
From: tvtur <tur.timothy@gmail.com>
Date: Sun, 23 Aug 2026 20:45:49 +0300
Subject: [PATCH] patch
---
dwl.c | 87 +++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 55 insertions(+), 32 deletions(-)
diff --git a/dwl.c b/dwl.c
index 44f3ad9..ec712e9 100644
--- a/dwl.c
+++ b/dwl.c
@@ -285,10 +285,11 @@ 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 gpureset(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);
@@ -519,7 +520,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));
@@ -813,7 +814,7 @@ closemon(Monitor *m)
if (c->mon == m)
setmon(c, selmon, c->tags);
}
- focusclient(focustop(selmon), 1);
+ focusclient(focustop(selmon, 0), 1);
printstatus();
}
@@ -1250,7 +1251,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, NULL, 0, 0, 0, 0);
wl_list_remove(&listener->link);
free(listener);
@@ -1289,7 +1290,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, NULL, 0, 0, 0, 0);
destroy:
@@ -1318,7 +1319,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);
}
@@ -1429,6 +1430,7 @@ focusclient(Client *c, int lift)
wl_list_insert(&fstack, &c->flink);
selmon = c->mon;
c->isurgent = 0;
+ hidebehindmonocle(c->mon);
/* Don't change border color if there is an exclusive focus or we are
* handling a drag operation */
@@ -1482,14 +1484,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 && !client_has_children(sel)))
return;
if (arg->i > 0) {
@@ -1515,12 +1517,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;
}
@@ -1566,6 +1571,25 @@ handlesig(int signo)
quit(NULL);
}
+void
+hidebehindmonocle(Monitor *m)
+{
+ Client *c;
+ if (m && m->lt[m->sellt]->arrange == monocle) {
+ wl_list_for_each(c, &clients, link) {
+ if (c->mon != m)
+ continue;
+ 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)
{
@@ -1705,7 +1729,7 @@ keyrepeat(void *data)
void
killclient(const Arg *arg)
{
- Client *sel = focustop(selmon);
+ Client *sel = focustop(selmon, 0);
if (sel)
client_send_close(sel);
}
@@ -1834,8 +1858,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
@@ -2101,7 +2124,7 @@ printstatus(void)
if (c->isurgent)
urg |= c->tags;
}
- if ((c = focustop(m))) {
+ if ((c = focustop(m, 0))) {
printf("%s title %s\n", m->wlr_output->name, client_get_title(c));
printf("%s appid %s\n", m->wlr_output->name, client_get_appid(c));
printf("%s fullscreen %d\n", m->wlr_output->name, c->isfullscreen);
@@ -2417,7 +2440,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
@@ -2691,12 +2714,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();
}
@@ -2704,7 +2727,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);
}
@@ -2746,7 +2769,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);
@@ -2755,7 +2778,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);
}
@@ -2764,12 +2787,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();
}
@@ -2782,7 +2805,7 @@ toggleview(const Arg *arg)
return;
selmon->tagset[selmon->seltags] = newtagset;
- focusclient(focustop(selmon), 1);
+ focusclient(focustop(selmon, 0), 1);
arrange(selmon);
printstatus();
}
@@ -2806,7 +2829,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, NULL, 0, 0, 0, 0);
}
@@ -2823,7 +2846,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);
@@ -2904,7 +2927,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,
@@ -2924,7 +2947,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));
@@ -2946,7 +2969,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();
}
@@ -2956,7 +2979,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;
@@ -2974,7 +2997,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();
}
@@ -3045,7 +3068,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;
@@ -3156,7 +3179,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) || !c->surface.xwayland->hints)
+ if (c == focustop(selmon, 0) || !c->surface.xwayland->hints)
return;
c->isurgent = xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints);
--
2.54.0
+3 -2
View File
@@ -2,8 +2,9 @@
Allows activating numlock or capslock at startup. Allows activating numlock or capslock at startup.
### Download ### Download
- [numlock-capslock-wlroots-next-f4249db.patch](/dwl/dwl-patches/raw/branch/main/patches/numlock-capslock/numlock-capslock-wlroots-next-f4249db.patch) - [numlock-capslock_main-5fd19fe.patch](/dwl/dwl-patches/raw/branch/main/patches/numlock-capslock/numlock-capslock_main-5fd19fe.patch)
- [numlock-capslock-0.8.patch](/dwl/dwl-patches/raw/branch/main/patches/numlock-capslock/numlock-capslock-0.8.patch) - [numlock-capslock_wlroots-next-f4249db.patch](/dwl/dwl-patches/raw/branch/main/patches/numlock-capslock/numlock-capslock_wlroots-next-f4249db.patch)
- [numlock-capslock_0.8.patch](/dwl/dwl-patches/raw/branch/main/patches/numlock-capslock/numlock-capslock_0.8.patch)
### Authors ### Authors
- [fauxmight](https://codeberg.org/fauxmight) - [fauxmight](https://codeberg.org/fauxmight)
@@ -0,0 +1,66 @@
diff --git a/config.def.h b/config.def.h
index 572984b..5dae6d3 100644
--- a/config.def.h
+++ b/config.def.h
@@ -56,6 +56,10 @@ static const struct xkb_rule_names xkb_rules = {
.options = NULL,
};
+/* numlock and capslock */
+static const int numlock = 1;
+static const int capslock = 0;
+
static const int repeat_rate = 25;
static const int repeat_delay = 600;
diff --git a/dwl.c b/dwl.c
index f902ace..7023cab 100644
--- a/dwl.c
+++ b/dwl.c
@@ -14,6 +14,7 @@
#include <wayland-server-core.h>
#include <wlr/backend.h>
#include <wlr/backend/libinput.h>
+#include <wlr/interfaces/wlr_keyboard.h>
#include <wlr/render/allocator.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_alpha_modifier_v1.h>
@@ -373,6 +374,7 @@ static void zoom(const Arg *arg);
/* variables */
static pid_t child_pid = -1;
static int locked;
+static uint32_t locked_mods = 0;
static void *exclusive_focus;
static struct wl_display *dpy;
static struct wl_event_loop *event_loop;
@@ -1019,6 +1021,8 @@ createkeyboard(struct wlr_keyboard *keyboard)
/* Set the keymap to match the group keymap */
wlr_keyboard_set_keymap(keyboard, kb_group->wlr_group->keyboard.keymap);
+ wlr_keyboard_notify_modifiers(keyboard, 0, 0, locked_mods, 0);
+
/* Add the new keyboard to the group */
wlr_keyboard_group_add_keyboard(kb_group->wlr_group, keyboard);
}
@@ -1040,6 +1044,21 @@ createkeyboardgroup(void)
die("failed to compile keymap");
wlr_keyboard_set_keymap(&group->wlr_group->keyboard, keymap);
+ if (numlock) {
+ xkb_mod_index_t mod_index = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_NUM);
+ if (mod_index != XKB_MOD_INVALID)
+ locked_mods |= (uint32_t)1 << mod_index;
+ }
+
+ if (capslock) {
+ xkb_mod_index_t mod_index = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
+ if (mod_index != XKB_MOD_INVALID)
+ locked_mods |= (uint32_t)1 << mod_index;
+ }
+
+ if (locked_mods)
+ wlr_keyboard_notify_modifiers(&group->wlr_group->keyboard, 0, 0, locked_mods, 0);
+
xkb_keymap_unref(keymap);
xkb_context_unref(context);
+3 -2
View File
@@ -4,8 +4,9 @@ Like smartborders. Don't put borders when there is only one window on the screen
### Download ### Download
- [git branch](https://codeberg.org/bencc/dwl/src/branch/simpleborders) - [git branch](https://codeberg.org/bencc/dwl/src/branch/simpleborders)
- [simpleborders-wlroots-next-f4249db](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/simpleborders/simpleborders-wlroots-next-f4249db.patch) - [simpleborders_main-5fd19fe.patch](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/simpleborders/simpleborders_main-5fd19fe.patch)
- [simpleborders-0.8.patch](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/simpleborders/simpleborders-v0.8.patch) - [simpleborders_wlroots-next-f4249db.patch](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/simpleborders/simpleborders_wlroots-next-f4249db.patch)
- [simpleborders_0.8.patch](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/simpleborders/simpleborders_0.8.patch)
### Authors ### Authors
- [A Frederick Christensen](https://codeberg.org/fauxmight) - [A Frederick Christensen](https://codeberg.org/fauxmight)
@@ -0,0 +1,61 @@
diff --git a/dwl.c b/dwl.c
index f902ace..5c3f0ee 100644
--- a/dwl.c
+++ b/dwl.c
@@ -275,6 +275,7 @@ static void closemon(Monitor *m);
static void commitlayersurfacenotify(struct wl_listener *listener, void *data);
static void commitnotify(struct wl_listener *listener, void *data);
static void commitpopup(struct wl_listener *listener, void *data);
+static int countclients(Monitor *m);
static void createdecoration(struct wl_listener *listener, void *data);
static void createidleinhibitor(struct wl_listener *listener, void *data);
static void createkeyboard(struct wlr_keyboard *keyboard);
@@ -323,6 +324,7 @@ static void motionnotify(uint32_t time, struct wlr_input_device *device, double
double sy, double sx_unaccel, double sy_unaccel);
static void motionrelative(struct wl_listener *listener, void *data);
static void moveresize(const Arg *arg);
+static int needsborder(Client *c);
static void outputmgrapply(struct wl_listener *listener, void *data);
static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test);
static void outputmgrtest(struct wl_listener *listener, void *data);
@@ -991,6 +993,17 @@ commitpopup(struct wl_listener *listener, void *data)
free(listener);
}
+int
+countclients(Monitor *m)
+{
+ unsigned int n = 0;
+ Client *c;
+ wl_list_for_each(c, &clients, link)
+ if (VISIBLEON(c, m) && !c->isfloating && !c->isfullscreen)
+ n++;
+ return n;
+}
+
void
createdecoration(struct wl_listener *listener, void *data)
{
@@ -2099,6 +2112,14 @@ moveresize(const Arg *arg)
}
}
+int
+needsborder(Client *c) {
+ return ((countclients(c->mon) > 1
+ && c->mon->lt[c->mon->sellt]->arrange != monocle)
+ || c->isfloating)
+ && !c->isfullscreen;
+}
+
void
outputmgrapply(struct wl_listener *listener, void *data)
{
@@ -2330,6 +2351,7 @@ resize(Client *c, struct wlr_box geo, int interact)
client_set_bounds(c, geo.width, geo.height);
c->geom = geo;
+ c->bw = needsborder(c) ? borderpx : 0;
applybounds(c, bbox);
/* Update scene-graph, including borders */
+1 -1
View File
@@ -3,7 +3,7 @@ Add a rule option to switch to the configured tag when a window opens, then swit
### Download ### Download
- [git branch](https://codeberg.org/guidocella/dwl/src/branch/switchtotag) - [git branch](https://codeberg.org/guidocella/dwl/src/branch/switchtotag)
- [2026-02-09](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/switchtotag/switchtotag.patch) - [2026-09-16](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/switchtotag/switchtotag.patch)
### Authors ### Authors
- [Guido Cella](https://codeberg.org/guidocella) - [Guido Cella](https://codeberg.org/guidocella)
+21 -23
View File
@@ -1,4 +1,4 @@
From bfcfb26b00cb93a359469cb8817861439818b430 Mon Sep 17 00:00:00 2001 From 2d466821072b6b3630169a784a10b0fe40666790 Mon Sep 17 00:00:00 2001
From: Guido Cella <guido@guidocella.xyz> From: Guido Cella <guido@guidocella.xyz>
Date: Mon, 30 Sep 2024 08:40:25 +0200 Date: Mon, 30 Sep 2024 08:40:25 +0200
Subject: [PATCH] allow switching to the configured tag when a window opens Subject: [PATCH] allow switching to the configured tag when a window opens
@@ -7,14 +7,14 @@ Add a rule option to switch to the configured tag when a window opens,
then switch back when it closes. then switch back when it closes.
--- ---
config.def.h | 6 +++--- config.def.h | 6 +++---
dwl.c | 23 +++++++++++++++++++---- dwl.c | 21 +++++++++++++++++----
2 files changed, 22 insertions(+), 7 deletions(-) 2 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/config.def.h b/config.def.h diff --git a/config.def.h b/config.def.h
index 8a6eda0..59e3ac5 100644 index 13c5322..1e52d05 100644
--- a/config.def.h --- a/config.def.h
+++ b/config.def.h +++ b/config.def.h
@@ -21,9 +21,9 @@ static const float fullscreen_bg[] = {0.0f, 0.0f, 0.0f, 1.0f}; /* You ca @@ -22,9 +22,9 @@ static const float fullscreen_bg[] = {0.0f, 0.0f, 0.0f, 1.0f}; /* You ca
static int log_level = WLR_ERROR; static int log_level = WLR_ERROR;
static const Rule rules[] = { static const Rule rules[] = {
@@ -28,18 +28,18 @@ index 8a6eda0..59e3ac5 100644
}; };
diff --git a/dwl.c b/dwl.c diff --git a/dwl.c b/dwl.c
index 44f3ad9..7a97d94 100644 index f7bda0b..a58bd9a 100644
--- a/dwl.c --- a/dwl.c
+++ b/dwl.c +++ b/dwl.c
@@ -138,6 +138,7 @@ typedef struct { @@ -158,6 +158,7 @@ typedef struct {
unsigned int bw; unsigned int bw;
uint32_t tags; uint32_t tags;
int isfloating, isurgent, isfullscreen; int isfloating, isurgent, isfullscreen;
+ int switchtotag; + int switchtotag;
uint32_t resize; /* configure serial of a pending resize */
} Client; } Client;
@@ -226,6 +227,7 @@ typedef struct { typedef struct {
@@ -245,6 +246,7 @@ typedef struct {
const char *id; const char *id;
const char *title; const char *title;
uint32_t tags; uint32_t tags;
@@ -47,7 +47,7 @@ index 44f3ad9..7a97d94 100644
int isfloating; int isfloating;
int monitor; int monitor;
} Rule; } Rule;
@@ -241,7 +243,7 @@ typedef struct { @@ -260,7 +262,7 @@ typedef struct {
/* function declarations */ /* function declarations */
static void applybounds(Client *c, struct wlr_box *bbox); static void applybounds(Client *c, struct wlr_box *bbox);
@@ -56,7 +56,7 @@ index 44f3ad9..7a97d94 100644
static void arrange(Monitor *m); static void arrange(Monitor *m);
static void arrangelayer(Monitor *m, struct wl_list *list, static void arrangelayer(Monitor *m, struct wl_list *list,
struct wlr_box *usable_area, int exclusive); struct wlr_box *usable_area, int exclusive);
@@ -474,7 +476,7 @@ applybounds(Client *c, struct wlr_box *bbox) @@ -509,7 +511,7 @@ applybounds(Client *c, struct wlr_box *bbox)
} }
void void
@@ -65,7 +65,7 @@ index 44f3ad9..7a97d94 100644
{ {
/* rule matching */ /* rule matching */
const char *appid, *title; const char *appid, *title;
@@ -496,6 +498,11 @@ applyrules(Client *c) @@ -531,6 +533,11 @@ applyrules(Client *c)
if (r->monitor == i++) if (r->monitor == i++)
mon = m; mon = m;
} }
@@ -77,7 +77,7 @@ index 44f3ad9..7a97d94 100644
} }
} }
@@ -864,7 +871,7 @@ commitnotify(struct wl_listener *listener, void *data) @@ -952,7 +959,7 @@ commitnotify(struct wl_listener *listener, void *data)
* a different monitor based on its title, this will likely select * a different monitor based on its title, this will likely select
* a wrong monitor. * a wrong monitor.
*/ */
@@ -86,7 +86,7 @@ index 44f3ad9..7a97d94 100644
if (c->mon) { if (c->mon) {
client_set_scale(client_surface(c), c->mon->wlr_output->scale); client_set_scale(client_surface(c), c->mon->wlr_output->scale);
} }
@@ -1790,7 +1797,7 @@ mapnotify(struct wl_listener *listener, void *data) @@ -1914,7 +1921,7 @@ mapnotify(struct wl_listener *listener, void *data)
c->isfloating = 1; c->isfloating = 1;
setmon(c, p->mon, p->tags); setmon(c, p->mon, p->tags);
} else { } else {
@@ -95,21 +95,19 @@ index 44f3ad9..7a97d94 100644
} }
printstatus(); printstatus();
@@ -2831,6 +2838,14 @@ unmapnotify(struct wl_listener *listener, void *data) @@ -3000,6 +3007,12 @@ unmapnotify(struct wl_listener *listener, void *data)
wl_list_remove(&c->flink); wlr_scene_node_destroy(&c->image_capture_scene->tree.node);
} wlr_scene_node_destroy(&c->scene->node);
client_surface(c)->data = NULL;
+
+ if (c->switchtotag) { + if (c->switchtotag) {
+ Arg a = { .ui = c->switchtotag }; + Arg a = { .ui = c->switchtotag };
+ // Call view() -> arrange() -> checkidleinhibitor() before
+ // wlr_scene_node_destroy() to prevent a rare use after free of
+ // tree->node.
+ view(&a); + view(&a);
+ } + }
+ +
wlr_scene_node_destroy(&c->scene->node);
printstatus(); printstatus();
motionnotify(0, NULL, 0, 0, 0, 0); motionnotify(0, NULL, 0, 0, 0, 0);
}
-- --
2.52.0 2.55.0
+1 -1
View File
@@ -2,8 +2,8 @@
Hide the mouse cursor if it isn't being used for a certain period of time. Hide the mouse cursor if it isn't being used for a certain period of time.
### Download ### Download
- [0.8](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/unclutter/unclutter.patch)
- [git branch](https://codeberg.org/guidocella/dwl/src/branch/unclutter) - [git branch](https://codeberg.org/guidocella/dwl/src/branch/unclutter)
- [2026-09-16](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/unclutter/unclutter.patch)
### Authors ### Authors
- [Guido Cella](https://github.com/guidocella) - [Guido Cella](https://github.com/guidocella)
+40 -70
View File
@@ -1,18 +1,18 @@
From 3e8ba5681dc34d7bf4229708af1f4eab243f520b Mon Sep 17 00:00:00 2001 From 0987dd26a7b5dd0071fdb509b5ef61e0efbcb6cd Mon Sep 17 00:00:00 2001
From: nate zhou <gnuunixchad@outlook.com> From: Guido Cella <guido@guidocella.xyz>
Date: Fri, 10 Apr 2026 19:13:25 +0800 Date: Thu, 17 Sep 2026 08:53:31 +0200
Subject: [PATCH] Patch: unclutter-0.8.patch Subject: [PATCH] hide the cursor when it isn't being used
--- ---
config.def.h | 2 ++ config.def.h | 2 ++
dwl.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++------ dwl.c | 40 +++++++++++++++++++++++++++++++++++++---
2 files changed, 65 insertions(+), 7 deletions(-) 2 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/config.def.h b/config.def.h diff --git a/config.def.h b/config.def.h
index 8a6eda0..0a1fff5 100644 index 13c5322..45c3c76 100644
--- a/config.def.h --- a/config.def.h
+++ b/config.def.h +++ b/config.def.h
@@ -102,6 +102,8 @@ LIBINPUT_CONFIG_TAP_MAP_LMR -- 1/2/3 finger tap maps to left/middle/right @@ -103,6 +103,8 @@ LIBINPUT_CONFIG_TAP_MAP_LMR -- 1/2/3 finger tap maps to left/middle/right
*/ */
static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TAP_MAP_LRM; static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TAP_MAP_LRM;
@@ -22,10 +22,10 @@ index 8a6eda0..0a1fff5 100644
#define MODKEY WLR_MODIFIER_ALT #define MODKEY WLR_MODIFIER_ALT
diff --git a/dwl.c b/dwl.c diff --git a/dwl.c b/dwl.c
index 44f3ad9..ac21ca3 100644 index f7bda0b..c8a2f3d 100644
--- a/dwl.c --- a/dwl.c
+++ b/dwl.c +++ b/dwl.c
@@ -288,6 +288,8 @@ static void focusstack(const Arg *arg); @@ -308,6 +308,8 @@ static void focusstack(const Arg *arg);
static Client *focustop(Monitor *m); static Client *focustop(Monitor *m);
static void fullscreennotify(struct wl_listener *listener, void *data); static void fullscreennotify(struct wl_listener *listener, void *data);
static void gpureset(struct wl_listener *listener, void *data); static void gpureset(struct wl_listener *listener, void *data);
@@ -34,30 +34,25 @@ index 44f3ad9..ac21ca3 100644
static void handlesig(int signo); static void handlesig(int signo);
static void incnmaster(const Arg *arg); static void incnmaster(const Arg *arg);
static void inputdevice(struct wl_listener *listener, void *data); static void inputdevice(struct wl_listener *listener, void *data);
@@ -389,6 +391,14 @@ static struct wlr_pointer_constraint_v1 *active_constraint; @@ -411,6 +413,8 @@ static struct wlr_pointer_constraint_v1 *active_constraint;
static struct wlr_cursor *cursor; static struct wlr_cursor *cursor;
static struct wlr_xcursor_manager *cursor_mgr; static struct wlr_xcursor_manager *cursor_mgr;
+static struct wl_event_source *hide_source; +static struct wl_event_source *hide_source;
+static bool cursor_hidden = false; +static bool cursor_hidden = false;
+static struct {
+ enum wp_cursor_shape_device_v1_shape shape;
+ struct wlr_surface *surface;
+ int hotspot_x;
+ int hotspot_y;
+} last_cursor;
static struct wlr_scene_rect *root_bg; static struct wlr_scene_rect *root_bg;
static struct wlr_session_lock_manager_v1 *session_lock_mgr; static struct wlr_session_lock_manager_v1 *session_lock_mgr;
@@ -610,6 +620,7 @@ axisnotify(struct wl_listener *listener, void *data) @@ -671,6 +675,8 @@ axisnotify(struct wl_listener *listener, void *data)
* for example when you move the scroll wheel. */ wlr_seat_pointer_notify_axis(seat,
struct wlr_pointer_axis_event *event = data; event->time_msec, event->orientation, event->delta,
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); event->delta_discrete, event->source, event->relative_direction);
+
+ handlecursoractivity(); + handlecursoractivity();
/* TODO: allow usage of scroll wheel for mousebindings, it can be implemented }
* by checking the event's orientation and the delta of the event */
/* Notify the client with pointer focus of the axis event. */ void
@@ -628,6 +639,7 @@ buttonpress(struct wl_listener *listener, void *data) @@ -684,6 +690,7 @@ buttonpress(struct wl_listener *listener, void *data)
const Button *b; const Button *b;
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
@@ -65,7 +60,7 @@ index 44f3ad9..ac21ca3 100644
switch (event->state) { switch (event->state) {
case WL_POINTER_BUTTON_STATE_PRESSED: case WL_POINTER_BUTTON_STATE_PRESSED:
@@ -1566,6 +1578,32 @@ handlesig(int signo) @@ -1662,6 +1669,28 @@ handlesig(int signo)
quit(NULL); quit(NULL);
} }
@@ -79,12 +74,8 @@ index 44f3ad9..ac21ca3 100644
+ +
+ cursor_hidden = false; + cursor_hidden = false;
+ +
+ if (last_cursor.shape) + wlr_seat_pointer_clear_focus(seat);
+ wlr_cursor_set_xcursor(cursor, cursor_mgr, + motionnotify(0, NULL, 0, 0, 0, 0);
+ wlr_cursor_shape_v1_name(last_cursor.shape));
+ else
+ wlr_cursor_set_surface(cursor, last_cursor.surface,
+ last_cursor.hotspot_x, last_cursor.hotspot_y);
+} +}
+ +
+int +int
@@ -98,7 +89,7 @@ index 44f3ad9..ac21ca3 100644
void void
incnmaster(const Arg *arg) incnmaster(const Arg *arg)
{ {
@@ -1907,6 +1945,7 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d @@ -2032,6 +2061,7 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d
wlr_cursor_move(cursor, device, dx, dy); wlr_cursor_move(cursor, device, dx, dy);
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
@@ -106,7 +97,7 @@ index 44f3ad9..ac21ca3 100644
/* Update selmon (even while dragging a window) */ /* Update selmon (even while dragging a window) */
if (sloppyfocus) if (sloppyfocus)
@@ -1931,7 +1970,7 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d @@ -2066,7 +2096,7 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d
/* If there's no client surface under the cursor, set the cursor image to a /* If there's no client surface under the cursor, set the cursor image to a
* default. This is what makes the cursor image appear when you move it * default. This is what makes the cursor image appear when you move it
* off of a client or over its border. */ * off of a client or over its border. */
@@ -114,8 +105,8 @@ index 44f3ad9..ac21ca3 100644
+ if (!surface && !seat->drag && !cursor_hidden) + if (!surface && !seat->drag && !cursor_hidden)
wlr_cursor_set_xcursor(cursor, cursor_mgr, "default"); wlr_cursor_set_xcursor(cursor, cursor_mgr, "default");
pointerfocus(c, surface, sx, sy, time); pointerfocus(c, l, surface, sx, sy, time);
@@ -2288,6 +2327,7 @@ run(char *startup_cmd) @@ -2429,6 +2459,7 @@ run(char *startup_cmd)
* monitor when displayed here */ * monitor when displayed here */
wlr_cursor_warp_closest(cursor, NULL, cursor->x, cursor->y); wlr_cursor_warp_closest(cursor, NULL, cursor->x, cursor->y);
wlr_cursor_set_xcursor(cursor, cursor_mgr, "default"); wlr_cursor_set_xcursor(cursor, cursor_mgr, "default");
@@ -123,62 +114,41 @@ index 44f3ad9..ac21ca3 100644
/* Run the Wayland event loop. This does not return until you exit the /* Run the Wayland event loop. This does not return until you exit the
* compositor. Starting the backend rigged up all of the necessary event * compositor. Starting the backend rigged up all of the necessary event
@@ -2311,9 +2351,16 @@ setcursor(struct wl_listener *listener, void *data) @@ -2452,7 +2483,7 @@ setcursor(struct wl_listener *listener, void *data)
* use the provided surface as the cursor image. It will set the * use the provided surface as the cursor image. It will set the
* hardware cursor on the output that it's currently on and continue to * hardware cursor on the output that it's currently on and continue to
* do so as the cursor moves between outputs. */ * do so as the cursor moves between outputs. */
- if (event->seat_client == seat->pointer_state.focused_client) - if (event->seat_client == seat->pointer_state.focused_client)
- wlr_cursor_set_surface(cursor, event->surface, + if (event->seat_client == seat->pointer_state.focused_client && !cursor_hidden)
- event->hotspot_x, event->hotspot_y); wlr_cursor_set_surface(cursor, event->surface,
+ if (event->seat_client == seat->pointer_state.focused_client) { event->hotspot_x, event->hotspot_y);
+ last_cursor.shape = 0;
+ last_cursor.surface = event->surface;
+ last_cursor.hotspot_x = event->hotspot_x;
+ last_cursor.hotspot_y = event->hotspot_y;
+
+ if (!cursor_hidden)
+ wlr_cursor_set_surface(cursor, event->surface,
+ event->hotspot_x, event->hotspot_y);
+ }
} }
@@ -2466,7 +2497,7 @@ setcursorshape(struct wl_listener *listener, void *data)
void
@@ -2325,9 +2372,14 @@ setcursorshape(struct wl_listener *listener, void *data)
/* This can be sent by any client, so we check to make sure this one /* This can be sent by any client, so we check to make sure this one
* actually has pointer focus first. If so, we can tell the cursor to * actually has pointer focus first. If so, we can tell the cursor to
* use the provided cursor shape. */ * use the provided cursor shape. */
- if (event->seat_client == seat->pointer_state.focused_client) - if (event->seat_client == seat->pointer_state.focused_client)
- wlr_cursor_set_xcursor(cursor, cursor_mgr, + if (event->seat_client == seat->pointer_state.focused_client && !cursor_hidden)
- wlr_cursor_shape_v1_name(event->shape)); wlr_cursor_set_xcursor(cursor, cursor_mgr,
+ if (event->seat_client == seat->pointer_state.focused_client) { wlr_cursor_shape_v1_name(event->shape));
+ last_cursor.shape = event->shape;
+ last_cursor.surface = NULL;
+
+ if (!cursor_hidden)
+ wlr_cursor_set_xcursor(cursor, cursor_mgr,
+ wlr_cursor_shape_v1_name(event->shape));
+ }
} }
@@ -2768,6 +2799,8 @@ setup(void)
void
@@ -2618,6 +2670,9 @@ setup(void)
cursor_shape_mgr = wlr_cursor_shape_manager_v1_create(dpy, 1); cursor_shape_mgr = wlr_cursor_shape_manager_v1_create(dpy, 1);
wl_signal_add(&cursor_shape_mgr->events.request_set_shape, &request_set_cursor_shape); wl_signal_add(&cursor_shape_mgr->events.request_set_shape, &request_set_cursor_shape);
+ hide_source = wl_event_loop_add_timer(wl_display_get_event_loop(dpy), + hide_source = wl_event_loop_add_timer(event_loop, hidecursor, cursor);
+ hidecursor, cursor);
+ +
/* /*
* Configures a seat, which is a single "seat" at which a user sits and * Configures a seat, which is a single "seat" at which a user sits and
* operates the computer. This conceptually includes up to one keyboard, * operates the computer. This conceptually includes up to one keyboard,
@@ -3002,6 +3057,7 @@ virtualpointer(struct wl_listener *listener, void *data) @@ -3185,6 +3218,7 @@ virtualpointer(struct wl_listener *listener, void *data)
wlr_cursor_attach_input_device(cursor, device);
if (event->suggested_output) if (event->suggested_output)
wlr_cursor_map_input_to_output(cursor, device, event->suggested_output); wlr_cursor_map_input_to_output(cursor, device, event->suggested_output);
wlr_seat_set_capabilities(seat, seat->capabilities | WL_SEAT_CAPABILITY_POINTER);
+ handlecursoractivity(); + handlecursoractivity();
} }
Monitor * Monitor *
-- --
2.53.0 2.55.0