Introduction
Introduction Statistics Contact Development Disclaimer Help
select or open new tab with Ctrl-T - tabbed - tab interface for application sup…
git clone git://git.suckless.org/tabbed
Log
Files
Refs
README
LICENSE
---
commit a1aa453e99f198186d39b90b1229cc1bcb8dc466
parent b46a3a278856bb33dc299d11d0be1b01d04df39c
Author: Markus Teich <[email protected]>
Date: Thu, 28 Nov 2013 18:26:21 +0100
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 <[email protected]>
Diffstat:
M config.def.h | 9 +++++++++
M tabbed.c | 51 ++++++++++++++++++++++++++---…
2 files changed, 53 insertions(+), 7 deletions(-)
---
diff --git 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'…
+ "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("_T…
{ MODKEY|ShiftMask, XK_l, rotate, { .i = +1 }…
{ MODKEY|ShiftMask, XK_h, rotate, { .i = -1 }…
diff --git 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", Fa…
+ 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|PropertyChan…
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]);
}
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.