[hackers] [wmii] Lots of fixes, cleanup. New 'config' make target to guess at and prompt for config.mk knobs.

From: Kris Maglione <jg_AT_suckless.org>
Date: Fri, 01 Jun 2007 01:09:39 -0000

changeset: 2098:1f7395ef920b
user: Kris Maglione <jg_AT_suckless.org>
date: Thu Apr 19 23:27:26 2007 -0400
summary: Lots of fixes, cleanup. New 'config' make target to guess at and prompt for config.mk knobs.

diff -r a46b948966fa -r 1f7395ef920b Makefile
--- a/Makefile Thu Apr 19 14:53:07 2007 -0400
+++ b/Makefile Thu Apr 19 23:27:26 2007 -0400
@@ -6,4 +6,7 @@ DIRS = libixp \
         rc \
         man
 
+config:
+ ROOT="${ROOT}" ${ROOT}/util/genconfig
+
 include ${ROOT}/mk/dir.mk
diff -r a46b948966fa -r 1f7395ef920b cmd/wmii/Makefile
--- a/cmd/wmii/Makefile Thu Apr 19 14:53:07 2007 -0400
+++ b/cmd/wmii/Makefile Thu Apr 19 23:27:26 2007 -0400
@@ -8,8 +8,8 @@ HFILES= dat.h fns.h
 HFILES= dat.h fns.h
 
 LIB = ${LIBIXP}
-EXLDFLAGS = -lm ${LIBX11} -lXext -L/usr/local/lib -liconv
-EXCFLAGS = ${INCX11}
+EXLDFLAGS = -lm ${LIBX11} -lXext ${LIBICONV}
+EXCFLAGS = ${INCX11} ${INCICONV}
 OBJ = area \
         bar \
         client \
diff -r a46b948966fa -r 1f7395ef920b cmd/wmii/area.c
--- a/cmd/wmii/area.c Thu Apr 19 14:53:07 2007 -0400
+++ b/cmd/wmii/area.c Thu Apr 19 23:27:26 2007 -0400
@@ -27,7 +27,7 @@ create_area(View *v, Area *pos, uint w)
         uint minwidth;
         Area *a;
 
- minwidth = Dx(screen->rect)/NCOL;
+ minwidth = Dx(screen->r)/NCOL;
 
         i = 0;
         for(a = v->area; a != pos; a = a->next)
@@ -41,19 +41,19 @@ create_area(View *v, Area *pos, uint w)
                 if(colnum) {
                         w = newcolw(v, max(i-1, 0));
                         if (w == 0)
- w = Dx(screen->rect) / (colnum + 1);
- }
- else
- w = Dx(screen->rect);
+ w = Dx(screen->r) / (colnum + 1);
+ }
+ else
+ w = Dx(screen->r);
         }
 
         if(w < minwidth)
                 w = minwidth;
- if(colnum && (colnum * minwidth + w) > Dx(screen->rect))
+ if(colnum && (colnum * minwidth + w) > Dx(screen->r))
                 return nil;
 
         if(pos)
- scale_view(v, Dx(screen->rect) - w);
+ scale_view(v, Dx(screen->r) - w);
 
         a = emallocz(sizeof *a);
         a->view = v;
@@ -62,9 +62,9 @@ create_area(View *v, Area *pos, uint w)
         a->frame = nil;
         a->sel = nil;
 
- a->rect = screen->rect;
- a->rect.max.x = a->rect.min.x + w;
- a->rect.max.x = screen->brect.min.y;
+ a->r = screen->r;
+ a->r.max.x = a->r.min.x + w;
+ a->r.max.x = screen->brect.min.y;
 
         if(pos) {
                 a->next = pos->next;
@@ -143,8 +143,8 @@ send_to_area(Area *to, Frame *f) {
 
         if(to->floating != from->floating) {
                 Rectangle temp = f->revert;
- f->revert = f->rect;
- f->rect = temp;
+ f->revert = f->r;
+ f->r = temp;
         }
         f->client->revert = from;
 
@@ -172,8 +172,8 @@ attach_to_area(Area *a, Frame *f, Bool s
 
         c->floating = a->floating;
         if(!a->floating) {
- f->rect = a->rect;
- f->rect.max.y = f->rect.min.y + Dx(a->rect) / n_frame;
+ f->r = a->r;
+ f->r.max.y = f->r.min.y + Dx(a->r) / n_frame;
         }
 
         insert_frame(a->sel, f, False);
@@ -182,7 +182,7 @@ attach_to_area(Area *a, Frame *f, Bool s
                 place_frame(f);
 
         focus_frame(f, False);
- resize_frame(f, f->rect);
+ resize_frame(f, f->r);
         restack_view(a->view);
 
         if(!a->floating)
@@ -290,7 +290,7 @@ place_frame(Frame *f) {
         uint i, j, x, y, cx, cy, maxx, maxy, diff, num;
         int snap;
 
- snap = Dy(screen->rect) / 66;
+ snap = Dy(screen->r) / 66;
         num = 0;
         fit = False;
         align = CENTER;
@@ -300,14 +300,14 @@ place_frame(Frame *f) {
 
         if(c->trans)
                 return;
- if(Dx(c->rect) >= Dx(a->rect)
- || Dy(c->rect) >= Dy(a->rect)
+ if(Dx(c->r) >= Dx(a->r)
+ || Dy(c->r) >= Dy(a->r)
                 || c->size.flags & USPosition
                 || c->size.flags & PPosition)
                 return;
         if(!field) {
- mx = Dx(screen->rect) / dx;
- my = Dy(screen->rect) / dy;
+ mx = Dx(screen->r) / dx;
+ my = Dy(screen->r) / dy;
                 mwidth = ceil((float)mx / devisor);
                 field = emallocz(sizeof(uint) * mwidth * my);
         }
@@ -315,23 +315,23 @@ place_frame(Frame *f) {
         memset(field, ~0, (sizeof(uint) * mwidth * my));
         for(fr=a->frame; fr; fr=fr->anext) {
                 if(fr == f) {
- cx = Dx(f->rect) / dx;
- cy = Dx(f->rect) / dy;
+ cx = Dx(f->r) / dx;
+ cy = Dx(f->r) / dy;
                         continue;
                 }
 
- if(fr->rect.min.x < 0)
+ if(fr->r.min.x < 0)
                         x = 0;
                 else
- x = fr->rect.min.x / dx;
-
- if(fr->rect.min.y < 0)
+ x = fr->r.min.x / dx;
+
+ if(fr->r.min.y < 0)
                         y = 0;
                 else
- y = fr->rect.min.y / dy;
-
- maxx = fr->rect.max.x / dx;
- maxy = fr->rect.max.y / dy;
+ 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);
@@ -364,21 +364,21 @@ place_frame(Frame *f) {
                 p1.y *= dy;
         }
 
- if(!fit || (p1.x + Dx(f->rect) > a->rect.max.x)) {
- diff = Dx(a->rect) - Dx(f->rect);
- p1.x = a->rect.min.x + (random() % min(diff, 1));
- }
-
- if(!fit && (p1.y + Dy(f->rect) > a->rect.max.y)) {
- diff = Dy(a->rect) - Dy(f->rect);
- p1.y = a->rect.min.y + (random() % min(diff, 1));
- }
-
- p1 = subpt(p1, f->rect.min);
- f->rect = rectaddpt(f->rect, p1);
+ 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() % min(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() % min(diff, 1));
+ }
+
+ p1 = subpt(p1, f->r.min);
+ f->r = rectaddpt(f->r, p1);
 
         rects = rects_of_view(a->view, &num, nil);
- snap_rect(rects, num, &f->rect, &align, snap);
+ snap_rect(rects, num, &f->r, &align, snap);
         if(rects)
                 free(rects);
 }
@@ -416,7 +416,7 @@ focus_area(Area *a) {
                 else
                         write_event("ColumnFocus %d\n", i);
                 if(a->frame)
- write_event("ClientFocus 0x%x\n", a->sel->client->win);
+ write_event("ClientFocus 0x%x\n", a->sel->client->w.w);
         }
 }
 
diff -r a46b948966fa -r 1f7395ef920b cmd/wmii/bar.c
--- a/cmd/wmii/bar.c Thu Apr 19 14:53:07 2007 -0400
+++ b/cmd/wmii/bar.c Thu Apr 19 23:27:26 2007 -0400
@@ -15,7 +15,7 @@ initbar(WMScreen *s) {
 initbar(WMScreen *s) {
         WinAttr wa;
 
- s->brect = s->rect;
+ s->brect = s->r;
         s->brect.min.y = s->brect.max.y - labelh(def.font);
 
         wa.override_redirect = 1;
@@ -81,7 +81,7 @@ resize_bar(WMScreen *s) {
 resize_bar(WMScreen *s) {
         View *v;
 
- s->brect = s->rect;
+ s->brect = s->r;
         s->brect.min.y = s->brect.max.y - labelh(def.font);
 
         reshapewin(s->barwin, s->brect);
diff -r a46b948966fa -r 1f7395ef920b cmd/wmii/client.c
--- a/cmd/wmii/client.c Thu Apr 19 14:53:07 2007 -0400
+++ b/cmd/wmii/client.c Thu Apr 19 23:27:26 2007 -0400
@@ -34,13 +34,13 @@ create_client(XWindow w, XWindowAttribut
 
         c = emallocz(sizeof(Client));
         c->border = wa->border_width;
- c->rect.min = Pt(wa->x, wa->y);
- c->rect.max = addpt(c->rect.min, Pt(wa->width, wa->height));
-
- c->win.type = WWindow;
- c->win.w = w;
-
- c->proto = winprotocols(&c->win);
+ c->r.min = Pt(wa->x, wa->y);
+ c->r.max = addpt(c->r.min, Pt(wa->width, wa->height));
+
+ c->w.type = WWindow;
+ c->w.w = w;
+
+ c->proto = winprotocols(&c->w);
         prop_client(c, XA_WM_TRANSIENT_FOR);
         prop_client(c, XA_WM_NORMAL_HINTS);
         prop_client(c, XA_WM_HINTS);
@@ -58,13 +58,13 @@ create_client(XWindow w, XWindowAttribut
                         | PointerMotionMask
                         | ButtonPressMask
                         | ButtonReleaseMask;
- c->framewin = createwindow(&scr.root, c->rect, scr.depth, InputOutput, &fwa,
+ c->framewin = createwindow(&scr.root, c->r, scr.depth, InputOutput, &fwa,
                           CWOverrideRedirect
                         | CWEventMask);
         c->framewin->aux = c;
- c->win.aux = c;
+ c->w.aux = c;
         sethandler(c->framewin, &framehandler);
- sethandler(&c->win, &handlers);
+ sethandler(&c->w, &handlers);
 
         grab_button(c->framewin->w, AnyButton, AnyModifier);
 
@@ -75,7 +75,7 @@ create_client(XWindow w, XWindowAttribut
                         break;
                 }
 
- write_event("CreateClient 0x%x\n", c->win);
+ write_event("CreateClient 0x%x\n", c->w.w);
         return c;
 }
 
@@ -84,12 +84,36 @@ ignoreerrors(Display *d, XErrorEvent *e)
         return 0;
 }
 
+Rectangle
+gravclient(Client *c, Rectangle *rp) {
+ Rectangle r;
+ Point p;
+
+ p = c->w.hints->grav;
+
+ if(rp)
+ return gravitate(*rp, c->w.r, p);
+
+ if(c->sel) {
+ if(c->sel->area->floating)
+ r = c->sel->r;
+ else
+ r = c->sel->revert;
+ }else
+ r = client2frame(nil, c->w.r);
+ p = addpt(p, Pt(2,2));
+ return gravitate(c->w.r, r, p);
+}
+
 void
 destroy_client(Client *c) {
         int (*handler)(Display*, XErrorEvent*);
+ Rectangle r;
         char *dummy;
         Client **tc;
         XEvent ev;
+
+ if(verbose) fprintf(stderr, "client.c:destroy_client(%p) %s\n", c, c->name);
 
         for(tc=&client; *tc; tc=&(*tc)->next)
                 if(*tc == c) {
@@ -106,11 +130,14 @@ destroy_client(Client *c) {
         update_client_views(c, &dummy);
 
         unmap_client(c, WithdrawnState);
- gravitate_client(c, True);
- reparent_client(c, &scr.root, c->rect.min);
+
+ r = gravclient(c, nil);
+ reparent_client(c, &scr.root, r.min);
+
+ write_event("DestroyClient 0x%x\n", (uint)c->w.w);
 
         destroywindow(c->framewin);
- sethandler(&c->win, nil);
+ sethandler(&c->w, nil);
 
         XSync(display, False);
         XSetErrorHandler(handler);
@@ -119,10 +146,9 @@ destroy_client(Client *c) {
         flushevents(EnterWindowMask, False);
 
         while(XCheckMaskEvent(display, StructureNotifyMask, &ev))
- if(ev.type != UnmapNotify || ev.xunmap.window != c->win.w)
+ if(ev.type != UnmapNotify || ev.xunmap.window != c->w.w)
                         dispatch_event(&ev);
 
- write_event("DestroyClient 0x%x\n", c->win);
         free(c);
 }
 
@@ -131,7 +157,7 @@ manage_client(Client *c) {
         XTextProperty tags = { 0 };
         Client *trans;
 
- XGetTextProperty(display, c->win.w, &tags, atom[TagsAtom]);
+ XGetTextProperty(display, c->w.w, &tags, atom[TagsAtom]);
 
         if((trans = win2client(c->trans)))
                 strncpy(c->tags, trans->tags, sizeof(c->tags));
@@ -139,7 +165,7 @@ manage_client(Client *c) {
                 strncpy(c->tags, (char *)tags.value, sizeof(c->tags));
         XFree(tags.value);
 
- gravitate_client(c, False);
+ //gravclient(c, nil);
         reparent_client(c, c->framewin, Pt(def.border, labelh(def.font)));
 
         if(!strlen(c->tags))
@@ -159,6 +185,7 @@ manage_client(Client *c) {
 /* Handlers */
 static void
 configreq_event(Window *w, XConfigureRequestEvent *e) {
+ Rectangle r;
         Rectangle *frect;
         Frame *f;
         Client *c;
@@ -166,46 +193,41 @@ configreq_event(Window *w, XConfigureReq
         c = w->aux;
         f = c->sel;
 
- gravitate_client(c, True);
+ r = gravclient(c, nil);
         if(e->value_mask & CWX)
- c->rect.min.x = e->x;
+ r.min.x = e->x;
         if(e->value_mask & CWY)
- c->rect.min.y = e->y;
+ r.min.y = e->y;
         if(e->value_mask & CWWidth)
- c->rect.max.x = c->rect.min.x + e->width;
+ r.max.x = r.min.x + e->width;
         if(e->value_mask & CWHeight)
- c->rect.max.y = c->rect.min.y + e->height;
+ r.max.y = r.min.y + e->height;
         if(e->value_mask & CWBorderWidth)
                 c->border = e->border_width;
- gravitate_client(c, False);
-
- if((Dx(c->rect) == Dx(screen->rect))
- && (Dy(c->rect) == Dy(screen->rect))) {
+ r = gravclient(c, &r);
+
+ if((Dx(r) == Dx(screen->r)) && (Dy(r) == Dy(screen->r))) {
                 c->fullscreen = True;
- if(c->sel) {
- if(!c->sel->area->floating)
- send_to_area(c->sel->view->area, c->sel);
+ if(f) {
+ if(!f->area->floating)
+ send_to_area(f->view->area, f);
                         focus_client(c);
- restack_view(c->sel->view);
- }
- }
-
- if(c->sel->area->floating)
- frect=&c->sel->rect;
- else
- frect=&c->sel->revert;
-
- *frect = insetrect(c->rect, -def.border);
- frect->min.y -= labelh(def.font);
-
- if(c->sel->area->floating || c->fullscreen)
+ restack_view(f->view);
+ }
+ }
+
+ if(c->sel->area->floating) {
+ c->sel->r = r;
                 resize_client(c, frect);
- else
+ }else {
+ c->sel->revert = r;
                 configure_client(c);
+ }
 }
 
 static void
 destroy_event(Window *w, XDestroyWindowEvent *e) {
+ if(verbose) fprintf(stderr, "client.c:destroy_event(%x)\n", (uint)w->w);
         destroy_client(w->aux);
 }
 
@@ -220,7 +242,8 @@ enter_event(Window *w, XCrossingEvent *e
                         focus(c, False);
                 }
                 set_cursor(c, cursor[CurNormal]);
- }else if(verbose) fprintf(stderr, "enter_notify(c[NotifyInferior]) => %s\n", c->name);
+ }else if(verbose)
+ fprintf(stderr, "enter_notify(c[NotifyInferior]) => %s\n", c->name);
 }
 
 static void
@@ -229,7 +252,8 @@ focusin_event(Window *w, XFocusChangeEve
 
         c = w->aux;
 
- //print_focus(c, c->name);
+ print_focus(c, c->name);
+
         if(e->mode == NotifyGrab)
                 screen->hasgrab = c;
 
@@ -256,7 +280,7 @@ focusout_event(Window *w, XFocusChangeEv
                         return;
         }else if(e->mode != NotifyGrab) {
                 if(screen->focus == c) {
- //print_focus(&c_magic, "<magic>");
+ print_focus(&c_magic, "<magic>");
                         screen->focus = &c_magic;
                 }
                 if(c->sel)
@@ -316,7 +340,7 @@ win2client(XWindow w) {
 win2client(XWindow w) {
         Client *c;
         for(c=client; c; c=c->next)
- if(c->win.w == w) break;
+ if(c->w.w == w) break;
         return c;
 }
 
@@ -331,14 +355,14 @@ update_client_name(Client *c) {
         list = nil;
 
         name.nitems = 0;
- XGetTextProperty(display, c->win.w, &name, atom[NetWMName]);
+ XGetTextProperty(display, c->w.w, &name, atom[NetWMName]);
         if(name.nitems > 0) {
                 if(Xutf8TextPropertyToTextList(display, &name, &list, &n) == Success) {
                         utfecpy(c->name, c->name+sizeof(c->name), list[0]);
                         XFreeStringList(list);
                 }
         }else {
- XGetWMName(display, c->win.w, &name);
+ XGetWMName(display, c->w.w, &name);
                 if(name.nitems > 0) {
                         str = toutf8((char*)name.value);
                         utfecpy(c->name, c->name+sizeof(c->name), str);
@@ -347,7 +371,7 @@ update_client_name(Client *c) {
                 }
         }
 
- XGetClassHint(display, c->win.w, &ch);
+ XGetClassHint(display, c->w.w, &ch);
         snprintf(c->props, sizeof(c->props), "%s:%s:%s",
                         str_nil(ch.res_class),
                         str_nil(ch.res_name),
@@ -363,7 +387,7 @@ set_client_state(Client * c, int state)
         long data[] = { state, None };
         XChangeProperty(
                 /* display */ display,
- /* parent */ c->win.w,
+ /* parent */ c->w.w,
                 /* property */ atom[WMState],
                 /* type */ atom[WMState],
                 /* format */ 32,
@@ -375,24 +399,22 @@ set_client_state(Client * c, int state)
 
 void
 map_client(Client *c) {
- if(!c->mapped) {
- XSelectInput(display, c->win.w, ClientMask & ~StructureNotifyMask);
- XMapWindow(display, c->win.w);
- XSelectInput(display, c->win.w, ClientMask);
+ if(!c->w.mapped) {
+ XSelectInput(display, c->w.w, ClientMask & ~StructureNotifyMask);
+ mapwin(&c->w);
+ XSelectInput(display, c->w.w, ClientMask);
                 set_client_state(c, NormalState);
- c->mapped = 1;
         }
 }
 
 void
 unmap_client(Client *c, int state) {
- if(c->mapped) {
+ if(c->w.mapped) {
                 c->unmapped++;
- XSelectInput(display, c->win.w, ClientMask & ~StructureNotifyMask);
- XUnmapWindow(display, c->win.w);
- XSelectInput(display, c->win.w, ClientMask);
+ XSelectInput(display, c->w.w, ClientMask & ~StructureNotifyMask);
+ unmapwin(&c->w);
+ XSelectInput(display, c->w.w, ClientMask);
                 set_client_state(c, state);
- c->mapped = 0;
         }
 }
 
@@ -408,9 +430,11 @@ unmap_frame(Client *c) {
 
 void
 reparent_client(Client *c, Window *w, Point pt) {
- XSelectInput(display, c->win.w, ClientMask & ~StructureNotifyMask);
- XReparentWindow(display, c->win.w, w->w, pt.x, pt.y);
- XSelectInput(display, c->win.w, ClientMask);
+ XSelectInput(display, c->w.w, ClientMask & ~StructureNotifyMask);
+
+ reparentwindow(&c->w, w, pt);
+
+ XSelectInput(display, c->w.w, ClientMask);
 }
 
 void
@@ -434,12 +458,12 @@ configure_client(Client *c) {
         if(!f)
                 return;
 
- r = rectaddpt(f->crect, f->rect.min);
+ r = rectaddpt(f->crect, f->r.min);
         r = insetrect(r, -c->border);
 
         e.type = ConfigureNotify;
- e.event = c->win.w;
- e.window = c->win.w;
+ e.event = c->w.w;
+ e.window = c->w.w;
         e.x = r.min.x;
         e.y = r.min.y;
         e.width = Dx(r);
@@ -447,7 +471,7 @@ configure_client(Client *c) {
         e.border_width = c->border;
         e.above = None;
         e.override_redirect = False;
- XSendEvent(display, c->win.w, False,
+ XSendEvent(display, c->w.w, False,
                         StructureNotifyMask, (XEvent *) & e);
         XSync(display, False);
 }
@@ -469,9 +493,9 @@ void
 void
 kill_client(Client * c) {
         if(c->proto & WM_PROTOCOL_DELWIN)
- send_client_message(c->win.w, atom[WMProtocols], atom[WMDelete]);
+ send_client_message(c->w.w, atom[WMProtocols], atom[WMDelete]);
         else
- XKillClient(display, c->win.w);
+ XKillClient(display, c->w.w);
 }
 
 static void
@@ -489,7 +513,7 @@ set_urgent(Client *c, Bool urgent, Bool
                 cnot = "";
 
         if(urgent != c->urgent) {
- write_event("%sUrgent 0x%x %s\n", cnot, c->win, cwrite);
+ write_event("%sUrgent 0x%x %s\n", cnot, c->w, cwrite);
                 c->urgent = urgent;
                 if(c->sel) {
                         if(c->sel->view == screen->sel)
@@ -506,13 +530,13 @@ set_urgent(Client *c, Bool urgent, Bool
         }
 
         if(write) {
- wmh = XGetWMHints(display, c->win.w);
+ wmh = XGetWMHints(display, c->w.w);
                 if(wmh) {
                         if(urgent)
                                 wmh->flags |= XUrgencyHint;
                         else
                                 wmh->flags &= ~XUrgencyHint;
- XSetWMHints(display, c->win.w, wmh);
+ XSetWMHints(display, c->w.w, wmh);
                         XFree(wmh);
                 }
         }
@@ -521,10 +545,9 @@ void
 void
 prop_client(Client *c, Atom a) {
         XWMHints *wmh;
- long msize;
 
         if(a == atom[WMProtocols])
- c->proto = winprotocols(&c->win);
+ c->proto = winprotocols(&c->w);
         else if(a== atom[NetWMName]) {
 wmname:
                 update_client_name(c);
@@ -533,19 +556,15 @@ wmname:
         }
         else switch (a) {
         case XA_WM_TRANSIENT_FOR:
- XGetTransientForHint(display, c->win.w, &c->trans);
+ XGetTransientForHint(display, c->w.w, &c->trans);
                 break;
         case XA_WM_NORMAL_HINTS:
- if(!XGetWMNormalHints(display, c->win.w, &c->size, &msize) || !c->size.flags)
- c->size.flags = PSize;
- c->fixedsize = False;
- if((c->size.flags & PMinSize) && (c->size.flags & PMaxSize)
- &&(c->size.min_width == c->size.max_width)
- &&(c->size.min_height == c->size.max_height))
- c->fixedsize = True;
+ sethints(&c->w);
+ if(c->w.hints)
+ c->fixedsize = eqpt(c->w.hints->min, c->w.hints->max);
                 break;
         case XA_WM_HINTS:
- wmh = XGetWMHints(display, c->win.w);
+ wmh = XGetWMHints(display, c->w.w);
                 if(wmh) {
                         set_urgent(c, (wmh->flags & XUrgencyHint) != 0, False);
                         XFree(wmh);
@@ -556,142 +575,36 @@ wmname:
         }
 }
 
-void
-gravitate_client(Client *c, Bool invert) {
- Point d;
- int gravity;
-
- gravity = NorthWestGravity;
- if(c->size.flags & PWinGravity) {
- gravity = c->size.win_gravity;
- }
-
- d.y = 0;
- switch (gravity) {
- case StaticGravity:
- case NorthWestGravity:
- case NorthGravity:
- case NorthEastGravity:
- d.y = labelh(def.font);
- break;
- case EastGravity:
- case CenterGravity:
- case WestGravity:
- d.y = -(Dy(c->rect) / 2) + labelh(def.font);
- break;
- case SouthEastGravity:
- case SouthGravity:
- case SouthWestGravity:
- d.y = -Dy(c->rect);
- break;
- default:
- break;
- }
-
- d.x = 0;
- switch (gravity) {
- case StaticGravity:
- case NorthWestGravity:
- case WestGravity:
- case SouthWestGravity:
- d.x = def.border;
- break;
- case NorthGravity:
- case CenterGravity:
- case SouthGravity:
- d.x = -(Dx(c->rect) / 2) + def.border;
- break;
- case NorthEastGravity:
- case EastGravity:
- case SouthEastGravity:
- d.x = -(Dy(c->rect) + def.border);
- break;
- default:
- break;
- }
-
- if(invert)
- rectsubpt(c->rect, d);
- else
- rectaddpt(c->rect, d);
-}
-
-void
-apply_sizehints(Client *c, Rectangle *r, Bool floating, Bool frame, Align sticky) {
- XSizeHints *s;
- Rectangle r2;
- uint bw, bh;
-
- bw = 0;
- bh = 0;
- s = &c->size;
-
- r2 = rectsubpt(*r, r->min);
- if(frame)
- r2 = frame2client(c->sel, r2);
-
- if(s->flags & PMinSize) {
- bw = s->min_width;
- bh = s->min_height;
- if(floating) {
- if(Dx(r2) < s->min_width)
- r2.max.x = s->min_width;
- if(Dy(r2) < s->min_height)
- r2.max.y = s->min_height;
- }
- }
- if(s->flags & PMaxSize) {
- if(Dx(r2) > s->max_width)
- r2.max.x = s->min_width;
- if(Dy(r2) > s->max_height)
- r2.max.y = s->min_height;
- }
-
- if(s->flags & PBaseSize) {
- bw = s->base_width;
- bh = s->base_height;
- }
-
- if(s->flags & PResizeInc) {
- if(s->width_inc > 0)
- r2.max.x -= (Dx(r2) - bw) % s->width_inc;
- if(s->height_inc > 0)
- r2.max.y -= (Dy(r2) - bh) % s->height_inc;
- }
-
- if((s->flags & (PBaseSize|PMinSize)) == PMinSize) {
- bw = 0;
- bh = 0;
- }
-
- if(s->flags & PAspect) {
- double min, max, initial;
-
- min = (double)s->min_aspect.x / s->min_aspect.y;
- max = (double)s->max_aspect.x / s->max_aspect.y;
- initial = (double)(Dx(r2) - bw) / (Dy(r2) - bh);
- if(initial < min)
- r2.max.y = bh + (Dx(r2) - bw) / min;
- if(initial > max)
- r2.max.x = bw + (Dy(r2) - bh) * max;
- }
-
- if(frame)
- r2 = client2frame(c->sel, r2);
-
- if(!(s->flags & PMinSize) || !floating) {
+Rectangle
+frame_hints(Frame *f, Rectangle r, Align sticky) {
+ Rectangle or;
+ Point p;
+ Client *c;
+
+ c = f->client;
+ if(c->w.hints == nil)
+ return r;
+
+ or = r;
+ r = frame2client(f, r);
+ r = sizehint(c->w.hints, r);
+ r = client2frame(f, r);
+
+ if(!f->area->floating) {
                 /* Not allowed to grow */
- if(Dx(r2) > Dx(*r))
- r2.max.x =Dx(*r);
- if(Dy(r2) > Dy(*r))
- r2.max.y = Dy(*r);
- }
-
- if((sticky & (EAST|WEST)) == EAST)
- r->min.x = r->max.x - Dx(r2);
- if((sticky & (NORTH|SOUTH)) == SOUTH)
- r->min.y = r->max.y - Dy(r2);
- *r = rectaddpt(r2, r->min);
+ if(Dx(r) > Dx(or))
+ r.max.x =r.min.x+Dx(or);
+ if(Dy(r) > Dy(or))
+ r.max.y = r.min.y+Dy(or);
+ }
+
+ p = ZP;
+ if((sticky&(EAST|WEST)) == EAST)
+ p.x = Dx(or) - Dx(r);
+ if((sticky&(NORTH|SOUTH)) == SOUTH)
+ p.y = Dy(or) - Dy(r);
+
+ return rectaddpt(r, p);
 }
 
 void
@@ -714,15 +627,19 @@ focus_client(Client *c) {
         flushevents(FocusChangeMask, True);
 
         if(verbose)
- fprintf(stderr, "focus_client(%p) => %s\n", c, (c ? c->name : nil));
+ fprintf(stderr, "focus_client(%p[%x]) => %s\n", c,
+ (c ? (uint)c->w.w : 0), (c ? c->name : nil));
+
         if(screen->focus != c) {
- if(c && verbose)
- fprintf(stderr, "\t%s => %s\n", (screen->focus ? screen->focus->name : "<nil>"),
+ if(verbose)
+ fprintf(stderr, "\t%s => %s\n",
+ (screen->focus ? screen->focus->name : "<nil>"),
                                         (c ? c->name : "<nil>"));
                 if(c)
- XSetInputFocus(display, c->win.w, RevertToParent, CurrentTime);
+ XSetInputFocus(display, c->w.w, RevertToParent, CurrentTime);
                 else
                         XSetInputFocus(display, screen->barwin->w, RevertToParent, CurrentTime);
+ XSync(display, False);
         }
 
         flushevents(FocusChangeMask, True);
@@ -741,19 +658,19 @@ resize_client(Client *c, Rectangle *r) {
                 return;
         }
 
- c->rect = rectaddpt(f->crect, f->rect.min);
+ c->r = rectaddpt(f->crect, f->r.min);
 
         if((f->area->mode == Colmax) && (f->area->sel != f)) {
                 unmap_frame(c);
                 unmap_client(c, IconicState);
         }else if(f->collapsed) {
- reshapewin(c->framewin, f->rect);
+ reshapewin(c->framewin, f->r);
                 map_frame(c);
                 unmap_client(c, IconicState);
         }else {
- reshapewin(&c->win, f->crect);
+ reshapewin(&c->w, f->crect);
                 map_client(c);
- reshapewin(c->framewin, f->rect);
+ reshapewin(c->framewin, f->r);
                 map_frame(c);
                 configure_client(c);
         }
@@ -1005,7 +922,7 @@ apply_tags(Client *c, const char *tags)
         toks[n] = nil;
 
         update_client_views(c, toks);
- XChangeProperty(display, c->win.w, atom[TagsAtom], XA_STRING, 8,
+ XChangeProperty(display, c->w.w, atom[TagsAtom], XA_STRING, 8,
                         PropModeReplace, (uchar *)c->tags, strlen(c->tags));
 }
 
diff -r a46b948966fa -r 1f7395ef920b cmd/wmii/column.c
--- a/cmd/wmii/column.c Thu Apr 19 14:53:07 2007 -0400
+++ b/cmd/wmii/column.c Thu Apr 19 23:27:26 2007 -0400
@@ -103,7 +103,7 @@ update_imgs() {
 
         w = 2 * (labelh(def.font) / 3);
         w = max(w, 10);
- h = Dy(screen->rect);
+ h = Dy(screen->r);
 
         if(divimg) {
                 if(w == Dx(divimg->r) && h == Dy(divimg->r)
@@ -135,12 +135,12 @@ update_divs() {
         for(a = v->area->next; a; a = a->next) {
                 d = get_div(dp);
                 dp = &d->next;
- setdiv(d, a->rect.min.x);
+ setdiv(d, a->r.min.x);
 
                 if(!a->next) {
                         d = get_div(dp);
                         dp = &d->next;
- setdiv(d, a->rect.max.x);
+ setdiv(d, a->r.max.x);
                 }
         }
         for(d = *dp; d; d = d->next)
@@ -220,7 +220,7 @@ scale_column(Area *a) {
                 else
                         nuncol++;
 
- surplus = Dy(a->rect);
+ surplus = Dy(a->r);
         surplus -= ncol * colh;
         surplus -= nuncol * uncolh;
         if(surplus < 0) {
@@ -242,7 +242,7 @@ scale_column(Area *a) {
         i = ncol - 1;
         j = nuncol - 1;
         for(f=a->frame; f; f=f->anext) {
- f->rect = rectsubpt(f->rect, f->rect.min);
+ f->r = rectsubpt(f->r, f->r.min);
                 f->crect = rectsubpt(f->crect, f->crect.min);
                 if(f == a->sel)
                         j++;
@@ -276,36 +276,36 @@ scale_column(Area *a) {
 
         i = nuncol;
                 for(f=a->frame; f; f=f->anext) {
- f->rect.max.x = Dx(a->rect);
+ f->r.max.x = Dx(a->r);
                         if(f->collapsed)
- f->rect.max.y = labelh(def.font);
+ f->r.max.y = labelh(def.font);
                         else {
                                 if(--i != 0)
- f->rect.max.y = (float)Dy(f->crect) / dy * surplus;
+ f->r.max.y = (float)Dy(f->crect) / dy * surplus;
                                 else
- f->rect.max.y = surplus;
- f->rect.max.y += uncolh;
+ f->r.max.y = surplus;
+ f->r.max.y += uncolh;
+ f->r = frame_hints(f, f->r, NWEST);
+
+ dy -= Dy(f->r) - uncolh;
+ surplus -= Dy(f->r) - uncolh;
         
- apply_sizehints(f->client, &f->rect, False, True, NWEST);
- dy -= Dy(f->rect) - uncolh;
- surplus -= Dy(f->rect) - uncolh;
-
- resize_frame(f, f->rect);
+ resize_frame(f, f->r);
                         }
                 }
 
- yoff = a->rect.min.y;
+ yoff = a->r.min.y;
         i = nuncol;
         for(f=a->frame; f; f=f->anext) {
- f->rect = rectaddpt(f->rect, Pt(a->rect.min.x, yoff));
- f->rect.max.x = a->rect.max.x;
+ f->r = rectaddpt(f->r, Pt(a->r.min.x, yoff));
+ f->r.max.x = a->r.max.x;
                 if(!f->collapsed) {
                         i--;
- f->rect.max.y += surplus / nuncol;
+ f->r.max.y += surplus / nuncol;
                         if(!i)
- f->rect.max.y += surplus % nuncol;
- }
- yoff = f->rect.max.y;
+ f->r.max.y += surplus % nuncol;
+ }
+ yoff = f->r.max.y;
         }
 }
 
@@ -331,7 +331,7 @@ arrange_column(Area *a, Bool dirty) {
         case Colmax:
                 for(f=a->frame; f; f=f->anext) {
                         f->collapsed = False;
- f->rect = a->rect;
+ f->r = a->r;
                 }
                 goto resize;
         default:
@@ -342,14 +342,14 @@ resize:
 resize:
         if(a->view == screen->sel) {
                 restack_view(a->view);
- resize_client(a->sel->client, &a->sel->rect);
+ resize_client(a->sel->client, &a->sel->r);
 
                 for(f=a->frame; f; f=f->anext)
                         if(!f->collapsed && f != a->sel)
- resize_client(f->client, &f->rect);
+ resize_client(f->client, &f->r);
                 for(f=a->frame; f; f=f->anext)
                         if(f->collapsed && f != a->sel)
- resize_client(f->client, &f->rect);
+ resize_client(f->client, &f->r);
         }
 }
 
@@ -361,9 +361,9 @@ resize_column(Area *a, int w) {
         an = a->next;
         assert(an != nil);
 
- dw = w - Dx(a->rect);
- a->rect.max.x += dw;
- an->rect.min.x += dw;
+ dw = w - Dx(a->r);
+ a->r.max.x += dw;
+ an->r.min.x += dw;
 
         arrange_view(a->view);
         focus_view(screen, a->view);
@@ -382,22 +382,22 @@ resize_colframeh(Frame *f, Rectangle *r)
         fp = f->aprev;
 
         if(fp)
- r->min.y = max(r->min.y, fp->rect.min.y + minh);
+ r->min.y = max(r->min.y, fp->r.min.y + minh);
         else
- r->min.y = max(r->min.y, a->rect.min.y);
+ r->min.y = max(r->min.y, a->r.min.y);
 
         if(fn)
- r->max.y = min(r->max.y, fn->rect.max.y - minh);
+ r->max.y = min(r->max.y, fn->r.max.y - minh);
         else
- r->max.y = min(r->max.y, a->rect.max.y);
+ r->max.y = min(r->max.y, a->r.max.y);
 
         if(fp) {
- fp->rect.max.y = r->min.y;
- resize_frame(fp, fp->rect);
+ fp->r.max.y = r->min.y;
+ resize_frame(fp, fp->r);
         }
         if(fn) {
- fn->rect.min.y = r->max.y;
- resize_frame(fn, fn->rect);
+ fn->r.min.y = r->max.y;
+ resize_frame(fn, fn->r);
         }
 
         resize_frame(f, *r);
@@ -414,38 +414,38 @@ resize_colframe(Frame *f, Rectangle *r)
         v = a->view;
         maxx = r->max.x;
 
- minw = Dx(screen->rect) / NCOL;
+ minw = Dx(screen->r) / NCOL;
 
         al = a->prev;
         ar = a->next;
 
         if(al)
- r->min.x = max(r->min.x, al->rect.min.x + minw);
+ r->min.x = max(r->min.x, al->r.min.x + minw);
         else
                 r->min.x = max(r->min.x, 0);
 
         if(ar) {
- if(maxx >= ar->rect.max.x - minw)
- maxx = ar->rect.max.x - minw;
+ if(maxx >= ar->r.max.x - minw)
+ maxx = ar->r.max.x - minw;
         }
         else
- if(maxx > screen->rect.max.x)
- maxx = screen->rect.max.x;
-
- dx = a->rect.min.x - r->min.x;
- dw = maxx - a->rect.max.x;
+ if(maxx > screen->r.max.x)
+ maxx = screen->r.max.x;
+
+ dx = a->r.min.x - r->min.x;
+ dw = maxx - a->r.max.x;
         if(al) {
- al->rect.max.x -= dx;
+ al->r.max.x -= dx;
                 arrange_column(al, False);
         }
         if(ar) {
- ar->rect.max.x -= dw;
+ ar->r.max.x -= dw;
                 arrange_column(ar, False);
         }
 
         resize_colframeh(f, r);
 
- a->rect.max.x = maxx;
+ a->r.max.x = maxx;
         arrange_view(a->view);
 
         focus_view(screen, v);
diff -r a46b948966fa -r 1f7395ef920b cmd/wmii/dat.h
--- a/cmd/wmii/dat.h Thu Apr 19 14:53:07 2007 -0400
+++ b/cmd/wmii/dat.h Thu Apr 19 23:27:26 2007 -0400
@@ -88,7 +88,7 @@ struct Area {
         Bool floating;
         ushort id;
         int mode;
- Rectangle rect;
+ Rectangle r;
 };
 
 struct Frame {
@@ -98,7 +98,7 @@ struct Frame {
         View *view;
         Area *area;
         ushort id;
- Rectangle rect;
+ Rectangle r;
         Rectangle crect;
         Rectangle revert;
         Client *client;
@@ -121,14 +121,12 @@ struct Client {
         Bool fixedsize;
         Bool fullscreen;
         Bool urgent;
- Bool mapped;
- Bool frame_mapped;
         int unmapped;
- Window win;
+ Window w;
         XWindow trans;
         Window *framewin;
         Cursor cursor;
- Rectangle rect;
+ Rectangle r;
         XSizeHints size;
         GC gc;
 };
@@ -201,7 +199,7 @@ struct WMScreen {
         Window *barwin;
         Image *ibuf;
 
- Rectangle rect;
+ Rectangle r;
         Rectangle brect;
 } *screens, *screen;
 
diff -r a46b948966fa -r 1f7395ef920b cmd/wmii/event.c
--- a/cmd/wmii/event.c Thu Apr 19 14:53:07 2007 -0400
+++ b/cmd/wmii/event.c Thu Apr 19 23:27:26 2007 -0400
@@ -1,5 +1,4 @@
-/* Copyright ©2004-2006 Anselm R. Garbe <garbeam at gmail dot com>
- * Copyright ©2006-2007 Kris Maglione <fbsdaemon_AT_gmail.com>
+/* Copyright ©2006-2007 Kris Maglione <fbsdaemon_AT_gmail.com>
  * See LICENSE file for license details.
  */
 #include <stdio.h>
@@ -11,6 +10,8 @@
 
 void
 dispatch_event(XEvent *e) {
+ if(verbose)
+ printevent(e);
         if(handler[e->type])
                 handler[e->type](e);
 }
@@ -34,7 +35,7 @@ buttonrelease(XEvent *e) {
         Window *w;
 
         ev = &e->xbutton;
- if((w = findwin(e->xany.window)))
+ if((w = findwin(ev->window)))
                 if(w->handler->bup)
                         w->handler->bup(w, ev);
 }
@@ -45,7 +46,7 @@ buttonpress(XEvent *e) {
         Window *w;
 
         ev = &e->xbutton;
- if((w = findwin(e->xany.window))) {
+ if((w = findwin(ev->window))) {
                 if(w->handler->bdown)
                         w->handler->bdown(w, ev);
         }
@@ -56,11 +57,11 @@ static void
 static void
 configurerequest(XEvent *e) {
         XConfigureRequestEvent *ev;
- Window *w;
         XWindowChanges wc;
+ Window *w;
 
         ev = &e->xconfigurerequest;
- if((w = findwin(e->xany.window))) {
+ if((w = findwin(ev->window))) {
                 if(w->handler->configreq)
                         w->handler->configreq(w, ev);
         }else{
@@ -71,9 +72,8 @@ configurerequest(XEvent *e) {
                 wc.border_width = ev->border_width;
                 wc.sibling = ev->above;
                 wc.stack_mode = ev->detail;
- ev->value_mask &= ~(CWStackMode|CWSibling);
+ //ev->value_mask &= ~(CWStackMode|CWSibling);
                 XConfigureWindow(display, ev->window, ev->value_mask, &wc);
- XSync(display, False);
         }
 }
 
@@ -81,11 +81,18 @@ destroynotify(XEvent *e) {
 destroynotify(XEvent *e) {
         XDestroyWindowEvent *ev;
         Window *w;
+ Client *c;
 
         ev = &e->xdestroywindow;
- if((w = findwin(e->xany.window))) {
+ if((w = findwin(ev->window))) {
                 if(w->handler->destroy)
                         w->handler->destroy(w, ev);
+ }else {
+ if(verbose)
+ fprintf(stderr, "DestroyWindow(%x) (no handler)\n", (uint)ev->window);
+ if((c = win2client(ev->window)))
+ fprintf(stderr, "Badness: Unhandled DestroyNotify: "
+ "Client: %p, Window: %x, Name: %s\n", c, (uint)c->w.w, c->name);
         }
 }
 
@@ -98,7 +105,7 @@ enternotify(XEvent *e) {
         if(ev->mode != NotifyNormal)
                 return;
 
- if((w = findwin(e->xany.window))) {
+ if((w = findwin(ev->window))) {
                 if(w->handler->enter)
                         w->handler->enter(w, ev);
         }
@@ -114,7 +121,7 @@ leavenotify(XEvent *e) {
         Window *w;
 
         ev = &e->xcrossing;
- w = findwin(e->xany.window);
+ w = findwin(ev->window);
         if((ev->window == scr.root.w) && !ev->same_screen) {
                 sel_screen = True;
                 draw_frames();
@@ -124,10 +131,11 @@ void
 void
 print_focus(Client *c, char *to) {
                 if(verbose) {
- fprintf(stderr, "screen->focus: %p => %p\n",
- screen->focus, c);
+ fprintf(stderr, "screen->focus: %p[%x] => %p[%x]\n",
+ screen->focus, (uint)(screen->focus ? screen->focus->w.w : 0),
+ c, (uint)(c ? c->w.w : 0));
                         fprintf(stderr, "\t%s => %s\n",
- screen->focus ? screen->focus->name : "<nil>",
+ (screen->focus ? screen->focus->name : "<nil>"),
                                 to);
                 }
 }
@@ -142,6 +150,8 @@ focusin(XEvent *e) {
         ev = &e->xfocus;
         /* Yes, we're focusing in on nothing, here. */
         if(ev->detail == NotifyDetailNone) {
+ print_focus(&c_magic, "<magic[none]>");
+ screen->focus = &c_magic;
                 XSetInputFocus(display, screen->barwin->w, RevertToParent, CurrentTime);
                 return;
         }
@@ -152,17 +162,16 @@ focusin(XEvent *e) {
            ||(ev->detail == NotifyInferior)
            ||(ev->detail == NotifyAncestor)))
                 return;
- if((ev->mode == NotifyWhileGrabbed)
- && (screen->hasgrab != &c_root))
- return;
-
- if((w = findwin(e->xany.window))) {
+ if((ev->mode == NotifyWhileGrabbed) && (screen->hasgrab != &c_root))
+ return;
+
+ if(ev->window == screen->barwin->w) {
+ print_focus(nil, "<nil>");
+ screen->focus = nil;
+ }
+ else if((w = findwin(ev->window))) {
                 if(w->handler->focusin)
                         w->handler->focusin(w, ev);
- }
- else if(ev->window == screen->barwin->w) {
- print_focus(nil, "<nil>");
- screen->focus = nil;
         }
         else if(ev->mode == NotifyGrab) {
                 if(ev->window == scr.root.w)
@@ -194,7 +203,7 @@ focusout(XEvent *e) {
         if(ev->mode == NotifyUngrab)
                 screen->hasgrab = nil;
 
- if((w = findwin(e->xany.window))) {
+ if((w = findwin(ev->window))) {
                 if(w->handler->focusout)
                         w->handler->focusout(w, ev);
         }
@@ -207,7 +216,7 @@ expose(XEvent *e) {
 
         ev = &e->xexpose;
         if(ev->count == 0) {
- if((w = findwin(e->xany.window))) {
+ if((w = findwin(ev->window))) {
                         if(w->handler->expose)
                                 w->handler->expose(w, ev);
                 }
@@ -220,7 +229,7 @@ keypress(XEvent *e) {
         Window *w;
 
         ev = &e->xkey;
- w = findwin(e->xany.window);
+ w = findwin(ev->window);
         ev->state &= valid_mask;
         if(ev->window == scr.root.w)
                 kpress(scr.root.w, ev->state, (KeyCode) ev->keycode);
@@ -243,9 +252,11 @@ maprequest(XEvent *e) {
         XWindowAttributes wa;
 
         ev = &e->xmaprequest;
- w = findwin(e->xany.window);
+ w = findwin(ev->window);
+
         if(!XGetWindowAttributes(display, ev->window, &wa))
                 return;
+
         if(wa.override_redirect) {
                 XSelectInput(display, ev->window,
                                 (StructureNotifyMask | PropertyChangeMask));
@@ -261,7 +272,7 @@ motionnotify(XEvent *e) {
         Window *w;
 
         ev = &e->xmotion;
- if((w = findwin(e->xany.window))) {
+ if((w = findwin(ev->window))) {
                 if(w->handler->motion)
                         w->handler->motion(w, ev);
         }
@@ -273,7 +284,7 @@ propertynotify(XEvent *e) {
         Window *w;
 
         ev = &e->xproperty;
- if((w = findwin(e->xany.window))) {
+ if((w = findwin(ev->window))) {
                 if(w->handler->property)
                         w->handler->property(w, ev);
         }
@@ -285,7 +296,7 @@ mapnotify(XEvent *e) {
         Window *w;
 
         ev = &e->xmap;
- if((w = findwin(e->xany.window))) {
+ if((w = findwin(ev->window))) {
                 if(w->handler->map)
                         w->handler->map(w, ev);
         }
@@ -297,7 +308,7 @@ unmapnotify(XEvent *e) {
         Window *w;
 
         ev = &e->xunmap;
- if((w = findwin(e->xany.window))) {
+ if((w = findwin(ev->window)) && (ev->event == w->parent->w)) {
                 if(ev->send_event || w->unmapped-- == 0)
                         if(w->handler->unmap)
                                 w->handler->unmap(w, ev);
@@ -328,8 +339,6 @@ check_x_event(IxpConn *c) {
         XEvent ev;
         while(XPending(display)) {
                 XNextEvent(display, &ev);
- if(verbose)
- printevent(&ev);
                 dispatch_event(&ev);
                 /* Hack to alleviate an apparant Xlib bug */
                 XPending(display);
diff -r a46b948966fa -r 1f7395ef920b cmd/wmii/fns.h
--- a/cmd/wmii/fns.h Thu Apr 19 14:53:07 2007 -0400
+++ b/cmd/wmii/fns.h Thu Apr 19 23:27:26 2007 -0400
@@ -66,6 +66,7 @@ void dispatch_event(XEvent*);
 void dispatch_event(XEvent*);
 void check_x_event(IxpConn*);
 uint flushevents(long even_mask, Bool dispatch);
+void print_focus(Client *c, char *to);
 
 /* frame.c */
 Frame *create_frame(Client*, View*);
@@ -76,6 +77,7 @@ void set_frame_cursor(Frame*, Point);
 void set_frame_cursor(Frame*, Point);
 void swap_frames(Frame*, Frame*);
 int frame_delta_h();
+Rectangle frame_hints(Frame*, Rectangle, Align);
 Rectangle frame2client(Frame*, Rectangle);
 Rectangle client2frame(Frame*, Rectangle);
 int ingrabbox(Frame*, int x, int y);
@@ -148,6 +150,7 @@ int win_proto(Window);
 /* x11.c */
 XRectangle XRect(Rectangle);
 int eqrect(Rectangle, Rectangle);
+int eqpt(Point, Point);
 Point addpt(Point, Point);
 Point subpt(Point, Point);
 Point divpt(Point, Point);
@@ -158,6 +161,7 @@ Image * allocimage(int w, int h, int dep
 Image * allocimage(int w, int h, int depth);
 void freeimage(Image *);
 Window *createwindow(Window *parent, Rectangle, int depth, uint class, WinAttr*, int valuemask);
+void reparentwindow(Window*, Window*, Point);
 void destroywindow(Window*);
 void setwinattr(Window*, WinAttr*, int valmask);
 void reshapewin(Window*, Rectangle);
@@ -188,8 +192,11 @@ Point querypointer(Window*);
 Point querypointer(Window*);
 void warppointer(Point);
 Point translate(Window*, Window*, Point);
-int grabpointer(Window*, Window *confine, Cursor cur, int mask);
+int grabpointer(Window*, Window *confine, Cursor, int mask);
 void ungrabpointer();
+Rectangle gravitate(Rectangle dst, Rectangle src, Point grav);
+Rectangle sizehint(WinHints*, Rectangle);
+void sethints(Window*);
 
 /* utf.c */
 int chartorune(Rune*, char*);
diff -r a46b948966fa -r 1f7395ef920b cmd/wmii/frame.c
--- a/cmd/wmii/frame.c Thu Apr 19 14:53:07 2007 -0400
+++ b/cmd/wmii/frame.c Thu Apr 19 23:27:26 2007 -0400
@@ -19,14 +19,14 @@ create_frame(Client *c, View *v) {
 
         if(c->sel) {
                 f->revert = c->sel->revert;
- f->rect = c->sel->rect;
+ f->r = c->sel->r;
         }
         else{
                 c->sel = f;
- f->rect = c->rect;
- f->rect.max.x += 2 * def.border;
- f->rect.max.y += frame_delta_h();
- f->revert = f->rect;
+ f->r = c->r;
+ f->r.max.x += 2 * def.border;
+ f->r.max.y += frame_delta_h();
+ f->revert = f->r;
         }
         f->collapsed = False;
 
@@ -108,7 +108,7 @@ frame_to_top(Frame *f) {
 
 Rectangle
 frame2client(Frame *f, Rectangle r) {
- if(f->area->floating) {
+ if(f == nil || f->area->floating) {
                 r.max.x -= def.border * 2;
                 r.max.y -= frame_delta_h();
         }else {
@@ -122,7 +122,7 @@ frame2client(Frame *f, Rectangle r) {
 
 Rectangle
 client2frame(Frame *f, Rectangle r) {
- if(f->area->floating) {
+ if(f == nil || f->area->floating) {
                 r.max.x += def.border * 2;
                 r.max.y += frame_delta_h();
         }else {
@@ -155,7 +155,7 @@ bdown_event(Window *w, XButtonEvent *e)
                         focus(c, True);
                         break;
                 case Button3:
- do_mouse_resize(c, False, quadrant(f->rect, Pt(e->x_root, e->y_root)));
+ do_mouse_resize(c, False, quadrant(f->r, Pt(e->x_root, e->y_root)));
                         frame_to_top(f);
                         focus(c, True);
                         break;
@@ -172,7 +172,7 @@ bdown_event(Window *w, XButtonEvent *e)
                                 do_mouse_resize(c, True, CENTER);
                         else if(f->area->floating)
                                 if(!e->subwindow && !ptinrect(Pt(e->x, e->y), f->titlebar))
- do_mouse_resize(c, False, quadrant(f->rect, Pt(e->x_root, e->y_root)));
+ do_mouse_resize(c, False, quadrant(f->r, Pt(e->x_root, e->y_root)));
 
                         if(f->client != selclient())
                                 focus(c, True);
@@ -184,7 +184,7 @@ bdown_event(Window *w, XButtonEvent *e)
                         XUngrabPointer(display, e->time);
                         XSync(display, False);
 
- write_event("ClientMouseDown 0x%x %d\n", f->client->win.w, e->button);
+ write_event("ClientMouseDown 0x%x %d\n", f->client->w.w, e->button);
                 }
         }
 }
@@ -213,7 +213,7 @@ expose_event(Window *w, XExposeEvent *e)
                 draw_frame(c->sel);
         else
                 fprintf(stderr, "Badness: Expose event on a client frame which shouldn't be visible: %x\n",
- (uint)c->win.w);
+ (uint)c->w.w);
 }
 
 static void
@@ -239,45 +239,44 @@ resize_frame(Frame *f, Rectangle r) {
         Client *c;
 
         c = f->client;
- stickycorner = get_sticky(f->rect, r);
-
- f->crect = r;
- apply_sizehints(c, &f->crect, f->area->floating, True, stickycorner);
+ stickycorner = get_sticky(f->r, r);
+
+ f->crect = frame_hints(f, r, stickycorner);
 
         if(Dx(r) <= 0 || Dy(r) <= 0)
                 fprintf(stderr, "Badness: Frame rect: %d,%d %dx%d\n",
                         r.min.x, r.min.y, Dx(r), Dy(r));
 
         if(f->area->floating)
- f->rect = f->crect;
+ f->r = f->crect;
         else
- f->rect = r;
+ f->r = r;
 
         f->crect = frame2client(f, f->crect);
         f->crect = rectsubpt(f->crect, f->crect.min);
 
         if(Dx(f->crect) < labelh(def.font)) {
- f->rect.max.x = f->rect.min.x + frame_delta_h();
+ f->r.max.x = f->r.min.x + frame_delta_h();
                 f->collapsed = True;
         }
 
         if(f->collapsed) {
- f->rect.max.y= f->rect.min.y + labelh(def.font);
- f->crect = f->rect;
+ f->r.max.y= f->r.min.y + labelh(def.font);
+ f->crect = f->r;
         }
 
         pt.y = labelh(def.font);
 
         if(f->area->floating) {
                 if(c->fullscreen) {
- f->crect = screen->rect;
- f->rect = client2frame(f, f->crect);
- pt.x = (Dx(f->rect) - Dx(f->crect)) / 2;
- f->rect = rectsubpt(f->rect, pt);
+ f->crect = screen->r;
+ f->r = client2frame(f, f->crect);
+ pt.x = (Dx(f->r) - Dx(f->crect)) / 2;
+ f->r = rectsubpt(f->r, pt);
                 }else
- f->rect = constrain(f->rect);
- }
- pt.x = (Dx(f->rect) - Dx(f->crect)) / 2;
+ f->r = constrain(f->r);
+ }
+ pt.x = (Dx(f->r) - Dx(f->crect)) / 2;
         f->crect = rectaddpt(f->crect, pt);
 }
 
@@ -289,7 +288,7 @@ set_frame_cursor(Frame *f, Point pt) {
         if(f->area->floating
         && !ptinrect(pt, f->titlebar)
         && !ptinrect(pt, f->crect)) {
- r = rectsubpt(f->rect, f->rect.min);
+ r = rectsubpt(f->r, f->r.min);
                  cur = cursor_of_quad(quadrant(r, pt));
                 set_cursor(f->client, cur);
         } else
@@ -323,9 +322,9 @@ swap_frames(Frame *fa, Frame *fb) {
         fb->area = fa->area;
         fa->area = a;
 
- trect = fa->rect;
- fa->rect = fb->rect;
- fb->rect = trect;
+ trect = fa->r;
+ fa->r = fb->r;
+ fb->r = trect;
 }
 
 void
@@ -356,7 +355,7 @@ focus_frame(Frame *f, Bool restack) {
 
         if((f != old)
         && (f->area == old_a))
- write_event("ClientFocus 0x%x\n", f->client->win);
+ write_event("ClientFocus 0x%x\n", f->client->w.w);
 
         if(restack)
                 restack_view(v);
@@ -435,7 +434,7 @@ constrain(Rectangle r) {
         Rectangle sr;
         Point p;
 
- sr = screen->rect;
+ sr = screen->r;
         sr.max.y = screen->brect.min.y;
 
         if(Dx(r) > Dx(sr))
diff -r a46b948966fa -r 1f7395ef920b cmd/wmii/fs.c
--- a/cmd/wmii/fs.c Thu Apr 19 14:53:07 2007 -0400
+++ b/cmd/wmii/fs.c Thu Apr 19 23:27:26 2007 -0400
@@ -252,6 +252,7 @@ parse_colors(char **buf, int *buflen, CT
         return nil;
 }
 
+#define strecmp(str, const) (strncmp((str), (const), sizeof(const)-1))
 char *
 message_root(char *message) {
         Font *fn;
@@ -261,32 +262,35 @@ message_root(char *message) {
                 snprintf(buffer, sizeof(buffer), "%s ", message);
                 message = buffer;
         }
- if(!strcmp(message, "quit "))
+
+ if(!strecmp(message, "quit "))
                 srv.running = 0;
- else if(!strncmp(message, "exec ", 5)) {
+ else if(!strecmp(message, "exec ")) {
+ message += sizeof("exec ")-1;
                 srv.running = 0;
- execstr = emalloc(strlen(&message[5]) + sizeof("exec "));
+ execstr = emalloc(strlen(message) + sizeof("exec "));
                 sprintf(execstr, "exec %s", &message[5]);
- message += strlen(message);
- }
- else if(!strncmp(message, "view ", 5))
- select_view(&message[5]);
- else if(!strncmp(message, "selcolors ", 10)) {
- fprintf(stderr, "wmii: warning: selcolors have been removed\n");
+ }
+ else if(!strecmp(message, "view ")) {
+ message += sizeof("view ")-1;
+ select_view(message);
+ }
+ else if(!strecmp(message, "selcolors ")) {
+ fprintf(stderr, "%s: warning: selcolors have been removed\n", argv0);
                 return Ebadcmd;
         }
- else if(!strncmp(message, "focuscolors ", 12)) {
- message += 12;
+ else if(!strecmp(message, "focuscolors ")) {
+ message += sizeof("focuscolors ")-1;
                 n = strlen(message);
                 return parse_colors(&message, (int *)&n, &def.focuscolor);
         }
- else if(!strncmp(message, "normcolors ", 11)) {
- message += 11;
+ else if(!strecmp(message, "normcolors ")) {
+ message += sizeof("normcolors ")-1;
                 n = strlen(message);
                 return parse_colors(&message, (int *)&n, &def.normcolor);
         }
- else if(!strncmp(message, "font ", 5)) {
- message += 5;
+ else if(!strecmp(message, "font ")) {
+ message += sizeof("font ")-1;
                 fn = loadfont(message);
                 if(fn) {
                         freefont(def.font);
@@ -295,15 +299,15 @@ message_root(char *message) {
                 }else
                         return "can't load font";
         }
- else if(!strncmp(message, "border ", 7)) {
- message += 7;
+ else if(!strecmp(message, "border ")) {
+ message += sizeof("border ")-1;
                 n = (uint)strtol(message, &message, 10);
                 if(*message)
                         return Ebadvalue;
                 def.border = n;
         }
- else if(!strncmp(message, "grabmod ", 8)) {
- message += 8;
+ else if(!strecmp(message, "grabmod ")) {
+ message += sizeof("grabmod ")-1;
                 ulong mod;
                 mod = mod_key_of_str(message);
                 if(!(mod & (Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)))
@@ -417,8 +421,8 @@ lookup_file(FileId *parent, char *name)
                                                 *last = file;
                                                 last = &file->next;
                                                 file->p.client = c;
- file->id = c->win.w;
- file->index = c->win.w;
+ file->id = c->w.w;
+ file->index = c->w.w;
                                                 file->tab = *dir;
                                                 file->tab.name = estrdup("sel");
                                         }if(name) goto LastItem;
@@ -428,16 +432,16 @@ lookup_file(FileId *parent, char *name)
                                         if(*name) goto NextItem;
                                 }
                                 for(c=client; c; c=c->next) {
- if(!name || c->win.w == id) {
+ if(!name || c->w.w == id) {
                                                 file = get_file();
                                                 *last = file;
                                                 last = &file->next;
                                                 file->p.client = c;
- file->id = c->win.w;
- file->index = c->win.w;
+ file->id = c->w.w;
+ file->index = c->w.w;
                                                 file->tab = *dir;
                                                 file->tab.name = emallocz(16);
- snprintf(file->tab.name, 16, "0x%x", (uint)c->win.w);
+ snprintf(file->tab.name, 16, "0x%x", (uint)c->w.w);
                                                 if(name) goto LastItem;
                                         }
                                 }
diff -r a46b948966fa -r 1f7395ef920b cmd/wmii/main.c
--- a/cmd/wmii/main.c Thu Apr 19 14:53:07 2007 -0400
+++ b/cmd/wmii/main.c Thu Apr 19 23:27:26 2007 -0400
@@ -215,7 +215,7 @@ init_screen(WMScreen *screen) {
                         | GCPlaneMask,
                         &gcv);
 
- screen->rect = scr.rect;
+ screen->r = scr.rect;
         def.snap = Dy(scr.rect) / 63;
 
         sel_screen = XQueryPointer(display, scr.root.w,
@@ -229,7 +229,7 @@ cleanup() {
         Client *c;
 
         for(c=client; c; c=c->next) {
- reparent_client(c, &scr.root, c->sel->rect.min);
+ reparent_client(c, &scr.root, c->sel->r.min);
                 if(c->sel->view != screen->sel)
                         unmap_client(c, IconicState);
         }
@@ -468,10 +468,11 @@ main(int argc, char *argv[]) {
                 s = &screens[i];
                 init_screen(s);
 
- s->ibuf = allocimage(Dx(s->rect), Dy(s->rect), scr.depth);
+ s->ibuf = allocimage(Dx(s->r), Dy(s->r), scr.depth);
 
                 wa.event_mask =
                                   SubstructureRedirectMask
+ | SubstructureNotifyMask
                                 | EnterWindowMask
                                 | LeaveWindowMask
                                 | FocusChangeMask;
diff -r a46b948966fa -r 1f7395ef920b cmd/wmii/mouse.c
--- a/cmd/wmii/mouse.c Thu Apr 19 14:53:07 2007 -0400
+++ b/cmd/wmii/mouse.c Thu Apr 19 23:27:26 2007 -0400
@@ -51,7 +51,7 @@ framerect(Framewin *f) {
         /* Keep onscreen */
         p = ZP;
         p.x -= min(r.min.x, 0);
- p.x -= max(r.max.x - screen->rect.max.x, 0);
+ p.x -= max(r.max.x - screen->r.max.x, 0);
         p.y -= min(r.min.y, 0);
         p.y -= max(r.max.y - screen->brect.min.y, 0);
         return rectaddpt(r, p);
@@ -126,30 +126,30 @@ vplace(Framewin *fw, Point pt) {
         v = screen->sel;
         
         for(a = v->area->next; a->next; a = a->next)
- if(pt.x < a->rect.max.x)
+ if(pt.x < a->r.max.x)
                         break;
 
         for(f = a->frame; f->anext; f = f->anext)
- if(pt.y < f->rect.max.y)
- break;
-
- if(abs(pt.y - f->rect.min.y) < labelh(def.font)) {
- pt.y = f->rect.min.y;
+ if(pt.y < f->r.max.y)
+ break;
+
+ if(abs(pt.y - f->r.min.y) < labelh(def.font)) {
+ pt.y = f->r.min.y;
                 if(f == fw->f)
                         pt.y += Dy(fw->w->r)/2;
                 else if(f->aprev == fw->f)
                         pt.y += labelh(def.font);
         }
- else if(abs(pt.y - f->rect.max.y) < labelh(def.font)) {
+ else if(abs(pt.y - f->r.max.y) < labelh(def.font)) {
                 if(f != fw->f) {
- pt.y = f->rect.max.y;
+ pt.y = f->r.max.y;
                         if(f->anext == fw->f)
                                 pt.y += Dy(fw->w->r)/2;
                 }
         }
         
- pt.x = a->rect.min.x;
- frameadjust(fw, pt, OHoriz, Dx(a->rect));
+ pt.x = a->r.min.x;
+ frameadjust(fw, pt, OHoriz, Dx(a->r));
 }
 
 static void
@@ -158,20 +158,20 @@ hplace(Framewin *fw, Point pt) {
         View *v;
         int minw;
         
- minw = Dx(screen->rect)/NCOL;
+ minw = Dx(screen->r)/NCOL;
         v = screen->sel;
 
         for(a = v->area->next; a->next; a = a->next)
- if(pt.x < a->rect.max.x)
- break;
-
- if(abs(pt.x - a->rect.min.x) < minw/2)
- pt.x = a->rect.min.x;
- else if(abs(pt.x - a->rect.max.x) < minw/2)
- pt.x = a->rect.max.x;
-
- pt.y = a->rect.min.y;
- frameadjust(fw, pt, OVert, Dy(a->rect));
+ if(pt.x < a->r.max.x)
+ break;
+
+ if(abs(pt.x - a->r.min.x) < minw/2)
+ pt.x = a->r.min.x;
+ else if(abs(pt.x - a->r.max.x) < minw/2)
+ pt.x = a->r.max.x;
+
+ pt.y = a->r.min.y;
+ frameadjust(fw, pt, OVert, Dy(a->r));
 }
 
 static void
@@ -190,10 +190,10 @@ do_managed_move(Client *c) {
 
         pt = querypointer(&scr.root);
 
- pt.x = f->area->rect.min.x;
- fw = framewin(f, pt, OHoriz, Dx(f->area->rect));
-
- r = screen->rect;
+ pt.x = f->area->r.min.x;
+ fw = framewin(f, pt, OHoriz, Dx(f->area->r));
+
+ r = screen->r;
         r.min.y += fw->gb.min.y + Dy(fw->gb)/2;
         r.max.y = r.min.y + 1;
         cwin = createwindow(&scr.root, r, 0, InputOnly, &wa, 0);
@@ -306,20 +306,20 @@ mouse_resizecolframe(Frame *f, Align ali
                 d = d->next;
 
         if(align&NORTH) {
- r.min.y = (f->aprev ? f->aprev->rect.min.y : screen->rect.min.y);
- r.max.y = f->rect.max.y;
+ r.min.y = (f->aprev ? f->aprev->r.min.y : screen->r.min.y);
+ r.max.y = f->r.max.y;
         }else {
- r.min.y = f->rect.min.y;
- r.max.y = (f->anext ? f->anext->rect.max.y : a->rect.max.y);
+ r.min.y = f->r.min.y;
+ r.max.y = (f->anext ? f->anext->r.max.y : a->r.max.y);
         }
         if(align&WEST) {
- r.min.x = (a->prev ? a->prev->rect.min.x : screen->rect.min.x);
- r.max.x = a->rect.max.x;
+ r.min.x = (a->prev ? a->prev->r.min.x : screen->r.min.x);
+ r.max.x = a->r.max.x;
         }else {
- r.min.x = a->rect.min.x;
- r.max.x = (a->next ? a->next->rect.max.x : screen->rect.max.x);
- }
- min.x = Dx(screen->rect)/NCOL;
+ r.min.x = a->r.min.x;
+ r.max.x = (a->next ? a->next->r.max.x : screen->r.max.x);
+ }
+ min.x = Dx(screen->r)/NCOL;
         min.y = frame_delta_h() + labelh(def.font);
         r.min = addpt(r.min, min);
         r.max = subpt(r.max, min);
@@ -327,7 +327,7 @@ mouse_resizecolframe(Frame *f, Align ali
         cwin = createwindow(&scr.root, r, 0, InputOnly, &wa, 0);
         mapwin(cwin);
 
- r = f->rect;
+ r = f->r;
         if(align&NORTH)
                 r.min.y--;
         else
@@ -339,8 +339,8 @@ mouse_resizecolframe(Frame *f, Align ali
         if(!grabpointer(&scr.root, cwin, cursor[CurSizing], MouseMask))
                 goto done;
         
- pt.x = ((align&WEST) ? f->rect.min.x : f->rect.max.x);
- pt.y = ((align&NORTH) ? f->rect.min.y : f->rect.max.y);
+ pt.x = ((align&WEST) ? f->r.min.x : f->r.max.x);
+ pt.y = ((align&NORTH) ? f->r.min.y : f->r.max.y);
         warppointer(pt);
 
         for(;;) {
@@ -372,21 +372,21 @@ mouse_resizecolframe(Frame *f, Align ali
                                 r.max.x = pt.x;
                         if(align&NORTH) {
                                 r.min.y = pt.y;
- r.max.y = f->rect.max.y;
+ r.max.y = f->r.max.y;
                         }else {
- r.min.y = f->rect.min.y;
+ r.min.y = f->r.min.y;
                                 r.max.y = pt.y;
                         }
                         resize_colframe(f, &r);
                         
                         if(align&WEST)
- pt.x = f->rect.min.x + 1;
+ pt.x = f->r.min.x + 1;
                         else
- pt.x = f->rect.max.x - 2;
+ pt.x = f->r.max.x - 2;
                         if(align&NORTH)
- pt.y = f->rect.min.y + 1;
+ pt.y = f->r.min.y + 1;
                         else
- pt.y = f->rect.max.y - 2;
+ pt.y = f->r.max.y - 2;
                         warppointer(pt);
                         goto done;
                 }
@@ -420,9 +420,9 @@ mouse_resizecol(Divide *d) {
 
         pt = querypointer(&scr.root);
 
- minw = Dx(screen->rect)/NCOL;
- r.min.x = a->rect.min.x + minw;
- r.max.x = a->next->rect.max.x - minw;
+ minw = Dx(screen->r)/NCOL;
+ r.min.x = a->r.min.x + minw;
+ r.max.x = a->next->r.max.x - minw;
         r.min.y = pt.y;
         r.max.y = pt.y+1;
 
@@ -445,7 +445,7 @@ mouse_resizecol(Divide *d) {
                         setdiv(d, pt.x);
                         break;
                 case ButtonRelease:
- resize_column(a, pt.x - a->rect.min.x);
+ resize_column(a, pt.x - a->r.min.x);
                         goto done;
                 }
         }
@@ -563,7 +563,6 @@ do_mouse_resize(Client *c, Bool opaque,
         Point d, pt, hr;
         float rx, ry, hrx, hry;
         uint num;
- Bool floating;
         Frame *f;
 
         f = c->sel;
@@ -576,7 +575,7 @@ do_mouse_resize(Client *c, Bool opaque,
                 return;
         }
 
- origin = frect = f->rect;
+ origin = frect = f->r;
         rects = rects_of_view(f->area->view, &num, (opaque ? c->frame : nil));
 
         cur = cursor_of_quad(align);
@@ -603,7 +602,7 @@ do_mouse_resize(Client *c, Bool opaque,
                 if(align&EAST) d.x += hr.x;
                 if(align&WEST) d.x -= hr.x;
 
- pt = addpt(d, f->rect.min);
+ pt = addpt(d, f->r.min);
                 warppointer(pt);
         }
         else if(f->client->fullscreen) {
@@ -611,10 +610,10 @@ do_mouse_resize(Client *c, Bool opaque,
                 return;
         }
         else if(!opaque) {
- hrx = (double)(Dx(screen->rect) + Dx(frect) - 2 * labelh(def.font))
- / Dx(screen->rect);
- hry = (double)(Dy(screen->rect) + Dy(frect) - 3 * labelh(def.font))
- / Dy(screen->rect);
+ hrx = (double)(Dx(screen->r) + Dx(frect) - 2 * labelh(def.font))
+ / Dx(screen->r);
+ hry = (double)(Dy(screen->r) + Dy(frect) - 3 * labelh(def.font))
+ / Dy(screen->r);
 
                 pt.x = frect.max.x - labelh(def.font);
                 pt.y = frect.max.y - labelh(def.font);
@@ -652,7 +651,7 @@ do_mouse_resize(Client *c, Bool opaque,
 
                         grav = snap_rect(rects, num, &frect, &align, def.snap);
 
- apply_sizehints(c, &frect, floating, True, grav);
+ frect = frame_hints(f, frect, grav);
                         frect = constrain(frect);
 
                         reshapewin(c->framewin, frect);
diff -r a46b948966fa -r 1f7395ef920b cmd/wmii/utf.c
--- a/cmd/wmii/utf.c Thu Apr 19 14:53:07 2007 -0400
+++ b/cmd/wmii/utf.c Thu Apr 19 23:27:26 2007 -0400
@@ -330,13 +330,13 @@ toutf8n(char *str, int nstr) {
                 cd = iconv_open("UTF-8", "");
         iconv(cd, nil, nil, nil, nil);
 
- bsize = nstr * 1.25;
+ bsize = nstr * 1.25 + 4;
         buf = emalloc(bsize);
         pos = buf;
         nbuf = bsize-1;
         while(iconv(cd, (void*)&str, &nstr, &pos, &nbuf) == -1)
                 if(errno == E2BIG) {
- bsize *= 1.25;
+ bsize *= 1.25 + 4;
                         nbuf = pos - buf;
                         buf = erealloc(buf, bsize);
                         pos = buf + nbuf;
diff -r a46b948966fa -r 1f7395ef920b cmd/wmii/view.c
--- a/cmd/wmii/view.c Thu Apr 19 14:53:07 2007 -0400
+++ b/cmd/wmii/view.c Thu Apr 19 23:27:26 2007 -0400
@@ -132,7 +132,7 @@ focus_view(WMScreen *s, View *v) {
         for(c=client; c; c=c->next)
                 if((f = c->sel)) {
                         if(f->view == v)
- resize_client(c, &f->rect);
+ resize_client(c, &f->r);
                         else {
                                 unmap_frame(c);
                                 unmap_client(c, IconicState);
@@ -236,7 +236,7 @@ scale_view(View *v, int w) {
         float scale, dx;
         int wdiff;
 
- min_width = Dx(screen->rect)/NCOL;
+ min_width = Dx(screen->r)/NCOL;
 
         if(!v->area->next)
                 return;
@@ -245,17 +245,17 @@ scale_view(View *v, int w) {
         dx = 0;
         for(a=v->area->next; a; a=a->next) {
                 num_col++;
- dx += Dx(a->rect);
+ dx += Dx(a->r);
         }
 
         scale = (float)w / dx;
         xoff = 0;
         for(a=v->area->next; a; a=a->next) {
- a->rect.min.x = xoff;
- a->rect.max.x = xoff + Dx(a->rect) * scale;
+ a->r.min.x = xoff;
+ a->r.max.x = xoff + Dx(a->r) * scale;
                 if(!a->next)
- a->rect.max.x = w;
- xoff = a->rect.max.x;
+ a->r.max.x = w;
+ xoff = a->r.max.x;
         }
 
         /* min_width can only be respected when there is enough space;
@@ -265,16 +265,16 @@ scale_view(View *v, int w) {
 
         xoff = 0;
         for(a=v->area->next, num_col--; a; a=a->next, num_col--) {
- a->rect.min.x = xoff;
+ a->r.min.x = xoff;
         
- if(Dx(a->rect) < min_width)
- a->rect.max.x = xoff + min_width;
- else if((wdiff = xoff + Dx(a->rect) - w + num_col * min_width) > 0)
- a->rect.max.x -= wdiff;
+ if(Dx(a->r) < min_width)
+ a->r.max.x = xoff + min_width;
+ else if((wdiff = xoff + Dx(a->r) - w + num_col * min_width) > 0)
+ a->r.max.x -= wdiff;
                 if(!a->next)
- a->rect.max.x = w;
-
- xoff = a->rect.max.x;
+ a->r.max.x = w;
+
+ xoff = a->r.max.x;
         }
 }
 
@@ -286,13 +286,13 @@ arrange_view(View *v) {
         if(!v->area->next)
                 return;
 
- scale_view(v, Dx(screen->rect));
+ scale_view(v, Dx(screen->r));
         xoff = 0;
         for(a=v->area->next; a; a=a->next) {
- a->rect.min.x = xoff;
- a->rect.min.y = 0;
- a->rect.max.y = screen->brect.min.y;
- xoff = a->rect.max.x;
+ a->r.min.x = xoff;
+ a->r.min.y = 0;
+ a->r.max.y = screen->brect.min.y;
+ xoff = a->r.max.x;
                 arrange_column(a, False);
         }
         if(v == screen->sel)
@@ -314,8 +314,8 @@ rects_of_view(View *v, uint *num, Frame
         i = 0;
         for(f=v->area->frame; f; f=f->anext)
                 if(f != ignore)
- result[i++] = f->rect;
- result[i++] = screen->rect;
+ result[i++] = f->r;
+ result[i++] = screen->r;
         result[i++] = screen->brect;
 
         *num = i;
@@ -336,23 +336,23 @@ view_index(View *v) {
         for((a=v->area), (i=0); a && len > 0; (a=a->next), i++) {
                 if(a->floating)
                         n = snprintf(buf, len, "# ~ %d %d\n",
- Dx(a->rect), Dy(a->rect));
+ Dx(a->r), Dy(a->r));
                 else
                         n = snprintf(buf, len, "# %d %d %d\n",
- i, a->rect.min.x, Dx(a->rect));
+ i, a->r.min.x, Dx(a->r));
 
                 buf += n;
                 len -= n;
                 for(f=a->frame; f && len > 0; f=f->anext) {
- Rectangle *r = &f->rect;
+ Rectangle *r = &f->r;
                         if(a->floating)
                                 n = snprintf(buf, len, "~ 0x%x %d %d %d %d %s\n",
- (uint)f->client->win.w,
+ (uint)f->client->w.w,
                                                 r->min.x, r->min.y, Dx(*r), Dy(*r),
                                                 f->client->props);
                         else
                                 n = snprintf(buf, len, "%d 0x%x %d %d %s\n",
- i, (uint)f->client->win.w,
+ i, (uint)f->client->w.w,
                                                 r->min.y, Dy(*r),
                                                 f->client->props);
                         if(len - n < 0)
@@ -381,7 +381,7 @@ client_of_message(View *v, char *message
                 return nil;
 
         for(c=client; c; c=c->next)
- if(c->win.w == id) break;
+ if(c->w.w == id) break;
         return c;
 }
 
@@ -496,7 +496,7 @@ newcolw(View *v, int num) {
                         n = tokenize(toks, 16, buf, '+');
                         if(n > num)
                                 if(sscanf(toks[num], "%u", &n) == 1)
- return Dx(screen->rect) * ((double)n / 100);
+ return Dx(screen->r) * ((double)n / 100);
                         break;
                 }
         return 0;
diff -r a46b948966fa -r 1f7395ef920b cmd/wmii/x11.c
--- a/cmd/wmii/x11.c Thu Apr 19 14:53:07 2007 -0400
+++ b/cmd/wmii/x11.c Thu Apr 19 23:27:26 2007 -0400
@@ -32,6 +32,11 @@ eqrect(Rectangle a, Rectangle b) {
                 && a.min.y==b.min.y && a.max.y==b.max.y;
 }
 
+int
+eqpt(Point p, Point q) {
+ return p.x==q.x && p.y==q.y;
+}
+
 Point
 addpt(Point p, Point q) {
         p.x += q.x;
@@ -43,6 +48,13 @@ subpt(Point p, Point q) {
 subpt(Point p, Point q) {
         p.x -= q.x;
         p.y -= q.y;
+ return p;
+}
+
+Point
+mulpt(Point p, Point q) {
+ p.x *= q.x;
+ p.y *= q.y;
         return p;
 }
 
@@ -96,6 +108,8 @@ initdisplay() {
         scr.root.w = RootWindow(display, scr.screen);
         scr.root.r = Rect(0, 0, DisplayWidth(display, scr.screen), DisplayHeight(display, scr.screen));
         scr.rect = scr.root.r;
+
+ scr.root.parent = &scr.root;
 
         wlist.next = wlist.prev = &wlist;
 }
@@ -134,6 +148,7 @@ createwindow(Window *parent, Rectangle r
 
         w = emallocz(sizeof *w);
         w->type = WWindow;
+ w->parent = parent;
 
         w->w = XCreateWindow(display, parent->w, r.min.x, r.min.y, Dx(r), Dy(r),
                                 0 /* border */, depth, class, scr.visual, valmask, wa);
@@ -149,12 +164,18 @@ createwindow(Window *parent, Rectangle r
 }
 
 void
+reparentwindow(Window *w, Window *par, Point p) {
+ XReparentWindow(display, w->w, par->w, p.x, p.y);
+ w->parent = par;
+}
+
+void
 destroywindow(Window *w) {
         assert(w->type == WWindow);
+ sethandler(w, nil);
         if(w->gc)
                 XFreeGC(display, w->gc);
         XDestroyWindow(display, w->w);
- sethandler(w, nil);
 }
 
 void
@@ -218,12 +239,15 @@ sethandler(Window *w, Handlers *new) {
         Window *wp;
 
         assert(w->type == WWindow);
+ assert((w->prev != nil && w->next != nil) || w->next == w->prev);
 
         old = w->handler;
- if(new == nil && w->prev) {
- w->prev->next = w->next;
- w->next->prev = w->prev;
- w->next = w->prev = nil;
+ if(new == nil) {
+ if(w->prev) {
+ w->prev->next = w->next;
+ w->next->prev = w->prev;
+ w->next = w->prev = nil;
+ }
         }else {
                 for(wp = wlist.next; wp != &wlist; wp = wp->next)
                         if(w->w <= wp->w) break;
@@ -574,3 +598,127 @@ ungrabpointer() {
 ungrabpointer() {
         XUngrabPointer(display, CurrentTime);
 }
+
+/* Insanity */
+void
+sethints(Window *w) {
+ enum { MaxInt = ((uint)(1<<(8*sizeof(int)-1))-1) };
+ XSizeHints xs;
+ WinHints *h;
+ Point p;
+ long size;
+
+ if(!XGetWMNormalHints(display, w->w, &xs, &size)) {
+ free(w->hints);
+ w->hints = nil;
+ return;
+ }
+
+ if(w->hints == nil)
+ w->hints = emalloc(sizeof *h);
+ h = w->hints;
+ memset(h, 0, sizeof *h);
+
+ h->max = Pt(MaxInt, MaxInt);
+ if(xs.flags&PMinSize) {
+ p.x = xs.min_width;
+ p.y = xs.min_height;
+ h->min = p;
+ }
+ if(xs.flags&PMaxSize) {
+ p.x = xs.max_width;
+ p.y = xs.max_height;
+ h->max = p;
+ }
+
+ h->base = h->min;
+ if(xs.flags&PBaseSize) {
+ p.x = xs.base_width;
+ p.y = xs.base_height;
+ h->base = p;
+ h->baspect = p;
+ }
+
+ h->inc = Pt(1,1);
+ if(xs.flags&PResizeInc) {
+ h->inc.x = xs.width_inc;
+ h->inc.y = xs.height_inc;
+ }
+
+ if(xs.flags&PAspect) {
+ p.x = xs.min_aspect.x;
+ p.y = xs.min_aspect.y;
+ h->aspect.min = p;
+ p.x = xs.max_aspect.x;
+ p.y = xs.max_aspect.y;
+ h->aspect.max = p;
+ }
+
+ p = ZP;
+ if((xs.flags&PWinGravity) == 0)
+ xs.win_gravity = NorthWestGravity;
+
+ switch (xs.win_gravity) {
+ case EastGravity:case CenterGravity:case WestGravity:
+ p.y = -1;
+ break;
+ case SouthEastGravity:case SouthGravity:case SouthWestGravity:
+ p.y = -2;
+ break;
+ }
+ switch (xs.win_gravity) {
+ case NorthGravity:case CenterGravity:case SouthGravity:
+ p.x = -1;
+ break;
+ case NorthEastGravity:case EastGravity:case SouthEastGravity:
+ p.x = -2;
+ break;
+ }
+ h->grav = p;
+}
+
+Rectangle
+sizehint(WinHints *h, Rectangle r) {
+ Point p, p2, o;
+
+ o = r.min;
+ r = rectsubpt(r, o);
+
+ /* Min/max */
+ r.max.x = max(r.max.x, h->min.x);
+ r.max.y = max(r.max.y, h->min.y);
+ r.max.x = min(r.max.x, h->max.x);
+ r.max.y = min(r.max.y, h->max.y);
+
+ /* Increment */
+ p = subpt(r.max, h->base);
+ r.max.x -= p.x % h->inc.x;
+ r.max.y -= p.y % h->inc.y;
+
+ /* Aspect */
+ p = subpt(r.max, h->baspect);
+ p.y = max(p.y, 1);
+ p2 = h->aspect.min;
+ if(p.x * p2.y / p.y < p2.x)
+ r.max.y = h->baspect.y + p.x * p2.y / p2.x;
+ p2 = h->aspect.max;
+ if(p.x * p2.y / p.y > p2.x)
+ r.max.x = h->baspect.x + p.y * p2.x / p2.y;
+
+ return rectaddpt(r, o);
+}
+
+Rectangle
+gravitate(Rectangle rd, Rectangle rs, Point grav) {
+ Point d;
+
+ rd = rectsubpt(rd, rd.min);
+ d = subpt(rs.max, rs.min);
+ d = subpt(rd.max, d);
+
+ d = divpt(d, Pt(2, 2));
+ d = mulpt(d, grav);
+
+ d = addpt(d, rs.min);
+ return rectaddpt(rd, d);
+}
diff -r a46b948966fa -r 1f7395ef920b cmd/wmii/x11.h
--- a/cmd/wmii/x11.h Thu Apr 19 14:53:07 2007 -0400
+++ b/cmd/wmii/x11.h Thu Apr 19 23:27:26 2007 -0400
@@ -13,6 +13,7 @@ typedef struct Rectangle Rectangle;
 typedef struct Rectangle Rectangle;
 typedef struct Screen Screen;
 typedef struct Window Window;
+typedef struct WinHints WinHints;
 typedef struct Handlers Handlers;
 typedef struct Window Image;
 typedef struct Font Font;
@@ -29,15 +30,25 @@ struct Window {
 struct Window {
         int type;
         XWindow w;
+ Window *parent;
         Drawable image;
         GC gc;
         Rectangle r;
         void *aux;
         Handlers *handler;
         Window *next, *prev;
+ WinHints *hints;
         Bool mapped;
         int unmapped;
         int depth;
+};
+
+struct WinHints {
+ Point min, max;
+ Point base, baspect;
+ Point inc;
+ Rectangle aspect;
+ Point grav;
 };
 
 struct Handlers {
diff -r a46b948966fa -r 1f7395ef920b cmd/wmii9rc.sh
--- a/cmd/wmii9rc.sh Thu Apr 19 14:53:07 2007 -0400
+++ b/cmd/wmii9rc.sh Thu Apr 19 23:27:26 2007 -0400
@@ -1,6 +1,7 @@
 #!/bin/sh -f
 RC=""
-for i in "$PLAN9" P9PATHS; do
+IFS=:
+for i in "$PLAN9" `echo P9PATHS`; do
         if [ -d "$i" -a -x "$i/bin/rc" ]; then
                 export PLAN9="$i"
                 RC="$i/bin/rc"
@@ -13,7 +14,7 @@ fi
 fi
 
 if [ -n "$1" ]; then
- exec $RC "$@"
+ exec "$RC" "$@"
 else
         true
 fi
diff -r a46b948966fa -r 1f7395ef920b config.mk
--- a/config.mk Thu Apr 19 14:53:07 2007 -0400
+++ b/config.mk Thu Apr 19 23:27:26 2007 -0400
@@ -9,11 +9,11 @@ INCLUDE = ${PREFIX}/include
 INCLUDE = ${PREFIX}/include
 
 # Includes and libs
-INCS = -I. -I${ROOT}/include -I${INCLUDE} -I/usr/include -I/usr/local/include
+INCPATH = .:${ROOT}/include:${INCLUDE}:/usr/include
 LIBS = -L/usr/lib -lc
 
 # Flags
-CFLAGS = -g -Wall ${INCS} -DVERSION=\"${VERSION}\"
+CFLAGS = -g -Wall -DVERSION=\"${VERSION}\"
 LDFLAGS = -g ${LIBS}
 STATIC = -static
 
@@ -21,15 +21,14 @@ CC = cc -c
 CC = cc -c
 # Linker (Under normal circumstances, this should *not* be 'ld')
 LD = cc
-# Other
-AR = ar cr
-RANLIB = ranlib
 
-AWKPATH = /usr/bin/awk
-P9PATHS = /usr/local/plan9 /usr/local/9 /opt/plan9 /opt/9 /usr/plan9 /usr/9
+AWKPATH = $$(which awk)
+P9PATHS = ${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
+LIBICONV = # Leave blank if your libc includes iconv (glibc does)
+INCICONV = /usr/include
 LIBIXP = ${ROOT}/libixp/libixp.a
 LIBIXP = ${LIBDIR}/libixp.a
 
@@ -38,3 +37,4 @@ LIBIXP = ${LIBDIR}/libixp.a
 #LDFLAGS = ${LIBS} -R${PREFIX}/lib
 #LDFLAGS += -lsocket -lnsl
 #CFLAGS += -xtarget=ultra
+
diff -r a46b948966fa -r 1f7395ef920b mk/hdr.mk
--- a/mk/hdr.mk Thu Apr 19 14:53:07 2007 -0400
+++ b/mk/hdr.mk Thu Apr 19 23:27:26 2007 -0400
@@ -74,7 +74,7 @@ install: printinstall mkdirs
 install: printinstall mkdirs
 
 FILTER = cat
-COMPILE= CC="${CC}" CFLAGS="${CFLAGS} ${EXCFLAGS}" ${ROOT}/util/compile
+COMPILE= CC="${CC}" CFLAGS="${CFLAGS} -I$$(echo ${INCPATH}|sed 's/:/ -I/g') ${EXCFLAGS}" ${ROOT}/util/compile
 LINK= LD="${LD}" LDFLAGS="${LDFLAGS} ${EXLDFLAGS}" ${ROOT}/util/link
 
 include ${ROOT}/config.mk
Received on Fri Jun 01 2007 - 03:09:38 UTC

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