first commit
This commit is contained in:
commit
0f0ad5dfdc
23
LICENSE
Normal file
23
LICENSE
Normal file
@ -0,0 +1,23 @@
|
||||
MIT/X Consortium License
|
||||
|
||||
© 2009-2011 Enno Boland <g s01 de>
|
||||
© 2011,2015 Connor Lane Smith <cls@lubutu.com>
|
||||
© 2012-2015 Christoph Lohmann <20h@r-36.net>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
65
Makefile
Normal file
65
Makefile
Normal file
@ -0,0 +1,65 @@
|
||||
# tabbed - tabbing interface
|
||||
# See LICENSE file for copyright and license details.
|
||||
|
||||
include config.mk
|
||||
|
||||
SRC = tabbed.c xembed.c
|
||||
OBJ = ${SRC:.c=.o}
|
||||
BIN = ${OBJ:.o=}
|
||||
|
||||
all: options ${BIN}
|
||||
|
||||
options:
|
||||
@echo tabbed build options:
|
||||
@echo "CFLAGS = ${CFLAGS}"
|
||||
@echo "LDFLAGS = ${LDFLAGS}"
|
||||
@echo "CC = ${CC}"
|
||||
|
||||
.c.o:
|
||||
@echo CC $<
|
||||
@${CC} -c ${CFLAGS} $<
|
||||
|
||||
${OBJ}: config.h config.mk
|
||||
|
||||
config.h:
|
||||
@echo creating $@ from config.def.h
|
||||
@cp config.def.h $@
|
||||
|
||||
.o:
|
||||
@echo CC -o $@
|
||||
@${CC} -o $@ $< ${LDFLAGS}
|
||||
|
||||
clean:
|
||||
@echo cleaning
|
||||
@rm -f ${BIN} ${OBJ} tabbed-${VERSION}.tar.gz
|
||||
|
||||
dist: clean
|
||||
@echo creating dist tarball
|
||||
@mkdir -p tabbed-${VERSION}
|
||||
@cp -R LICENSE Makefile README config.def.h config.mk \
|
||||
tabbed.1 arg.h ${SRC} tabbed-${VERSION}
|
||||
@tar -cf tabbed-${VERSION}.tar tabbed-${VERSION}
|
||||
@gzip tabbed-${VERSION}.tar
|
||||
@rm -rf tabbed-${VERSION}
|
||||
|
||||
install: all
|
||||
@echo installing executable files to ${DESTDIR}${PREFIX}/bin
|
||||
@mkdir -p "${DESTDIR}${PREFIX}/bin"
|
||||
@cp -f ${BIN} "${DESTDIR}${PREFIX}/bin"
|
||||
@chmod 755 "${DESTDIR}${PREFIX}/bin/tabbed"
|
||||
@echo installing manual pages to ${DESTDIR}${MANPREFIX}/man1
|
||||
@mkdir -p "${DESTDIR}${MANPREFIX}/man1"
|
||||
@sed "s/VERSION/${VERSION}/g" < tabbed.1 > "${DESTDIR}${MANPREFIX}/man1/tabbed.1"
|
||||
@chmod 644 "${DESTDIR}${MANPREFIX}/man1/tabbed.1"
|
||||
@sed "s/VERSION/${VERSION}/g" < xembed.1 > "${DESTDIR}${MANPREFIX}/man1/xembed.1"
|
||||
@chmod 644 "${DESTDIR}${MANPREFIX}/man1/xembed.1"
|
||||
|
||||
uninstall:
|
||||
@echo removing executable files from ${DESTDIR}${PREFIX}/bin
|
||||
@rm -f "${DESTDIR}${PREFIX}/bin/tabbed"
|
||||
@rm -f "${DESTDIR}${PREFIX}/bin/xembed"
|
||||
@echo removing manual pages from ${DESTDIR}${MANPREFIX}/man1
|
||||
@rm -f "${DESTDIR}${MANPREFIX}/man1/tabbed.1"
|
||||
@rm -f "${DESTDIR}${MANPREFIX}/man1/xembed.1"
|
||||
|
||||
.PHONY: all options clean dist install uninstall
|
22
README
Normal file
22
README
Normal file
@ -0,0 +1,22 @@
|
||||
tabbed - generic tabbed interface
|
||||
=================================
|
||||
tabbed is a simple tabbed X window container.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
In order to build tabbed you need the Xlib header files.
|
||||
|
||||
Installation
|
||||
------------
|
||||
Edit config.mk to match your local setup (tabbed is installed into
|
||||
the /usr/local namespace by default).
|
||||
|
||||
Afterwards enter the following command to build and install tabbed
|
||||
(if necessary as root):
|
||||
|
||||
make clean install
|
||||
|
||||
Running tabbed
|
||||
--------------
|
||||
See the man page for details.
|
||||
|
4
TODO
Normal file
4
TODO
Normal file
@ -0,0 +1,4 @@
|
||||
# TODO
|
||||
* add some way to detach windows
|
||||
* add some way to attach windows
|
||||
|
48
arg.h
Normal file
48
arg.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copy me if you can.
|
||||
* by 20h
|
||||
*/
|
||||
|
||||
#ifndef ARG_H__
|
||||
#define ARG_H__
|
||||
|
||||
extern char *argv0;
|
||||
|
||||
/* use main(int argc, char *argv[]) */
|
||||
#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\
|
||||
argv[0] && argv[0][0] == '-'\
|
||||
&& argv[0][1];\
|
||||
argc--, argv++) {\
|
||||
char argc_;\
|
||||
char **argv_;\
|
||||
int brk_;\
|
||||
if (argv[0][1] == '-' && argv[0][2] == '\0') {\
|
||||
argv++;\
|
||||
argc--;\
|
||||
break;\
|
||||
}\
|
||||
for (brk_ = 0, argv[0]++, argv_ = argv;\
|
||||
argv[0][0] && !brk_;\
|
||||
argv[0]++) {\
|
||||
if (argv_ != argv)\
|
||||
break;\
|
||||
argc_ = argv[0][0];\
|
||||
switch (argc_)
|
||||
#define ARGEND }\
|
||||
}
|
||||
|
||||
#define ARGC() argc_
|
||||
|
||||
#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\
|
||||
((x), abort(), (char *)0) :\
|
||||
(brk_ = 1, (argv[0][1] != '\0')?\
|
||||
(&argv[0][1]) :\
|
||||
(argc--, argv++, argv[0])))
|
||||
|
||||
#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\
|
||||
(char *)0 :\
|
||||
(brk_ = 1, (argv[0][1] != '\0')?\
|
||||
(&argv[0][1]) :\
|
||||
(argc--, argv++, argv[0])))
|
||||
|
||||
#endif
|
66
config.def.h
Normal file
66
config.def.h
Normal file
@ -0,0 +1,66 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
/* appearance */
|
||||
static const char font[] = "monospace:size=9";
|
||||
static const char* normbgcolor = "#222222";
|
||||
static const char* normfgcolor = "#cccccc";
|
||||
static const char* selbgcolor = "#555555";
|
||||
static const char* selfgcolor = "#ffffff";
|
||||
static const char* urgbgcolor = "#111111";
|
||||
static const char* urgfgcolor = "#cc0000";
|
||||
static const char before[] = "<";
|
||||
static const char after[] = ">";
|
||||
static const char titletrim[] = "...";
|
||||
static const int tabwidth = 200;
|
||||
static const Bool foreground = True;
|
||||
static Bool urgentswitch = False;
|
||||
|
||||
/*
|
||||
* Where to place a new tab when it is opened. When npisrelative is True,
|
||||
* then the current position is changed + newposition. If npisrelative
|
||||
* is False, then newposition is an absolute position.
|
||||
*/
|
||||
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 -w $1`\" &&" \
|
||||
"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|ShiftMask, XK_l, rotate, { .i = +1 } },
|
||||
{ MODKEY|ShiftMask, XK_h, rotate, { .i = -1 } },
|
||||
{ MODKEY|ShiftMask, XK_j, movetab, { .i = -1 } },
|
||||
{ MODKEY|ShiftMask, XK_k, movetab, { .i = +1 } },
|
||||
{ MODKEY, XK_Tab, rotate, { .i = 0 } },
|
||||
|
||||
{ MODKEY, XK_grave, spawn, SETPROP("_TABBED_SELECT_TAB") },
|
||||
{ MODKEY, XK_1, move, { .i = 0 } },
|
||||
{ MODKEY, XK_2, move, { .i = 1 } },
|
||||
{ MODKEY, XK_3, move, { .i = 2 } },
|
||||
{ MODKEY, XK_4, move, { .i = 3 } },
|
||||
{ MODKEY, XK_5, move, { .i = 4 } },
|
||||
{ MODKEY, XK_6, move, { .i = 5 } },
|
||||
{ MODKEY, XK_7, move, { .i = 6 } },
|
||||
{ MODKEY, XK_8, move, { .i = 7 } },
|
||||
{ MODKEY, XK_9, move, { .i = 8 } },
|
||||
{ MODKEY, XK_0, move, { .i = 9 } },
|
||||
|
||||
{ MODKEY, XK_q, killclient, { 0 } },
|
||||
|
||||
{ MODKEY, XK_u, focusurgent, { 0 } },
|
||||
{ MODKEY|ShiftMask, XK_u, toggle, { .v = (void*) &urgentswitch } },
|
||||
|
||||
{ 0, XK_F11, fullscreen, { 0 } },
|
||||
};
|
58
config.h
Normal file
58
config.h
Normal file
@ -0,0 +1,58 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
/* appearance */
|
||||
static const char font[] = "Iosevka:pixelsize=14:antialias=true:autohint=true";
|
||||
#include "/home/spy/.config/cols/tabbed.h"
|
||||
static const char before[] = "<";
|
||||
static const char after[] = ">";
|
||||
static const char titletrim[] = "...";
|
||||
static const int tabwidth = 200;
|
||||
static const Bool foreground = True;
|
||||
static Bool urgentswitch = False;
|
||||
|
||||
/*
|
||||
* Where to place a new tab when it is opened. When npisrelative is True,
|
||||
* then the current position is changed + newposition. If npisrelative
|
||||
* is False, then newposition is an absolute position.
|
||||
*/
|
||||
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 -w $1`\" &&" \
|
||||
"xprop -id $1 -f $0 8s -set $0 \"$prop\"", \
|
||||
p, winid, NULL \
|
||||
} \
|
||||
}
|
||||
|
||||
#define MODKEY ControlMask
|
||||
static Key keys[] = {
|
||||
/* modifier key function argument */
|
||||
{ MODKEY, XK_Return, focusonce, { 0 } },
|
||||
{ MODKEY, XK_Return, spawn, { 0 } },
|
||||
|
||||
{ MODKEY, XK_h, movetab, { .i = -1 } },
|
||||
{ MODKEY, XK_l, movetab, { .i = +1 } },
|
||||
{ MODKEY, XK_j, rotate, { .i = +1 } },
|
||||
{ MODKEY, XK_k, rotate, { .i = -1 } },
|
||||
{ MODKEY, XK_Tab, rotate, { .i = 0 } },
|
||||
|
||||
{ MODKEY, XK_grave, spawn, SETPROP("_TABBED_SELECT_TAB") },
|
||||
{ MODKEY, XK_1, move, { .i = 0 } },
|
||||
{ MODKEY, XK_2, move, { .i = 1 } },
|
||||
{ MODKEY, XK_3, move, { .i = 2 } },
|
||||
{ MODKEY, XK_4, move, { .i = 3 } },
|
||||
{ MODKEY, XK_5, move, { .i = 4 } },
|
||||
{ MODKEY, XK_6, move, { .i = 5 } },
|
||||
{ MODKEY, XK_7, move, { .i = 6 } },
|
||||
{ MODKEY, XK_8, move, { .i = 7 } },
|
||||
{ MODKEY, XK_9, move, { .i = 8 } },
|
||||
{ MODKEY, XK_0, move, { .i = 9 } },
|
||||
{ MODKEY, XK_q, killclient, { 0 } },
|
||||
{ MODKEY, XK_u, focusurgent, { 0 } },
|
||||
{ MODKEY|ShiftMask, XK_u, toggle, { .v = (void*) &urgentswitch } },
|
||||
{ MODKEY, XK_f, fullscreen, { 0 } },
|
||||
};
|
33
config.mk
Normal file
33
config.mk
Normal file
@ -0,0 +1,33 @@
|
||||
# tabbed version
|
||||
VERSION = 0.6
|
||||
|
||||
# Customize below to fit your system
|
||||
|
||||
# paths
|
||||
PREFIX = /usr/local
|
||||
MANPREFIX = ${PREFIX}/share/man
|
||||
|
||||
X11INC = /usr/X11R6/include
|
||||
X11LIB = /usr/X11R6/lib
|
||||
|
||||
# freetype
|
||||
FREETYPELIBS = -lfontconfig -lXft
|
||||
FREETYPEINC = /usr/include/freetype2
|
||||
# OpenBSD (uncomment)
|
||||
#FREETYPEINC = ${X11INC}/freetype2
|
||||
|
||||
# includes and libs
|
||||
INCS = -I. -I/usr/include -I$(X11INC) -I${FREETYPEINC}
|
||||
LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${FREETYPELIBS}
|
||||
|
||||
# flags
|
||||
CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE
|
||||
CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
|
||||
LDFLAGS = -s ${LIBS}
|
||||
|
||||
# Solaris
|
||||
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
|
||||
#LDFLAGS = ${LIBS}
|
||||
|
||||
# compiler and linker
|
||||
CC = cc
|
171
tabbed.1
Normal file
171
tabbed.1
Normal file
@ -0,0 +1,171 @@
|
||||
.TH TABBED 1 tabbed\-VERSION
|
||||
.SH NAME
|
||||
tabbed \- generic tabbed interface
|
||||
.SH SYNOPSIS
|
||||
.B tabbed
|
||||
.RB [ \-c ]
|
||||
.RB [ \-d ]
|
||||
.RB [ \-k ]
|
||||
.RB [ \-s ]
|
||||
.RB [ \-v ]
|
||||
.RB [ \-g
|
||||
.IR geometry ]
|
||||
.RB [ \-n
|
||||
.IR name ]
|
||||
.RB [ \-p
|
||||
.RB [ s {+/-} ] \fIpos\fR ]
|
||||
.RB [ \-o
|
||||
.IR normbgcol ]
|
||||
.RB [ \-O
|
||||
.IR normfgcol ]
|
||||
.RB [ \-t
|
||||
.IR selbgcol ]
|
||||
.RB [ \-T
|
||||
.IR selfgcol ]
|
||||
.RB [ \-u
|
||||
.IR urgbgcol ]
|
||||
.RB [ \-U
|
||||
.IR urgfgcol ]
|
||||
.RB [ \-r
|
||||
.IR narg ]
|
||||
.RI [ "command ..." ]
|
||||
.SH DESCRIPTION
|
||||
.B tabbed
|
||||
is a simple tabbed container for applications which support XEmbed. Tabbed
|
||||
will then run the provided command with the xid of tabbed as appended
|
||||
argument. (See EXAMPLES.) The automatic spawning of the command can be
|
||||
disabled by providing the -s parameter. If no command is provided
|
||||
tabbed will just print its xid and run no command.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-c
|
||||
close tabbed when the last tab is closed. Mutually exclusive with -f.
|
||||
.TP
|
||||
.B \-d
|
||||
detaches tabbed from the terminal and prints its XID to stdout.
|
||||
.TP
|
||||
.B \-f
|
||||
fill up tabbed again by spawning the provided command, when the last tab is
|
||||
closed. Mutually exclusive with -c.
|
||||
.TP
|
||||
.BI \-g " geometry"
|
||||
defines the X11 geometry string, which will fixate the height and width of
|
||||
tabbed.
|
||||
The syntax is
|
||||
.RI [=][ width {xX} height ][{+-} xoffset {+-} yoffset ].
|
||||
See
|
||||
.BR XParseGeometry (3)
|
||||
for further details.
|
||||
.TP
|
||||
.B \-k
|
||||
close foreground tabbed client (instead of tabbed and all clients) when
|
||||
WM_DELETE_WINDOW is sent.
|
||||
.TP
|
||||
.BI \-n " name"
|
||||
will set the WM_CLASS attribute to
|
||||
.I name.
|
||||
.TP
|
||||
.BR \-p " [" s {+-}] \fIpos\fR
|
||||
will set the absolute or relative position of where to start a new tab. When
|
||||
.I pos
|
||||
is is given without 's' in front it is an absolute position. Then negative
|
||||
numbers will be the position from the last tab, where -1 is the last tab.
|
||||
If 's' is given, then
|
||||
.I pos
|
||||
is a relative position to the current selected tab. If this reaches the limits
|
||||
of the tabs; those limits then apply.
|
||||
.TP
|
||||
.BI \-r " narg"
|
||||
will replace the
|
||||
.I narg
|
||||
th argument in
|
||||
.I command
|
||||
with the window id, rather than appending it to the end.
|
||||
.TP
|
||||
.B \-s
|
||||
will disable automatic spawning of the command.
|
||||
.TP
|
||||
.BI \-o " normbgcol"
|
||||
defines the normal background color.
|
||||
.RI # RGB ,
|
||||
.RI # RRGGBB ,
|
||||
and X color names are supported.
|
||||
.TP
|
||||
.BI \-O " normfgcol"
|
||||
defines the normal foreground color.
|
||||
.TP
|
||||
.BI \-t " selbgcol"
|
||||
defines the selected background color.
|
||||
.TP
|
||||
.BI \-T " selfgbcol"
|
||||
defines the selected foreground color.
|
||||
.TP
|
||||
.BI \-u " urgbgcol"
|
||||
defines the urgent background color.
|
||||
.TP
|
||||
.BI \-U " urgfgbcol"
|
||||
defines the urgent foreground color.
|
||||
.TP
|
||||
.B \-v
|
||||
prints version information to stderr, then exits.
|
||||
.SH USAGE
|
||||
.TP
|
||||
.B Ctrl\-Shift\-Return
|
||||
open new tab
|
||||
.TP
|
||||
.B Ctrl\-Shift\-h
|
||||
previous tab
|
||||
.TP
|
||||
.B Ctrl\-Shift\-l
|
||||
next tab
|
||||
.TP
|
||||
.B Ctrl\-Shift\-j
|
||||
move selected tab one to the left
|
||||
.TP
|
||||
.B Ctrl\-Shift\-k
|
||||
move selected tab one to the right
|
||||
.TP
|
||||
.B Ctrl\-Shift\-u
|
||||
toggle autofocus of urgent tabs
|
||||
.TP
|
||||
.B Ctrl\-Tab
|
||||
toggle between the selected and last selected tab
|
||||
.TP
|
||||
.B Ctrl\-`
|
||||
open dmenu to either create a new tab appending the entered string or select
|
||||
an already existing tab.
|
||||
.TP
|
||||
.B Ctrl\-q
|
||||
close tab
|
||||
.TP
|
||||
.B Ctrl\-u
|
||||
focus next urgent tab
|
||||
.TP
|
||||
.B Ctrl\-[0..9]
|
||||
jumps to nth tab
|
||||
.TP
|
||||
.B F11
|
||||
Toggle fullscreen mode.
|
||||
.SH EXAMPLES
|
||||
$ tabbed surf -e
|
||||
.TP
|
||||
$ tabbed urxvt -embed
|
||||
.TP
|
||||
$ tabbed xterm -into
|
||||
.TP
|
||||
$ $(tabbed -d >/tmp/tabbed.xid); urxvt -embed $(</tmp/tabbed.xid);
|
||||
.TP
|
||||
$ tabbed -r 2 st -w '' -e tmux
|
||||
.SH CUSTOMIZATION
|
||||
.B tabbed
|
||||
can be customized by creating a custom config.h and (re)compiling the source
|
||||
code. This keeps it fast, secure and simple.
|
||||
.SH AUTHORS
|
||||
See the LICENSE file for the authors.
|
||||
.SH LICENSE
|
||||
See the LICENSE file for the terms of redistribution.
|
||||
.SH SEE ALSO
|
||||
.BR st (1),
|
||||
.BR xembed (1)
|
||||
.SH BUGS
|
||||
Please report them.
|
35
xembed.1
Normal file
35
xembed.1
Normal file
@ -0,0 +1,35 @@
|
||||
.TH XEMBED 1 tabbed\-VERSION
|
||||
.SH NAME
|
||||
xembed \- XEmbed foreground process
|
||||
.SH SYNOPSIS
|
||||
.B xembed
|
||||
.I flag command
|
||||
.RI [ "argument ..." ]
|
||||
.SH DESCRIPTION
|
||||
If the environment variable XEMBED is set, and
|
||||
.B xembed
|
||||
is in the foreground of its controlling tty, it will execute
|
||||
.IP
|
||||
command flag $XEMBED [argument ...]
|
||||
.LP
|
||||
Otherwise it will execute
|
||||
.IP
|
||||
command [argument ...]
|
||||
.LP
|
||||
.SH EXAMPLE
|
||||
In a terminal emulator within a
|
||||
.B tabbed
|
||||
session, the shell alias
|
||||
.IP
|
||||
$ alias surf='xembed -e surf'
|
||||
.LP
|
||||
will cause `surf' to open in a new tab, unless it is run in the background,
|
||||
i.e. `surf &', in which case it will instead open in a new window.
|
||||
.SH AUTHORS
|
||||
See the LICENSE file for the authors.
|
||||
.SH LICENSE
|
||||
See the LICENSE file for the terms of redistribution.
|
||||
.SH SEE ALSO
|
||||
.BR tabbed (1)
|
||||
.SH BUGS
|
||||
Please report them.
|
45
xembed.c
Normal file
45
xembed.c
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* See LICENSE file for copyright and license details.
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *xembed;
|
||||
int tty;
|
||||
pid_t pgrp, tcpgrp;
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "usage: %s flag cmd ...\n", argv[0]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (!(xembed = getenv("XEMBED")))
|
||||
goto noembed;
|
||||
|
||||
if ((tty = open("/dev/tty", O_RDONLY)) < 0)
|
||||
goto noembed;
|
||||
|
||||
pgrp = getpgrp();
|
||||
tcpgrp = tcgetpgrp(tty);
|
||||
|
||||
close(tty);
|
||||
|
||||
if (pgrp == tcpgrp) { /* in foreground of tty */
|
||||
argv[0] = argv[2];
|
||||
argv[2] = xembed;
|
||||
} else {
|
||||
noembed:
|
||||
argv += 2;
|
||||
}
|
||||
|
||||
execvp(argv[0], argv);
|
||||
|
||||
perror(argv[0]); /* failed to execute */
|
||||
return 1;
|
||||
}
|
Loading…
Reference in New Issue
Block a user