aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md16
-rw-r--r--dwm-fullscreenhook-6.8.diff76
2 files changed, 53 insertions, 39 deletions
diff --git a/README.md b/README.md
index 8957a6c..3018956 100644
--- a/README.md
+++ b/README.md
@@ -5,21 +5,21 @@
This patch publishes the active fullscreen window on the root window so other
programs can react to it. It applies to dwm 6.8.
-dwm sets `_DWM_FULLSCREEN` to the window id of the fullscreen client when it
-enters fullscreen, and removes the property when it leaves or is unmanaged. A
-compositor, notification daemon or GameMode helper can watch it with:
+dwm sets `_DWM_FULLSCREEN` to the window id of the selected fullscreen client.
+It removes the property when the selected client is not fullscreen. Focus and
+fullscreen changes update the property, so it remains correct across tags,
+monitors, client exits, and multiple fullscreen clients. A compositor,
+notification daemon or GameMode helper can watch it with:
xprop -root -spy _DWM_FULLSCREEN
No configuration and no spawned commands.
-Assumes one fullscreen client at a time. With two, the property tracks the
-most recent one to enter.
-
## Testing
-Applies and builds against dwm 6.8. Runtime tested under Xvfb: the property
-is set on enter and cleared on exit and on unmanage.
+Applies and builds against dwm 6.8. Runtime tested under Xvfb. Tests covered
+fullscreen entry and exit, tag changes, selecting a normal client, and
+falling back to another fullscreen client after the active one was destroyed.
## Download
diff --git a/dwm-fullscreenhook-6.8.diff b/dwm-fullscreenhook-6.8.diff
index 9d267c3..f90def6 100644
--- a/dwm-fullscreenhook-6.8.diff
+++ b/dwm-fullscreenhook-6.8.diff
@@ -1,22 +1,30 @@
-From 8b2c41af886b758126c7738fbd302fc1dfcc3172 Mon Sep 17 00:00:00 2001
+From 70197161511b1504a6d6d655a288d2d922938a0f Mon Sep 17 00:00:00 2001
From: Daniel Guihot <daniel@guihot.net>
Date: Wed, 16 Sep 2026 05:09:22 +1000
-Subject: [PATCH] fullscreenhook: publish the fullscreen window on the root
- window
+Subject: [PATCH] fullscreenhook: publish the active fullscreen window
-Set _DWM_FULLSCREEN on the root window to the window id of the client
-that is fullscreen and clear it when the client exits, so a compositor,
-notification daemon or GameMode helper can react without scanning every
-window. Assumes one fullscreen client at a time.
+Set _DWM_FULLSCREEN on the root window to the selected fullscreen
+client, and clear it when the selected client is not fullscreen.
+Update the property on focus and fullscreen changes so it remains
+correct across tags, monitors, client exits, and multiple fullscreen
+clients.
---
- dwm.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
+ dwm.c | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/dwm.c b/dwm.c
-index 53b393e..1868c5c 100644
+index 53b393e..d1cb48c 100644
--- a/dwm.c
+++ b/dwm.c
-@@ -258,7 +258,7 @@ static void (*handler[LASTEvent]) (XEvent *) = {
+@@ -199,6 +199,7 @@ static void sendmon(Client *c, Monitor *m);
+ static void setclientstate(Client *c, long state);
+ static void setfocus(Client *c);
+ static void setfullscreen(Client *c, int fullscreen);
++static void setfullscreenprop(Client *c);
+ static void setlayout(const Arg *arg);
+ static void setmfact(const Arg *arg);
+ static void setup(void);
+@@ -258,7 +259,7 @@ static void (*handler[LASTEvent]) (XEvent *) = {
[PropertyNotify] = propertynotify,
[UnmapNotify] = unmapnotify
};
@@ -25,36 +33,42 @@ index 53b393e..1868c5c 100644
static int running = 1;
static Cur *cursor[CurLast];
static Clr **scheme;
-@@ -1492,9 +1492,12 @@ setfullscreen(Client *c, int fullscreen)
- c->isfloating = 1;
- resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh);
- XRaiseWindow(dpy, c->win);
+@@ -807,6 +808,7 @@ focus(Client *c)
+ XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
+ }
+ selmon->sel = c;
++ setfullscreenprop(c);
+ drawbars();
+ }
+
+@@ -1505,6 +1507,18 @@ setfullscreen(Client *c, int fullscreen)
+ resizeclient(c, c->x, c->y, c->w, c->h);
+ arrange(c->mon);
+ }
++ if (c == selmon->sel)
++ setfullscreenprop(c);
++}
++
++void
++setfullscreenprop(Client *c)
++{
++ if (c && c->isfullscreen)
+ XChangeProperty(dpy, root, dwmfullscreen, XA_WINDOW, 32,
+ PropModeReplace, (unsigned char *)&c->win, 1);
- } else if (!fullscreen && c->isfullscreen){
- XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
- PropModeReplace, (unsigned char*)0, 0);
++ else
+ XDeleteProperty(dpy, root, dwmfullscreen);
- c->isfullscreen = 0;
- c->isfloating = c->oldstate;
- c->bw = c->oldbw;
-@@ -1579,6 +1582,7 @@ setup(void)
+ }
+
+ void
+@@ -1579,6 +1593,8 @@ setup(void)
netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
+ dwmfullscreen = XInternAtom(dpy, "_DWM_FULLSCREEN", False);
++ XDeleteProperty(dpy, root, dwmfullscreen);
/* init cursors */
cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
-@@ -1783,6 +1787,8 @@ unmanage(Client *c, int destroyed)
-
- detach(c);
- detachstack(c);
-+ if (c->isfullscreen)
-+ XDeleteProperty(dpy, root, dwmfullscreen);
- if (!destroyed) {
- wc.border_width = c->oldbw;
- XGrabServer(dpy); /* avoid race conditions */
--
2.55.0