Included is a patch to add functionality to see a screen-like list of
windows from tabbed using dmenu to tabbed-0.2.

Currently it uses popen() to open a pipe to dmenu, which then sets an
xproperty, which on update switches to the window matching that title.
As you can imagine this is a little hackish and I'm not particularly
proud of this, but it works for the most part and I figured other
people may be willing to expand on the idea.

My idea for a cleaner version would involve hacking dmenu as well, so
I could pass both a unique window identifier and a display string,
then pass back two values to tabbed. This doesn't solve the
popen/xproperty problem, though. The "cleanest" way I can see would be
to embed dmenu in tabbed, but I wouldn't call doubling the program's
size desirable.

-- 
Samuel Baldwin - logik.li
diff -up tabbed-0.2/config.def.h tabbed-0.2-modified/config.def.h
--- tabbed-0.2/config.def.h     2009-10-30 08:41:29.000000000 -0400
+++ tabbed-0.2-modified/config.def.h    2010-04-15 23:13:55.000000000 -0400
@@ -24,4 +24,7 @@ static Key keys[] = { \
        { MODKEY,                       XK_9,      move,           { .i = 8 } },
        { MODKEY,                       XK_0,      move,           { .i = 9 } },
        { MODKEY,                       XK_q,      killclient,     { 0 } },
+       { MODKEY|Mod1Mask,              XK_l,      list,           { .v = (char 
*[]){ \
+               "prop=\"`dmenu -l`\" && xprop -id %s -f TABBED_LIST 8s -set 
TABBED_LIST \"$prop\"", \
+               winid, NULL } } },
 };
diff -up tabbed-0.2/tabbed.c tabbed-0.2-modified/tabbed.c
--- tabbed-0.2/tabbed.c 2009-10-30 08:41:29.000000000 -0400
+++ tabbed-0.2-modified/tabbed.c        2010-04-15 23:15:58.000000000 -0400
@@ -110,6 +110,7 @@ static void initfont(const char *fontstr
 static Bool isprotodel(Client *c);
 static void keypress(const XEvent *e);
 static void killclient(const Arg *arg);
+static void list(const Arg *arg);
 static void manage(Window win);
 static void maprequest(const XEvent *e);
 static void move(const Arg *arg);
@@ -554,6 +555,20 @@ killclient(const Arg *arg) {
 }
 
 void
+list(const Arg *arg) {
+       FILE *l;
+       Client *c;
+       static char cmd[164];
+
+       snprintf(cmd, LENGTH(cmd), ((char **)arg->v)[0], ((char **)arg->v)[1]);
+       l = popen(cmd, "w");
+       for(c = clients; c; c = c->next)
+               if (c)
+               fprintf(l, "%s\n", c->name);
+       pclose(l);
+}
+
+void
 manage(Window w) {
        updatenumlockmask();
        {
@@ -619,10 +634,20 @@ void
 propertynotify(const XEvent *e) {
        const XPropertyEvent *ev = &e->xproperty;
        Client *c;
+       static char buf[256];
+       Atom listprop = XInternAtom(dpy, "TABBED_LIST", False);
 
        if(ev->state != PropertyDelete && ev->atom == XA_WM_NAME
                        && (c = getclient(ev->window))) {
                updatetitle(c);
+       } else if(ev->state != PropertyDelete && ev->atom == listprop) {
+               gettextprop(win, listprop, buf, sizeof buf);
+
+               for(c = clients; c; c = c->next) {
+                       fprintf(stderr, "%s <-> %s\n", buf, c->name);
+                       if(!strncmp(buf, c->name, 10))
+                               focus(c);
+               }
        }
 }
 
@@ -724,7 +749,7 @@ setup(void) {
        XMapRaised(dpy, win);
        XSelectInput(dpy, win, SubstructureNotifyMask|FocusChangeMask|
                        ButtonPressMask|ExposureMask|KeyPressMask|
-                       StructureNotifyMask|SubstructureRedirectMask);
+                       
StructureNotifyMask|SubstructureRedirectMask|PropertyChangeMask);
        xerrorxlib = XSetErrorHandler(xerror);
        XClassHint class_hint;
        class_hint.res_name = "tabbed";

Reply via email to