commit 89622e41b248eb18ee7b36aa3f95f9eb4b4ad4a0
parent 9f9e39604dc3dbcc8b6b56b421a110548ec608fb
Author: Enno Boland (tox) <[email protected]>
Date: Mon, 26 Oct 2009 16:50:38 +0100
code cleaning, windows are properly closed on exit; if last client quits, exit
Diffstat:
2 files changed, 31 insertions(+), 30 deletions(-)
diff --git a/config.def.h b/config.def.h
@@ -7,12 +7,10 @@ static const int tabwidth = 200;
static const char before[] = "<";
static const char after[] = ">";
-#define EXEC "surf", "-e", winid
#define MODKEY ControlMask
static Key keys[] = { \
/* modifier key function argument */
- { MODKEY|ShiftMask, XK_Return, spawn, { .v = (char*[]){ EXEC, NULL} } },
- { MODKEY|ShiftMask, XK_t, spawn, { .v = (char*[]){ EXEC, NULL} } },
+ { MODKEY|ShiftMask, XK_Return, spawn, { .v = (char*[]){ "surf", "-e", winid, NULL} } },
{ MODKEY|ShiftMask, XK_l, rotate, { .i = +1 } },
{ MODKEY|ShiftMask, XK_h, rotate, { .i = -1 } },
{ MODKEY, XK_1, move, { .i = 1 } },
diff --git a/tabbed.c b/tabbed.c
@@ -47,11 +47,9 @@
#define LENGTH(x) (sizeof x / sizeof x[0])
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask))
#define TEXTW(x) (textnw(x, strlen(x)) + dc.font.height)
-#define XEMBED_EMBEDDED_NOTIFY 0
enum { ColFG, ColBG, ColLast }; /* color */
-enum { NetSupported, NetWMName, NetLast }; /* EWMH atoms */
-enum { WMProtocols, WMDelete, WMState, WMLast }; /* default atoms */
+enum { WMProtocols, WMDelete, WMLast }; /* default atoms */
typedef union {
int i;
@@ -147,10 +145,10 @@ static void (*handler[LASTEvent]) (const XEvent *) = {
};
static int bh, wx, wy, ww, wh;
static unsigned int numlockmask = 0;
-static Bool running = True, badwindow = False;
+static Bool running = True, hadclients = False;
static Display *dpy;
static DC dc;
-static Atom wmatom[WMLast], netatom[NetLast], xembedatom;
+static Atom wmatom[WMLast], xembedatom;
static Window root, win;
static Client *clients = NULL, *sel = NULL;
static int (*xerrorxlib)(Display *, XErrorEvent *);
@@ -177,6 +175,15 @@ buttonpress(const XEvent *e) {
void
cleanup(void) {
+ Client *c, *n;
+
+ for(c = clients; c; c = n) {
+ killclient(NULL);
+ focus(c);
+ XReparentWindow(dpy, c->win, root, 0, 0);
+ n = c->next;
+ unmanage(c);
+ }
if(dc.font.set)
XFreeFontSet(dpy, dc.font.set);
else
@@ -191,9 +198,9 @@ void
clientmessage(const XEvent *e) {
const XClientMessageEvent *ev = &e->xclient;
- if(ev->message_type == xembedatom) {
- printf("%ld %ld %ld %ld %ld\n", ev->data.l[0], ev->data.l[1], ev->data.l[2], ev->data.l[3], ev->data.l[4]);
- }
+ if(ev->message_type == wmatom[WMProtocols]
+ && ev->data.l[0] == wmatom[WMDelete])
+ running = False;
}
void
@@ -552,14 +559,11 @@ manage(Window w) {
Client *c;
XEvent e;
+ hadclients = True;
XWithdrawWindow(dpy, w, 0);
XReparentWindow(dpy, w, win, 0, bh);
XSelectInput(dpy, w, PropertyChangeMask|StructureNotifyMask|EnterWindowMask);
XSync(dpy, False);
- if(badwindow) {
- badwindow = False;
- return;
- }
for(i = 0; i < LENGTH(keys); i++) {
if((code = XKeysymToKeycode(dpy, keys[i].keysym)))
for(j = 0; j < LENGTH(modifiers); j++)
@@ -679,9 +683,6 @@ setup(void) {
/* init atoms */
wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
- wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False);
- netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
- netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
xembedatom = XInternAtom(dpy, "_XEMBED", False);
/* init appearance */
wx = 0;
@@ -701,12 +702,13 @@ setup(void) {
XMapRaised(dpy, win);
XSelectInput(dpy, win, SubstructureNotifyMask|FocusChangeMask|
ButtonPressMask|ExposureMask|KeyPressMask|
- StructureNotifyMask);
+ StructureNotifyMask|SubstructureRedirectMask);
xerrorxlib = XSetErrorHandler(xerror);
XClassHint class_hint;
class_hint.res_name = "tabbed";
class_hint.res_class = "Tabbed";
XSetClassHint(dpy, win, &class_hint);
+ XSetWMProtocols(dpy, win, &wmatom[WMDelete], 1);
snprintf(winid, LENGTH(winid), "%u", (int)win);
focus(clients);
}
@@ -749,14 +751,16 @@ unmanage(Client *c) {
if(!clients)
return;
else if(c == clients)
- clients = c->next;
+ pc = clients = c->next;
else {
for(pc = clients; pc && pc->next && pc->next != c; pc = pc->next);
pc->next = c->next;
}
+ focus(c->next ? c->next : pc);
free(c);
- focus(clients);
XSync(dpy, False);
+ if(hadclients && !clients)
+ running = False;
}
void
@@ -798,10 +802,6 @@ updatetitle(Client *c) {
* default error handler, which may call exit. */
int
xerror(Display *dpy, XErrorEvent *ee) {
- if(ee->error_code == BadWindow) {
- badwindow = True;
- return 0;
- }
fprintf(stderr, "tabbed: fatal error: request code=%d, error code=%d\n",
ee->request_code, ee->error_code);
return xerrorxlib(dpy, ee); /* may call exit */
@@ -825,12 +825,15 @@ main(int argc, char *argv[]) {
setup();
printf("%i\n", (int)win);
fflush(NULL);
- if(detach && fork() != 0) {
- if(dpy)
- close(ConnectionNumber(dpy));
- return EXIT_SUCCESS;
+ if(detach) {
+ if(fork() == 0)
+ fclose(stdout);
+ else {
+ if(dpy)
+ close(ConnectionNumber(dpy));
+ return EXIT_SUCCESS;
+ }
}
- fclose(stdout);
run();
cleanup();
XCloseDisplay(dpy);