Hello comrades,
attached is the patch for dwm, which integrates [0] and the magic
»_NET_WM_WINDOW_TYPE« property, which is set in onscreen key-
boards to »_NET_WM_WINDOW_TYPE_TOOLBAR«. This provides the needed
distinction between the window being a panel, which shouldn't be
shown as title or not. This replaces the fixed string comparison
for a title, from the previous patch.
Sincerely,
Christoph Lohmann
[0] http://www.mail-archive.com/[email protected]/msg06872.html
diff -r 8a52ed2f6e59 dwm.c
--- a/dwm.c Wed Mar 23 08:58:57 2011 +0000
+++ b/dwm.c Thu Mar 24 23:27:07 2011 +0100
@@ -58,7 +58,7 @@
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
enum { ColBorder, ColFG, ColBG, ColLast }; /* color */
enum { NetSupported, NetWMName, NetWMState,
- NetWMFullscreen, NetLast }; /* EWMH atoms */
+ NetWMFullscreen, NetWMWindowType, NetLast }; /* EWMH atoms */
enum { WMProtocols, WMDelete, WMState, WMLast }; /* default atoms */
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
@@ -88,7 +88,7 @@
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
int bw, oldbw;
unsigned int tags;
- Bool isfixed, isfloating, isurgent, oldstate;
+ Bool isfixed, isfloating, isurgent, oldstate, isfocusable, istoolbar;
Client *next;
Client *snext;
Monitor *mon;
@@ -96,7 +96,7 @@
};
typedef struct {
- int x, y, w, h;
+ int x, y, w, h, dw;
unsigned long norm[ColLast];
unsigned long sel[ColLast];
Drawable drawable;
@@ -233,6 +233,7 @@
static void updatenumlockmask(void);
static void updatesizehints(Client *c);
static void updatestatus(void);
+static void updatewindowtype(Client *c);
static void updatetitle(Client *c);
static void updatewmhints(Client *c);
static void view(const Arg *arg);
@@ -548,7 +549,7 @@
if(updategeom()) {
if(dc.drawable != 0)
XFreePixmap(dpy, dc.drawable);
- dc.drawable = XCreatePixmap(dpy, root, sw, bh,
DefaultDepth(dpy, screen));
+ dc.drawable = XCreatePixmap(dpy, root, dc.dw, bh,
DefaultDepth(dpy, screen));
updatebars();
for(m = mons; m; m = m->next)
XMoveResizeWindow(dpy, m->barwin, m->wx, m->by,
m->ww, bh);
@@ -681,7 +682,6 @@
unsigned int i, occ = 0, urg = 0;
unsigned long *col;
Client *c;
-
for(c = m->clients; c; c = c->next) {
occ |= c->tags;
if(c->isurgent)
@@ -821,7 +821,8 @@
attachstack(c);
grabbuttons(c, True);
XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]);
- XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
+ if(c->isfocusable)
+ XSetInputFocus(dpy, c->win, RevertToPointerRoot,
CurrentTime);
}
else
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
@@ -857,17 +858,17 @@
if(!selmon->sel)
return;
if(arg->i > 0) {
- for(c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next);
+ for(c = selmon->sel->next; c && (!ISVISIBLE(c) ||
c->istoolbar); c = c->next);
if(!c)
- for(c = selmon->clients; c && !ISVISIBLE(c); c =
c->next);
+ for(c = selmon->clients; c && (!ISVISIBLE(c) ||
c->istoolbar); c = c->next);
}
else {
for(i = selmon->clients; i != selmon->sel; i = i->next)
- if(ISVISIBLE(i))
+ if(ISVISIBLE(i) && !c->istoolbar)
c = i;
if(!c)
for(; i; i = i->next)
- if(ISVISIBLE(i))
+ if(ISVISIBLE(i) && !c->istoolbar)
c = i;
}
if(c) {
@@ -1102,6 +1103,9 @@
c->w = c->oldw = wa->width;
c->h = c->oldh = wa->height;
c->oldbw = wa->border_width;
+
+ c->isfocusable = True;
+ c->istoolbar = False;
if(c->w == c->mon->mw && c->h == c->mon->mh) {
c->isfloating = True;
c->x = c->mon->mx;
@@ -1276,6 +1280,8 @@
if(c == c->mon->sel)
drawbar(c->mon);
}
+ if(ev->atom == netatom[NetWMWindowType])
+ updatewindowtype(c);
}
}
@@ -1521,6 +1527,7 @@
netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN",
False);
+ netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE",
False);
/* init cursors */
cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
@@ -1532,7 +1539,7 @@
dc.sel[ColBorder] = getcolor(selbordercolor);
dc.sel[ColBG] = getcolor(selbgcolor);
dc.sel[ColFG] = getcolor(selfgcolor);
- dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), bh,
DefaultDepth(dpy, screen));
+ dc.drawable = XCreatePixmap(dpy, root, dc.dw, bh, DefaultDepth(dpy,
screen));
dc.gc = XCreateGC(dpy, root, 0, NULL);
XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
if(!dc.font.set)
@@ -1776,9 +1783,14 @@
/* only consider unique geometries as separate screens */
if(!(unique = (XineramaScreenInfo
*)malloc(sizeof(XineramaScreenInfo) * nn)))
die("fatal: could not malloc() %u bytes\n",
sizeof(XineramaScreenInfo) * nn);
+ dc.dw = 0;
for(i = 0, j = 0; i < nn; i++)
- if(isuniquegeom(unique, j, &info[i]))
- memcpy(&unique[j++], &info[i],
sizeof(XineramaScreenInfo));
+ if(isuniquegeom(unique, j, &info[i])) {
+ memcpy(&unique[j], &info[i],
sizeof(XineramaScreenInfo));
+ if(unique[j].width > dc.dw)
+ dc.dw = unique[j].width;
+ ++j;
+ }
XFree(info);
nn = j;
if(n <= nn) {
@@ -1830,6 +1842,7 @@
mons = createmon();
if(mons->mw != sw || mons->mh != sh) {
dirty = True;
+ dc.dw = sw;
mons->mw = mons->ww = sw;
mons->mh = mons->wh = sh;
updatebarpos(mons);
@@ -1908,6 +1921,19 @@
}
void
+updatewindowtype(Client *c) {
+ char windowtype[32];
+
+ if(!gettextprop(c->win, netatom[NetWMWindowType], windowtype,
+ sizeof windowtype)) {
+ gettextprop(c->win, netatom[NetWMWindowType], windowtype,
+ sizeof windowtype);
+ if(strstr(windowtype, "_NET_WM_WINDOW_TYPE_TOOLBAR"))
+ c->istoolbar = True;
+ }
+}
+
+void
updatetitle(Client *c) {
if(!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name))
gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name);
@@ -1933,6 +1959,8 @@
}
else
c->isurgent = (wmh->flags & XUrgencyHint) ? True :
False;
+
+ c->isfocusable = !(wmh->flags & InputHint) || wmh->input;
XFree(wmh);
}
}