GTK3 checks for this property in some of its functions and simply give
up if it's not there and set correctly. This notably caused fullscreen
to be broken on recent versions of Firefox.

This is mostly arg's 762b66a resurrected ("hack that adds
NET_SUPPORTING_WM_CHECK handling..."), but we have to create a dedicated
window which remains unmapped as bar windows can now be destroyed at any
time with their monitor.

Ref: 
https://specifications.freedesktop.org/wm-spec/1.5/ar01s03.html#idm139870830066480
---
 dwm.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/dwm.c b/dwm.c
index 421bf27..4cce3fa 100644
--- a/dwm.c
+++ b/dwm.c
@@ -61,7 +61,7 @@
 /* enums */
 enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
 enum { SchemeNorm, SchemeSel, SchemeLast }; /* color schemes */
-enum { NetSupported, NetWMName, NetWMState,
+enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
        NetWMFullscreen, NetActiveWindow, NetWMWindowType,
        NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
 enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms 
*/
@@ -267,7 +267,7 @@ static Scm scheme[SchemeLast];
 static Display *dpy;
 static Drw *drw;
 static Monitor *mons, *selmon;
-static Window root;
+static Window root, wmcheckwin;
 
 /* configuration, allows nested code to access above variables */
 #include "config.h"
@@ -485,6 +485,7 @@ cleanup(void)
                drw_cur_free(drw, cursor[i]);
        for (i = 0; i < SchemeLast; i++)
                free(scheme[i]);
+       XDestroyWindow(dpy, wmcheckwin);
        drw_free(drw);
        XSync(dpy, False);
        XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
@@ -1550,6 +1551,7 @@ void
 setup(void)
 {
        XSetWindowAttributes wa;
+       Atom utf8string;
 
        /* clean up any zombies immediately */
        sigchld(0);
@@ -1566,6 +1568,7 @@ setup(void)
        bh = drw->fonts->h + 2;
        updategeom();
        /* init atoms */
+       utf8string = XInternAtom(dpy, "UTF8_STRING", False);
        wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
        wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
        wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False);
@@ -1574,6 +1577,7 @@ setup(void)
        netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
        netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
        netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
+       netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", 
False);
        netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", 
False);
        netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", 
False);
        netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, 
"_NET_WM_WINDOW_TYPE_DIALOG", False);
@@ -1588,6 +1592,14 @@ setup(void)
        /* init bars */
        updatebars();
        updatestatus();
+       /* supporting window for NetWMCheck */
+       wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0);
+       XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32,
+                       PropModeReplace, (unsigned char *) &wmcheckwin, 1);
+       XChangeProperty(dpy, wmcheckwin, netatom[NetWMName], utf8string, 8,
+                       PropModeReplace, (unsigned char *) "dwm", 4);
+       XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32,
+                       PropModeReplace, (unsigned char *) &wmcheckwin, 1);
        /* EWMH support per view */
        XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
                        PropModeReplace, (unsigned char *) netatom, NetLast);
-- 
2.10.2

Reply via email to