commit 16ea538e501a0f4c0f5bdc6218acbefad8e08bca
parent 0950fa8b4858736f14adac8e418c21dc5cd4c29a
Author: wh1tepearl <wh1tepearl@gmail.com>
Date: Tue, 3 Feb 2026 15:49:37 +0000
Support for windowmap
Diffstat:
7 files changed, 77 insertions(+), 4 deletions(-)
diff --git a/config.def.h b/config.def.h
@@ -87,7 +87,7 @@ static const Layout layouts[] = {
#define TAGKEYS(KEY,TAG) \
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
- { Mod1Mask, KEY, tag, {.ui = 1 << TAG} }, \
+ { Mod1Mask, KEY, tag, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
diff --git a/modules.def.h b/modules.def.h
@@ -42,7 +42,10 @@
#define EWMH_TAGS 0 // Support for EWMH tags, recommended if you want to use external bars with less pain
#define ALWAYS_CENTER_NEW_FLOATING_WINDOWS 0 //so, basically, it does what it says.
#define TAG_TO_TAG 0 // If you switch to tag where you already are, it'll switch to previous tag.
-
+#define WINDOWMAP 0
+/* This makes the windows get mapped or unmapped in X11. This results in certain
+ behaviour being enabled, for example when you use a compositor like picom - your
+ windows will fade in and out when you switch dwm tags. */
/* Floating */
diff --git a/modules/vxwm_includes.c b/modules/vxwm_includes.c
@@ -29,4 +29,8 @@
#include "betterresize/betterresize.c"
#endif
+#if WINDOWMAP
+#include "windowmap/windowmap.c"
+#endif
+
#endif
diff --git a/modules/vxwm_includes.h b/modules/vxwm_includes.h
@@ -25,4 +25,8 @@
#include "etf/etf.h"
#endif
+#if WINDOWMAP
+#include "windowmap/windowmap.h"
+#endif
+
#endif
diff --git a/modules/windowmap/windowmap.c b/modules/windowmap/windowmap.c
@@ -0,0 +1,44 @@
+void
+window_set_state(Display *dpy, Window win, long state)
+{
+ long data[] = { state, None };
+
+ XChangeProperty(dpy, win, wmatom[WMState], wmatom[WMState], 32,
+ PropModeReplace, (unsigned char*)data, 2);
+}
+
+void
+window_map(Display *dpy, Client *c, int deiconify)
+{
+ Window win = c->win;
+
+ if (deiconify)
+ window_set_state(dpy, win, NormalState);
+
+ XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
+ XSetInputFocus(dpy, win, RevertToPointerRoot, CurrentTime);
+ XMapWindow(dpy, win);
+}
+
+void
+window_unmap(Display *dpy, Window win, Window root, int iconify)
+{
+ static XWindowAttributes ca, ra;
+
+ XGrabServer(dpy);
+ XGetWindowAttributes(dpy, root, &ra);
+ XGetWindowAttributes(dpy, win, &ca);
+
+ /* Prevent UnmapNotify events */
+ XSelectInput(dpy, root, ra.your_event_mask & ~SubstructureNotifyMask);
+ XSelectInput(dpy, win, ca.your_event_mask & ~StructureNotifyMask);
+
+ XUnmapWindow(dpy, win);
+
+ if (iconify)
+ window_set_state(dpy, win, IconicState);
+
+ XSelectInput(dpy, root, ra.your_event_mask);
+ XSelectInput(dpy, win, ca.your_event_mask);
+ XUngrabServer(dpy);
+}
diff --git a/modules/windowmap/windowmap.h b/modules/windowmap/windowmap.h
@@ -0,0 +1,3 @@
+static void window_set_state(Display *dpy, Window win, long state);
+static void window_map(Display *dpy, Client *c, int deiconify);
+static void window_unmap(Display *dpy, Window win, Window root, int iconify);
diff --git a/vxwm.c b/vxwm.c
@@ -1879,15 +1879,23 @@ showhide(Client *c)
return;
if (ISVISIBLE(c)) {
/* show clients top down */
+#if !WINDOWMAP
XMoveWindow(dpy, c->win, c->x, c->y);
if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen)
resize(c, c->x, c->y, c->w, c->h, 0);
- showhide(c->snext);
+#else
+ window_map(dpy, c, 1);
+#endif
+ showhide(c->snext);
} else {
/* hide clients bottom up */
showhide(c->snext);
+#if !WINDOWMAP
XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y);
- }
+#else
+ window_unmap(dpy, c->win, root, 1);
+#endif
+ }
}
void
@@ -2342,6 +2350,7 @@ updatewmhints(Client *c)
}
#if TAG_TO_TAG
+
void
view(const Arg *arg)
{
@@ -2357,8 +2366,10 @@ view(const Arg *arg)
#if EWMH_TAGS
updatecurrentdesktop();
#endif
+
}
#else
+
void
view(const Arg *arg)
{
@@ -2369,8 +2380,12 @@ view(const Arg *arg)
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
focus(NULL);
arrange(selmon);
+#if EWMH_TAGS
+ updatecurrentdesktop();
+#endif
}
#endif
+
Client *
wintoclient(Window w)
{