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) {