aboutsummaryrefslogtreecommitdiffstats
path: root/dwm-unmapfullscreen-6.8.diff
blob: 30eb3ae2955fd72acc0af648bf30b7bc124e3a71 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
From d175466d1ecff304ff32ae3ba852e1eec29a9561 Mon Sep 17 00:00:00 2001
From: Daniel Guihot <daniel@guihot.net>
Date: Wed, 16 Sep 2026 05:20:00 +1000
Subject: [PATCH] unmapfullscreen: unmap hidden fullscreen clients

showhide() hides windows by moving them off-screen, which some games
and Wine builds treat as a broken or minimized state and do not recover
from when the tag returns. Unmap and map fullscreen clients instead.

dwm selects StructureNotifyMask on clients and SubstructureNotifyMask on
the root, so the unmap would reach unmapnotify() and unmanage the
client. unmapclient() suppresses both masks around the unmap, the same
approach the windowmap patch uses.

Hidden fullscreen clients are still parked off-screen so the initial map
from manage() does not put them on the wrong tag.
---
 dwm.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/dwm.c b/dwm.c
index 53b393e..4bd3988 100644
--- a/dwm.c
+++ b/dwm.c
@@ -214,6 +214,7 @@ static void toggletag(const Arg *arg);
 static void toggleview(const Arg *arg);
 static void unfocus(Client *c, int setfocus);
 static void unmanage(Client *c, int destroyed);
+static void unmapclient(Client *c);
 static void unmapnotify(XEvent *e);
 static void updatebarpos(Monitor *m);
 static void updatebars(void);
@@ -1634,12 +1635,16 @@ showhide(Client *c)
 	if (ISVISIBLE(c)) {
 		/* show clients top down */
 		XMoveWindow(dpy, c->win, c->x, c->y);
+		if (c->isfullscreen)
+			XMapWindow(dpy, c->win);
 		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 {
 		/* hide clients bottom up */
 		showhide(c->snext);
+		if (c->isfullscreen)
+			unmapclient(c);
 		XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y);
 	}
 }
@@ -1801,6 +1806,23 @@ unmanage(Client *c, int destroyed)
 	arrange(m);
 }
 
+void
+unmapclient(Client *c)
+{
+	static XWindowAttributes ra, ca;
+
+	if (!XGetWindowAttributes(dpy, c->win, &ca) || ca.map_state == IsUnmapped)
+		return;
+	XGrabServer(dpy);
+	XGetWindowAttributes(dpy, root, &ra);
+	XSelectInput(dpy, root, ra.your_event_mask & ~SubstructureNotifyMask);
+	XSelectInput(dpy, c->win, ca.your_event_mask & ~StructureNotifyMask);
+	XUnmapWindow(dpy, c->win);
+	XSelectInput(dpy, root, ra.your_event_mask);
+	XSelectInput(dpy, c->win, ca.your_event_mask);
+	XUngrabServer(dpy);
+}
+
 void
 unmapnotify(XEvent *e)
 {
-- 
2.55.0