[hackers] [wmii] Several changes:

From: Kris Maglione <jg_AT_suckless.org>
Date: Mon Jan 21 00:31:07 2008

changeset: 2234:22d23ba8e687
user: Kris Maglione <jg_AT_suckless.org>
date: Sat Jan 19 18:05:50 2008 -0500
summary: Several changes:

diff -r 17e5122b3d37 -r 22d23ba8e687 cmd/wihack.sh
--- a/cmd/wihack.sh Thu Jan 17 17:50:35 2008 -0500
+++ b/cmd/wihack.sh Sat Jan 19 18:05:50 2008 -0500
@@ -7,6 +7,7 @@ usage() {
 }
 
 checkarg='[ ${#@} -gt 0 ] || usage'
+export WMII_HACK_TIME=$(date +%s)
 
 while [ ${#@} -gt 0 ]
 do
diff -r 17e5122b3d37 -r 22d23ba8e687 cmd/wmii/Makefile
--- a/cmd/wmii/Makefile Thu Jan 17 17:50:35 2008 -0500
+++ b/cmd/wmii/Makefile Sat Jan 19 18:05:50 2008 -0500
@@ -15,8 +15,10 @@ OBJ = area \
         bar \
         client \
         column \
+ div \
         event \
         ewmh \
+ float \
         frame \
         fs \
         geom \
diff -r 17e5122b3d37 -r 22d23ba8e687 cmd/wmii/area.c
--- a/cmd/wmii/area.c Thu Jan 17 17:50:35 2008 -0500
+++ b/cmd/wmii/area.c Sat Jan 19 18:05:50 2008 -0500
@@ -1,13 +1,11 @@
-/* Copyright ©2004-2006 Anselm R. Garbe <garbeam at gmail dot com>
- * Copyright ©2006-2008 Kris Maglione <fbsdaemon_AT_gmail.com>
+/* Copyright ©2006-2008 Kris Maglione <fbsdaemon_AT_gmail.com>
  * See LICENSE file for license details.
  */
 #include "dat.h"
 #include <assert.h>
 #include <math.h>
+#include <sys/limits.h>
 #include "fns.h"
-
-static void place_frame(Frame *f);
 
 Client*
 area_selclient(Area *a) {
@@ -48,13 +46,13 @@ area_create(View *v, Area *pos, uint w)
         int colnum;
         Area *a;
 
- minwidth = Dx(screen->r)/NCOL;
+ minwidth = Dx(v->r)/NCOL;
 
         i = 0;
- for(a = v->area; a != pos; a = a->next)
- i++;
+ if(pos)
+ i = area_idx(pos);
         areanum = 0;
- for(a = v->area; a; a = a->next)
+ for(a=v->area; a; a=a->next)
                 areanum++;
 
         colnum = areanum - 1;
@@ -62,19 +60,19 @@ area_create(View *v, Area *pos, uint w)
                 if(colnum >= 0) {
                         w = view_newcolw(v, i);
                         if (w == 0)
- w = Dx(screen->r) / (colnum + 1);
+ w = Dx(v->r) / (colnum + 1);
                 }
                 else
- w = Dx(screen->r);
+ w = Dx(v->r);
         }
 
         if(w < minwidth)
                 w = minwidth;
- if(colnum && (colnum * minwidth + w) > Dx(screen->r))
+ if(colnum && (colnum * minwidth + w) > Dx(v->r))
                 return nil;
 
         if(pos)
- view_scale(v, Dx(screen->r) - w);
+ view_scale(v, Dx(v->r) - w);
 
         a = emallocz(sizeof *a);
         a->view = v;
@@ -83,10 +81,9 @@ area_create(View *v, Area *pos, uint w)
         a->frame = nil;
         a->sel = nil;
 
- a->r = screen->r;
+ a->r = v->r;
         a->r.min.x = 0;
         a->r.max.x = w;
- a->r.max.y = screen->brect.min.y;
 
         if(pos) {
                 a->next = pos->next;
@@ -113,7 +110,6 @@ area_create(View *v, Area *pos, uint w)
 
 void
 area_destroy(Area *a) {
- Client *c;
         Area *ta;
         View *v;
         int idx;
@@ -126,19 +122,12 @@ area_destroy(Area *a) {
         if(v->revert == a)
                 v->revert = nil;
 
- for(c=client; c; c=c->next)
- if(c->revert == a)
- c->revert = nil;
-
         idx = area_idx(a);
 
         if(a->prev && !a->prev->floating)
                 ta = a->prev;
         else
                 ta = a->next;
-
- if(a == v->colsel)
- v->colsel = ta;
 
         /* Can only destroy the floating area when destroying a
          * view---after destroying all columns.
@@ -149,9 +138,9 @@ area_destroy(Area *a) {
         if(a->next)
                 a->next->prev = a->prev;
 
- if(ta && v->sel == a) {
+ if(ta && v->sel == a)
                 area_focus(ta);
- }
+ view_arrange(v);
         event("DestroyArea %d\n", idx);
         /* Deprecated */
         event("DestroyColumn %d\n", idx);
@@ -161,6 +150,7 @@ area_destroy(Area *a) {
 
 void
 area_moveto(Area *to, Frame *f) {
+ Rectangle tr;
         Area *from;
 
         assert(to->view == f->view);
@@ -168,16 +158,18 @@ area_moveto(Area *to, Frame *f) {
         from = f->area;
 
         if(to->floating != from->floating) {
- Rectangle tr;
-
+ /* XXX: This must be changed. */
                 tr = f->revert;
                 f->revert = f->r;
                 f->r = tr;
         }
- f->client->revert = from;
 
         area_detach(f);
         area_attach(to, f);
+
+ /* Temporary kludge. */
+ if(!to->floating && to->floating != from->floating)
+ column_resizeframe(f, &tr);
 }
 
 void
@@ -193,38 +185,14 @@ area_setsel(Area *a, Frame *f) {
 
 void
 area_attach(Area *a, Frame *f) {
- uint nframe;
- Frame *ft;
- Client *c;
-
- c = f->client;
 
         f->area = a;
-
- nframe = 0;
- for(ft=a->frame; ft; ft=ft->anext)
- nframe++;
- nframe = max(nframe, 1);
-
- c->floating = a->floating;
- if(!a->floating) {
- f->r = a->r;
- f->r.max.y = Dy(a->r) / nframe;
- }
-
- frame_insert(a->sel, f);
-
- if(a->floating) {
- place_frame(f);
- client_resize(f->client, f->r);
- }
-
- if(!a->sel)
- area_setsel(a, f);
+ if(a->floating)
+ float_attach(a, f);
+ else
+ column_attach(a, f);
+
         view_restack(a->view);
-
- if(!a->floating)
- column_arrange(a, False);
 
         if(a->frame)
                 assert(a->sel);
@@ -233,180 +201,23 @@ void
 void
 area_detach(Frame *f) {
         Frame *pr;
- Client *c;
         Area *a;
- View *v;
 
         a = f->area;
- v = a->view;
- c = f->client;
-
         pr = f->aprev;
- frame_remove(f);
-
- if(!a->floating) {
- if(a->frame)
- column_arrange(a, False);
- else {
- if(v->area->next->next)
- area_destroy(a);
- else if((a->frame == nil) && (v->area->frame))
- area_focus(v->area);
- view_arrange(v);
- }
- }else if(v->oldsel)
- area_focus(v->oldsel);
- else if(!a->frame) {
- if(v->colsel->frame)
- area_focus(v->colsel);
- }else
- assert(a->sel);
-
+
+ if(a->floating)
+ float_detach(f);
+ else
+ column_detach(f);
+
+ f->area = nil;
         if(a->sel == f) {
                 if(!pr)
                         pr = a->frame;
+ a->sel = nil;
                 area_setsel(a, pr);
         }
-}
-
-static void
-bit_set(uint *field, uint width, uint x, uint y, int set) {
- enum { divisor = sizeof(uint) * 8 };
- uint bx, mask;
- div_t d;
-
- d = div(x, divisor);
- bx = d.quot;
- mask = 1 << d.rem;
- if(set)
- field[y*width + bx] |= mask;
- else
- field[y*width + bx] &= ~mask;
-}
-
-static bool
-bit_get(uint *field, uint width, uint x, uint y) {
- enum { divisor = sizeof(uint) * 8 };
- uint bx, mask;
- div_t d;
-
- d = div(x, divisor);
- bx = d.quot;
- mask = 1 << d.rem;
-
- return (field[y*width + bx] & mask) != 0;
-}
-
-/* TODO: Replace this. */
-static void
-place_frame(Frame *f) {
- enum { divisor = sizeof(uint) * 8 };
- enum { dx = 8, dy = 8 };
- static uint mwidth, mx, my;
- static uint *field = nil;
- Align align;
- Point p1 = ZP;
- Point p2 = ZP;
- Rectangle *rects;
- Frame *fr;
- Client *c;
- Area *a;
- bool fit;
- uint i, j, x, y, cx, cy, maxx, maxy, diff, num;
- int snap;
-
- snap = Dy(screen->r) / 66;
- num = 0;
- fit = False;
- align = CENTER;
-
- a = f->area;
- c = f->client;
-
- if(c->trans)
- return;
- if(c->fullscreen || c->w.hints->position || starting) {
- f->r = client_grav(c, c->r);
- return;
- }
- if(!field) {
- mx = Dx(screen->r) / dx;
- my = Dy(screen->r) / dy;
- mwidth = ceil((float)mx / divisor);
- field = emallocz(sizeof(uint) * mwidth * my);
- }
-
- SET(cx);
- SET(cy);
- memset(field, ~0, (sizeof(uint) * mwidth * my));
- for(fr=a->frame; fr; fr=fr->anext) {
- if(fr == f) {
- cx = Dx(f->r) / dx;
- cy = Dx(f->r) / dy;
- continue;
- }
-
- if(fr->r.min.x < 0)
- x = 0;
- else
- x = fr->r.min.x / dx;
-
- if(fr->r.min.y < 0)
- y = 0;
- else
- y = fr->r.min.y / dy;
-
- maxx = fr->r.max.x / dx;
- maxy = fr->r.max.y / dy;
- for(j = y; j < my && j < maxy; j++)
- for(i = x; i < mx && i < maxx; i++)
- bit_set(field, mwidth, i, j, False);
- }
-
- for(y = 0; y < my; y++)
- for(x = 0; x < mx; x++) {
- if(bit_get(field, mwidth, x, y)) {
- for(i = x; i < mx; i++)
- if(bit_get(field, mwidth, i, y) == 0)
- break;
- for(j = y; j < my; j++)
- if(bit_get(field, mwidth, x, j) == 0)
- break;
-
- if(((i - x) * (j - y) > (p2.x - p1.x) * (p2.y - p1.y))
- && (i - x > cx) && (j - y > cy))
- {
- fit = True;
- p1.x = x;
- p1.y = y;
- p2.x = i;
- p2.y = j;
- }
- }
- }
-
- if(fit) {
- p1.x *= dx;
- p1.y *= dy;
- }
-
- if(!fit || (p1.x + Dx(f->r) > a->r.max.x)) {
- diff = Dx(a->r) - Dx(f->r);
- p1.x = a->r.min.x + (random() % max(diff, 1));
- }
-
- if(!fit && (p1.y + Dy(f->r) > a->r.max.y)) {
- diff = Dy(a->r) - Dy(f->r);
- p1.y = a->r.min.y + (random() % max(diff, 1));
- }
-
- p1 = subpt(p1, f->r.min);
- f->r = rectaddpt(f->r, p1);
-
- rects = view_rects(a->view, &num, nil);
- snap_rect(rects, num, &f->r, &align, snap);
- if(rects)
- free(rects);
 }
 
 void
@@ -419,12 +230,12 @@ area_focus(Area *a) {
         f = a->sel;
         old_a = v->sel;
 
- if(view_fullscreen_p(v) && a != v->area)
+ if(view_fullscreen_p(v) && !a->floating)
                 return;
 
         v->sel = a;
         if(!a->floating)
- v->colsel = a;
+ v->selcol = area_idx(a);
 
         if((old_a) && (a->floating != old_a->floating))
                 v->revert = old_a;
diff -r 17e5122b3d37 -r 22d23ba8e687 cmd/wmii/client.c
--- a/cmd/wmii/client.c Thu Jan 17 17:50:35 2008 -0500
+++ b/cmd/wmii/client.c Sat Jan 19 18:05:50 2008 -0500
@@ -32,10 +32,14 @@ group_init(Client *c) {
         XWindow w;
         long n;
 
- n = getprop_long(&c->w, "WM_CLIENT_LEADER", "WINDOW", 0L, &ret, 1L);
- if(n == 0)
- return;
- w = *ret;
+ w = c->w.hints->group;
+ if(w == 0) {
+ /* Not quite ICCCM compliant, but it seems to work. */
+ n = getprop_long(&c->w, "WM_CLIENT_LEADER", "WINDOW", 0L, &ret, 1L);
+ if(n == 0)
+ return;
+ w = *ret;
+ }
 
         for(g=group; g; g=g->next)
                 if(g->leader == w)
@@ -160,6 +164,10 @@ client_manage(Client *c) {
         Frame *f;
         char *tags;
 
+ if(Dx(c->r) == Dx(screen->r))
+ if(Dy(c->r) == Dy(screen->r))
+ fullscreen(c, true);
+
         tags = getprop_string(&c->w, "_WMII_TAGS");
 
         trans = win2client(c->trans);
@@ -167,15 +175,15 @@ client_manage(Client *c) {
                 trans = group_leader(c->group);
 
         if(tags)
- utflcpy(c->tags, tags, sizeof(c->tags));
+ utflcpy(c->tags, tags, sizeof c->tags);
         else if(trans)
- utflcpy(c->tags, trans->tags, sizeof(c->tags));
+ utflcpy(c->tags, trans->tags, sizeof c->tags);
         free(tags);
 
- if(c->tags[0])
- apply_tags(c, c->tags);
- else
+ /* Maybe not the best idea... */
+ if(!trans || !c->tags[0])
                 apply_rules(c);
+ apply_tags(c, c->tags);
 
         if(!starting)
                 view_update_all();
@@ -210,7 +218,7 @@ client_destroy(Client *c) {
 client_destroy(Client *c) {
         int (*handler)(Display*, XErrorEvent*);
         Rectangle r;
- char *dummy;
+ char *none;
         Client **tc;
         bool hide;
 
@@ -233,9 +241,8 @@ client_destroy(Client *c) {
         /* In case the client is already unmapped */
         handler = XSetErrorHandler(ignoreerrors);
 
- dummy = nil;
- client_setviews(c, &dummy);
- client_unmap(c, IconicState);
+ none = nil;
+ client_setviews(c, &none);
         sethandler(&c->w, nil);
 
         if(hide)
@@ -330,6 +337,24 @@ client_grav(Client *c, Rectangle rd) {
         }
 }
 
+bool
+client_floats_p(Client *c) {
+ return c->trans
+ || c->floating
+ || c->fixedsize
+ || c->titleless
+ || c->borderless
+ || c->fullscreen
+ || (c->w.ewmh.type & (TypeDialog|TypeSplash|TypeDock));
+}
+
+Frame*
+client_groupframe(Client *c, View *v) {
+ if(c->group && c->group->client)
+ return client_viewframe(c->group->client, v);
+ return nil;
+}
+
 Rectangle
 frame_hints(Frame *f, Rectangle r, Align sticky) {
         Rectangle or;
@@ -403,8 +428,10 @@ focus(Client *c, bool user) {
         f = c->sel;
         if(!f)
                 return;
+ /*
         if(!user && c->noinput)
                 return;
+ */
 
         v = f->view;
         if(v != screen->sel)
@@ -505,24 +532,10 @@ client_configure(Client *c) {
         sendevent(&c->w, false, StructureNotifyMask, (XEvent*)&e);
 }
 
-static void
-client_sendmessage(Client *c, char *name, char *value) {
- XClientMessageEvent e;
-
- e.type = ClientMessage;
- e.window = c->w.w;
- e.message_type = xatom(name);
- e.format = 32;
- e.data.l[0] = xatom(value);
- e.data.l[1] = xtime;
- sendevent(&c->w, false, NoEventMask, (XEvent*)&e);
- sync();
-}
-
 void
 client_kill(Client *c, bool nice) {
         if(nice && (c->proto & ProtoDelete)) {
- client_sendmessage(c, "WM_PROTOCOLS", "WM_DELETE_WINDOW");
+ sendmessage(&c->w, "WM_PROTOCOLS", "WM_DELETE_WINDOW", 0, 0, 0);
                 ewmh_pingclient(c);
         }
         else
@@ -532,6 +545,7 @@ void
 void
 fullscreen(Client *c, int fullscreen) {
         Frame *f;
+ bool wassel;
         
         if(fullscreen == Toggle)
                 fullscreen = c->fullscreen ^ On;
@@ -542,37 +556,42 @@ fullscreen(Client *c, int fullscreen) {
         c->fullscreen = fullscreen;
         ewmh_updatestate(c);
 
- if((f = c->sel)) {
- if(fullscreen) {
- if(f->area->floating)
- f->revert = f->r;
- else {
- f->r = f->revert;
- area_moveto(f->view->area, f);
+ if(!fullscreen)
+ for(f=c->frame; f; f=f->cnext) {
+ if(f->oldarea == 0)
+ frame_resize(f, f->oldr); /* XXX: oldr Replace with floatr */
+ else if(f->oldarea > 0) {
+ wassel = (f == f->area->sel);
+ area_moveto(view_findarea(f->view, f->oldarea, true), f);
+ f->revert = f->oldr; /* XXX: oldr */
+ if(wassel)
+ frame_focus(f);
                         }
- focus(c, true);
- }else
- frame_resize(f, f->revert);
- if(f->view == screen->sel)
- view_focus(screen, f->view);
- }
-}
-
-void
-client_seturgent(Client *c, int urgent, bool write) {
+ }
+ else {
+ for(f=c->frame; f; f=f->cnext)
+ f->oldarea = -1;
+ if((f = c->sel))
+ if(f->view == screen->sel)
+ view_focus(screen, f->view);
+ }
+}
+
+void
+client_seturgent(Client *c, bool urgent, int from) {
         XWMHints *wmh;
- char *cwrite, *cnot;
+ char *cfrom, *cnot;
         Frame *f, *ff;
         Area *a;
 
         if(urgent == Toggle)
                 urgent = c->urgent ^ On;
 
- cwrite = (write ? "Manager" : "Client");
+ cfrom = (from == UrgManager ? "Manager" : "Client");
         cnot = (urgent ? "" : "Not");
 
         if(urgent != c->urgent) {
- event("%sUrgent %C %s\n", cnot, c, cwrite);
+ event("%sUrgent %C %s\n", cnot, c, cfrom);
                 c->urgent = urgent;
                 ewmh_updatestate(c);
                 if(c->sel) {
@@ -585,12 +604,12 @@ client_seturgent(Client *c, int urgent,
                                                 for(ff=a->frame; ff; ff=ff->anext)
                                                         if(ff->client->urgent) break;
                                 if(urgent || ff == nil)
- event("%sUrgentTag %s %s\n", cnot, cwrite, f->view->name);
+ event("%sUrgentTag %s %s\n", cnot, cfrom, f->view->name);
                         }
                 }
         }
 
- if(write) {
+ if(from == UrgManager) {
                 wmh = XGetWMHints(display, c->w.w);
                 if(wmh == nil)
                         wmh = emallocz(sizeof *wmh);
@@ -679,16 +698,16 @@ client_prop(Client *c, Atom a) {
         char **class;
         int n;
 
- if(a == xatom("WM_PROTOCOLS")) {
+ if(a == xatom("WM_PROTOCOLS"))
                 c->proto = winprotocols(&c->w);
- }
- else if(a == xatom("_NET_WM_NAME")) {
+ else
+ if(a == xatom("_NET_WM_NAME"))
                 goto wmname;
- }
- else if(a == xatom("_MOTIF_WM_HINTS")) {
+ else
+ if(a == xatom("_MOTIF_WM_HINTS"))
                 updatemwm(c);
- }
- else switch (a) {
+ else
+ switch (a) {
         default:
                 ewmh_prop(c, a);
                 break;
@@ -704,7 +723,7 @@ client_prop(Client *c, Atom a) {
                 wmh = XGetWMHints(display, c->w.w);
                 if(wmh) {
                         c->noinput = !((wmh->flags&InputFocus) && wmh->input);
- client_seturgent(c, (wmh->flags & XUrgencyHint) != 0, False);
+ client_seturgent(c, (wmh->flags & XUrgencyHint) != 0, UrgClient);
                         XFree(wmh);
                 }
                 break;
@@ -749,9 +768,6 @@ configreq_event(Window *w, XConfigureReq
         r.max = addpt(r.min, r.max);
         cr = r;
         r = client_grav(c, r);
-
- if((Dx(cr) == Dx(screen->r)) && (Dy(cr) == Dy(screen->r)))
- fullscreen(c, True);
 
         if(c->sel->area->floating) {
                 client_resize(c, r);
@@ -954,7 +970,9 @@ apply_tags(Client *c, const char *tags)
         j = 0;
         while(buf[n] && n < sizeof(buf) && j < 32) {
                 for(i = n; i < sizeof(buf) - 1; i++)
- if(buf[i] == '+' || buf[i] == '-' || buf[i] == '\0')
+ if(buf[i] == '+'
+ || buf[i] == '-'
+ || buf[i] == '\0')
                                 break;
                 last = buf[i];
                 buf[i] = '\0';
@@ -962,9 +980,11 @@ apply_tags(Client *c, const char *tags)
                 cur = nil;
                 if(!strcmp(buf+n, "~"))
                         c->floating = add;
- else if(!strcmp(buf+n, "!") || !strcmp(buf+n, "sel"))
+ else
+ if(!strcmp(buf+n, "!") || !strcmp(buf+n, "sel"))
                         cur = screen->sel->name;
- else if(!Mbsearch(buf+n, badtags, bsstrcmp))
+ else
+ if(!Mbsearch(buf+n, badtags, bsstrcmp))
                         cur = buf+n;
 
                 n = i + 1;
@@ -979,30 +999,25 @@ apply_tags(Client *c, const char *tags)
                         }
                 }
 
- switch(last) {
- case '+':
+ if(last == '+')
                         add = True;
- break;
- case '-':
+ if(last == '-')
                         add = False;
- break;
- case '\0':
+ if(last == '\0')
                         buf[n] = '\0';
- break;
- }
         }
 
         if(!j)
                 return;
 
- qsort(toks, j, sizeof(char *), strpcmp);
+ qsort(toks, j, sizeof *toks, strpcmp);
 
         c->tags[0] = '\0';
         for(i=0, n=0; i < j; i++)
                 if(n == 0 || strcmp(toks[i], toks[n-1])) {
                         if(i > 0)
- strlcat(c->tags, "+", sizeof(c->tags));
- strlcat(c->tags, toks[i], sizeof(c->tags));
+ strlcat(c->tags, "+", sizeof c->tags);
+ strlcat(c->tags, toks[i], sizeof c->tags);
                         toks[n++] = toks[i];
                 }
         toks[n] = nil;
@@ -1015,18 +1030,14 @@ void
 void
 apply_rules(Client *c) {
         Rule *r;
-
- if(strlen(c->tags))
- return;
 
         if(def.tagrules.string)
                 for(r=def.tagrules.rule; r; r=r->next)
                         if(regexec(r->regex, c->props, nil, 0)) {
                                 apply_tags(c, r->value);
- if(c->tags[0] && strcmp(c->tags, "nil"))
- break;
+ break;
                         }
         if(c->tags[0] == '\0')
- apply_tags(c, "nil");
-}
-
+ apply_tags(c, "sel");
+}
+
diff -r 17e5122b3d37 -r 22d23ba8e687 cmd/wmii/column.c
--- a/cmd/wmii/column.c Thu Jan 17 17:50:35 2008 -0500
+++ b/cmd/wmii/column.c Sat Jan 19 18:05:50 2008 -0500
@@ -8,10 +8,6 @@
 #include <strings.h>
 #include "fns.h"
 
-static Image *divimg, *divmask;
-static CTuple divc;
-static Handlers divhandler;
-
 char *modes[] = {
         [Coldefault] = "default",
         [Colstack] = "stack",
@@ -29,164 +25,11 @@ str2colmode(const char *str) {
 }
 
 char*
-colmode2str(int i) {
+colmode2str(uint i) {
         if(i < nelem(modes))
                 return modes[i];
         return nil;
 }
-
-static Divide*
-getdiv(Divide **dp) {
- WinAttr wa;
- Divide *d;
-
- if(*dp)
- return *dp;
-
- d = emallocz(sizeof *d);
-
- wa.override_redirect = True;
- wa.cursor = cursor[CurDHArrow];
- wa.event_mask =
- ExposureMask
- | EnterWindowMask
- | ButtonPressMask
- | ButtonReleaseMask;
- d->w = createwindow(&scr.root, Rect(0, 0, 1, 1), scr.depth, InputOutput, &wa,
- CWOverrideRedirect
- | CWEventMask
- | CWCursor);
- d->w->aux = d;
- sethandler(d->w, &divhandler);
-
- *dp = d;
- return d;
-}
-
-static void
-mapdiv(Divide *d) {
- mapwin(d->w);
-}
-
-static void
-unmapdiv(Divide *d) {
- unmapwin(d->w);
-}
-
-void
-div_set(Divide *d, int x) {
- Rectangle r;
-
- d->x = x;
- r = rectaddpt(divimg->r, Pt(x - Dx(divimg->r)/2, 0));
- r.max.y = screen->brect.min.y;
-
- reshapewin(d->w, r);
- mapdiv(d);
-}
-
-static void
-drawimg(Image *img, ulong cbg, ulong cborder) {
- Point pt[6];
-
- pt[0] = Pt(0, 0);
- pt[1] = Pt(Dx(img->r)/2 - 1, Dx(img->r)/2 - 1);
-
- pt[2] = Pt(pt[1].x, Dy(img->r));
- pt[3] = Pt(Dx(img->r)/2, pt[2].y);
-
- pt[4] = Pt(pt[3].x, Dx(img->r)/2 - 1);
- pt[5] = Pt(Dx(img->r) - 1, 0);
-
- fillpoly(img, pt, nelem(pt), cbg);
- drawpoly(img, pt, nelem(pt), CapNotLast, 1, cborder);
-}
-
-static void
-drawdiv(Divide *d) {
- copyimage(d->w, divimg->r, divimg, ZP);
- setshapemask(d->w, divmask, ZP);
-}
-
-static void
-update_imgs(void) {
- Divide *d;
- int w, h;
-
- w = 2 * (labelh(def.font) / 3);
- w = max(w, 10);
- h = Dy(screen->r);
-
- if(divimg) {
- if(w == Dx(divimg->r) && h == Dy(divimg->r)
- && !memcmp(&divc, &def.normcolor, sizeof(divc)))
- return;
- freeimage(divimg);
- freeimage(divmask);
- }
-
- divimg = allocimage(w, h, scr.depth);
- divmask = allocimage(w, h, 1);
- divc = def.normcolor;
-
- fill(divmask, divmask->r, 0);
- drawimg(divmask, 1, 1);
- drawimg(divimg, divc.bg, divc.border);
-
- for(d = divs; d && d->w->mapped; d = d->next)
- drawdiv(d);
-}
-
-void
-div_update_all(void) {
- Divide **dp, *d;
- Area *a;
- View *v;
-
- update_imgs();
-
- v = screen->sel;
- dp = &divs;
- for(a = v->area->next; a; a = a->next) {
- d = getdiv(dp);
- dp = &d->next;
- div_set(d, a->r.min.x);
-
- if(!a->next) {
- d = getdiv(dp);
- dp = &d->next;
- div_set(d, a->r.max.x);
- }
- }
- for(d = *dp; d; d = d->next)
- unmapdiv(d);
-}
-
-/* Div Handlers */
-static void
-bdown_event(Window *w, XButtonEvent *e) {
- Divide *d;
-
- USED(e);
-
- d = w->aux;
- mouse_resizecol(d);
-}
-
-static void
-expose_event(Window *w, XExposeEvent *e) {
- Divide *d;
-
- USED(e);
-
- d = w->aux;
- drawdiv(d);
-}
-
-static Handlers divhandler = {
- .bdown = bdown_event,
- .expose = expose_event,
-};
 
 Area*
 column_new(View *v, Area *pos, uint w) {
@@ -202,8 +45,51 @@ column_new(View *v, Area *pos, uint w) {
         return a;
 }
 
+void
+column_attach(Area *a, Frame *f) {
+ uint nframe;
+ Frame *ft;
+
+ nframe = 0;
+ for(ft=a->frame; ft; ft=ft->anext)
+ nframe++;
+ nframe = max(nframe, 1);
+
+ f->column = area_idx(a);
+ f->r = a->r;
+ f->r.max.y = Dy(a->r) / nframe;
+
+ frame_insert(f, a->sel);
+ if(a->sel == nil)
+ area_setsel(a, f);
+
+ column_arrange(a, false);
+}
+
+void
+column_detach(Frame *f) {
+ Client *c;
+ Area *a;
+ View *v;
+
+ a = f->area;
+ v = a->view;
+ c = f->client;
+
+ frame_remove(f);
+
+ if(a->frame)
+ column_arrange(a, False);
+ else {
+ if(v->area->next->next)
+ area_destroy(a);
+ else if(v->area->frame)
+ area_focus(v->area);
+ }
+}
+
 static void
-scale_column(Area *a) {
+column_scale(Area *a) {
         Frame *f, **fp;
         uint minh, yoff, dy;
         uint ncol, nuncol;
@@ -353,7 +239,7 @@ column_arrange(Area *a, bool dirty) {
                 die("can't get here");
                 break;
         }
- scale_column(a);
+ column_scale(a);
 resize:
         if(a->view == screen->sel) {
                 view_restack(a->view);
@@ -385,7 +271,7 @@ column_resize(Area *a, int w) {
 }
 
 static void
-resize_colframeh(Frame *f, Rectangle *r) {
+column_resizeframe_h(Frame *f, Rectangle *r) {
         Area *a;
         Frame *fn, *fp;
         uint minh;
@@ -429,7 +315,7 @@ column_resizeframe(Frame *f, Rectangle *
         v = a->view;
         maxx = r->max.x;
 
- minw = Dx(screen->r) / NCOL;
+ minw = Dx(v->r) / NCOL;
 
         al = a->prev;
         ar = a->next;
@@ -442,7 +328,7 @@ column_resizeframe(Frame *f, Rectangle *
         if(ar)
                 maxx = min(maxx, a->r.max.x - minw);
         else
- maxx = min(maxx, screen->r.max.x);
+ maxx = min(maxx, v->r.max.x);
 
         dx = a->r.min.x - r->min.x;
         dw = maxx - a->r.max.x;
@@ -455,7 +341,7 @@ column_resizeframe(Frame *f, Rectangle *
                 column_arrange(ar, False);
         }
 
- resize_colframeh(f, r);
+ column_resizeframe_h(f, r);
 
         a->r.max.x = maxx;
         view_arrange(a->view);
diff -r 17e5122b3d37 -r 22d23ba8e687 cmd/wmii/dat.h
--- a/cmd/wmii/dat.h Thu Jan 17 17:50:35 2008 -0500
+++ b/cmd/wmii/dat.h Sat Jan 19 18:05:50 2008 -0500
@@ -22,6 +22,11 @@
 
 enum {
         PingTime = 10000,
+};
+
+enum {
+ UrgManager,
+ UrgClient,
 };
 
 enum EWMHType {
@@ -117,7 +122,6 @@ struct Bar {
 
 struct Client {
         Client* next;
- Area* revert;
         Frame* frame;
         Frame* sel;
         Window w;
@@ -155,13 +159,16 @@ struct Frame {
         Frame* aprev;
         Frame* snext;
         Frame* sprev;
+ Client* client;
         View* view;
         Area* area;
- Client* client;
+ int oldarea;
+ int column;
         ushort id;
         bool collapsed;
         float ratio;
         Rectangle r;
+ Rectangle oldr;
         Rectangle crect;
         Rectangle revert;
         Rectangle grabbox;
@@ -222,10 +229,27 @@ struct View {
         ushort id;
         Area* area;
         Area* sel;
- Area* colsel;
         Area* oldsel;
         Area* revert;
-};
+ int selcol;
+ Rectangle r;
+};
+
+/* Yuck. */
+#define VECTOR(type, nam, c) \
+typedef struct Vector_##nam Vector_##nam; \
+struct Vector_##nam { \
+ type* ary; \
+ long n; \
+ long size; \
+}; \
+void vector_##c##free(Vector_##nam*); \
+void vector_##c##init(Vector_##nam*); \
+void vector_##c##push(Vector_##nam*, type); \
+
+VECTOR(long, long, l)
+VECTOR(Rectangle, rect, r)
+#undef VECTOR
 
 #ifndef EXTERN
 # define EXTERN extern
diff -r 17e5122b3d37 -r 22d23ba8e687 cmd/wmii/event.c
--- a/cmd/wmii/event.c Thu Jan 17 17:50:35 2008 -0500
+++ b/cmd/wmii/event.c Sat Jan 19 18:05:50 2008 -0500
@@ -10,7 +10,7 @@ dispatch_event(XEvent *e) {
 dispatch_event(XEvent *e) {
         Debug(DEvent)
                 printevent(e);
- if(handler[e->type])
+ if(e->type < nelem(handler) && handler[e->type])
                 handler[e->type](e);
 }
 
@@ -356,7 +356,5 @@ check_x_event(IxpConn *c) {
         while(XPending(display)) {
                 XNextEvent(display, &ev);
                 dispatch_event(&ev);
- /* Hack to alleviate an apparant Xlib bug */
- XPending(display);
- }
-}
+ }
+}
diff -r 17e5122b3d37 -r 22d23ba8e687 cmd/wmii/ewmh.c
--- a/cmd/wmii/ewmh.c Thu Jan 17 17:50:35 2008 -0500
+++ b/cmd/wmii/ewmh.c Sat Jan 19 18:05:50 2008 -0500
@@ -16,22 +16,6 @@ Window *ewmhwin;
 #define ACTION(x) xatom(Action(x))
 #define STATE(x) xatom(State(x))
 #define TYPE(x) xatom(Type(x))
-
-static void
-senemessage(Window *w, char *name, char *value, long l2, long l3, long l4) {
- XClientMessageEvent e;
-
- e.type = ClientMessage;
- e.window = w->w;
- e.message_type = xatom(name);
- e.format = 32;
- e.data.l[0] = xatom(value);
- e.data.l[1] = xtime;
- e.data.l[2] = l2;
- e.data.l[3] = l3;
- e.data.l[4] = l4;
- sendevent(w, false, NoEventMask, (XEvent*)&e);
-}
 
 void
 ewmh_init(void) {
@@ -143,7 +127,8 @@ ewmh_destroyclient(Client *c) {
 
         e = &c->w.ewmh;
         if(e->timer)
- ixp_unsettimer(&srv, e->timer);
+ if(!ixp_unsettimer(&srv, e->timer))
+ fprint(2, "Badness: %C: Can't unset timer\n", c);
 }
 
 static void
@@ -167,18 +152,21 @@ ewmh_pingclient(Client *c) {
         if(e->ping)
                 return;
 
- senemessage(&c->w, "WM_PROTOCOLS", Net("WM_PING"), c->w.w, 0, 0);
+ sendmessage(&c->w, "WM_PROTOCOLS", Net("WM_PING"), c->w.w, 0, 0);
         e->ping = xtime++;
         e->timer = ixp_settimer(&srv, PingTime, pingtimeout, c);
 }
 
-void
+int
 ewmh_prop(Client *c, Atom a) {
         if(a == NET("WM_WINDOW_TYPE"))
                 ewmh_getwintype(c);
         else
         if(a == NET("WM_STRUT_PARTIAL"))
                 ewmh_getstrut(c);
+ else
+ return 0;
+ return 1;
 }
 
 typedef struct Prop Prop;
@@ -336,7 +324,7 @@ ewmh_clientmessage(XClientMessageEvent *
                                 fullscreen(c, action);
                         else
                         if(l[i] == STATE("DEMANDS_ATTENTION"))
- client_seturgent(c, action, false);
+ client_seturgent(c, action, UrgClient);
                 }
                 return 1;
         }else
@@ -415,7 +403,7 @@ ewmh_updatestate(Client *c) {
         int i;
 
         f = c->sel;
- if(f->view != screen->sel)
+ if(f == nil || f->view != screen->sel)
                 return;
 
         i = 0;
diff -r 17e5122b3d37 -r 22d23ba8e687 cmd/wmii/fns.h
--- a/cmd/wmii/fns.h Thu Jan 17 17:50:35 2008 -0500
+++ b/cmd/wmii/fns.h Sat Jan 19 18:05:50 2008 -0500
@@ -8,44 +8,6 @@
 # pragma varargck type "C" Client*
 # pragma varargck type "r" void
 #endif
-
-/* XXX: These don't belong here. */
-
-typedef struct Vector_long Vector_long;
-struct Vector_long {
- long* ary;
- long n;
- long size;
-};
-
-static void
-vector_linit(Vector_long *v) {
- memset(v, 0, sizeof *v);
-}
-
-static void
-vector_lfree(Vector_long *v) {
- free(v->ary);
- memset(v, 0, sizeof *v);
-}
-
-static void
-vector_lpush(Vector_long *v, long val) {
- if(v->n == v->size) {
- if(v->size == 0)
- v->size = 2;
- v->size <<= 2;
- v->ary = erealloc(v->ary, v->size * sizeof *v->ary);
- }
- v->ary[v->n++] = val;
-}
-
-static inline void
-__grr__(void) {
- vector_linit(nil);
- vector_lfree(nil);
- vector_lpush(nil, 0);
-}
 
 /* area.c */
 void area_attach(Area*, Frame*);
@@ -74,7 +36,9 @@ void client_configure(Client*);
 void client_configure(Client*);
 Client* client_create(XWindow, XWindowAttributes*);
 void client_destroy(Client*);
+bool client_floats_p(Client*);
 void client_focus(Client*);
+Frame* client_groupframe(Client*, View*);
 void client_kill(Client*, bool);
 void client_manage(Client*);
 void client_map(Client*);
@@ -82,7 +46,7 @@ void client_reparent(Client*, Window*, P
 void client_reparent(Client*, Window*, Point);
 void client_resize(Client*, Rectangle);
 void client_setcursor(Client*, Cursor);
-void client_seturgent(Client*, int urgent, bool write);
+void client_seturgent(Client*, bool, int);
 void client_unmap(Client*, int state);
 Frame* client_viewframe(Client *c, View *v);
 char* clientname(Client*);
@@ -96,15 +60,17 @@ Rectangle client_grav(Client*, Rectangle
 Rectangle client_grav(Client*, Rectangle);
 
 /* column.c */
-char* colmode2str(int);
-int str2colmode(const char*);
+char* colmode2str(uint);
 void column_arrange(Area*, bool dirty);
+void column_attach(Area*, Frame*);
+void column_detach(Frame*);
 Area* column_new(View*, Area *, uint);
 void column_resize(Area*, int);
 void column_resizeframe(Frame*, Rectangle*);
 void div_draw(Divide*);
 void div_set(Divide*, int x);
 void div_update_all(void);
+int str2colmode(const char*);
 
 /* event.c */
 void check_x_event(IxpConn*);
@@ -122,7 +88,7 @@ void ewmh_init(void);
 void ewmh_init(void);
 void ewmh_initclient(Client*);
 void ewmh_pingclient(Client*);
-void ewmh_prop(Client*, Atom);
+int ewmh_prop(Client*, Atom);
 long ewmh_protocols(Window*);
 void ewmh_updateclient(Client*);
 void ewmh_updateclientlist(void);
@@ -132,6 +98,10 @@ void ewmh_updateview(void);
 void ewmh_updateview(void);
 void ewmh_updateviews(void);
 
+/* float.c */
+void float_attach(Area*, Frame*);
+void float_detach(Frame*);
+
 /* frame.c */
 Frame* frame_create(Client*, View*);
 int frame_delta_h(void);
@@ -139,7 +109,7 @@ void frame_draw_all(void);
 void frame_draw_all(void);
 void frame_focus(Frame*);
 uint frame_idx(Frame*);
-void frame_insert(Frame *pos, Frame*);
+void frame_insert(Frame*, Frame *pos);
 void frame_remove(Frame*);
 void frame_resize(Frame*, Rectangle);
 bool frame_restack(Frame*, Frame*);
@@ -167,10 +137,13 @@ void event(const char*, ...);
 void event(const char*, ...);
 
 /* geom.c */
+Align get_sticky(Rectangle src, Rectangle dst);
 Cursor quad_cursor(Align);
-Align get_sticky(Rectangle src, Rectangle dst);
+Align quadrant(Rectangle, Point);
+bool rect_contains_p(Rectangle, Rectangle);
 bool rect_haspoint_p(Point, Rectangle);
-Align quadrant(Rectangle, Point);
+bool rect_intersect_p(Rectangle, Rectangle);
+Rectangle rect_intersection(Rectangle, Rectangle);
 
 /* key.c */
 void init_lock_keys(void);
@@ -194,7 +167,8 @@ char* msg_parsecolors(IxpMsg*, CTuple*);
 char* msg_parsecolors(IxpMsg*, CTuple*);
 char* msg_selectarea(Area*, IxpMsg*);
 char* msg_sendclient(View*, IxpMsg*, bool swap);
-char* root_readctl(void);
+char* readctl_root(void);
+char* readctl_view(View*);
 Area* strarea(View*, const char*);
 
 /* mouse.c */
@@ -211,8 +185,8 @@ void view_arrange(View*);
 void view_arrange(View*);
 void view_attach(View*, Frame*);
 View* view_create(const char*);
-char* view_ctl(View *v);
 void view_destroy(View*);
+Area* view_findarea(View*, int, bool);
 void view_focus(WMScreen*, View*);
 bool view_fullscreen_p(View*);
 char* view_index(View*);
diff -r 17e5122b3d37 -r 22d23ba8e687 cmd/wmii/frame.c
--- a/cmd/wmii/frame.c Thu Jan 17 17:50:35 2008 -0500
+++ b/cmd/wmii/frame.c Sat Jan 19 18:05:50 2008 -0500
@@ -35,7 +35,8 @@ frame_create(Client *c, View *v) {
                 f->revert = f->r;
                 c->sel = f;
         }
- f->collapsed = False;
+ f->collapsed = false;
+ f->oldarea = -1;
 
         return f;
 }
@@ -64,7 +65,7 @@ frame_remove(Frame *f) {
 }
 
 void
-frame_insert(Frame *pos, Frame *f) {
+frame_insert(Frame *f, Frame *pos) {
         Area *a;
 
         a = f->area;
@@ -433,6 +434,8 @@ frame_draw(Frame *f) {
 
         if(f->view != screen->sel)
                 return;
+ if(f->area == nil) /* Blech. */
+ return;
 
         if(f->client == screen->focus
         || f->client == selclient())
diff -r 17e5122b3d37 -r 22d23ba8e687 cmd/wmii/fs.c
--- a/cmd/wmii/fs.c Thu Jan 17 17:50:35 2008 -0500
+++ b/cmd/wmii/fs.c Sat Jan 19 18:05:50 2008 -0500
@@ -659,7 +659,7 @@ fs_read(Ixp9Req *r) {
                         respond(r, nil);
                         return;
                 case FsFRctl:
- buf = root_readctl();
+ buf = readctl_root();
                         write_buf(r, buf, strlen(buf));
                         respond(r, nil);
                         return;
@@ -679,7 +679,7 @@ fs_read(Ixp9Req *r) {
                         respond(r, nil);
                         return;
                 case FsFTctl:
- buf = view_ctl(f->p.view);
+ buf = readctl_view(f->p.view);
                         n = strlen(buf);
                         write_buf(r, buf, n);
                         respond(r, nil);
diff -r 17e5122b3d37 -r 22d23ba8e687 cmd/wmii/geom.c
--- a/cmd/wmii/geom.c Thu Jan 17 17:50:35 2008 -0500
+++ b/cmd/wmii/geom.c Sat Jan 19 18:05:50 2008 -0500
@@ -8,6 +8,34 @@ rect_haspoint_p(Point pt, Rectangle r) {
 rect_haspoint_p(Point pt, Rectangle r) {
         return (pt.x >= r.min.x) && (pt.x < r.max.x)
                 && (pt.y >= r.min.y) && (pt.y < r.max.y);
+}
+
+bool
+rect_intersect_p(Rectangle r, Rectangle r2) {
+ return r.min.x <= r2.max.x
+ && r.max.x >= r2.min.x
+ && r.min.y <= r2.max.y
+ && r.max.y >= r2.min.y;
+}
+
+Rectangle
+rect_intersection(Rectangle r, Rectangle r2) {
+ Rectangle ret;
+
+ /* canonrect(ret) != ret if not intersection */
+ ret.min.x = max(r.min.x, r2.min.x);
+ ret.max.x = min(r.max.x, r2.max.x);
+ ret.min.y = max(r.min.y, r2.min.y);
+ ret.max.y = min(r.max.y, r2.max.y);
+ return ret;
+}
+
+bool
+rect_contains_p(Rectangle r, Rectangle r2) {
+ return r2.min.x >= r.min.x
+ && r2.max.x <= r.max.x
+ && r2.min.y >= r.min.y
+ && r2.max.y <= r.max.y;
 }
 
 Align
@@ -60,3 +88,32 @@ get_sticky(Rectangle src, Rectangle dst)
 
         return stickycorner;
 }
+
+/* XXX: These don't belong here. */
+/* Blech. */
+#define VECTOR(type, nam, c) \
+void \
+vector_##c##init(Vector_##nam *v) { \
+ memset(v, 0, sizeof *v); \
+} \
+ \
+void \
+vector_##c##free(Vector_##nam *v) { \
+ free(v->ary); \
+ memset(v, 0, sizeof *v); \
+} \
+ \
+void \
+vector_##c##push(Vector_##nam *v, type val) { \
+ if(v->n == v->size) { \
+ if(v->size == 0) \
+ v->size = 2; \
+ v->size <<= 2; \
+ v->ary = erealloc(v->ary, v->size * sizeof *v->ary); \
+ } \
+ v->ary[v->n++] = val; \
+} \
+
+VECTOR(long, long, l)
+VECTOR(Rectangle, rect, r)
+
diff -r 17e5122b3d37 -r 22d23ba8e687 cmd/wmii/message.c
--- a/cmd/wmii/message.c Thu Jan 17 17:50:35 2008 -0500
+++ b/cmd/wmii/message.c Sat Jan 19 18:05:50 2008 -0500
@@ -156,13 +156,13 @@ msg_getword(IxpMsg *m) {
         Rune r;
         int n;
 
- eatrunes(m, isspacerune, 1);
+ eatrunes(m, isspacerune, true);
         ret = m->pos;
- eatrunes(m, isspacerune, 0);
+ eatrunes(m, isspacerune, false);
         n = chartorune(&r, m->pos);
         *m->pos = '\0';
         m->pos += n;
- eatrunes(m, isspacerune, 1);
+ eatrunes(m, isspacerune, true);
 
         if(ret == m->end)
                 return nil;
@@ -285,7 +285,7 @@ message_client(Client *c, IxpMsg *m) {
                 i = gettoggle(m);
                 if(i == -1)
                         return Ebadusage;
- client_seturgent(c, i, True);
+ client_seturgent(c, i, UrgManager);
                 break;
         default:
                 return Ebadcmd;
@@ -391,9 +391,9 @@ message_view(View *v, IxpMsg *m) {
         case LSELECT:
                 return msg_selectarea(v->sel, m);
         case LSEND:
- return msg_sendclient(v, m, 0);
+ return msg_sendclient(v, m, false);
         case LSWAP:
- return msg_sendclient(v, m, 1);
+ return msg_sendclient(v, m, true);
         default:
                 return Ebadcmd;
         }
@@ -410,23 +410,6 @@ printdebug(void) {
                                 bufprint(" ");
                         bufprint("%s", debugtab[i]);
                 }
-}
-
-char*
-root_readctl(void) {
- bufclear();
- bufprint("view %s\n", screen->sel->name);
- bufprint("focuscolors %s\n", def.focuscolor.colstr);
- bufprint("normcolors %s\n", def.normcolor.colstr);
- bufprint("font %s\n", def.font->name);
- bufprint("grabmod %s\n", def.grabmod);
- bufprint("border %d\n", def.border);
- if(debug) {
- bufprint("debug ");
- printdebug();
- bufprint("\n");
- }
- return buffer;
 }
 
 static char*
@@ -490,7 +473,7 @@ msg_parsecolors(IxpMsg *m, CTuple *col)
         *p = c;
 
         m->pos = p;
- eatrunes(m, isspacerune, 1);
+ eatrunes(m, isspacerune, true);
         return nil;
 }
 
@@ -655,10 +638,10 @@ msg_sendclient(View *v, IxpMsg *m, bool
         case LTOGGLE:
                 if(!a->floating)
                         to = v->area;
- else if(c->revert && !c->revert->floating)
- to = c->revert;
+ else if(f->column)
+ to = view_findarea(v, f->column, true);
                 else
- to = v->area->next;
+ to = view_findarea(v, v->selcol, true);
                 break;
         default:
                 if(!getulong(s, &i) || i == 0)
@@ -716,7 +699,7 @@ msg_sendframe(Frame *f, int sym, bool sw
                 frame_swap(f, fp);
         }else {
                 frame_remove(f);
- frame_insert(fp, f);
+ frame_insert(f, fp);
         }
 
         view_arrange(f->view);
@@ -727,3 +710,43 @@ msg_sendframe(Frame *f, int sym, bool sw
         return nil;
 }
 
+char*
+readctl_root(void) {
+ bufclear();
+ bufprint("view %s\n", screen->sel->name);
+ bufprint("focuscolors %s\n", def.focuscolor.colstr);
+ bufprint("normcolors %s\n", def.normcolor.colstr);
+ bufprint("font %s\n", def.font->name);
+ bufprint("grabmod %s\n", def.grabmod);
+ bufprint("border %d\n", def.border);
+ if(debug) {
+ bufprint("debug ");
+ printdebug();
+ bufprint("\n");
+ }
+ return buffer;
+}
+
+char*
+readctl_view(View *v) {
+ Area *a;
+ uint i;
+
+ bufclear();
+ bufprint("%s\n", v->name);
+
+ /* select <area>[ <frame>] */
+ bufprint("select %s", area_name(v->sel));
+ if(v->sel->sel)
+ bufprint(" %d", frame_idx(v->sel->sel));
+ bufprint("\n");
+
+ /* select client <client> */
+ if(v->sel->sel)
+ bufprint("select client %C\n", v->sel->sel->client);
+
+ for(a = v->area->next, i = 1; a; a = a->next, i++)
+ bufprint("colmode %d %s\n", i, colmode2str(a->mode));
+ return buffer;
+}
+
diff -r 17e5122b3d37 -r 22d23ba8e687 cmd/wmii/mouse.c
--- a/cmd/wmii/mouse.c Thu Jan 17 17:50:35 2008 -0500
+++ b/cmd/wmii/mouse.c Sat Jan 19 18:05:50 2008 -0500
@@ -202,8 +202,8 @@ hplace(Framewin *fw, Point pt) {
         View *v;
         int minw;
         
- minw = Dx(screen->r)/NCOL;
         v = screen->sel;
+ minw = Dx(v->r)/NCOL;
 
         for(a = v->area->next; a->next; a = a->next)
                 if(pt.x < a->r.max.x)
@@ -289,7 +289,7 @@ horiz:
 
                                 frame_remove(f);
                                 f->area = fw->ra;
- frame_insert(fw->fp, f);
+ frame_insert(f, fw->fp);
 
                                 if(f->aprev) {
                                         f->aprev->r.max.y = fw->fr.min.y;
@@ -394,7 +394,7 @@ mouse_resizecolframe(Frame *f, Align ali
         if(align&EAST)
                 d = d->next;
 
- min.x = Dx(screen->r)/NCOL;
+ min.x = Dx(v->r)/NCOL;
         min.y = frame_delta_h() + labelh(def.font);
         if(align&NORTH) {
                 if(f->aprev) {
@@ -526,7 +526,7 @@ mouse_resizecol(Divide *d) {
 
         pt = querypointer(&scr.root);
 
- minw = Dx(screen->r)/NCOL;
+ minw = Dx(v->r)/NCOL;
         r.min.x = a->r.min.x + minw;
         r.max.x = a->next->r.max.x - minw;
         r.min.y = pt.y;
diff -r 17e5122b3d37 -r 22d23ba8e687 cmd/wmii/rule.c
--- a/cmd/wmii/rule.c Thu Jan 17 17:50:35 2008 -0500
+++ b/cmd/wmii/rule.c Sat Jan 19 18:05:50 2008 -0500
@@ -6,36 +6,43 @@
 #include <assert.h>
 #include "fns.h"
 
-/* basic rule matching language /regex/ -> value
- * regex might contain POSIX regex syntax defined in regex(3) */
-enum {
- IGNORE,
- REGEX,
- VALUE
-};
-
 void
 trim(char *str, const char *chars) {
         const char *cp;
         char *p, *q;
         char c;
 
- for(cp = chars; (c = *cp); cp++) {
- q = str;
- for(p = q; *p; p++)
- if(*p != c)
- *q++ = *p;
- *q = '\0';
+ q = str;
+ for(p = str; *p; p++) {
+ for(cp = chars; (c = *cp); cp++)
+ if(*p == c)
+ goto nextchar;
+ *q++ = *p;
+ nextchar:
+ continue;
         }
+ *q = '\0';
 }
 
+/* XXX: I hate this. --KM */
 void
 update_rules(Rule **rule, const char *data) {
- int state = IGNORE;
+ /* basic rule matching language /regex/ -> value
+ * regex might contain POSIX regex syntax defined in regex(3) */
+ enum {
+ IGNORE,
+ REGEX,
+ VALUE,
+ COMMENT,
+ };
+ int state;
         Rule *rul;
         char regex[256], value[256];
+ char *regex_end = regex + sizeof(regex) - 1;
+ char *value_end = value + sizeof(value) - 1;
         char *r, *v;
         const char *p;
+ char c;
         
         SET(r);
         SET(v);
@@ -47,42 +54,54 @@ update_rules(Rule **rule, const char *da
                 free(rul->regex);
                 free(rul);
         }
- for(p = data; *p; p++)
+ state = IGNORE;
+ for(p = data; (c = *p); p++)
                 switch(state) {
+ case COMMENT:
+ if(c == '\n')
+ state = IGNORE;
+ break;
                 case IGNORE:
- if(*p == '/') {
+ if(c == '#')
+ state = COMMENT;
+ else if(c == '/') {
                                 r = regex;
                                 state = REGEX;
                         }
- else if(*p == '>') {
+ else if(c == '>') {
                                 value[0] = 0;
                                 v = value;
                                 state = VALUE;
                         }
                         break;
                 case REGEX:
- if(*p == '/') {
+ if(c == '\\' && p[1] == '/')
+ p++;
+ else if(c == '/') {
                                 *r = 0;
                                 state = IGNORE;
+ break;
                         }
- else
- *r++ = *p;
+ if(r < regex_end)
+ *r++ = c;
                         break;
                 case VALUE:
- if(*p == '\n' || *p == 0) {
- *rule = emallocz(sizeof(Rule));
+ if(c == '\n' || c == '#' || c == 0) {
                                 *v = 0;
                                 trim(value, " \t/");
+ *rule = emallocz(sizeof *rule);
                                 (*rule)->regex = regcomp(regex);
                                 if((*rule)->regex) {
                                         utflcpy((*rule)->value, value, sizeof(rul->value));
                                         rule = &(*rule)->next;
- }
- else free(*rule);
+ }else
+ free(*rule);
                                 state = IGNORE;
+ if(c == '#')
+ state = COMMENT;
                         }
- else
- *v++ = *p;
+ else if(v < value_end)
+ *v++ = c;
                         break;
                 default: /* can't happen */
                         die("invalid state");
diff -r 17e5122b3d37 -r 22d23ba8e687 cmd/wmii/view.c
--- a/cmd/wmii/view.c Thu Jan 17 17:50:35 2008 -0500
+++ b/cmd/wmii/view.c Sat Jan 19 18:05:50 2008 -0500
@@ -51,6 +51,8 @@ view_create(const char *name) {
 
         v = emallocz(sizeof(View));
         v->id = id++;
+ v->r = screen->r;
+ v->r.max.y = screen->barwin->r.min.y;
 
         utflcpy(v->name, name, sizeof(v->name));
 
@@ -99,6 +101,16 @@ view_destroy(View *v) {
         ewmh_updateviews();
 }
 
+Area*
+view_findarea(View *v, int idx, bool create) {
+ Area *a;
+
+ for(a=v->area->next; a && --idx > 0; a=a->next)
+ if(create && a->next == nil)
+ return area_create(v, a, 0);
+ return a;
+}
+
 static void
 update_frame_selectors(View *v) {
         Area *a;
@@ -111,8 +123,10 @@ update_frame_selectors(View *v) {
 
 void
 view_focus(WMScreen *s, View *v) {
- Frame *f;
         Client *c;
+ Frame *f;
+ Area *a;
+ bool fscrn;
         
         USED(s);
 
@@ -121,6 +135,21 @@ view_focus(WMScreen *s, View *v) {
         _view_select(v);
         update_frame_selectors(v);
         div_update_all();
+ fscrn = false;
+ for(a=v->area; a; a=a->next)
+ for(f=a->frame; f; f=f->anext)
+ if(f->client->fullscreen) {
+ fscrn = true;
+ if(!f->area->floating) {
+ f->oldr = f->revert;
+ f->oldarea = area_idx(f->area);
+ area_moveto(v->area, f);
+ area_setsel(v->area, f);
+ }else if(f->oldarea == -1) {
+ f->oldr = f->r; /* XXX: oldr */
+ f->oldarea = 0;
+ }
+ }
         for(c=client; c; c=c->next)
                 if((f = c->sel)) {
                         if(f->view == v)
@@ -134,7 +163,10 @@ view_focus(WMScreen *s, View *v) {
                 }
 
         view_restack(v);
- area_focus(v->sel);
+ if(fscrn)
+ area_focus(v->area);
+ else
+ area_focus(v->sel);
         frame_draw_all();
 
         sync();
@@ -165,15 +197,11 @@ view_attach(View *v, Frame *f) {
         Area *a;
         
         c = f->client;
- c->revert = nil;
 
         a = v->sel;
- if(c->trans || c->floating || c->fixedsize
- || c->titleless || c->borderless || c->fullscreen
- || (c->w.ewmh.type & (TypeDialog|TypeSplash|TypeDock)))
+ if(client_floats_p(c))
                 a = v->area;
- else if(c->group && c->group->client
- && (ff = client_viewframe(c->group->client, v)))
+ else if((ff = client_groupframe(c, v)))
                 a = ff->area;
         else if(starting && v->sel->floating)
                 a = v->area->next;
@@ -228,7 +256,7 @@ view_scale(View *v, int w) {
         float scale;
         int wdiff, dx;
 
- minwidth = Dx(screen->r)/NCOL;
+ minwidth = Dx(v->r)/NCOL;
 
         if(!v->area->next)
                 return;
@@ -278,7 +306,7 @@ view_arrange(View *v) {
         if(!v->area->next)
                 return;
 
- view_scale(v, Dx(screen->r));
+ view_scale(v, Dx(v->r));
         xoff = 0;
         for(a=v->area->next; a; a=a->next) {
                 a->r.min.x = xoff;
@@ -312,6 +340,44 @@ view_rects(View *v, uint *num, Frame *ig
 
         *num = i;
         return result;
+}
+
+void
+view_update_all(void) {
+ View *n, *v, *old;
+
+ old = screen->sel;
+ for(v=view; v; v=v->next)
+ update_frame_selectors(v);
+
+ for(v=view; v; v=n) {
+ n=v->next;
+ if(v != old && empty_p(v))
+ view_destroy(v);
+ }
+
+ view_focus(screen, screen->sel);
+}
+
+uint
+view_newcolw(View *v, int num) {
+ Rule *r;
+ ulong n;
+
+ for(r=def.colrules.rule; r; r=r->next)
+ if(regexec(r->regex, v->name, nil, 0)) {
+ char buf[sizeof r->value];
+ char *toks[16];
+
+ strcpy(buf, r->value);
+
+ n = tokenize(toks, 16, buf, '+');
+ if(num < n)
+ if(getulong(toks[num], &n))
+ return Dx(v->r) * (n / 100.0);
+ break;
+ }
+ return 0;
 }
 
 char*
@@ -346,72 +412,3 @@ view_index(View *v) {
         return buffer;
 }
 
-char*
-view_ctl(View *v) {
- Area *a;
- uint i;
-
- bufclear();
- bufprint("%s\n", v->name);
-
- /* select <area>[ <frame>] */
- bufprint("select %s", area_name(v->sel));
- if(v->sel->sel)
- bufprint(" %d", frame_idx(v->sel->sel));
- bufprint("\n");
-
- /* select client <client> */
- if(v->sel->sel)
- bufprint("select client %C\n", v->sel->sel->client);
-
- for(a = v->area->next, i = 1; a; a = a->next, i++)
- bufprint("colmode %d %s\n", i, colmode2str(a->mode));
- return buffer;
-}
-
-void
-view_update_all(void) {
- View *n, *v, *old;
- int found;
-
- old = screen->sel;
- for(v=view; v; v=v->next)
- update_frame_selectors(v);
-
- found = 0;
- for(v=view; v; v=n) {
- n=v->next;
- if(v != old) {
- if(empty_p(v))
- view_destroy(v);
- else
- found++;
- }
- }
-
- if(found && !strcmp(old->name, "nil") && empty_p(old))
- view_destroy(old);
- view_focus(screen, screen->sel);
-}
-
-uint
-view_newcolw(View *v, int num) {
- Rule *r;
- ulong n;
-
- for(r=def.colrules.rule; r; r=r->next)
- if(regexec(r->regex, v->name, nil, 0)) {
- char buf[sizeof r->value];
- char *toks[16];
-
- strcpy(buf, r->value);
-
- n = tokenize(toks, 16, buf, '+');
- if(num < n)
- if(getulong(toks[num], &n))
- return Dx(screen->r) * (n / 100.0);
- break;
- }
- return 0;
-}
-
diff -r 17e5122b3d37 -r 22d23ba8e687 cmd/wmii/x11.c
--- a/cmd/wmii/x11.c Thu Jan 17 17:50:35 2008 -0500
+++ b/cmd/wmii/x11.c Sat Jan 19 18:05:50 2008 -0500
@@ -600,6 +600,22 @@ xatom(char *name) {
 }
 
 void
+sendmessage(Window *w, char *name, char *value, long l2, long l3, long l4) {
+ XClientMessageEvent e;
+
+ e.type = ClientMessage;
+ e.window = w->w;
+ e.message_type = xatom(name);
+ e.format = 32;
+ e.data.l[0] = xatom(value);
+ e.data.l[1] = xtime;
+ e.data.l[2] = l2;
+ e.data.l[3] = l3;
+ e.data.l[4] = l4;
+ sendevent(w, false, NoEventMask, (XEvent*)&e);
+}
+
+void
 sendevent(Window *w, bool propegate, long mask, XEvent *e) {
         XSendEvent(display, w->w, propegate, mask, e);
 }
@@ -835,6 +851,7 @@ sethints(Window *w) {
 sethints(Window *w) {
         enum { MaxInt = ((uint)(1<<(8*sizeof(int)-1))-1) };
         XSizeHints xs;
+ XWMHints *wmh;
         WinHints *h;
         Point p;
         long size;
@@ -847,6 +864,13 @@ sethints(Window *w) {
 
         h->max = Pt(MaxInt, MaxInt);
         h->inc = Pt(1,1);
+
+ wmh = XGetWMHints(display, w->w);
+ if(wmh) {
+ if(wmh->flags&WindowGroupHint)
+ h->group = wmh->window_group;
+ free(wmh);
+ }
 
         if(!XGetWMNormalHints(display, w->w, &xs, &size))
                 return;
diff -r 17e5122b3d37 -r 22d23ba8e687 config.mk
--- a/config.mk Thu Jan 17 17:50:35 2008 -0500
+++ b/config.mk Sat Jan 19 18:05:50 2008 -0500
@@ -26,7 +26,7 @@ AR = ar crs
 AR = ar crs
 
 AWKPATH = $$(which awk)
-P9PATHS = ${PLAN9}:"'$$(HOME)/plan9'":/usr/local/plan9:/usr/local/9:/opt/plan9:/opt/9:/usr/plan9:/usr/9
+P9PATHS = ${PLAN9}:"'$${HOME}/plan9'":/usr/local/plan9:/usr/local/9:/opt/plan9:/opt/9:/usr/plan9:/usr/9
 
 INCX11 = -I/usr/X11R6/include
 LIBX11 = -L/usr/X11R6/lib -lX11
diff -r 17e5122b3d37 -r 22d23ba8e687 include/x11.h
--- a/include/x11.h Thu Jan 17 17:50:35 2008 -0500
+++ b/include/x11.h Sat Jan 19 18:05:50 2008 -0500
@@ -79,13 +79,16 @@ struct Window {
 };
 
 struct WinHints {
- Point min, max;
- Point base, baspect;
- Point inc;
+ Point min;
+ Point max;
+ Point base;
+ Point baspect;
+ Point inc;
+ Point grav;
         Rectangle aspect;
- Point grav;
- bool gravstatic;
- bool position;
+ XWindow group;
+ bool gravstatic;
+ bool position;
 };
 
 struct Handlers {
@@ -224,6 +227,7 @@ Window* window(XWindow);
 Window* window(XWindow);
 long winprotocols(Window*);
 Atom xatom(char*);
+void sendmessage(Window*, char*, char*, long, long, long);
 XRectangle XRect(Rectangle);
 Rectangle gravitate(Rectangle dst, Rectangle src, Point grav);
 Rectangle insetrect(Rectangle, int);
diff -r 17e5122b3d37 -r 22d23ba8e687 libwmii_hack/hack.c
--- a/libwmii_hack/hack.c Thu Jan 17 17:50:35 2008 -0500
+++ b/libwmii_hack/hack.c Sat Jan 19 18:05:50 2008 -0500
@@ -24,6 +24,7 @@ static char* tags[32];
 static char* tags[32];
 static long ntags;
 static long pid;
+static long stime;
 static char hostname[256];
 static long nmsec;
 
@@ -88,6 +89,10 @@ init(Display *d) { /* Hrm... assumes one
                 ntags = n;
                 free(s);
         }
+ if((s = getenv("WMII_HACK_TIME"))) {
+ getlong(s, &stime);
+ unsetenv("WMII_HACK_TIME");
+ }
 
         pid = getpid();
         gethostname(hostname, sizeof hostname);
@@ -95,12 +100,17 @@ init(Display *d) { /* Hrm... assumes one
 
 static void
 setprops(Display *d, Window w) {
+ long *l;
 
         if(!xlib)
                 init(d);
 
- changeprop_long(d, w, "_NET_WM_PID", "CARDINAL", &pid, 1);
- changeprop_string(d, w, "_NET_WM_CLIENT_MACHINE", hostname);
+ if(getprop_long(d, w, "_NET_WM_PID", "CARDINAL", 0L, &l, 1L))
+ free(l);
+ else {
+ changeprop_long(d, w, "_NET_WM_PID", "CARDINAL", &pid, 1);
+ changeprop_string(d, w, "WM_CLIENT_MACHINE", hostname);
+ }
 
         /* Kludge. */
         if(nmsec == 0)
@@ -114,6 +124,8 @@ setprops(Display *d, Window w) {
                 changeprop_long(d, w, "_NET_WM_WINDOW_TYPE", "ATOM", (long*)types, ntypes);
         if(ntags)
                 changeprop_textlist(d, w, "_WMII_TAGS", "UTF8_STRING", tags);
+ if(stime)
+ changeprop_long(d, w, "_WMII_LAUNCH_TIME", "CARDINAL", &stime, 1);
 }
 
 int
diff -r 17e5122b3d37 -r 22d23ba8e687 libwmii_hack/x11.c
--- a/libwmii_hack/x11.c Thu Jan 17 17:50:35 2008 -0500
+++ b/libwmii_hack/x11.c Sat Jan 19 18:05:50 2008 -0500
@@ -79,7 +79,6 @@ freestringlist(char *list[]) {
 }
 #endif
 
-#if 0
 static ulong
 getprop(Display *display, Window w, char *prop, char *type, Atom *actual, int *format, ulong offset, uchar **ret, ulong length) {
         Atom typea;
@@ -102,7 +101,6 @@ getprop(Display *display, Window w, char
         }
         return n;
 }
-#endif
 
 #if 0
 static ulong
@@ -113,7 +111,6 @@ getproperty(Display *display, Window w,
 }
 #endif
 
-#if 0
 static ulong
 getprop_long(Display *display, Window w, char *prop, char *type, ulong offset, long **ret, ulong length) {
         Atom actual;
@@ -127,7 +124,6 @@ getprop_long(Display *display, Window w,
         *ret = 0;
         return 0;
 }
-#endif
 
 #ifdef notdef
 static char**
diff -r 17e5122b3d37 -r 22d23ba8e687 libwmii_hack/x11.h
--- a/libwmii_hack/x11.h Thu Jan 17 17:50:35 2008 -0500
+++ b/libwmii_hack/x11.h Sat Jan 19 18:05:50 2008 -0500
@@ -10,7 +10,7 @@ static void changeproperty(Display*, Win
 static void changeproperty(Display*, Window, char*, char*, int width, uchar*, int);
 /* static void delproperty(Display*, Window, char*); */
 /* static void freestringlist(char**); */
-/* static ulong getprop_long(Display*, Window, char*, char*, ulong, long**, ulong); */
+static ulong getprop_long(Display*, Window, char*, char*, ulong, long**, ulong);
 /* static char* getprop_string(Display*, Window, char*); */
 /* static int getprop_textlist(Display*, Window, char*, char**[]); */
 /* static ulong getproperty(Display*, Window, char*, char*, Atom*, ulong, uchar**, ulong); */
diff -r 17e5122b3d37 -r 22d23ba8e687 man/wmiiloop.tex
--- a/man/wmiiloop.tex Thu Jan 17 17:50:35 2008 -0500
+++ b/man/wmiiloop.tex Sat Jan 19 18:05:50 2008 -0500
@@ -1,4 +1,4 @@
-\begin{Name}{1}{wmiiloop}{Kris Maglione}{}{wmiir}
+\begin{Name}{1}{wmiiloop}{Kris Maglione}{}{wmiiloop}
         \Prog{wmiiloop}-VERSION
 \end{Name}
 
diff -r 17e5122b3d37 -r 22d23ba8e687 mk/hdr.mk
--- a/mk/hdr.mk Thu Jan 17 17:50:35 2008 -0500
+++ b/mk/hdr.mk Sat Jan 19 18:05:50 2008 -0500
@@ -22,8 +22,12 @@ all:
         ${COMPILE} ${<:.c=.o} $<
         ${LINK} $@ ${<:.c=.o}
 
-
-.rc.O .sh.O .awk.O:
+.sh.O:
+ echo FILTER $(BASE)$<
+ $(FILTER) $< >$@
+ sh -n $@
+ chmod 0755 $@
+.rc.O .awk.O:
         echo FILTER $(BASE)$<
         $(FILTER) $< >$@
         chmod 0755 $@
diff -r 17e5122b3d37 -r 22d23ba8e687 mk/so.mk
--- a/mk/so.mk Thu Jan 17 17:50:35 2008 -0500
+++ b/mk/so.mk Sat Jan 19 18:05:50 2008 -0500
@@ -1,5 +1,5 @@ SOPTARG = $(ROOT)/lib/$(TARG)
 SOPTARG = $(ROOT)/lib/$(TARG)
-SO = $(PTARG).so
+SO = $(SOPTARG).so
 SONAME = $(TARG).so
 OFILES_PIC = ${OBJ:=.o_pic}
 
diff -r 17e5122b3d37 -r 22d23ba8e687 rc/rc.wmii.rc
--- a/rc/rc.wmii.rc Thu Jan 17 17:50:35 2008 -0500
+++ b/rc/rc.wmii.rc Sat Jan 19 18:05:50 2008 -0500
@@ -15,8 +15,8 @@ RIGHT=l
 # Theme
 wmiifont='drift,-*-fixed-*-*-*-*-9-*-*-*-*-*-*-*'
 wmiifont='-*-fixed-medium-r-*-*-13-*-*-*-*-*-*-*'
-wmiinormcol=`{echo '#222222 #5FBF77 #2A7F3F'}
-wmiifocuscol=`{echo '#ffffff #153F1F #2A7F3F'}
+wmiinormcol=`{echo '#000000 #c1c48b #81654f'}
+wmiifocuscol=`{echo '#000000 #81654f #000000'}
 wmiibackground='#333333'
 
 # Programs
@@ -24,7 +24,8 @@ WMII_TERM=(xterm)
 
 # Column Rules
 wmiir write /colrules <<!
-/./ -> 60+40
+/gimp/ -> 17+83+41
+/./ -> 62+38 # Golden Ratio
 !
 
 # Tagging Rules
@@ -32,7 +33,6 @@ wmiir write /tagrules <<!
 /VLC/ -> ~
 /XMMS.*/ -> ~
 /MPlayer.*/ -> ~
-/.*/ -> sel
 !
 
 # Status Bar Info
@@ -102,7 +102,7 @@ fn Action {
 }
 
 fn Action-rehash {
- comm -23 <{ls $WMII_NS_DIR/proglist.* | awk -F'\.' '{print $NF}'} \
+ comm -23 <{ls $WMII_NS_DIR/proglist.* >[2]/dev/null | awk -F'\.' '{print $NF}'} \
                  <{ps | awk '{print $2}'} |
         while(id=`{read})
                 rm $WMII_NS_DIR/proglist.$id
Received on Mon Jan 21 2008 - 00:31:07 UTC

This archive was generated by hypermail 2.2.0 : Sun Jul 13 2008 - 15:59:03 UTC