From 3a9a7eea52ee0de4f9ff2b2d6b05d7d1742c95fe Mon Sep 17 00:00:00 2001 From: Jakub Leszczak Date: Sat, 18 Apr 2020 19:17:46 +0200 Subject: [PATCH] Respect decoration hints Make dwm respect _MOTIF_WM_HINTS property. Applications use this property to notify window managers to not draw window decorations. Not respecting this property leads to issues with applications that draw their own borders, like chromium (with "Use system title bar and borders" turned off) and vlc in fullscreen mode. --- config.def.h | 1 + config.h | 1 + dwm.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/config.def.h b/config.def.h index 2d41ee4..c283208 100644 --- a/config.def.h +++ b/config.def.h @@ -107,6 +107,7 @@ static const float mfact = 0.55; /* factor of master area size [0.05..0.95] static const int nmaster = 1; /* number of clients in master area */ static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ +static const int decorhints = 1; /* 1 means respect decoration hints */ static const Layout layouts[] = { /* symbol arrange function */ diff --git a/config.h b/config.h index b17cd0b..4bcff75 100644 --- a/config.h +++ b/config.h @@ -98,6 +98,7 @@ static const float mfact = 0.55; /* factor of master area size [0.05..0.95] static const int nmaster = 1; /* number of clients in master area */ static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ +static const int decorhints = 1; /* 1 means respect decoration hints */ #define STATUSBAR "dwmblocks" diff --git a/dwm.c b/dwm.c index ba15b23..642715c 100644 --- a/dwm.c +++ b/dwm.c @@ -83,6 +83,13 @@ } \ } +#define MWM_HINTS_FLAGS_FIELD 0 +#define MWM_HINTS_DECORATIONS_FIELD 2 +#define MWM_HINTS_DECORATIONS (1 << 1) +#define MWM_DECOR_ALL (1 << 0) +#define MWM_DECOR_BORDER (1 << 1) +#define MWM_DECOR_TITLE (1 << 3) + /* enums */ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ enum { SchemeNorm, SchemeSel }; /* color schemes */ @@ -319,6 +326,7 @@ static void updatebarpos(Monitor *m); static void updatebars(void); static void updateclientlist(void); static int updategeom(void); +static void updatemotifhints(Client *c); static void updatenumlockmask(void); static void updatesizehints(Client *c); static void updatestatus(void); @@ -365,7 +373,7 @@ static void (*handler[LASTEvent]) (XEvent *) = { [ResizeRequest] = resizerequest, [UnmapNotify] = unmapnotify }; -static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast]; +static Atom wmatom[WMLast], netatom[NetLast], motifatom, xatom[XLast]; static int running = 1; static Cur *cursor[CurLast]; static Clr **scheme; @@ -1583,6 +1591,7 @@ manage(Window w, XWindowAttributes *wa) updatewindowtype(c); updatesizehints(c); updatewmhints(c); + updatemotifhints(c); XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); grabbuttons(c, 0); if (!c->isfloating) @@ -1786,6 +1795,8 @@ propertynotify(XEvent *e) if (c == c->mon->sel) drawbar(c->mon); } + if (ev->atom == motifatom) + updatemotifhints(c); } } @@ -2211,6 +2222,7 @@ setup(void) netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); + motifatom = XInternAtom(dpy, "_MOTIF_WM_HINTS", False); /* init cursors */ cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); cursor[CurResize] = drw_cur_create(drw, XC_sizing); @@ -2717,6 +2729,39 @@ updategeom(void) return dirty; } +void +updatemotifhints(Client *c) +{ + Atom real; + int format; + unsigned char *p = NULL; + unsigned long n, extra; + unsigned long *motif; + int width, height; + + if (!decorhints) + return; + + if (XGetWindowProperty(dpy, c->win, motifatom, 0L, 5L, False, motifatom, + &real, &format, &n, &extra, &p) == Success && p != NULL) { + motif = (unsigned long*)p; + if (motif[MWM_HINTS_FLAGS_FIELD] & MWM_HINTS_DECORATIONS) { + width = WIDTH(c); + height = HEIGHT(c); + + if (motif[MWM_HINTS_DECORATIONS_FIELD] & MWM_DECOR_ALL || + motif[MWM_HINTS_DECORATIONS_FIELD] & MWM_DECOR_BORDER || + motif[MWM_HINTS_DECORATIONS_FIELD] & MWM_DECOR_TITLE) + c->bw = c->oldbw = borderpx; + else + c->bw = c->oldbw = 0; + + resize(c, c->x, c->y, width - (2*c->bw), height - (2*c->bw), 0); + } + XFree(p); + } +} + void updatenumlockmask(void) {