summaryrefslogtreecommitdiffstats
path: root/tabbed.c
diff options
context:
space:
mode:
authorMarkus Teich <markus.teich@stusta.mhn.de>2013-11-28 18:26:21 +0100
committerChristoph Lohmann <20h@r-36.net>2013-12-01 20:03:40 +0100
commita1aa453e99f198186d39b90b1229cc1bcb8dc466 (patch)
tree11aa790d4945fed6da24092b542b5656e066033e /tabbed.c
parentb46a3a278856bb33dc299d11d0be1b01d04df39c (diff)
downloadtabbed-a1aa453e99f198186d39b90b1229cc1bcb8dc466.tar.gz
select or open new tab with Ctrl-T
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. Signed-off-by: Christoph Lohmann <20h@r-36.net>
Diffstat (limited to 'tabbed.c')
-rw-r--r--tabbed.c51
1 files changed, 44 insertions, 7 deletions
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]);
}