wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

commit 85c2e1b09612d34a48593ab04126aeec83c82957
parent cb7c8e9ccfb6ddd7a699403ebd258c788e46e5e2
Author: Kris Maglione <jg@suckless.org>
Date:   Sun, 18 May 2008 13:31:58 -0400

Fix tickets #2, #10, #15, #16 (dup of #10).

Diffstat:
cmd/wmii.rc.rc | 4++--
cmd/wmii/_util.c | 64++++++++++++++++++++++++++++++++++++++++++++--------------------
cmd/wmii/client.c | 10++++++++--
cmd/wmii/column.c | 35++++++++++++++++++++++++++++++-----
cmd/wmii/dat.h | 5++++-
cmd/wmii/fns.h | 1+
cmd/wmii/fs.c | 28++++++++++++++++++----------
cmd/wmii/mouse.c | 23+++++++++++++++++------
cmd/wmii/view.c | 2++
rc/rc.wmii.rc | 3++-
10 files changed, 128 insertions(+), 47 deletions(-)

diff --git a/cmd/wmii.rc.rc b/cmd/wmii.rc.rc @@ -125,10 +125,10 @@ fn wi_runcmd { @{ } fn wi_getfuns { - env | sed -n 's/^fn#'^$1^'-([^=]+).*/\1/p' + env | sed -n 's/^fn#'^$1^'-([^=]+).*/\1/p' | sort | uniq } -for(i in Key Event Action) +for(i in Key Event Action '*Menu') fns=`{wi_getfuns $i} { if(! ~ $fns '') fn $i-^$fns} diff --git a/cmd/wmii/_util.c b/cmd/wmii/_util.c @@ -6,6 +6,7 @@ #include <fcntl.h> #include <sys/wait.h> #include <unistd.h> +#include <bio.h> #include "fns.h" /* Blech. */ @@ -89,8 +90,10 @@ spawn3(int fd[3], const char *file, char *argv[]) { break; default: close(p[1]); - if(read(p[0], &_errno, sizeof _errno) == sizeof _errno) + if(read(p[0], &_errno, sizeof _errno) == sizeof _errno) { pid = -1; + errno = _errno; + } close(p[0]); break; case -1: /* can't happen */ @@ -117,6 +120,7 @@ spawn3l(int fd[3], const char *file, ...) { argv = emalloc((n+1) * sizeof *argv); va_start(ap, file); + quotefmtinstall(); for(i=0; i <= n; i++) argv[i] = va_arg(ap, char*); va_end(ap); @@ -128,14 +132,20 @@ spawn3l(int fd[3], const char *file, ...) { * doesn't like -x <pipe>, and /proc/%d/exe is the correct /proc * path. */ +#ifdef __linux__ +# define PROGTXT "exe" +#else +# define PROGTXT "file" +#endif void backtrace(char *btarg) { - char *proc, *spid; - int fd[3], p[2], q[2]; - int pid, status, n; + char *proc, *spid, *gdbcmd; + int fd[3], p[2]; + int pid, status, cmdfd; - proc = sxprint("/proc/%d/file", getpid()); + proc = sxprint("/proc/%d/" PROGTXT, getpid()); spid = sxprint("%d", getpid()); + switch(pid = fork()) { case -1: return; @@ -146,29 +156,43 @@ backtrace(char *btarg) { return; } - if(pipe(p) < 0 || pipe(q) < 0) + + if(pipe(p) < 0) exit(0); - closeexec(p[1]); - closeexec(q[0]); + closeexec(p[0]); - fd[0] = p[0]; - fd[1] = q[1]; - fd[2] = open("/dev/null", O_WRONLY); - if(spawn3l(fd, "gdb", "gdb", "-batch", "-x", "/dev/fd/0", proc, spid, nil) < 0) + gdbcmd = estrdup("/tmp/gdbcmd.XXXXXX"); + cmdfd = mkstemp(gdbcmd); + if(cmdfd < 0) exit(1); - fprint(p[1], "bt %s\n", btarg); - fprint(p[1], "detach\n"); - close(p[1]); + fprint(cmdfd, "bt %s\n", btarg); + fprint(cmdfd, "detach\n"); + close(cmdfd); + + fd[0] = open("/dev/null", O_RDONLY); + fd[1] = p[1]; + fd[2] = dup(2); + if(spawn3l(fd, "gdb", "gdb", "-batch", "-x", gdbcmd, proc, spid, nil) < 0) { + unlink(gdbcmd); + exit(1); + } /* Why? Because gdb freezes waiting for user input * if its stdout is a tty. + * Might be easier to pipe to sed 2,4d here. */ - /* It'd be nice to make this a /debug file at some point, - * anyway. - */ - while((n = read(q[0], buffer, sizeof buffer)) > 0) - write(2, buffer, n); + Biobuf bp; + char *s; + int i = 0; + + Binit(&bp, p[0], OREAD); + while((s = Brdstr(&bp, '\n', 1))) { + if(i++ >= 4) + fprint(2, "%s\n", s); + free(s); + } + unlink(gdbcmd); exit(0); } diff --git a/cmd/wmii/client.c b/cmd/wmii/client.c @@ -4,6 +4,7 @@ */ #include "dat.h" #include <ctype.h> +#include <strings.h> #include <X11/Xatom.h> #include "fns.h" @@ -490,7 +491,7 @@ client_focus(Client *c) { if(c) { if(!c->noinput) setfocus(&c->w, RevertToParent); - if(c->proto & ProtoTakeFocus) { + else if(c->proto & ProtoTakeFocus) { xtime_kludge(); client_message(c, "WM_TAKE_FOCUS", 0); } @@ -751,6 +752,7 @@ updatemwm(Client *c) { void client_prop(Client *c, Atom a) { + WinHints h; XWMHints *wmh; char **class; int n; @@ -772,9 +774,13 @@ client_prop(Client *c, Atom a) { XGetTransientForHint(display, c->w.w, &c->trans); break; case XA_WM_NORMAL_HINTS: + memset(&h, 0, sizeof h); + if(c->w.hints) + bcopy(c->w.hints, &h, sizeof h); sethints(&c->w); if(c->w.hints) c->fixedsize = eqpt(c->w.hints->min, c->w.hints->max); + if(memcmp(&h, c->w.hints, sizeof h)) if(c->sel && c->sel->view == screen->sel) view_focus(screen, screen->sel); break; @@ -966,7 +972,7 @@ client_setviews(Client *c, char **tags) { f = frame_create(c, view_create(*tags)); if(f->view == screen->sel || !c->sel) c->sel = f; - kludge = c; + kludge = c; /* FIXME */ view_attach(f->view, f); kludge = nil; f->cnext = *fp; diff --git a/cmd/wmii/column.c b/cmd/wmii/column.c @@ -147,6 +147,18 @@ column_scale(Area *a) { if(!a->frame) return; + /* Kludge. This should be idempotent, but the algorithm is + * flawed, so it's not. Well, with this, it is. + */ + if(eqrect(a->r, a->r_old)) { + for(f=a->frame; f; f=f->anext) + if(!eqrect(f->r, f->colr_old) + || f->anext != f->anext_old) + break; + if(f == nil) + return; + } + /* The minimum heights of collapsed and uncollpsed frames. */ minh = labelh(def.font); @@ -164,6 +176,15 @@ column_scale(Area *a) { nuncol++; } + if(nuncol == 0) { + nuncol++; + ncol--; + if(a->sel) + a->sel->collapsed = false; + else + a->frame->collapsed = false; + } + /* FIXME: Kludge. */ dy = Dy(a->view->r) - Dy(a->r); minh = colh * (ncol + nuncol - 1) + uncolh; @@ -251,12 +272,11 @@ column_scale(Area *a) { f->r.max.y += ((float)f->dy / dy) * osurplus; frame_resize(f, f->r); + f->r.max.y = Dy(f->crect) + colh + 1; - f->r.max.y = Dy(f->crect) + labelh(def.font) + 1; surplus -= Dy(f->r) - i; f->dy = Dy(f->r); - - if(Dy(f->r) == i) + if(f->dy == i) f->dy = 0; } } @@ -273,7 +293,7 @@ column_scale(Area *a) { frame_resize(f, f->r); f->r.max.y = Dy(f->crect) + labelh(def.font) + 1; surplus -= Dy(f->r) - dy; - } + } if(surplus < 0) { print("Badness: surplus = %d\n", surplus); @@ -294,9 +314,12 @@ column_scale(Area *a) { f->r.max.y += surplus / nuncol; if(!i) f->r.max.y += surplus % nuncol; + f->colr_old = f->r; /* Kludge. */ + f->anext_old = f->anext; } yoff = f->r.max.y; } + a->r_old = a->r; /* Kludge. */ } void @@ -316,8 +339,10 @@ column_arrange(Area *a, bool dirty) { f->r = Rect(0, 0, 100, 100); break; case Colstack: - for(f=a->frame; f; f=f->anext) + for(f=a->frame; f; f=f->anext) { f->collapsed = (f != a->sel); + f->r = Rect(0, 0, 1, 1); + } break; case Colmax: for(f=a->frame; f; f=f->anext) { diff --git a/cmd/wmii/dat.h b/cmd/wmii/dat.h @@ -121,6 +121,7 @@ struct Area { ushort id; int mode; Rectangle r; + Rectangle r_old; }; struct Bar { @@ -181,6 +182,7 @@ struct Frame { Frame* cnext; Frame* anext; Frame* aprev; + Frame* anext_old; Frame* snext; Frame* sprev; Client* client; @@ -193,6 +195,7 @@ struct Frame { int dy; Rectangle r; Rectangle colr; + Rectangle colr_old; Rectangle floatr; Rectangle crect; Rectangle grabbox; @@ -362,6 +365,6 @@ EXTERN Client* kludge; extern char* debugtab[]; -#define Debug(x) if((debugflag|debugfile)&(x) && setdebug(x)) +#define Debug(x) if(((debugflag|debugfile)&(x)) && setdebug(x)) #define Dprint(x, ...) BLOCK( if((debugflag|debugfile)&(x)) debug(x, __VA_ARGS__) ) diff --git a/cmd/wmii/fns.h b/cmd/wmii/fns.h @@ -192,6 +192,7 @@ void warning(const char*, ...); /* debug */ void debug(int, const char*, ...); void dprint(const char*, ...); +void dwrite(int, void*, int, bool); int getdebug(char*); bool setdebug(int); void vdebug(int, const char*, va_list); diff --git a/cmd/wmii/fs.c b/cmd/wmii/fs.c @@ -5,6 +5,7 @@ #include <ctype.h> #include <stdarg.h> #include <time.h> +#include <unistd.h> #include "fns.h" @@ -430,7 +431,6 @@ setdebug(int flag) { void vdebug(int flag, const char *fmt, va_list ap) { char *s; - int i, len; if(flag == 0) flag = dflags; @@ -439,15 +439,7 @@ vdebug(int flag, const char *fmt, va_list ap) { return; s = vsmprint(fmt, ap); - len = strlen(s); - - if(debugflag&flag) - print("%s", s); - - if(debugfile&flag) - for(i=0; i < nelem(pdebug); i++) - if(flag & (1<<i)) - pending_write(pdebug+i, s, len); + dwrite(flag, s, strlen(s), false); free(s); } @@ -469,6 +461,22 @@ dprint(const char *fmt, ...) { va_end(ap); } +void +dwrite(int flag, void *buf, int n, bool always) { + int i; + + if(flag == 0) + flag = dflags; + + if(always || debugflag&flag) + write(2, buf, n); + + if(debugfile&flag) + for(i=0; i < nelem(pdebug); i++) + if(flag & (1<<i)) + pending_write(pdebug+i, buf, n); +} + static void dostat(Stat *s, uint len, FileId *f) { s->type = 0; diff --git a/cmd/wmii/mouse.c b/cmd/wmii/mouse.c @@ -150,8 +150,11 @@ vplace(Framewin *fw, Point pt) { hr = Dy(r)/2; fw->xy = pt.y; + if(a->frame == nil) + goto done; + for(f = a->frame; f->anext; f = f->anext) - if(pt.y < f->r.max.y) + if(f->r.max.y > pt.y) break; if(!f->collapsed) { @@ -160,14 +163,18 @@ vplace(Framewin *fw, Point pt) { if(f == fw->f) { fw->fprev = f->aprev; - fw->fprev_r.max = f->r.max; - if(_vsnap(fw, f->r.min.y+hr)) - goto done; + fw->fprev_r.min.y = pt.y - hr; + //if(_vsnap(fw, f->r.min.y+hr)) + goto done; } if(_vsnap(fw, f->r.max.y - hr)) { - fw->fprev_r.min.y = f->r.max.y - labelh(def.font); - goto done; + if(f == fw->f->aprev) + fw->xy = pt.y; + else { + fw->fprev_r.min.y = f->r.max.y - labelh(def.font); + goto done; + } } if(_vsnap(fw, f->r.min.y+Dy(r)+hr)) { fw->fprev_r.min.y = f->r.min.y + labelh(def.font); @@ -177,6 +184,7 @@ vplace(Framewin *fw, Point pt) { _vsnap(fw, f->r.min.y); else if(_vsnap(fw, f->r.min.y-hr)) fw->fprev = f->aprev; + fw->fprev_r.min.y = pt.y - hr; if(fw->fprev && fw->fprev->anext == fw->f) fw->fprev_r.max = fw->f->r.max; @@ -780,6 +788,9 @@ thcol(Frame *f) { else r.max.y = f->area->r.max.y; + Dprint(DGeneric, "fw->fprev: %C fprev: %C f: %C f->r: %R fprev_r: %R\n", + (fw->fprev?fw->fprev->client:nil), (fprev?fprev->client:nil), + f->client, f->r, fw->fprev_r); frame_resize(f, fw->fprev_r); if(!a->frame && !a->floating) diff --git a/cmd/wmii/view.c b/cmd/wmii/view.c @@ -295,6 +295,8 @@ view_attach(View *v, Frame *f) { area_attach(a, f); + /* TODO: Decide whether to focus this frame */ + if(c->sel == nil) c->sel = f; } diff --git a/rc/rc.wmii.rc b/rc/rc.wmii.rc @@ -149,9 +149,10 @@ if not echo $wmiinormcol | wmiir create $noticebar # Key Bindings +_keys = `{wi_getfuns Key} fn key { key=() - for(k in Key-$*) if(! wi_fn-p $k) key = ($key $k) + for(k) if(! ~ $_keys $k) key = ($key Key-$k) ~ $#key 0} # This is... ugly.