Compare commits

...
2 Commits
Author SHA1 Message Date
tvtur 462f12a29e hide-behind-deck 2026-09-08 13:29:22 +02:00
tvtur b7fa1424bd hide-behind-monocle-0.8 2026-09-06 22:57:49 +03:00
4 changed files with 473 additions and 0 deletions
+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)
- [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.8.patch](/dwl/dwl-patches/raw/branch/main/patches/hide-behind-monocle/hide-behind-monocle-0.8.patch)
### Authors
- [tvtur](https://codeberg.org/tvtur)
- [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