I do a lot of roaming, and long story short, nm-applet is nearly a requirement for me. No biggie, I just run it in stalonetray and set it to all tags, shoved up in the corner, only I've ran into two little issues:
1) sticky windows put an indicator on every tag in the bar. I know it's on every tag, I put it there, tell me something I don't know. The patch hides any window which has tags=~0 from the indicators. ( this is simply the 2 lines in drawbar() ) 2) since it's on every tag, every time i switch tags, it is the first thing focused. I dont need to type into a system tray, so the patch also adds a flag to designate a window as "nofocus" which tells dwm to skip it when trying to find a window to focus. To do this, I had to add a way to designate a window as nofocus, so Rule.isfloating is now a bitmask Rule.flags, with enums for the 3 settings right now: Normal, Floating, NoFocus. So my config.h, for example, has this Rule: { "stalonetray", NULL, NULL, ~0, Floating|NoFocus }, Patch against tip attached, if anyone else is interested - it only adds 7 lines so its still nice and small. =) Jeremy
# HG changeset patch # User [EMAIL PROTECTED] # Date 1227289871 18000 # Node ID 811a88242229049dfd367487ae7312f238972179 # Parent f6c3491c41f1a5e149eaa0e28d59e5b69d7682c1 hide sticky(tags=~0) windows from tag-bar indicators also add ability to designate windows as "nofocus" ie, switching tags will never auto-focus "nofocus" windows, but will skip to next window. Rules now have a bitmask for the 4th parameter instead of the boolean isfloating. You can now use the list of enums: Normal, Floating, NoFocus. For example: { "stalonetray", NULL, NULL, ~0, Floating|NoFocus }, will make stalonetray never automatically recieve focus, it will always be floating, and it will be on every tag, yet not put an indicator in the bar. diff -r f6c3491c41f1 -r 811a88242229 config.def.h --- a/config.def.h Sun Nov 16 13:22:24 2008 +0000 +++ b/config.def.h Fri Nov 21 12:51:11 2008 -0500 @@ -21,9 +21,9 @@ static unsigned int tagset[] = {1, 1}; /* after start, first tag is selected */ static Rule rules[] = { - /* class instance title tags mask isfloating */ - { "Gimp", NULL, NULL, 0, True }, - { "Firefox", NULL, NULL, 1 << 8, True }, + /* class instance title tags mask flags */ + { "Gimp", NULL, NULL, 0, Floating }, + { "Firefox", NULL, NULL, 1 << 8, Floating }, }; /* layout(s) */ diff -r f6c3491c41f1 -r 811a88242229 dwm.c --- a/dwm.c Sun Nov 16 13:22:24 2008 +0000 +++ b/dwm.c Fri Nov 21 12:51:11 2008 -0500 @@ -65,6 +65,7 @@ enum { WMProtocols, WMDelete, WMState, WMLast }; /* default atoms */ enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ +enum { Normal, Floating, NoFocus=2 }; /* Client flags for Rules */ typedef union { int i; @@ -89,7 +90,7 @@ int basew, baseh, incw, inch, maxw, maxh, minw, minh; int bw, oldbw; unsigned int tags; - Bool isfixed, isfloating, isurgent; + Bool isfixed, isfloating, isurgent, nofocus; Client *next; Client *snext; Window win; @@ -127,7 +128,7 @@ const char *instance; const char *title; unsigned int tags; - Bool isfloating; + unsigned int flags; } Rule; /* function declarations */ @@ -258,7 +259,8 @@ if((!r->title || strstr(c->name, r->title)) && (!r->class || (ch.res_class && strstr(ch.res_class, r->class))) && (!r->instance || (ch.res_name && strstr(ch.res_name, r->instance)))) { - c->isfloating = r->isfloating; + c->isfloating = (r->flags&Floating)!=0; + c->nofocus = (r->flags&NoFocus)!=0; c->tags |= r->tags & TAGMASK; } } @@ -498,7 +500,8 @@ Client *c; for(c = clients; c; c = c->next) { - occ |= c->tags; + if(c->tags!=TAGMASK) + occ |= c->tags; if(c->isurgent) urg |= c->tags; } @@ -508,7 +511,7 @@ dc.w = TEXTW(tags[i]); col = tagset[seltags] & 1 << i ? dc.sel : dc.norm; drawtext(tags[i], col, urg & 1 << i); - drawsquare(sel && sel->tags & 1 << i, occ & 1 << i, urg & 1 << i, col); + drawsquare(sel && tagset[seltags] & sel->tags & 1 << i, occ & 1 << i, urg & 1 << i, col); dc.x += dc.w; } if(blw > 0) { @@ -610,6 +613,7 @@ void focus(Client *c) { + Client *inc=c; if(!c || !ISVISIBLE(c)) for(c = stack; c && !ISVISIBLE(c); c = c->snext); if(sel && sel != c) { @@ -619,6 +623,9 @@ if(c) { detachstack(c); attachstack(c); + } + while( !inc && c && c->nofocus ) c=c->next; + if(c) { grabbuttons(c, True); XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]); XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); @@ -644,17 +651,17 @@ if(!sel) return; if (arg->i > 0) { - for(c = sel->next; c && !ISVISIBLE(c); c = c->next); + for(c = sel->next; c && !ISVISIBLE(c) && c->nofocus; c = c->next); if(!c) - for(c = clients; c && !ISVISIBLE(c); c = c->next); + for(c = clients; c && !ISVISIBLE(c) && c->nofocus; c = c->next); } else { for(i = clients; i != sel; i = i->next) - if(ISVISIBLE(i)) + if(ISVISIBLE(i) && i->nofocus) c = i; if(!c) for(; i; i = i->next) - if(ISVISIBLE(i)) + if(ISVISIBLE(i) && i->nofocus) c = i; } if(c) {