Hi,
i tried dwm for the first time a few days ago, after years of using
wmii. my impression was, that it is much more simpler than wmii. but
something i missed where clickable buttons in the status bar, and so i
started to play a little bit with the code. 

The result is an statusbar, where the stdin is splitted by "|" to
several buttons, for each button actions can be defined.

It looks like this:
http://img161.imageshack.us/img161/115/200703042014361024x768ssk9.png

i attached an diff of the actual mercurial version

didi
diff -r 4f1ff9e068d3 draw.c
--- a/draw.c    Thu Mar 01 12:33:45 2007 +0100
+++ b/draw.c    Sun Mar 04 19:34:02 2007 +0100
@@ -3,6 +3,7 @@
  */
 #include "dwm.h"
 #include <string.h>
+#include <malloc.h>
 
 /* static */
 
@@ -52,7 +53,8 @@ textnw(const char *text, unsigned int le
 
 void
 drawstatus(void) {
-       int i, x;
+       int i, x, fc = 0, xp = 0;
+        char **fields;
 
        dc.x = dc.y = 0;
        for(i = 0; i < ntags; i++) {
@@ -70,13 +72,20 @@ drawstatus(void) {
        dc.w = blw;
        drawtext(lt->symbol, dc.norm);
        x = dc.x + dc.w;
-       dc.w = textw(stext);
-       dc.x = sw - dc.w;
-       if(dc.x < x) {
-               dc.x = x;
-               dc.w = sw - x;
-       }
-       drawtext(stext, dc.norm);
+
+        fc = rsplit(stext, "|", &fields);        
+        for(i = 0; i < fc; i++) {
+          dc.w = textw(fields[i]);
+          xp += dc.w;
+          dc.x = sw - xp;
+          if(dc.x < x) {
+                  dc.x = x;
+          }
+          drawtext(fields[i], ((i + ((fc % 2)?1:0))% 2)?dc.norm:dc.sel);
+        }
+
+        free(fields);
+
        if((dc.w = dc.x - x) > bh) {
                dc.x = x;
                if(sel) {
diff -r 4f1ff9e068d3 dwm.h
--- a/dwm.h     Thu Mar 01 12:33:45 2007 +0100
+++ b/dwm.h     Sun Mar 04 19:18:42 2007 +0100
@@ -145,3 +145,7 @@ void *emallocz(unsigned int size);  /* al
 void *emallocz(unsigned int size);     /* allocates zero-initialized memory, 
exits on error */
 void eprint(const char *errstr, ...);  /* prints errstr and exits with 1 */
 void spawn(const char *arg);           /* forks a new subprocess with arg's 
cmd */
+int rsplit(const char *line, const char *delim, char ***result); 
+                                        /* Splits a line at delim, reverse 
order ( last becomes 
+                                         * first ) saved in result 
+                                         */
diff -r 4f1ff9e068d3 event.c
--- a/event.c   Thu Mar 01 12:33:45 2007 +0100
+++ b/event.c   Sun Mar 04 19:54:58 2007 +0100
@@ -16,7 +16,15 @@ typedef struct {
        const char *arg;
 } Key;
 
+typedef struct {
+       unsigned long label;
+        unsigned long button;
+       void (*func)(const char *arg);
+       const char *arg;
+} BarAction;
+
 KEYS
+BARACTIONS
 
 #define CLEANMASK(mask) (mask & ~(numlockmask | LockMask))
 #define MOUSEMASK              (BUTTONMASK | PointerMotionMask)
@@ -114,7 +122,8 @@ static void
 static void
 buttonpress(XEvent *e) {
        static char buf[32];
-       unsigned int i, x;
+       unsigned int i, x, fc, bw, bx, xp = 0;
+        char **fields;
        Client *c;
        XButtonPressedEvent *ev = &e->xbutton;
 
@@ -146,6 +155,27 @@ buttonpress(XEvent *e) {
                                setlayout(NULL);
                                break;
                        }
+                else {
+                  fc = rsplit(stext, "|", &fields);        
+                  for(i = 0; i < fc; i++) {
+                    bw = textw(fields[i]);
+                    xp += bw;
+                    bx = sw - xp;
+                    if(bx < (x + blw)) 
+                      bx = x;
+                    if ( ev->x >= bx && ev->x <= (bx + bw)) {
+                      free(fields);
+                     static unsigned int len = sizeof baractions / sizeof 
baractions[0];
+                     for(x = 0; x < len; x++) 
+                        if ( baractions[x].label == i 
+                            && baractions[x].button == ev->button
+                            && baractions[x].func )
+                          baractions[x].func(baractions[x].arg);
+                      return;
+                    }
+                  }
+                  free(fields);
+                }
        }
        else if((c = getclient(ev->window))) {
                focus(c);
diff -r 4f1ff9e068d3 util.c
--- a/util.c    Thu Mar 01 12:33:45 2007 +0100
+++ b/util.c    Sun Mar 04 19:19:03 2007 +0100
@@ -4,6 +4,7 @@
 #include "dwm.h"
 #include <stdarg.h>
 #include <stdio.h>
+#include <string.h>
 #include <stdlib.h>
 #include <sys/wait.h>
 #include <unistd.h>
@@ -52,3 +53,28 @@ spawn(const char *arg) {
        }
        wait(0);
 }
+
+int
+rsplit(const char *line, const char *delim, char ***result)
+{
+  char *p, **fields, *t_line;
+  int fc = 0, i = 0;
+
+  if (!line || !delim) return 0;
+
+  for(p = stext; p && *p ; p++)
+    if (*p == '|') fc++;
+  fields = emallocz((fc + 1) * sizeof(char *));
+  t_line = strdup(line);
+  if (!t_line) eprint("fatal: couldn't alloc enough memory");
+
+  fields[fc] = strtok(t_line, delim);
+  if (fields[fc] == NULL) fields[fc] = t_line;
+  while((p = strtok(NULL, delim))) {
+    i++;
+    fields[fc - i] = p;
+  }
+  free(t_line);
+  *result = fields;
+  return fc + 1;
+}

Attachment: pgphLZryhzvUm.pgp
Description: PGP signature

Reply via email to