Hi,

Here it's a modification of Nibble's patch for dwm tip version that permits to 
select visible clients by clicking on the taskbar. That way we can have a 
"fully functional taskbar".

This patch is useful when working on floating or monocle layouts using 
applications that require us to use constantly the mouse and to have multiple 
windows (as gimp for example).

Kind Regards,

Delta
diff -r deaa276abac1 dwm.c
--- a/dwm.c	Thu Mar 19 13:06:15 2009 +0000
+++ b/dwm.c	Tue Apr 14 11:39:33 2009 +0200
@@ -150,6 +150,7 @@
 static void enternotify(XEvent *e);
 static void expose(XEvent *e);
 static void focus(Client *c);
+static void focusclienttaskbar(const Arg *arg);
 static void focusin(XEvent *e);
 static void focusstack(const Arg *arg);
 static Client *getclient(Window w);
@@ -210,6 +211,7 @@
 static int sx, sy, sw, sh; /* X display screen geometry x, y, width, height */ 
 static int by, bh, blw;    /* bar geometry y, height and layout symbol width */
 static int wx, wy, ww, wh; /* window area geometry x, y, width, height, bar excluded */
+static int ncc; /* number of client clicked */
 static unsigned int seltags = 0, sellt = 0;
 static int (*xerrorxlib)(Display *, XErrorEvent *);
 static unsigned int numlockmask = 0;
@@ -359,7 +361,8 @@
 
 void
 buttonpress(XEvent *e) {
-	unsigned int i, x, click;
+	unsigned int i, x, click, n = 0;
+	float wpc; //width per client
 	Arg arg = {0};
 	Client *c;
 	XButtonPressedEvent *ev = &e->xbutton;
@@ -376,8 +379,14 @@
 			click = ClkLtSymbol;
 		else if(ev->x > wx + ww - TEXTW(stext))
 			click = ClkStatusText;
-		else
+		else {
 			click = ClkWinTitle;
+			for(c = clients; c; c = c->next)
+			    if(ISVISIBLE(c))
+	    			n++;
+			wpc = (wx + ww - TEXTW(stext) - x - blw) / n;
+			ncc = (ev->x - x - blw) / wpc; 
+		}
 	}
 	else if((c = getclient(ev->window))) {
 		focus(c);
@@ -551,8 +560,8 @@
 
 void
 drawbar(void) {
-	int x;
-	unsigned int i, occ = 0, urg = 0;
+	int x, stx;
+	unsigned int i, occ = 0, urg = 0, n = 0;
 	unsigned long *col;
 	Client *c;
 
@@ -560,6 +569,8 @@
 		occ |= c->tags;
 		if(c->isurgent)
 			urg |= c->tags;
+		if(ISVISIBLE(c))
+			n++;
 	}
 
 	dc.x = 0;
@@ -584,12 +595,18 @@
 		dc.w = ww - x;
 	}
 	drawtext(stext, dc.norm, False);
-	if((dc.w = dc.x - x) > bh) {
+	if((dc.w = n > 0 ? (dc.x - x) / n : dc.x - x) > bh) {
+		stx = dc.x;
 		dc.x = x;
-		if(sel) {
-			drawtext(sel->name, dc.sel, False);
-			drawsquare(sel->isfixed, sel->isfloating, False, dc.sel);
-		}
+		if(sel)
+			for(c = clients, i = 1; c; c = c->next) {
+				if(ISVISIBLE(c)) {
+					drawtext(c->name, (c == sel ? dc.sel : dc.norm), c->isurgent);
+					drawsquare(c->isfixed, c->isfloating, c->isurgent, (c == sel ? dc.sel : dc.norm));
+					dc.x += dc.w;
+					dc.w = ++i < n ? dc.w : stx - dc.x;
+				}
+			}
 		else
 			drawtext(NULL, dc.norm, False);
 	}
@@ -690,6 +707,17 @@
 	drawbar();
 }
 
+void focusclienttaskbar(const Arg *arg) {
+    Client *c;
+
+    for(c = clients; c; c = c->next)
+		if (ISVISIBLE(c) && --ncc < 0) {
+    		focus(c);
+    		restack();
+			break;
+		}
+}
+
 void
 focusin(XEvent *e) { /* there are some broken focus acquiring clients */
 	XFocusChangeEvent *ev = &e->xfocus;

Reply via email to