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

This commit is contained in:
Kris Maglione 2007-04-19 23:27:26 -04:00
parent 7b2a84531b
commit e1e28cdb9b
20 changed files with 594 additions and 497 deletions

View File

@ -6,4 +6,7 @@ DIRS = libixp \
rc \
man
config:
ROOT="${ROOT}" ${ROOT}/util/genconfig
include ${ROOT}/mk/dir.mk

View File

@ -8,8 +8,8 @@ TARG = wmii
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 \

View File

@ -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);
w = Dx(screen->r) / (colnum + 1);
}
else
w = Dx(screen->rect);
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 send) {
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 send) {
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;
x = fr->r.min.x / dx;
if(fr->rect.min.y < 0)
if(fr->r.min.y < 0)
y = 0;
else
y = fr->rect.min.y / dy;
y = fr->r.min.y / dy;
maxx = fr->rect.max.x / dx;
maxy = fr->rect.max.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.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->rect) > a->rect.max.y)) {
diff = Dy(a->rect) - Dy(f->rect);
p1.y = a->rect.min.y + (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->rect.min);
f->rect = rectaddpt(f->rect, p1);
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);
}
}

View File

@ -15,7 +15,7 @@ void
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 @@ void
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);

View File

@ -34,13 +34,13 @@ create_client(XWindow w, XWindowAttributes *wa) {
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->r.min = Pt(wa->x, wa->y);
c->r.max = addpt(c->r.min, Pt(wa->width, wa->height));
c->win.type = WWindow;
c->win.w = w;
c->w.type = WWindow;
c->w.w = w;
c->proto = winprotocols(&c->win);
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, XWindowAttributes *wa) {
| 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, XWindowAttributes *wa) {
break;
}
write_event("CreateClient 0x%x\n", c->win);
write_event("CreateClient 0x%x\n", c->w.w);
return c;
}
@ -84,13 +84,37 @@ 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) {
*tc = c->next;
@ -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, XConfigureRequestEvent *e) {
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);
r = gravclient(c, &r);
if((Dx(c->rect) == Dx(screen->rect))
&& (Dy(c->rect) == Dy(screen->rect))) {
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);
restack_view(f->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)
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, XFocusChangeEvent *e) {
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, XFocusChangeEvent *e) {
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 @@ Client *
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 @@ send_client_message(XWindow w, Atom a, long value) {
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 write) {
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 write) {
}
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 @@ set_urgent(Client *c, Bool urgent, Bool write) {
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;
Rectangle
frame_hints(Frame *f, Rectangle r, Align sticky) {
Rectangle or;
Point p;
Client *c;
gravity = NorthWestGravity;
if(c->size.flags & PWinGravity) {
gravity = c->size.win_gravity;
}
c = f->client;
if(c->w.hints == nil)
return r;
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;
}
or = r;
r = frame2client(f, r);
r = sizehint(c->w.hints, r);
r = client2frame(f, r);
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) {
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(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);
}
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);
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));
}

View File

@ -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;
f->r.max.y += surplus % nuncol;
}
yoff = f->rect.max.y;
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 @@ arrange_column(Area *a, Bool dirty) {
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;
if(maxx > screen->r.max.x)
maxx = screen->r.max.x;
dx = a->rect.min.x - r->min.x;
dw = maxx - a->rect.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);

View File

@ -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;

View File

@ -1,5 +1,4 @@
/* Copyright ©2004-2006 Anselm R. Garbe <garbeam at gmail dot com>
* Copyright ©2006-2007 Kris Maglione <fbsdaemon@gmail.com>
/* Copyright ©2006-2007 Kris Maglione <fbsdaemon@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 @@ buttonpress(XEvent *e) {
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 @@ static void
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 @@ leavenotify(XEvent *e) {
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,18 +162,17 @@ focusin(XEvent *e) {
||(ev->detail == NotifyInferior)
||(ev->detail == NotifyAncestor)))
return;
if((ev->mode == NotifyWhileGrabbed)
&& (screen->hasgrab != &c_root))
if((ev->mode == NotifyWhileGrabbed) && (screen->hasgrab != &c_root))
return;
if((w = findwin(e->xany.window))) {
if(w->handler->focusin)
w->handler->focusin(w, ev);
}
else if(ev->window == screen->barwin->w) {
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->mode == NotifyGrab) {
if(ev->window == scr.root.w)
if(XCheckMaskEvent(display, KeyPressMask, &me)) {
@ -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);

View File

@ -66,6 +66,7 @@ Area *new_column(View*, Area *pos, uint w);
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 @@ Bool frame_to_top(Frame *f);
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 @@ void initdisplay();
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 @@ Atom xatom(char*);
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*);

View File

@ -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);
stickycorner = get_sticky(f->r, r);
f->crect = r;
apply_sizehints(c, &f->crect, f->area->floating, True, stickycorner);
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);
f->r = constrain(f->r);
}
pt.x = (Dx(f->rect) - Dx(f->crect)) / 2;
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))

View File

@ -252,6 +252,7 @@ parse_colors(char **buf, int *buflen, CTuple *col) {
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;
}
}

View File

@ -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;

View File

@ -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)
if(pt.y < f->r.max.y)
break;
if(abs(pt.y - f->rect.min.y) < labelh(def.font)) {
pt.y = f->rect.min.y;
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)
if(pt.x < a->r.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;
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->rect.min.y;
frameadjust(fw, pt, OVert, Dy(a->rect));
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));
pt.x = f->area->r.min.x;
fw = framewin(f, pt, OHoriz, Dx(f->area->r));
r = screen->rect;
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 align) {
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);
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->rect)/NCOL;
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 align) {
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 align) {
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 align) {
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, Align align) {
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, Align align) {
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, Align align) {
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, Align align) {
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, Align align) {
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);

View File

@ -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;

View File

@ -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;
a->r.max.x = w;
xoff = a->rect.max.x;
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 *ignore) {
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, uint *next) {
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;

View File

@ -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;
@ -46,6 +51,13 @@ subpt(Point p, Point q) {
return p;
}
Point
mulpt(Point p, Point q) {
p.x *= q.x;
p.y *= q.y;
return p;
}
Point
divpt(Point p, Point q) {
p.x /= q.x;
@ -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, int depth, uint class,
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);
@ -148,13 +163,19 @@ createwindow(Window *parent, Rectangle r, int depth, uint class,
return w;
}
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 @@ void
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);
}

View File

@ -13,6 +13,7 @@ typedef struct Point Point;
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,17 +30,27 @@ struct Rectangle {
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 {
void (*bdown)(Window*, XButtonEvent*);
void (*bup)(Window*, XButtonEvent*);

View File

@ -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 @@ if [ ! -n "$RC" ]; then
fi
if [ -n "$1" ]; then
exec $RC "$@"
exec "$RC" "$@"
else
true
fi

View File

@ -9,11 +9,11 @@ LIBDIR = ${PREFIX}/lib
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 @@ STATIC = -static
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

View File

@ -74,7 +74,7 @@ clean:
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