The default config will display all open tabs in dmenu. You can either select
one of them, or if you enter a string, that does not start with „0x“, tabbed
will open a new tab and run the command specified at tabbed-startup but append
the entered string to the command first.

With
tabbed -r 2 surf -e ''
you can hit Ctrl-T and either select an already opened tab or enter an URL,
which will be opened in a new tab with surf.
---

Hello,

I had the insight, that it would not be surfs responsibility to know about tabs,
so here is a tabbed only patch achieving the above mentioned features.

--Markus


 config.def.h |  9 +++++++++
 tabbed.c     | 51 ++++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/config.def.h b/config.def.h
index ca4b8d6..3a92bd9 100644
--- a/config.def.h
+++ b/config.def.h
@@ -19,11 +19,20 @@ static const Bool foreground    = True;
 static int  newposition   = 0;
 static Bool npisrelative  = False;
 
+#define SETPROP(p) { \
+       .v = (char *[]){ "/bin/sh", "-c", \
+               "prop=\"`xwininfo -children -id $1 | grep '^     0x' | sed 
-e's@^ *\\(0x[0-9a-f]*\\) \"\\([^\"]*\\)\".*@\\1 \\2@' | xargs -0 printf %b | 
dmenu -l 10`\" &&" \
+               "xprop -id $1 -f $0 8s -set $0 \"$prop\"", \
+               p, winid, NULL \
+       } \
+}
+
 #define MODKEY ControlMask
 static Key keys[] = { \
        /* modifier                     key        function        argument */
        { MODKEY|ShiftMask,             XK_Return, focusonce,      { 0 } },
        { MODKEY|ShiftMask,             XK_Return, spawn,          { 0 } },
+       { MODKEY,                       XK_t,      spawn,          
SETPROP("_TABBED_SELECT_TAB") },
 
        { MODKEY|ShiftMask,             XK_l,      rotate,         { .i = +1 } 
},
        { MODKEY|ShiftMask,             XK_h,      rotate,         { .i = -1 } 
},
diff --git a/tabbed.c b/tabbed.c
index 3a6e7f9..e870db4 100644
--- a/tabbed.c
+++ b/tabbed.c
@@ -48,7 +48,7 @@
 
 enum { ColFG, ColBG, ColLast };                         /* color */
 enum { WMProtocols, WMDelete, WMName, WMState, WMFullscreen,
-       XEmbed, WMLast };                               /* default atoms */
+       XEmbed, WMSelectTab, WMLast };                      /* default atoms */
 
 typedef union {
        int i;
@@ -103,6 +103,7 @@ static void focus(int c);
 static void focusin(const XEvent *e);
 static void focusonce(const Arg *arg);
 static void fullscreen(const Arg *arg);
+static char* getatom(int a);
 static int getclient(Window w);
 static unsigned long getcolor(const char *colstr);
 static int getfirsttab(void);
@@ -157,6 +158,7 @@ static Window root, win;
 static Client **clients = NULL;
 static int nclients = 0, sel = -1, lastsel = -1;
 static int (*xerrorxlib)(Display *, XErrorEvent *);
+static int cmd_append_pos = 0;
 static char winid[64];
 static char **cmd = NULL;
 static char *wmname = "tabbed";
@@ -428,6 +430,7 @@ focus(int c) {
 
        /* If c, sel and clients are -1, raise tabbed-win itself */
        if(nclients == 0) {
+               cmd[cmd_append_pos] = NULL;
                for(i = 0, n = strlen(buf); cmd[i] && n < sizeof(buf); i++)
                        n += snprintf(&buf[n], sizeof(buf) - n, " %s", cmd[i]);
 
@@ -489,6 +492,26 @@ fullscreen(const Arg *arg) {
        XSendEvent(dpy, root, False, SubstructureNotifyMask, &e);
 }
 
+char *
+getatom(int a) {
+       static char buf[BUFSIZ];
+       Atom adummy;
+       int idummy;
+       unsigned long ldummy;
+       unsigned char *p = NULL;
+
+       XGetWindowProperty(dpy, win, wmatom[a], 0L, BUFSIZ, False, XA_STRING,
+                       &adummy, &idummy, &ldummy, &ldummy, &p);
+       if(p) {
+               strncpy(buf, (char *)p, LENGTH(buf)-1);
+       } else {
+               buf[0] = '\0';
+       }
+       XFree(p);
+
+       return buf;
+}
+
 int
 getclient(Window w) {
        int i;
@@ -775,8 +798,20 @@ void
 propertynotify(const XEvent *e) {
        const XPropertyEvent *ev = &e->xproperty;
        int c;
+       char* selection = NULL;
+       Arg arg;
 
-       if(ev->state != PropertyDelete && ev->atom == XA_WM_NAME
+       if(ev->state == PropertyNewValue && ev->atom == wmatom[WMSelectTab]) {
+               selection = getatom(WMSelectTab);
+               if(!strncmp(selection, "0x", 2)) {
+                       arg.i = getclient(strtoul(selection, NULL, 0));
+                       move(&arg);
+               } else {
+                       cmd[cmd_append_pos] = selection;
+                       arg.v = cmd;
+                       spawn(&arg);
+               }
+       } else if(ev->state != PropertyDelete && ev->atom == XA_WM_NAME
                        && (c = getclient(ev->window)) > -1) {
                updatetitle(c);
        }
@@ -862,13 +897,14 @@ void
 setcmd(int argc, char *argv[], int replace) {
        int i;
 
-       cmd = emallocz((argc+2) * sizeof(*cmd));
+       cmd = emallocz((argc+3) * sizeof(*cmd));
        if (argc == 0)
                return;
        for(i = 0; i < argc; i++)
                cmd[i] = argv[i];
        cmd[(replace > 0)? replace : argc] = winid;
-       cmd[argc + !(replace > 0)] = NULL;
+       cmd_append_pos = argc + !replace;
+       cmd[cmd_append_pos] = cmd[cmd_append_pos+1] = NULL;
 }
 
 void
@@ -892,8 +928,8 @@ setup(void) {
        wmatom[XEmbed] = XInternAtom(dpy, "_XEMBED", False);
        wmatom[WMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
        wmatom[WMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
-       wmatom[WMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN",
-                       False);
+       wmatom[WMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", 
False);
+       wmatom[WMSelectTab] = XInternAtom(dpy, "_TABBED_SELECT_TAB", False);
 
        /* init appearance */
        wx = 0;
@@ -943,7 +979,7 @@ setup(void) {
                        dc.norm[ColFG], dc.norm[ColBG]);
        XMapRaised(dpy, win);
        XSelectInput(dpy, win, SubstructureNotifyMask|FocusChangeMask|
-                       ButtonPressMask|ExposureMask|KeyPressMask|
+                       
ButtonPressMask|ExposureMask|KeyPressMask|PropertyChangeMask|
                        StructureNotifyMask|SubstructureRedirectMask);
        xerrorxlib = XSetErrorHandler(xerror);
 
@@ -993,6 +1029,7 @@ spawn(const Arg *arg) {
                        fprintf(stderr, "tabbed: execvp %s",
                                        ((char **)arg->v)[0]);
                } else {
+                       cmd[cmd_append_pos] = NULL;
                        execvp(cmd[0], cmd);
                        fprintf(stderr, "tabbed: execvp %s", cmd[0]);
                }
-- 
1.8.2


Reply via email to