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:
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.