changeset: 2349:fe9282224a76
user: Kris Maglione <jg_AT_suckless.org>
date: Sat Oct 11 19:05:24 2008 -0400
files: cmd/wmii/client.c cmd/wmii/layout.c cmd/wmii/main.c cmd/wmii/view.c cmd/wmii/x11.c include/x11.h
description:
Better, cleaner error handling.
diff -r 8044f5372bf7 -r fe9282224a76 cmd/wmii/client.c
--- a/cmd/wmii/client.c Mon Sep 29 11:10:54 2008 -0400
+++ b/cmd/wmii/client.c Sat Oct 11 19:05:24 2008 -0400
@@ -159,7 +159,6 @@
p.x = def.border;
p.y = labelh(def.font);
- reparentwindow(&c->w, c->framewin, p);
group_init(c);
@@ -172,6 +171,20 @@
break;
}
+
+ /*
+ * It's actually possible for a window to be destroyed
+ * before we get a chance to reparant it. Check for that
+ * now, because otherwise we'll wind up mapping an empty
+ * frame.
+ */
+ traperrors(true);
+ reparentwindow(&c->w, c->framewin, p);
+ if(traperrors(false)) {
+ client_destroy(c);
+ return nil;
+ }
+
ewmh_initclient(c);
event("CreateClient %C\n", c);
@@ -181,7 +194,7 @@
void
client_manage(Client *c) {
- Client *trans;
+ Client *leader;
Frame *f;
char *tags;
@@ -192,14 +205,14 @@
tags = getprop_string(&c->w, "_WMII_TAGS");
- trans = win2client(c->trans);
- if(trans == nil && c->group)
- trans = group_leader(c->group);
+ leader = win2client(c->trans);
+ if(leader == nil && c->group)
+ leader = group_leader(c->group);
- if(tags && (!trans || starting))
+ if(tags && (!leader || leader == c || starting))
utflcpy(c->tags, tags, sizeof c->tags);
- else if(trans)
- utflcpy(c->tags, trans->tags, sizeof c->tags);
+ else if(leader)
+ utflcpy(c->tags, leader->tags, sizeof c->tags);
free(tags);
if(!c->tags[0])
@@ -231,15 +244,8 @@
}
}
-static int /* Temporary Xlib error handler */
-ignoreerrors(Display *d, XErrorEvent *e) {
- USED(d, e);
- return 0;
-}
-
void
client_destroy(Client *c) {
- int (*handler)(Display*, XErrorEvent*);
Rectangle r;
char *none;
Client **tc;
@@ -261,8 +267,9 @@
hide = true;
XGrabServer(display);
+
/* In case the client is already destroyed. */
- handler = XSetErrorHandler(ignoreerrors);
+ traperrors(true);
sethandler(&c->w, nil);
if(hide)
@@ -270,8 +277,7 @@
else
reparentwindow(&c->w, &scr.root, r.min);
- sync();
- XSetErrorHandler(handler);
+ traperrors(false);
XUngrabServer(display);
none = nil;
diff -r 8044f5372bf7 -r fe9282224a76 cmd/wmii/layout.c
--- a/cmd/wmii/layout.c Mon Sep 29 11:10:54 2008 -0400
+++ b/cmd/wmii/layout.c Sat Oct 11 19:05:24 2008 -0400
@@ -235,10 +235,15 @@
trampoline(int fn, Frame *f) {
while(fn > 0) {
+ resizing = fn != TFloat;
+ view_update(f->view);
+ warppointer(grabboxcenter(f));
//f->collapsed = false;
fn = tramp[fn](f);
}
ungrabpointer();
+ resizing = false;
+ view_update(f->view);
}
void
@@ -255,17 +260,11 @@
y = (float)p.y / Dy(f->r);
}
- resizing = true;
- view_update(f->view);
- warppointer(grabboxcenter(f));
-
if(f->area->floating)
trampoline(TFloat, f);
else
trampoline(THCol, f);
- resizing = false;
- view_update(f->view);
if(grabmod)
warppointer(addpt(f->r.min, Pt(x * Dx(f->r),
y * Dy(f->r))));
diff -r 8044f5372bf7 -r fe9282224a76 cmd/wmii/main.c
--- a/cmd/wmii/main.c Mon Sep 29 11:10:54 2008 -0400
+++ b/cmd/wmii/main.c Sat Oct 11 19:05:24 2008 -0400
@@ -17,10 +17,8 @@
static const char
version[] = "wmii-"VERSION", ©2008 Kris Maglione\n";
-static int (*xlib_errorhandler) (Display*, XErrorEvent*);
static char* address;
static char* ns_path;
-static bool check_other_wm;
static int sleeperfd;
static int sock;
static int exitsignal;
@@ -136,6 +134,23 @@
XFreePixmap(display, pix);
}
+/*
+ * There's no way to check accesses to destroyed windows, thus
+ * those cases are ignored (especially on UnmapNotifies).
+ * Other types of errors call Xlib's default error handler, which
+ * calls exit().
+ */
+ErrorCode ignored_xerrors[] = {
+ { 0, BadWindow },
+ { X_SetInputFocus, BadMatch },
+ { X_PolyText8, BadDrawable },
+ { X_PolyFillRectangle, BadDrawable },
+ { X_PolySegment, BadDrawable },
+ { X_ConfigureWindow, BadMatch },
+ { X_GrabKey, BadAccess },
+ { X_GetAtomName, BadAtom },
+};
+
void
init_screen(WMScreen *screen) {
@@ -155,51 +170,6 @@
client_destroy(client);
ixp_server_close(&srv);
close(sleeperfd);
-}
-
-/*
- * There's no way to check accesses to destroyed windows, thus
- * those cases are ignored (especially on UnmapNotifies).
- * Other types of errors call Xlib's default error handler, which
- * calls exit().
- */
-static int
-errorhandler(Display *dpy, XErrorEvent *error) {
- static struct {
- uchar rcode, ecode;
- } itab[] = {
- { 0, BadWindow },
- { X_SetInputFocus, BadMatch },
- { X_PolyText8, BadDrawable },
- { X_PolyFillRectangle, BadDrawable },
- { X_PolySegment, BadDrawable },
- { X_ConfigureWindow, BadMatch },
- { X_GrabKey, BadAccess },
- { X_GetAtomName, BadAtom },
- };
- static int dead;
- int i;
-
- USED(dpy);
-
- if(check_other_wm)
- fatal("another window manager is already running");
-
- for(i = 0; i < nelem(itab); i++)
- if((itab[i].rcode == 0 || itab[i].rcode == error->request_code)
- && (itab[i].ecode == 0 || itab[i].ecode == error->error_code))
- return 0;
-
- fprint(2, "%s: fatal error: Xrequest code=%d, Xerror code=%d\n",
- argv0, error->request_code, error->error_code);
-
- /* Try to cleanup, but only try once, in case we're called recursively. */
- USED(dead);
-#ifdef notdef
- if(!dead++)
- cleanup();
-#endif
- return xlib_errorhandler(display, error); /* calls exit() */
}
static void
@@ -338,14 +308,12 @@
initdisplay();
- xlib_errorhandler = XSetErrorHandler(errorhandler);
-
- check_other_wm = true;
+ traperrors(true);
selectinput(&scr.root, SubstructureRedirectMask
| EnterWindowMask);
sync();
-
- check_other_wm = false;
+ if(traperrors(false))
+ fatal("another window manager is already running");
passwd = getpwuid(getuid());
user = estrdup(passwd->pw_name);
diff -r 8044f5372bf7 -r fe9282224a76 cmd/wmii/view.c
--- a/cmd/wmii/view.c Mon Sep 29 11:10:54 2008 -0400
+++ b/cmd/wmii/view.c Sat Oct 11 19:05:24 2008 -0400
@@ -252,10 +252,11 @@
for(c=client; c; c=c->next) {
f = c->sel;
- if(f && f->view == v
- && !(f->area && f->area->max && f->area->floating && f->area != v->sel))
- client_resize(c, f->r);
- else {
+ if((f && f->view == v)
+ && (f->area == v->sel || !(f->area && f->area->max && f->area->floating))) {
+ if(f->area)
+ client_resize(c, f->r);
+ }else {
unmap_frame(c);
client_unmap(c, IconicState);
}
@@ -304,8 +305,11 @@
c = f->client;
- oldsel = nil;
+ oldsel = v->oldsel;
a = v->sel;
+ print("view: %s\n", v->name);
+ print("client: %C\n", c);
+ print("< sel: %a\n", v->sel);
if(client_floats_p(c)) {
if(v->sel != v->area)
oldsel = v->sel;
@@ -323,6 +327,7 @@
else if(starting || c->sel && c->sel->area && !c->sel->area->floating)
a = v->area->next;
}
+ print("< sel: %a oldsel: %a\n", v->sel, oldsel);
area_attach(a, f);
/* TODO: Decide whether to focus this frame */
@@ -341,6 +346,7 @@
if(oldsel)
v->oldsel = oldsel;
+ print("< sel: %a oldsel: %a\n", v->sel, oldsel);
if(c->sel == nil)
c->sel = f;
diff -r 8044f5372bf7 -r fe9282224a76 cmd/wmii/x11.c
--- a/cmd/wmii/x11.c Mon Sep 29 11:10:54 2008 -0400
+++ b/cmd/wmii/x11.c Sat Oct 11 19:05:24 2008 -0400
@@ -26,6 +26,9 @@
static Map atommap;
static MapEnt* wbucket[137];
static MapEnt* abucket[137];
+
+static int errorhandler(Display*, XErrorEvent*);
+static int (*xlib_errorhandler) (Display*, XErrorEvent*);
/* Rectangles/Points */
@@ -185,6 +188,46 @@
fmtinstall('R', Rfmt);
fmtinstall('P', Pfmt);
fmtinstall('W', Wfmt);
+
+ xlib_errorhandler = XSetErrorHandler(errorhandler);
+}
+
+/* Error handling */
+
+ErrorCode ignored_xerrors[];
+static bool _trap_errors;
+static long nerrors;
+
+static int
+errorhandler(Display *dpy, XErrorEvent *error) {
+ ErrorCode *e;
+
+ USED(dpy);
+
+ if(_trap_errors)
+ nerrors++;
+
+ e = ignored_xerrors;
+ if(e)
+ for(; e->rcode || e->ecode; e++)
+ if((e->rcode == 0 || e->rcode == error->request_code)
+ && (e->ecode == 0 || e->ecode == error->error_code))
+ return 0;
+
+ fprint(2, "%s: fatal error: Xrequest code=%d, Xerror code=%d\n",
+ argv0, error->request_code, error->error_code);
+ return xlib_errorhandler(display, error); /* calls exit() */
+}
+
+int
+traperrors(bool enable) {
+
+ sync();
+ _trap_errors = enable;
+ if (enable)
+ nerrors = 0;
+ return nerrors;
+
}
/* Images */
diff -r 8044f5372bf7 -r fe9282224a76 include/x11.h
--- a/include/x11.h Mon Sep 29 11:10:54 2008 -0400
+++ b/include/x11.h Sat Oct 11 19:05:24 2008 -0400
@@ -48,6 +48,7 @@
};
typedef struct CTuple CTuple;
+typedef struct ErrorCode ErrorCode;
typedef struct Ewmh Ewmh;
typedef struct Font Font;
typedef struct Handlers Handlers;
@@ -61,6 +62,11 @@
ulong fg;
ulong border;
char colstr[24]; /* #RRGGBB #RRGGBB #RRGGBB */
+};
+
+struct ErrorCode {
+ uchar rcode;
+ uchar ecode;
};
struct Ewmh {
@@ -234,6 +240,7 @@
void sync(void);
uint textwidth(Font*, char*);
uint textwidth_l(Font*, char*, uint len);
+int traperrors(bool);
Point translate(Window*, Window*, Point);
void ungrabpointer(void);
int unmapwin(Window*);
Received on Sun Oct 12 2008 - 00:31:21 UTC
This archive was generated by hypermail 2.2.0 : Sun Oct 12 2008 - 00:36:05 UTC