patchset 1

This commit is contained in:
Xory 2026-03-15 18:22:56 +02:00
parent a2d03cf618
commit 47a1135b59
19 changed files with 7580 additions and 141 deletions

141
patches/autostart.patch Normal file
View file

@ -0,0 +1,141 @@
From e8932f159793012a54047c48b3710703a63c07fb Mon Sep 17 00:00:00 2001
From: A Frederick Christensen <dwl@ivories.org>
Date: Fri, 27 Feb 2026 12:29:02 -0600
Subject: [PATCH] Applied autostart patch
---
config.def.h | 6 ++++++
dwl.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 61 insertions(+), 3 deletions(-)
diff --git a/config.def.h b/config.def.h
index 8a6eda0..6eb0db4 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 8a9715d..3450817 100644
--- a/dwl.c
+++ b/dwl.c
@@ -248,6 +248,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);
@@ -451,6 +452,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"
@@ -605,6 +609,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)
{
@@ -701,12 +726,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);
@@ -1562,10 +1598,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
@@ -2252,6 +2303,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.52.0

1271
patches/bar.patch Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,132 @@
From e0cecc228d436425c0d921a1eec5e0370d24613d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Desgualdo=20Pereira?= <desgua@gmail.com>
Date: Thu, 13 Nov 2025 09:09:22 -0300
Subject: [PATCH] controlled fullscreen fix
---
dwl.c | 32 ++++++++++++--------------------
1 file changed, 12 insertions(+), 20 deletions(-)
diff --git a/dwl.c b/dwl.c
index 12f441e..4f124eb 100644
--- a/dwl.c
+++ b/dwl.c
@@ -518,9 +518,6 @@ arrange(Monitor *m)
}
}
- wlr_scene_node_set_enabled(&m->fullscreen_bg->node,
- (c = focustop(m)) && c->isfullscreen);
-
strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol));
/* We move all clients (except fullscreen and unmanaged) to LyrTile while
@@ -878,7 +875,7 @@ commitnotify(struct wl_listener *listener, void *data)
return;
}
- resize(c, c->geom, (c->isfloating && !c->isfullscreen));
+ resize(c, c->geom, (c->isfloating));
/* mark a pending resize as completed */
if (c->resize && c->resize <= c->surface.xdg->current.configure_serial)
@@ -1490,7 +1487,7 @@ focusstack(const Arg *arg)
{
/* Focus the next or previous client (in tiling order) on selmon */
Client *c, *sel = focustop(selmon);
- if (!sel || (sel->isfullscreen && !client_has_children(sel)))
+ if (!sel)
return;
if (arg->i > 0) {
wl_list_for_each(c, &sel->link, link) {
@@ -1826,7 +1823,7 @@ monocle(Monitor *m)
int n = 0;
wl_list_for_each(c, &clients, link) {
- if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
+ if (!VISIBLEON(c, m) || c->isfloating)
continue;
resize(c, m->w, 0);
n++;
@@ -1957,7 +1954,7 @@ moveresize(const Arg *arg)
if (cursor_mode != CurNormal && cursor_mode != CurPressed)
return;
xytonode(cursor->x, cursor->y, NULL, &grabc, NULL, NULL, NULL);
- if (!grabc || client_is_unmanaged(grabc) || grabc->isfullscreen)
+ if (!grabc || client_is_unmanaged(grabc))
return;
/* Float the window and tell motionnotify to grab it */
@@ -2332,14 +2329,12 @@ setcursorshape(struct wl_listener *listener, void *data)
void
setfloating(Client *c, int floating)
{
- Client *p = client_get_parent(c);
c->isfloating = floating;
/* If in floating layout do not change the client's layer */
if (!c->mon || !client_surface(c)->mapped || !c->mon->lt[c->mon->sellt]->arrange)
return;
- wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen ||
- (p && p->isfullscreen) ? LyrFS
- : c->isfloating ? LyrFloat : LyrTile]);
+ wlr_scene_node_reparent(&c->scene->node,
+ layers[c->isfloating ? LyrFloat : LyrTile]);
arrange(c->mon);
printstatus();
}
@@ -2352,12 +2347,12 @@ setfullscreen(Client *c, int fullscreen)
return;
c->bw = fullscreen ? 0 : borderpx;
client_set_fullscreen(c, fullscreen);
- wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen
- ? LyrFS : c->isfloating ? LyrFloat : LyrTile]);
+ wlr_scene_node_reparent(&c->scene->node,
+ layers[c->isfloating ? LyrFloat : LyrTile]);
if (fullscreen) {
c->prev = c->geom;
- resize(c, c->mon->m, 0);
+ resize(c, c->mon->w, 0);
} else {
/* restore previous size instead of arrange for floating windows since
* client positions are set by the user and cannot be recalculated */
@@ -2716,7 +2711,7 @@ tile(Monitor *m)
Client *c;
wl_list_for_each(c, &clients, link)
- if (VISIBLEON(c, m) && !c->isfloating && !c->isfullscreen)
+ if (VISIBLEON(c, m) && !c->isfloating)
n++;
if (n == 0)
return;
@@ -2727,7 +2722,7 @@ tile(Monitor *m)
mw = m->w.width;
i = my = ty = 0;
wl_list_for_each(c, &clients, link) {
- if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
+ if (!VISIBLEON(c, m) || c->isfloating)
continue;
if (i < m->nmaster) {
resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw,
@@ -2747,7 +2742,7 @@ togglefloating(const Arg *arg)
{
Client *sel = focustop(selmon);
/* return if fullscreen */
- if (sel && !sel->isfullscreen)
+ if (sel)
setfloating(sel, !sel->isfloating);
}
@@ -2902,9 +2897,6 @@ updatemons(struct wl_listener *listener, void *data)
arrangelayers(m);
/* 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)
- resize(c, m->m, 0);
/* Try to re-set the gamma LUT when updating monitors,
* it's only really needed when enabling a disabled output, but meh. */
--
2.51.0

216
patches/dim_unfocused.patch Normal file
View file

@ -0,0 +1,216 @@
diff --git a/client.h b/client.h
index dabea35..3a31c25 100644
--- a/client.h
+++ b/client.h
@@ -319,6 +319,12 @@ client_set_border_color(Client *c, const float color[static 4])
wlr_scene_rect_set_color(c->border[i], color);
}
+static inline void
+client_set_dimmer_state(Client *c, const int dim)
+{
+ wlr_scene_node_set_enabled(&c->dimmer->node, DIMOPT && !c->neverdim && dim);
+}
+
static inline void
client_set_fullscreen(Client *c, int fullscreen)
{
diff --git a/config.def.h b/config.def.h
index 22d2171..4ca21c9 100644
--- a/config.def.h
+++ b/config.def.h
@@ -10,6 +10,7 @@ static const unsigned int borderpx = 1; /* border pixel of windows */
static const float rootcolor[] = COLOR(0x222222ff);
static const float bordercolor[] = COLOR(0x444444ff);
static const float focuscolor[] = COLOR(0x005577ff);
+static const float unfocuseddim[] = COLOR(0x00000088);
static const float urgentcolor[] = COLOR(0xff0000ff);
/* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */
static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */
@@ -22,10 +23,11 @@ static int log_level = WLR_ERROR;
/* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */
static const Rule rules[] = {
- /* app_id title tags mask isfloating monitor */
- /* examples: */
- { "Gimp_EXAMPLE", NULL, 0, 1, -1 }, /* Start on currently visible tags floating, not tiled */
- { "firefox_EXAMPLE", NULL, 1 << 8, 0, -1 }, /* Start on ONLY tag "9" */
+ /* app_id title tags mask isfloating neverdim monitor */
+ /* examples:
+ { "Gimp_example", NULL, 0, 1, 0, -1 },
+ */
+ { "firefox_example", NULL, 1 << 8, 0, 1, -1 },
};
/* layout(s) */
@@ -140,8 +142,9 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
{ MODKEY, XKB_KEY_space, setlayout, {0} },
+ { MODKEY, XKB_KEY_apostrophe, toggledimming, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
- { MODKEY, XKB_KEY_e, togglefullscreen, {0} },
+ { MODKEY, XKB_KEY_e, togglefullscreen, {0} },
{ MODKEY, XKB_KEY_0, view, {.ui = ~0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} },
{ MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} },
@@ -172,5 +175,6 @@ static const Key keys[] = {
static const Button buttons[] = {
{ MODKEY, BTN_LEFT, moveresize, {.ui = CurMove} },
{ MODKEY, BTN_MIDDLE, togglefloating, {0} },
+ { MODKEY|ShiftMask, BTN_MIDDLE, toggledimmingclient, {0} },
{ MODKEY, BTN_RIGHT, moveresize, {.ui = CurResize} },
};
diff --git a/dwl.c b/dwl.c
index dc0c861..dcc3ece 100644
--- a/dwl.c
+++ b/dwl.c
@@ -112,6 +112,7 @@ typedef struct {
Monitor *mon;
struct wlr_scene_tree *scene;
struct wlr_scene_rect *border[4]; /* top, bottom, left, right */
+ struct wlr_scene_rect *dimmer;
struct wlr_scene_tree *scene_surface;
struct wl_list link;
struct wl_list flink;
@@ -141,7 +142,7 @@ typedef struct {
#endif
unsigned int bw;
uint32_t tags;
- int isfloating, isurgent, isfullscreen;
+ int isfloating, isurgent, isfullscreen, neverdim;
uint32_t resize; /* configure serial of a pending resize */
} Client;
@@ -231,6 +232,7 @@ typedef struct {
const char *title;
uint32_t tags;
int isfloating;
+ int neverdim;
int monitor;
} Rule;
@@ -338,6 +340,8 @@ static void startdrag(struct wl_listener *listener, void *data);
static void tag(const Arg *arg);
static void tagmon(const Arg *arg);
static void tile(Monitor *m);
+static void toggledimming(const Arg *arg);
+static void toggledimmingclient(const Arg *arg);
static void togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg);
static void toggletag(const Arg *arg);
@@ -410,6 +414,7 @@ static struct wlr_output_layout *output_layout;
static struct wlr_box sgeom;
static struct wl_list mons;
static Monitor *selmon;
+static int DIMOPT = 1;
#ifdef XWAYLAND
static void activatex11(struct wl_listener *listener, void *data);
@@ -466,6 +471,7 @@ applyrules(Client *c)
if ((!r->title || strstr(title, r->title))
&& (!r->id || strstr(appid, r->id))) {
c->isfloating = r->isfloating;
+ c->neverdim = r-> neverdim;
newtags |= r->tags;
i = 0;
wl_list_for_each(m, &mons, link) {
@@ -1365,8 +1371,10 @@ focusclient(Client *c, int lift)
/* Don't change border color if there is an exclusive focus or we are
* handling a drag operation */
- if (!exclusive_focus && !seat->drag)
+ if (!exclusive_focus && !seat->drag) {
client_set_border_color(c, focuscolor);
+ client_set_dimmer_state(c, 0);
+ }
}
/* Deactivate old client if focus is changing */
@@ -1384,7 +1392,7 @@ focusclient(Client *c, int lift)
* and probably other clients */
} else if (old_c && !client_is_unmanaged(old_c) && (!c || !client_wants_focus(c))) {
client_set_border_color(old_c, bordercolor);
-
+ client_set_dimmer_state(old_c, 1);
client_activate_surface(old, 0);
}
}
@@ -1681,8 +1689,7 @@ void
mapnotify(struct wl_listener *listener, void *data)
{
/* Called when the surface is mapped, or ready to display on-screen. */
- Client *p = NULL;
- Client *w, *c = wl_container_of(listener, c, map);
+ Client *p, *w, *d, *c = wl_container_of(listener, c, map);
Monitor *m;
int i;
@@ -1716,6 +1723,10 @@ mapnotify(struct wl_listener *listener, void *data)
c->border[i]->node.data = c;
}
+ c->dimmer = wlr_scene_rect_create(c->scene, 0, 0, unfocuseddim);
+ c->dimmer->node.data = c;
+ client_set_dimmer_state(c, 1);
+
/* Initialize client geometry with room for border */
client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT);
c->geom.width += 2 * c->bw;
@@ -1734,6 +1745,10 @@ mapnotify(struct wl_listener *listener, void *data)
setmon(c, p->mon, p->tags);
} else {
applyrules(c);
+ d = focustop(selmon);
+ if (d) {
+ client_set_dimmer_state(d, 0);
+ }
}
printstatus();
@@ -2160,7 +2175,7 @@ resize(Client *c, struct wlr_box geo, int interact)
c->geom = geo;
applybounds(c, bbox);
- /* Update scene-graph, including borders */
+ /* Update scene-graph, including borders and dimmer*/
wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y);
wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw);
wlr_scene_rect_set_size(c->border[0], c->geom.width, c->bw);
@@ -2170,6 +2185,8 @@ resize(Client *c, struct wlr_box geo, int interact)
wlr_scene_node_set_position(&c->border[1]->node, 0, c->geom.height - c->bw);
wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw);
wlr_scene_node_set_position(&c->border[3]->node, c->geom.width - c->bw, c->bw);
+ wlr_scene_rect_set_size(c->dimmer, c->geom.width - 2*c->bw, c-> geom.height - 2*c->bw);
+ wlr_scene_node_set_position(&c->dimmer->node, c->bw, c->bw);
/* this is a no-op if size hasn't changed */
c->resize = client_set_size(c, c->geom.width - 2 * c->bw,
@@ -2681,6 +2698,27 @@ tile(Monitor *m)
}
}
+void toggledimming(const Arg *arg)
+{
+ Client *c;
+ DIMOPT ^= 1;
+ wl_list_for_each(c, &clients, link)
+ {
+ client_set_dimmer_state(c, 1);
+ }
+ c = focustop(selmon);
+ if (c)
+ client_set_dimmer_state(c, 0);
+}
+
+void
+toggledimmingclient(const Arg *arg)
+{
+ Client *sel = focustop(selmon);
+ if (sel)
+ sel -> neverdim ^= 1;
+}
+
void
togglefloating(const Arg *arg)
{

127
patches/gaps.patch Normal file
View file

@ -0,0 +1,127 @@
From 50e3dd4746b6cb719efb9f8213b94ac52a5320d9 Mon Sep 17 00:00:00 2001
From: peesock <kcormn@gmail.com>
Date: Mon, 24 Jun 2024 20:06:42 -0700
Subject: [PATCH] gaps!
Co-authored-by: sewn <sewn@disroot.org>
Co-authored-by: serenevoid <ajuph9224@gmail.com>
---
config.def.h | 4 ++++
dwl.c | 34 ++++++++++++++++++++++++++--------
2 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/config.def.h b/config.def.h
index 22d2171..b388b4e 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);
@@ -135,6 +138,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 dc0437e..dc851df 100644
--- a/dwl.c
+++ b/dwl.c
@@ -199,6 +199,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];
@@ -336,6 +337,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);
@@ -949,6 +951,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)) {
@@ -2638,7 +2642,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;
@@ -2647,23 +2651,30 @@ tile(Monitor *m)
n++;
if (n == 0)
return;
+ if (smartgaps == n)
+ e = 0;
if (n > m->nmaster)
- mw = m->nmaster ? (int)roundf(m->w.width * m->mfact) : 0;
+ mw = m->nmaster ? (int)roundf((m->w.width + gappx*e) * m->mfact) : 0;
else
mw = m->w.width;
- i = my = ty = 0;
+ 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 - 2*gappx*e, .height = h}, 0);
+ my += c->geom.height + gappx*e;
} else {
+ 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, .y = m->w.y + ty,
- .width = m->w.width - mw, .height = (m->w.height - ty) / (n - i)}, 0);
- ty += c->geom.height;
+ .width = m->w.width - mw - gappx*e, .height = h}, 0);
+ ty += c->geom.height + gappx*e;
}
i++;
}
@@ -2686,6 +2697,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.45.2

87
patches/movestack.patch Normal file
View file

@ -0,0 +1,87 @@
From 08230817bd3926e29d9897657eb1852cb27d461f Mon Sep 17 00:00:00 2001
From: Nikita Ivanov <nikita.vyach.ivanov@gmail.com>
Date: Tue, 4 Feb 2025 23:21:19 +0100
Subject: [PATCH] Allows you to move a window up and down the stack
---
config.def.h | 2 ++
dwl.c | 43 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 45 insertions(+)
diff --git a/config.def.h b/config.def.h
index 22d2171..2c129f2 100644
--- a/config.def.h
+++ b/config.def.h
@@ -129,6 +129,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.05f} },
diff --git a/dwl.c b/dwl.c
index def2562..045d6fa 100644
--- a/dwl.c
+++ b/dwl.c
@@ -303,6 +303,7 @@ static void locksession(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, struct wlr_input_device *device, double sx,
double sy, double sx_unaccel, double sy_unaccel);
@@ -1786,6 +1787,48 @@ 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 (&c->link == &clients) {
+ c = wl_container_of(&clients, c, link);
+ break; /* wrap past the sentinel node */
+ }
+ if (VISIBLEON(c, selmon) || &c->link == &clients) {
+ break; /* found it */
+ }
+ }
+ } else {
+ wl_list_for_each_reverse(c, &sel->link, link) {
+ if (&c->link == &clients) {
+ c = wl_container_of(&clients, c, link);
+ break; /* wrap past the sentinel node */
+ }
+ 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.48.1

View file

@ -0,0 +1,73 @@
From 09759c3ef75158c366e9fc63814485fbb31a3ccf Mon Sep 17 00:00:00 2001
From: Ben Collerson <benc@benc.cc>
Date: Sat, 30 Dec 2023 13:39:31 +1000
Subject: [PATCH] simpleborders
---
dwl.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/dwl.c b/dwl.c
index a2711f67..415fe1a0 100644
--- a/dwl.c
+++ b/dwl.c
@@ -259,6 +259,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);
@@ -308,6 +309,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);
@@ -849,6 +851,17 @@ commitpopup(struct wl_listener *listener, void *data)
wl_list_remove(&listener->link);
}
+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)
{
@@ -1927,6 +1940,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)
{
@@ -2190,6 +2211,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 */
--
2.45.2

192
patches/unclutter.patch Normal file
View file

@ -0,0 +1,192 @@
From 68914f40359ebccc7b684a1f74d82419b1796cdf Mon Sep 17 00:00:00 2001
From: Guido Cella <guido@guidocella.xyz>
Date: Thu, 25 Jul 2024 17:59:05 +0200
Subject: [PATCH] =?UTF-8?q?hide=20the=20mouse=20cursor=20if=20it=20isn?=
=?UTF-8?q?=E2=80=99t=20being=20used?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
config.def.h | 2 ++
dwl.c | 74 +++++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 67 insertions(+), 9 deletions(-)
diff --git a/config.def.h b/config.def.h
index 22d2171..790c73d 100644
--- a/config.def.h
+++ b/config.def.h
@@ -106,6 +106,8 @@ LIBINPUT_CONFIG_TAP_MAP_LMR -- 1/2/3 finger tap maps to left/middle/right
*/
static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TAP_MAP_LRM;
+static const int cursor_timeout = 5;
+
/* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */
#define MODKEY WLR_MODIFIER_ALT
diff --git a/dwl.c b/dwl.c
index 775dadf..621779e 100644
--- a/dwl.c
+++ b/dwl.c
@@ -288,6 +288,8 @@ static void focusstack(const Arg *arg);
static Client *focustop(Monitor *m);
static void fullscreennotify(struct wl_listener *listener, void *data);
static void gpureset(struct wl_listener *listener, void *data);
+static void handlecursoractivity(void);
+static int hidecursor(void *data);
static void handlesig(int signo);
static void incnmaster(const Arg *arg);
static void inputdevice(struct wl_listener *listener, void *data);
@@ -389,6 +391,14 @@ static struct wlr_pointer_constraint_v1 *active_constraint;
static struct wlr_cursor *cursor;
static struct wlr_xcursor_manager *cursor_mgr;
+static struct wl_event_source *hide_source;
+static bool cursor_hidden = false;
+static struct {
+ enum wp_cursor_shape_device_v1_shape shape;
+ struct wlr_surface *surface;
+ int hotspot_x;
+ int hotspot_y;
+} last_cursor;
static struct wlr_scene_rect *root_bg;
static struct wlr_session_lock_manager_v1 *session_lock_mgr;
@@ -609,8 +619,9 @@ axisnotify(struct wl_listener *listener, void *data)
* for example when you move the scroll wheel. */
struct wlr_pointer_axis_event *event = data;
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
- /* TODO: allow usage of scroll wheel for mousebindings, it can be implemented
- * by checking the event's orientation and the delta of the event */
+ handlecursoractivity();
+ /* TODO: allow usage of scroll wheel for mousebindings, it can be implemented
+ * checking the event's orientation and the delta of the event */
/* Notify the client with pointer focus of the axis event. */
wlr_seat_pointer_notify_axis(seat,
event->time_msec, event->orientation, event->delta,
@@ -627,6 +638,7 @@ buttonpress(struct wl_listener *listener, void *data)
const Button *b;
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
+ handlecursoractivity();
switch (event->state) {
case WL_POINTER_BUTTON_STATE_PRESSED:
@@ -1563,6 +1575,32 @@ handlesig(int signo)
quit(NULL);
}
+void
+handlecursoractivity(void)
+{
+ wl_event_source_timer_update(hide_source, cursor_timeout * 1000);
+
+ if (!cursor_hidden)
+ return;
+
+ cursor_hidden = false;
+
+ if (last_cursor.shape)
+ wlr_cursor_set_xcursor(cursor, cursor_mgr,
+ wlr_cursor_shape_v1_name(last_cursor.shape));
+ else
+ wlr_cursor_set_surface(cursor, last_cursor.surface,
+ last_cursor.hotspot_x, last_cursor.hotspot_y);
+}
+
+int
+hidecursor(void *data)
+{
+ wlr_cursor_unset_image(cursor);
+ cursor_hidden = true;
+ return 1;
+}
+
void
incnmaster(const Arg *arg)
{
@@ -1903,6 +1941,7 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d
wlr_cursor_move(cursor, device, dx, dy);
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
+ handlecursoractivity();
/* Update selmon (even while dragging a window) */
if (sloppyfocus)
@@ -1927,7 +1966,7 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d
/* If there's no client surface under the cursor, set the cursor image to a
* default. This is what makes the cursor image appear when you move it
* off of a client or over its border. */
- if (!surface && !seat->drag)
+ if (!surface && !seat->drag && !cursor_hidden)
wlr_cursor_set_xcursor(cursor, cursor_mgr, "default");
pointerfocus(c, surface, sx, sy, time);
@@ -2284,6 +2323,7 @@ run(char *startup_cmd)
* monitor when displayed here */
wlr_cursor_warp_closest(cursor, NULL, cursor->x, cursor->y);
wlr_cursor_set_xcursor(cursor, cursor_mgr, "default");
+ handlecursoractivity();
/* Run the Wayland event loop. This does not return until you exit the
* compositor. Starting the backend rigged up all of the necessary event
@@ -2307,9 +2347,16 @@ setcursor(struct wl_listener *listener, void *data)
* use the provided surface as the cursor image. It will set the
* hardware cursor on the output that it's currently on and continue to
* do so as the cursor moves between outputs. */
- if (event->seat_client == seat->pointer_state.focused_client)
- wlr_cursor_set_surface(cursor, event->surface,
- event->hotspot_x, event->hotspot_y);
+ if (event->seat_client == seat->pointer_state.focused_client) {
+ last_cursor.shape = 0;
+ last_cursor.surface = event->surface;
+ last_cursor.hotspot_x = event->hotspot_x;
+ last_cursor.hotspot_y = event->hotspot_y;
+
+ if (!cursor_hidden)
+ wlr_cursor_set_surface(cursor, event->surface,
+ event->hotspot_x, event->hotspot_y);
+ }
}
void
@@ -2321,9 +2368,14 @@ setcursorshape(struct wl_listener *listener, void *data)
/* This can be sent by any client, so we check to make sure this one
* actually has pointer focus first. If so, we can tell the cursor to
* use the provided cursor shape. */
- if (event->seat_client == seat->pointer_state.focused_client)
- wlr_cursor_set_xcursor(cursor, cursor_mgr,
- wlr_cursor_shape_v1_name(event->shape));
+ if (event->seat_client == seat->pointer_state.focused_client) {
+ last_cursor.shape = event->shape;
+ last_cursor.surface = NULL;
+
+ if (!cursor_hidden)
+ wlr_cursor_set_xcursor(cursor, cursor_mgr,
+ wlr_cursor_shape_v1_name(event->shape));
+ }
}
void
@@ -2614,6 +2666,9 @@ setup(void)
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);
+ hide_source = wl_event_loop_add_timer(wl_display_get_event_loop(dpy),
+ hidecursor, cursor);
+
/*
* Configures a seat, which is a single "seat" at which a user sits and
* operates the computer. This conceptually includes up to one keyboard,
@@ -2998,6 +3053,7 @@ virtualpointer(struct wl_listener *listener, void *data)
wlr_cursor_attach_input_device(cursor, device);
if (event->suggested_output)
wlr_cursor_map_input_to_output(cursor, device, event->suggested_output);
+ handlecursoractivity();
}
Monitor *
--
2.49.0

71
patches/warpcursor.patch Normal file
View file

@ -0,0 +1,71 @@
From 4951ccc89dac2b557994b2f6c3aacb2398e2d1b1 Mon Sep 17 00:00:00 2001
From: Ben Collerson <benc@benc.cc>
Date: Thu, 4 Jan 2024 20:30:01 +1000
Subject: [PATCH] warpcursor
---
dwl.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/dwl.c b/dwl.c
index 145fd018..f7ad6c13 100644
--- a/dwl.c
+++ b/dwl.c
@@ -347,6 +347,7 @@ static void urgent(struct wl_listener *listener, void *data);
static void view(const Arg *arg);
static void virtualkeyboard(struct wl_listener *listener, void *data);
static void virtualpointer(struct wl_listener *listener, void *data);
+static void warpcursor(const Client *c);
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);
@@ -514,6 +515,7 @@ arrange(Monitor *m)
m->lt[m->sellt]->arrange(m);
motionnotify(0, NULL, 0, 0, 0, 0);
checkidleinhibitor(NULL);
+ warpcursor(focustop(selmon));
}
void
@@ -1323,6 +1325,10 @@ focusclient(Client *c, int lift)
if (locked)
return;
+ /* Warp cursor to center of client if it is outside */
+ if (lift)
+ warpcursor(c);
+
/* Raise client in stacking order if requested */
if (c && lift)
wlr_scene_node_raise_to_top(&c->scene->node);
@@ -2927,6 +2933,27 @@ virtualpointer(struct wl_listener *listener, void *data)
wlr_cursor_map_input_to_output(cursor, &pointer.base, event->suggested_output);
}
+void
+warpcursor(const Client *c) {
+ if (cursor_mode != CurNormal) {
+ return;
+ }
+ if (!c && selmon) {
+ wlr_cursor_warp_closest(cursor,
+ NULL,
+ selmon->w.x + selmon->w.width / 2.0 ,
+ selmon->w.y + selmon->w.height / 2.0);
+ }
+ else if ( c && (cursor->x < c->geom.x ||
+ cursor->x > c->geom.x + c->geom.width ||
+ cursor->y < c->geom.y ||
+ cursor->y > c->geom.y + c->geom.height))
+ wlr_cursor_warp_closest(cursor,
+ NULL,
+ c->geom.x + c->geom.width / 2.0,
+ c->geom.y + c->geom.height / 2.0);
+}
+
Monitor *
xytomon(double x, double y)
{
--
2.45.2