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); } }