wmii

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

commit 69ddb68f004252c64fb8da7018185dd614045549
parent f5bdd9a03d2698a2a111afb0a60497505736c598
Author: Anselm R. Garbe <garbeam@wmii.de>
Date:   Wed, 12 Apr 2006 10:44:07 +0200

made cmd/wm code more concise


Diffstat:
cmd/wm/Makefile | 3++-
cmd/wm/area.c | 380++++---------------------------------------------------------------------------
cmd/wm/bar.c | 50+++++++++++++++++++++++++-------------------------
cmd/wm/client.c | 67+++++++++++++++++++++++++++++++++++++++----------------------------
cmd/wm/column.c | 328+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
cmd/wm/event.c | 42+++++++++++++++++++++---------------------
cmd/wm/frame.c | 49++++++++++++++++++++++++++++++++++++++++++++++---
cmd/wm/fs.c | 38+++++++++++++++++++-------------------
cmd/wm/kb.c | 292-------------------------------------------------------------------------------
cmd/wm/key.c | 292+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
cmd/wm/mouse.c | 44++++++++++----------------------------------
cmd/wm/rule.c | 6+++---
cmd/wm/view.c | 66+++++++++++++++++++++++++++++++++---------------------------------
cmd/wm/wm.c | 15++-------------
cmd/wm/wm.h | 101++++++++++++++++++++++++++++++++++++++++---------------------------------------
liblitz/blitz.h | 1+
liblitz/geometry.c | 24++++++++++++++++++++++++
17 files changed, 913 insertions(+), 885 deletions(-)

diff --git a/cmd/wm/Makefile b/cmd/wm/Makefile @@ -9,7 +9,8 @@ LDFLAGS += -L../../liblitz -llitz -L../../libixp -lixp -L../../libcext -lcext - # Solaris # LDFLAGS += -lsocket -SRC = area.c bar.c fs.c frame.c wm.c kb.c client.c event.c mouse.c rule.c view.c +SRC = area.c bar.c client.c column.c event.c frame.c fs.c key.c mouse.c \ + rule.c view.c wm.c OBJ = ${SRC:.c=.o} all: wmiiwm diff --git a/cmd/wm/area.c b/cmd/wm/area.c @@ -15,7 +15,7 @@ area2vector(AreaVector *av) } Area * -alloc_area(View *v) +create_area(View *v) { static unsigned short id = 1; Area *a = cext_emallocz(sizeof(Area)); @@ -39,7 +39,7 @@ destroy_area(Area *a) return; if(a->frame.data) free(a->frame.data); - if(v->revert == area2index(a)) + if(v->revert == idx_of_area(a)) v->revert = 0; for(i = 0; i < client.size; i++) if(client.data[i]->revert == a) @@ -51,7 +51,7 @@ destroy_area(Area *a) } int -area2index(Area *a) +idx_of_area(Area *a) { int i; View *v = a->view; @@ -62,7 +62,7 @@ area2index(Area *a) } int -aid2index(View *v, unsigned short id) +idx_of_area_id(View *v, unsigned short id) { int i; for(i = 0; i < v->area.size; i++) @@ -76,7 +76,7 @@ select_area(Area *a, char *arg) { Area *new; View *v = a->view; - int i = area2index(a); + int i = idx_of_area(a); if(i == -1) return; @@ -120,20 +120,14 @@ select_area(Area *a, char *arg) } void -send2area(Area *to, Area *from, Client *c) +send_to_area(Area *to, Area *from, Client *c) { c->revert = from; - detach_fromarea(from, c); - attach_toarea(to, c); + detach_from_area(from, c); + attach_to_area(to, c); focus_client(c); } -static Vector * -frame2vector(FrameVector *fv) -{ - return (Vector *) fv; -} - void place_client(Area *a, Client *c) { @@ -209,24 +203,12 @@ place_client(Area *a, Client *c) } void -attach_toarea(Area *a, Client *c) +attach_to_area(Area *a, Client *c) { - static unsigned short id = 1; - unsigned int aidx = area2index(a); - Frame *f; + unsigned int aidx = idx_of_area(a); + Frame *f = create_frame(a, c); c->floating = !aidx; - f = cext_emallocz(sizeof(Frame)); - f->id = id++; - f->area = a; - f->client = c; - f->rect = c->rect; - f->rect.width += 2 * def.border; - f->rect.height += def.border + bar_height(); - cext_vattach(frame2vector(&c->frame), f); - c->sel = c->frame.size - 1; - cext_vattach(frame2vector(&a->frame),f); - a->sel = a->frame.size - 1; if(aidx) { /* column */ if(a->frame.size > 1) f->rect.height = a->rect.height / (a->frame.size - 1); @@ -239,27 +221,18 @@ attach_toarea(Area *a, Client *c) } void -detach_fromarea(Area *a, Client *c) +detach_from_area(Area *a, Client *c) { - Frame *f = nil; View *v = a->view; int i; for(i = 0; i < c->frame.size; i++) if(c->frame.data[i]->area == a) { - f = c->frame.data[i]; + destroy_frame(c->frame.data[i]); break; } - cext_vdetach(frame2vector(&c->frame), f); - cext_vdetach(frame2vector(&a->frame), f); - free(f); - if(c->sel > 0) - c->sel--; - if(a->sel > 0) - a->sel--; - - i = area2index(a); + i = idx_of_area(a); if(i && a->frame.size) arrange_column(a, False); else { @@ -273,11 +246,11 @@ detach_fromarea(Area *a, Client *c) else if(!i && !a->frame.size) { if(c->trans) { /* focus area of transient, if possible */ - Client *cl = win2client(c->trans); + Client *cl = client_of_win(c->trans); if(cl && cl->frame.size) { a = cl->frame.data[cl->sel]->area; if(a->view == v) - v->sel = area2index(a); + v->sel = idx_of_area(a); } } else if(v->area.data[1]->frame.size) @@ -286,327 +259,8 @@ detach_fromarea(Area *a, Client *c) } } -char * -mode2str(int mode) -{ - switch(mode) { - case Coldefault: return "default"; break; - case Colstack: return "stack"; break; - case Colmax: return "max"; break; - default: break; - } - return nil; -} - -int -str2mode(char *arg) -{ - if(!strncmp("default", arg, 8)) - return Coldefault; - if(!strncmp("stack", arg, 6)) - return Colstack; - if(!strncmp("max", arg, 4)) - return Colmax; - return -1; -} - -static void -relax_area(Area *a) -{ - unsigned int i, yoff, h, hdiff; - Bool fallthrough = False; - - if(!a->frame.size) - return; - - switch(a->mode) { - case Coldefault: - h = a->rect.height; - h /= a->frame.size; - if(h < 2 * bar_height()) - fallthrough = True; - break; - case Colstack: - yoff = a->rect.y; - h = a->rect.height - (a->frame.size - 1) * bar_height(); - if(h < 3 * bar_height()) - fallthrough = True; - break; - default: - break; - } - - if(fallthrough) { - for(i = 0; i < a->frame.size; i++) { - Frame *f = a->frame.data[i]; - f->rect.x = a->rect.x + (a->rect.width - f->rect.width) / 2; - f->rect.y = a->rect.y + (a->rect.height - f->rect.height) / 2; - resize_client(f->client, &f->rect, False); - } - return; - } - - /* some relaxing from potential increment gaps */ - h = 0; - for(i = 0; i < a->frame.size; i++) { - Frame *f = a->frame.data[i]; - if(a->mode == Colmax) { - if(h < f->rect.height) - h = f->rect.height; - } - else - h += f->rect.height; - } - - /* try to add rest space to all clients if not COL_STACK mode */ - if(a->mode != Colstack) { - for(i = 0; (h < a->rect.height) && (i < a->frame.size); i++) { - Frame *f = a->frame.data[i]; - unsigned int tmp = f->rect.height; - f->rect.height += (a->rect.height - h); - resize_client(f->client, &f->rect, True); - h += (f->rect.height - tmp); - } - } - - hdiff = (a->rect.height - h) / a->frame.size; - yoff = a->rect.y + hdiff / 2; - for(i = 0; i < a->frame.size; i++) { - Frame *f = a->frame.data[i]; - f->rect.x = a->rect.x + (a->rect.width - f->rect.width) / 2; - f->rect.y = yoff; - if(a->mode != Colmax) - yoff = f->rect.y + f->rect.height + hdiff; - resize_client(f->client, &f->rect, False); - } -} - -void -arrange_column(Area *a, Bool dirty) -{ - unsigned int i, yoff = a->rect.y, h, dy = 0; - float scale = 1.0; - - if(!a->frame.size) - return; - - switch(a->mode) { - case Coldefault: - h = a->rect.height / a->frame.size; - if(h < (2 * bar_height())) - goto Fallthrough; - if(dirty) { - for(i = 0; i < a->frame.size; i++) - a->frame.data[i]->rect.height = h; - } - for(i = 0; i < a->frame.size; i++) - dy += a->frame.data[i]->rect.height; - scale = (float)a->rect.height / (float)dy; - for(i = 0; i < a->frame.size; i++) { - Frame *f = a->frame.data[i]; - f->rect.x = a->rect.x; - f->rect.y = yoff; - f->rect.width = a->rect.width; - f->rect.height *= scale; - if(i == a->frame.size - 1) - f->rect.height = a->rect.height - f->rect.y + a->rect.y; - yoff += f->rect.height; - resize_client(f->client, &f->rect, True); - } - break; - case Colstack: - h = a->rect.height - (a->frame.size - 1) * bar_height(); - if(h < 3 * bar_height()) - goto Fallthrough; - for(i = 0; i < a->frame.size; i++) { - Frame *f = a->frame.data[i]; - f->rect = a->rect; - f->rect.y = yoff; - if(i == a->sel) - f->rect.height = h; - else - f->rect.height = bar_height(); - yoff += f->rect.height; - resize_client(f->client, &f->rect, True); - } - break; -Fallthrough: - case Colmax: - for(i = 0; i < a->frame.size; i++) { - Frame *f = a->frame.data[i]; - f->rect = a->rect; - resize_client(f->client, &f->rect, True); - } - break; - default: - break; - } - - relax_area(a); -} - -static void -match_horiz(Area *a, XRectangle *r) -{ - unsigned int i; - - for(i = 0; i < a->frame.size; i++) { - Frame *f = a->frame.data[i]; - f->rect.x = r->x; - f->rect.width = r->width; - resize_client(f->client, &f->rect, False); - } -} - - -static void -drop_resize(Frame *f, XRectangle *new) -{ - Area *west = nil, *east = nil, *a = f->area; - View *v = a->view; - Frame *north = nil, *south = nil; - unsigned int i; - unsigned int min_height = 2 * bar_height(); - - for(i = 1; (i < v->area.size) && (v->area.data[i] != a); i++); - /* first managed area is indexed 1, thus (i > 1) ? ... */ - west = (i > 1) ? v->area.data[i - 1] : nil; - east = i + 1 < v->area.size ? v->area.data[i + 1] : nil; - - for(i = 0; (i < a->frame.size) && (a->frame.data[i] != f); i++); - north = i ? a->frame.data[i - 1] : nil; - south = i + 1 < a->frame.size ? a->frame.data[i + 1] : nil; - - /* validate (and trim if necessary) horizontal resize */ - if(new->width < MIN_COLWIDTH) { - if(new->x + new->width == f->rect.x + f->rect.width) - new->x = a->rect.x + a->rect.width - MIN_COLWIDTH; - new->width = MIN_COLWIDTH; - } - if(west && (new->x != f->rect.x)) { - if(new->x < 0 || new->x < (west->rect.x + MIN_COLWIDTH)) { - new->width -= (west->rect.x + MIN_COLWIDTH) - new->x; - new->x = west->rect.x + MIN_COLWIDTH; - } - } else { - new->width += new->x - a->rect.x; - new->x = a->rect.x; - } - if(east && (new->x + new->width != f->rect.x + f->rect.width)) { - if((new->x + new->width) > (east->rect.x + east->rect.width - MIN_COLWIDTH)) - new->width = (east->rect.x + east->rect.width - MIN_COLWIDTH) - new->x; - } else - new->width = (a->rect.x + a->rect.width) - new->x; - if(new->width < MIN_COLWIDTH) - goto AfterHorizontal; - - /* horizontal resize */ - if(west && (new->x != a->rect.x)) { - west->rect.width = new->x - west->rect.x; - a->rect.width += a->rect.x - new->x; - a->rect.x = new->x; - match_horiz(a, &a->rect); - match_horiz(west, &west->rect); - relax_area(west); - } - if(east && (new->x + new->width != a->rect.x + a->rect.width)) { - east->rect.width -= new->x + new->width - east->rect.x; - east->rect.x = new->x + new->width; - a->rect.width = (new->x + new->width) - a->rect.x; - match_horiz(a, &a->rect); - match_horiz(east, &east->rect); - relax_area(east); - } -AfterHorizontal: - - /* skip vertical resize unless the column is in equal mode */ - if(a->mode != Coldefault) - goto AfterVertical; - - /* validate (and trim if necessary) vertical resize */ - if(new->height < min_height) { - if(f->rect.height < min_height - && (new->y == f->rect.y || new->y + new->height == f->rect.y + f->rect.height)) - goto AfterVertical; - if(new->y + new->height == f->rect.y + f->rect.height) - new->y = f->rect.y + f->rect.height - min_height; - new->height = min_height; - } - if(north && (new->y != f->rect.y)) - if(new->y < 0 || new->y < (north->rect.y + min_height)) { - new->height -= (north->rect.y + min_height) - new->y; - new->y = north->rect.y + min_height; - } - if(south && (new->y + new->height != f->rect.y + f->rect.height)) { - if((new->y + new->height) > (south->rect.y + south->rect.height - min_height)) - new->height = (south->rect.y + south->rect.height - min_height) - new->y; - } - if(new->height < min_height) - goto AfterVertical; - - /* vertical resize */ - if(north && (new->y != f->rect.y)) { - north->rect.height = new->y - north->rect.y; - f->rect.height += f->rect.y - new->y; - f->rect.y = new->y; - resize_client(north->client, &north->rect, False); - resize_client(f->client, &f->rect, False); - } - if(south && (new->y + new->height != f->rect.y + f->rect.height)) { - south->rect.height -= new->y + new->height - south->rect.y; - south->rect.y = new->y + new->height; - f->rect.y = new->y; - f->rect.height = new->height; - resize_client(f->client, &f->rect, False); - resize_client(south->client, &south->rect, False); - } -AfterVertical: - - relax_area(a); -} - -static void -drop_moving(Frame *f, XRectangle *new, XPoint * pt) -{ - Area *tgt = nil, *src = f->area; - View *v = src->view; - unsigned int i; - - if(!pt || src->frame.size < 2) - return; - - for(i = 1; (i < v->area.size) && - !blitz_ispointinrect(pt->x, pt->y, &v->area.data[i]->rect); i++); - if((tgt = ((i < v->area.size) ? v->area.data[i] : nil))) { - if(tgt != src) - send2area(tgt, src, f->client); - else { - for(i = 0; (i < src->frame.size) && !blitz_ispointinrect( - pt->x, pt->y, &src->frame.data[i]->rect); i++); - if((i < src->frame.size) && (f != src->frame.data[i])) { - unsigned int j = frame2index(f); - Frame *tmp = src->frame.data[j]; - src->frame.data[j] = src->frame.data[i]; - src->frame.data[i] = tmp; - arrange_column(src, False); - focus_client(f->client); - } - } - } -} - -void -resize_area(Client *c, XRectangle *r, XPoint *pt) -{ - Frame *f = c->frame.data[c->sel]; - if((f->rect.width == r->width) && (f->rect.height == r->height)) - drop_moving(f, r, pt); - else - drop_resize(f, r); -} - Bool -clientofarea(Area *a, Client *c) +is_of_area(Area *a, Client *c) { unsigned int i; for(i = 0; i < a->frame.size; i++) diff --git a/cmd/wm/bar.c b/cmd/wm/bar.c @@ -11,8 +11,8 @@ static int comp_label_intern(const void *l1, const void *l2) { - Label *ll1 = *(Label **)l1; - Label *ll2 = *(Label **)l2; + Bar *ll1 = *(Bar **)l1; + Bar *ll2 = *(Bar **)l2; if(ll1->intern && !ll2->intern) return -1; if(!ll1->intern && ll2->intern) @@ -23,57 +23,57 @@ comp_label_intern(const void *l1, const void *l2) static int comp_label_name(const void *l1, const void *l2) { - Label *ll1 = *(Label **)l1; - Label *ll2 = *(Label **)l2; + Bar *ll1 = *(Bar **)l1; + Bar *ll2 = *(Bar **)l2; return strcmp(ll1->name, ll2->name); } static Vector * -label2vector(LabelVector *lv) +label2vector(BarVector *lv) { return (Vector *) lv; } -Label * -get_label(char *name, Bool intern) +Bar * +create_bar(char *name, Bool intern) { static unsigned int id = 1; - Label *l = name2label(name); + Bar *l = bar_of_name(name); if(l) return l; - l = cext_emallocz(sizeof(Label)); + l = cext_emallocz(sizeof(Bar)); l->id = id++; l->intern = intern; cext_strlcpy(l->name, name, sizeof(l->name)); cext_strlcpy(l->colstr, def.selcolor, sizeof(l->colstr)); l->color = def.sel; cext_vattach(label2vector(&label), l); - qsort(label.data, label.size, sizeof(Label *), comp_label_name); - qsort(label.data, label.size, sizeof(Label *), comp_label_intern); + qsort(label.data, label.size, sizeof(Bar *), comp_label_name); + qsort(label.data, label.size, sizeof(Bar *), comp_label_intern); return l; } void -destroy_label(Label *l) +destroy_bar(Bar *l) { cext_vdetach(label2vector(&label), l); } unsigned int -bar_height() +height_of_bar() { enum { BAR_PADDING = 4 }; return xfont->ascent + xfont->descent + BAR_PADDING; } void -update_bar_geometry() +resize_bar() { unsigned int i, j; brect = rect; - brect.height = bar_height(); + brect.height = height_of_bar(); brect.y = rect.height - brect.height; XMoveResizeWindow(dpy, barwin, brect.x, brect.y, brect.width, brect.height); XSync(dpy, False); @@ -101,7 +101,7 @@ draw_bar() unsigned int i = 0, w = 0; int exp = -1; Draw d = { 0 }; - Label *l = nil; + Bar *l = nil; d.gc = bargc; d.drawable = barpmap; @@ -168,7 +168,7 @@ draw_bar() } int -label2index(Label *l) +idx_of_bar(Bar *l) { int i; for(i = 0; i < label.size; i++) @@ -178,7 +178,7 @@ label2index(Label *l) } int -lid2index(unsigned short id) +idx_of_bar_id(unsigned short id) { int i; for(i = 0; i < label.size; i++) @@ -187,8 +187,8 @@ lid2index(unsigned short id) return -1; } -Label * -name2label(const char *name) +Bar * +bar_of_name(const char *name) { static char buf[256]; unsigned int i; @@ -201,20 +201,20 @@ name2label(const char *name) } void -update_bar_tags() +update_view_bars() { unsigned int i; - Label *l = nil; + Bar *l = nil; for(i = 0; (i < label.size) && label.data[i]->intern; i++) { l = label.data[i]; - if(!name2view(l->name)) { - destroy_label(l); + if(!view_of_name(l->name)) { + destroy_bar(l); i--; } } for(i = 0; i < view.size; i++) { - l = get_label(view.data[i]->name, True); + l = create_bar(view.data[i]->name, True); cext_strlcpy(l->data, view.data[i]->name, sizeof(l->data)); } diff --git a/cmd/wm/client.c b/cmd/wm/client.c @@ -19,7 +19,7 @@ client2vector(ClientVector *cv) } Client * -alloc_client(Window w, XWindowAttributes *wa) +create_client(Window w, XWindowAttributes *wa) { XTextProperty name; Client *c = (Client *) cext_emallocz(sizeof(Client)); @@ -59,7 +59,7 @@ alloc_client(Window w, XWindowAttributes *wa) c->framewin = XCreateWindow(dpy, root, c->rect.x, c->rect.y, c->rect.width + 2 * def.border, - c->rect.height + def.border + bar_height(), 0, + c->rect.height + def.border + height_of_bar(), 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &fwa); @@ -86,10 +86,10 @@ focus_client(Client *c) Client *old = sel_client(); Frame *f = c->frame.data[c->sel]; View *v = f->area->view; - int i = area2index(f->area); + int i = idx_of_area(f->area); v->sel = i; - f->area->sel = frame2index(f); + f->area->sel = idx_of_frame(f); if(old) draw_client(old); restack_view(v); @@ -178,7 +178,7 @@ kill_client(Client * c) } void -update_client_property(Client *c, XPropertyEvent *e) +prop_client(Client *c, XPropertyEvent *e) { XTextProperty name; long msize; @@ -237,7 +237,7 @@ draw_client(Client *c) } d.rect.x = 0; d.rect.y = 0; - d.rect.height = bar_height(); + d.rect.height = height_of_bar(); d.notch = nil; d.align = WEST; @@ -264,7 +264,7 @@ draw_client(Client *c) } void -gravitate(Client *c, Bool invert) +gravitate_client(Client *c, Bool invert) { int dx = 0, dy = 0; int gravity = NorthWestGravity; @@ -279,12 +279,12 @@ gravitate(Client *c, Bool invert) case NorthWestGravity: case NorthGravity: case NorthEastGravity: - dy = bar_height(); + dy = height_of_bar(); break; case EastGravity: case CenterGravity: case WestGravity: - dy = -(c->rect.height / 2) + bar_height(); + dy = -(c->rect.height / 2) + height_of_bar(); break; case SouthEastGravity: case SouthGravity: @@ -330,10 +330,10 @@ manage_client(Client *c) { Client *trans; - if(c->trans && (trans = win2client(c->trans))) + if(c->trans && (trans = client_of_win(c->trans))) cext_strlcpy(c->tags, trans->tags, sizeof(c->tags)); else - match_tags(c); + apply_rules(c); reparent_client(c, c->framewin, c->rect.x, c->rect.y); update_views(c); @@ -354,7 +354,7 @@ destroy_client(Client *c) XSetErrorHandler(dummy_error_handler); for(i = 0; i < view.size; i++) - detach_fromview(view.data[i], c); + detach_from_view(view.data[i], c); unmap_client(c); @@ -415,7 +415,7 @@ match_sizehints(Client *c) if(s->width_inc > 0) c->frame.data[c->sel]->rect.width -= w % s->width_inc; - h = c->frame.data[c->sel]->rect.height - def.border - bar_height() - h; + h = c->frame.data[c->sel]->rect.height - def.border - height_of_bar() - h; if(s->height_inc > 0) c->frame.data[c->sel]->rect.height -= h % s->height_inc; } @@ -427,7 +427,7 @@ resize_client(Client *c, XRectangle *r, Bool ignore_xcall) Frame *f = c->frame.data[c->sel]; f->rect = *r; - if((f->area->mode != Colstack) || (f->area->sel == frame2index(f))) + if((f->area->mode != Colstack) || (f->area->sel == idx_of_frame(f))) match_sizehints(c); if(!ignore_xcall) { @@ -439,11 +439,11 @@ resize_client(Client *c, XRectangle *r, Bool ignore_xcall) f->rect.y, f->rect.width, f->rect.height); } - if((f->area->mode != Colstack) || (f->area->sel == frame2index(f))) { + if((f->area->mode != Colstack) || (f->area->sel == idx_of_frame(f))) { c->rect.x = def.border; - c->rect.y = bar_height(); + c->rect.y = height_of_bar(); c->rect.width = f->rect.width - 2 * def.border; - c->rect.height = f->rect.height - def.border - bar_height(); + c->rect.height = f->rect.height - def.border - height_of_bar(); XMoveResizeWindow(dpy, c->win, c->rect.x, c->rect.y, c->rect.width, c->rect.height); configure_client(c); @@ -455,7 +455,7 @@ select_client(Client *c, char *arg) { Frame *f = c->frame.data[c->sel]; Area *a = f->area; - int i = frame2index(f); + int i = idx_of_frame(f); if(i == -1) return; if(!strncmp(arg, "prev", 5)) { @@ -484,7 +484,7 @@ swap_client(Client *c, char *arg) Frame *f1 = c->frame.data[c->sel], *f2; Area *o, *a = f1->area; View *v = a->view; - int i = area2index(a), j = frame2index(f1); + int i = idx_of_area(a), j = idx_of_frame(f1); if(i == -1 || j == -1) return; @@ -529,19 +529,19 @@ Swaparea: a->frame.data[j] = a->frame.data[i]; a->frame.data[i] = f1; } - if(area2index(a)) + if(idx_of_area(a)) arrange_column(a, False); focus_client(c); } void -send2area_client(Client *c, char *arg) +send_client_to(Client *c, char *arg) { const char *errstr; Frame *f = c->frame.data[c->sel]; Area *to, *a = f->area; View *v = a->view; - int i = area2index(a); + int i = idx_of_area(a); if(i == -1) return; @@ -554,7 +554,7 @@ send2area_client(Client *c, char *arg) else { Area *p, *n; unsigned int j; - p = to = alloc_area(v); + p = to = create_area(v); for(j = 1; j < v->area.size; j++) { n = v->area.data[j]; v->area.data[j] = p; @@ -569,7 +569,7 @@ send2area_client(Client *c, char *arg) if(i < v->area.size - 1) to = v->area.data[i + 1]; else { - to = alloc_area(v); + to = create_area(v); arrange_view(v, True); } } @@ -587,7 +587,7 @@ send2area_client(Client *c, char *arg) return; to = v->area.data[i]; } - send2area(to, a, c); + send_to_area(to, a, c); } void @@ -597,8 +597,8 @@ resize_all_clients() for(i = 0; i < client.size; i++) { Client *c = client.data[i]; if(c->frame.size && c->frame.data[c->sel]->area) { - if(area2index(c->frame.data[c->sel]->area)) - resize_area(c, &c->frame.data[c->sel]->rect, nil); + if(idx_of_area(c->frame.data[c->sel]->area)) + resize_column(c, &c->frame.data[c->sel]->rect, nil); else resize_client(c, &c->frame.data[c->sel]->rect, False); } @@ -622,7 +622,7 @@ focus(Client *c) } int -cid2index(unsigned short id) +idx_of_client_id(unsigned short id) { int i; for(i = 0; i < client.size; i++) @@ -630,3 +630,14 @@ cid2index(unsigned short id) return i; return -1; } + +Client * +client_of_win(Window w) +{ + unsigned int i; + + for(i = 0; (i < client.size) && client.data[i]; i++) + if(client.data[i]->win == w) + return client.data[i]; + return nil; +} diff --git a/cmd/wm/column.c b/cmd/wm/column.c @@ -0,0 +1,328 @@ +/* + * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> + * See LICENSE file for license details. + */ + +#include <stdlib.h> +#include <string.h> + +#include "wm.h" + +char * +str_of_column_mode(int mode) +{ + switch(mode) { + case Coldefault: return "default"; break; + case Colstack: return "stack"; break; + case Colmax: return "max"; break; + default: break; + } + return nil; +} + +int +column_mode_of_str(char *arg) +{ + if(!strncmp("default", arg, 8)) + return Coldefault; + if(!strncmp("stack", arg, 6)) + return Colstack; + if(!strncmp("max", arg, 4)) + return Colmax; + return -1; +} + +static void +relax_column(Area *a) +{ + unsigned int i, yoff, h, hdiff; + Bool fallthrough = False; + + if(!a->frame.size) + return; + + switch(a->mode) { + case Coldefault: + h = a->rect.height; + h /= a->frame.size; + if(h < 2 * height_of_bar()) + fallthrough = True; + break; + case Colstack: + yoff = a->rect.y; + h = a->rect.height - (a->frame.size - 1) * height_of_bar(); + if(h < 3 * height_of_bar()) + fallthrough = True; + break; + default: + break; + } + + if(fallthrough) { + for(i = 0; i < a->frame.size; i++) { + Frame *f = a->frame.data[i]; + f->rect.x = a->rect.x + (a->rect.width - f->rect.width) / 2; + f->rect.y = a->rect.y + (a->rect.height - f->rect.height) / 2; + resize_client(f->client, &f->rect, False); + } + return; + } + + /* some relaxing from potential increment gaps */ + h = 0; + for(i = 0; i < a->frame.size; i++) { + Frame *f = a->frame.data[i]; + if(a->mode == Colmax) { + if(h < f->rect.height) + h = f->rect.height; + } + else + h += f->rect.height; + } + + /* try to add rest space to all clients if not COL_STACK mode */ + if(a->mode != Colstack) { + for(i = 0; (h < a->rect.height) && (i < a->frame.size); i++) { + Frame *f = a->frame.data[i]; + unsigned int tmp = f->rect.height; + f->rect.height += (a->rect.height - h); + resize_client(f->client, &f->rect, True); + h += (f->rect.height - tmp); + } + } + + hdiff = (a->rect.height - h) / a->frame.size; + yoff = a->rect.y + hdiff / 2; + for(i = 0; i < a->frame.size; i++) { + Frame *f = a->frame.data[i]; + f->rect.x = a->rect.x + (a->rect.width - f->rect.width) / 2; + f->rect.y = yoff; + if(a->mode != Colmax) + yoff = f->rect.y + f->rect.height + hdiff; + resize_client(f->client, &f->rect, False); + } +} + +void +arrange_column(Area *a, Bool dirty) +{ + unsigned int i, yoff = a->rect.y, h, dy = 0; + float scale = 1.0; + + if(!a->frame.size) + return; + + switch(a->mode) { + case Coldefault: + h = a->rect.height / a->frame.size; + if(h < (2 * height_of_bar())) + goto Fallthrough; + if(dirty) { + for(i = 0; i < a->frame.size; i++) + a->frame.data[i]->rect.height = h; + } + for(i = 0; i < a->frame.size; i++) + dy += a->frame.data[i]->rect.height; + scale = (float)a->rect.height / (float)dy; + for(i = 0; i < a->frame.size; i++) { + Frame *f = a->frame.data[i]; + f->rect.x = a->rect.x; + f->rect.y = yoff; + f->rect.width = a->rect.width; + f->rect.height *= scale; + if(i == a->frame.size - 1) + f->rect.height = a->rect.height - f->rect.y + a->rect.y; + yoff += f->rect.height; + resize_client(f->client, &f->rect, True); + } + break; + case Colstack: + h = a->rect.height - (a->frame.size - 1) * height_of_bar(); + if(h < 3 * height_of_bar()) + goto Fallthrough; + for(i = 0; i < a->frame.size; i++) { + Frame *f = a->frame.data[i]; + f->rect = a->rect; + f->rect.y = yoff; + if(i == a->sel) + f->rect.height = h; + else + f->rect.height = height_of_bar(); + yoff += f->rect.height; + resize_client(f->client, &f->rect, True); + } + break; +Fallthrough: + case Colmax: + for(i = 0; i < a->frame.size; i++) { + Frame *f = a->frame.data[i]; + f->rect = a->rect; + resize_client(f->client, &f->rect, True); + } + break; + default: + break; + } + + relax_column(a); +} + +static void +match_horiz(Area *a, XRectangle *r) +{ + unsigned int i; + + for(i = 0; i < a->frame.size; i++) { + Frame *f = a->frame.data[i]; + f->rect.x = r->x; + f->rect.width = r->width; + resize_client(f->client, &f->rect, False); + } +} + + +static void +drop_resize(Frame *f, XRectangle *new) +{ + Area *west = nil, *east = nil, *a = f->area; + View *v = a->view; + Frame *north = nil, *south = nil; + unsigned int i; + unsigned int min_height = 2 * height_of_bar(); + + for(i = 1; (i < v->area.size) && (v->area.data[i] != a); i++); + /* first managed area is indexed 1, thus (i > 1) ? ... */ + west = (i > 1) ? v->area.data[i - 1] : nil; + east = i + 1 < v->area.size ? v->area.data[i + 1] : nil; + + for(i = 0; (i < a->frame.size) && (a->frame.data[i] != f); i++); + north = i ? a->frame.data[i - 1] : nil; + south = i + 1 < a->frame.size ? a->frame.data[i + 1] : nil; + + /* validate (and trim if necessary) horizontal resize */ + if(new->width < MIN_COLWIDTH) { + if(new->x + new->width == f->rect.x + f->rect.width) + new->x = a->rect.x + a->rect.width - MIN_COLWIDTH; + new->width = MIN_COLWIDTH; + } + if(west && (new->x != f->rect.x)) { + if(new->x < 0 || new->x < (west->rect.x + MIN_COLWIDTH)) { + new->width -= (west->rect.x + MIN_COLWIDTH) - new->x; + new->x = west->rect.x + MIN_COLWIDTH; + } + } else { + new->width += new->x - a->rect.x; + new->x = a->rect.x; + } + if(east && (new->x + new->width != f->rect.x + f->rect.width)) { + if((new->x + new->width) > (east->rect.x + east->rect.width - MIN_COLWIDTH)) + new->width = (east->rect.x + east->rect.width - MIN_COLWIDTH) - new->x; + } else + new->width = (a->rect.x + a->rect.width) - new->x; + if(new->width < MIN_COLWIDTH) + goto AfterHorizontal; + + /* horizontal resize */ + if(west && (new->x != a->rect.x)) { + west->rect.width = new->x - west->rect.x; + a->rect.width += a->rect.x - new->x; + a->rect.x = new->x; + match_horiz(a, &a->rect); + match_horiz(west, &west->rect); + relax_column(west); + } + if(east && (new->x + new->width != a->rect.x + a->rect.width)) { + east->rect.width -= new->x + new->width - east->rect.x; + east->rect.x = new->x + new->width; + a->rect.width = (new->x + new->width) - a->rect.x; + match_horiz(a, &a->rect); + match_horiz(east, &east->rect); + relax_column(east); + } +AfterHorizontal: + + /* skip vertical resize unless the column is in equal mode */ + if(a->mode != Coldefault) + goto AfterVertical; + + /* validate (and trim if necessary) vertical resize */ + if(new->height < min_height) { + if(f->rect.height < min_height + && (new->y == f->rect.y || new->y + new->height == f->rect.y + f->rect.height)) + goto AfterVertical; + if(new->y + new->height == f->rect.y + f->rect.height) + new->y = f->rect.y + f->rect.height - min_height; + new->height = min_height; + } + if(north && (new->y != f->rect.y)) + if(new->y < 0 || new->y < (north->rect.y + min_height)) { + new->height -= (north->rect.y + min_height) - new->y; + new->y = north->rect.y + min_height; + } + if(south && (new->y + new->height != f->rect.y + f->rect.height)) { + if((new->y + new->height) > (south->rect.y + south->rect.height - min_height)) + new->height = (south->rect.y + south->rect.height - min_height) - new->y; + } + if(new->height < min_height) + goto AfterVertical; + + /* vertical resize */ + if(north && (new->y != f->rect.y)) { + north->rect.height = new->y - north->rect.y; + f->rect.height += f->rect.y - new->y; + f->rect.y = new->y; + resize_client(north->client, &north->rect, False); + resize_client(f->client, &f->rect, False); + } + if(south && (new->y + new->height != f->rect.y + f->rect.height)) { + south->rect.height -= new->y + new->height - south->rect.y; + south->rect.y = new->y + new->height; + f->rect.y = new->y; + f->rect.height = new->height; + resize_client(f->client, &f->rect, False); + resize_client(south->client, &south->rect, False); + } +AfterVertical: + + relax_column(a); +} + +static void +drop_moving(Frame *f, XRectangle *new, XPoint *pt) +{ + Area *tgt = nil, *src = f->area; + View *v = src->view; + unsigned int i; + + if(!pt || src->frame.size < 2) + return; + + for(i = 1; (i < v->area.size) && + !blitz_ispointinrect(pt->x, pt->y, &v->area.data[i]->rect); i++); + if((tgt = ((i < v->area.size) ? v->area.data[i] : nil))) { + if(tgt != src) + send_to_area(tgt, src, f->client); + else { + for(i = 0; (i < src->frame.size) && !blitz_ispointinrect( + pt->x, pt->y, &src->frame.data[i]->rect); i++); + if((i < src->frame.size) && (f != src->frame.data[i])) { + unsigned int j = idx_of_frame(f); + Frame *tmp = src->frame.data[j]; + src->frame.data[j] = src->frame.data[i]; + src->frame.data[i] = tmp; + arrange_column(src, False); + focus_client(f->client); + } + } + } +} + +void +resize_column(Client *c, XRectangle *r, XPoint *pt) +{ + Frame *f = c->frame.data[c->sel]; + if((f->rect.width == r->width) && (f->rect.height == r->height)) + drop_moving(f, r, pt); + else + drop_resize(f, r); +} diff --git a/cmd/wm/event.c b/cmd/wm/event.c @@ -62,32 +62,32 @@ handle_buttonpress(XEvent *e) unsigned int i; for(i = 0; i < label.size; i++) if(blitz_ispointinrect(ev->x, ev->y, &label.data[i]->rect)) { - snprintf(buf, sizeof(buf), "LabelClick %s %d\n", + snprintf(buf, sizeof(buf), "BarClick %s %d\n", label.data[i]->name, ev->button); write_event(buf); return; } } - else if((c = win2clientframe(ev->window))) { + else if((c = frame_of_win(ev->window))) { ev->state &= valid_mask; if((ev->state & Mod1Mask) && (ev->button == Button3)) { if(sel_client() != c) focus(c); else { - Align align = xy2align(&c->rect, ev->x, ev->y); + Align align = blitz_align_of_rect(&c->rect, ev->x, ev->y); if(align != CENTER) - mouse_resize(c, align); + do_mouse_resize(c, align); } } else if(ev->button == Button1) { if(sel_client() != c) focus(c); else - mouse_move(c); + do_mouse_move(c); } if(c->frame.size) { snprintf(buf, sizeof(buf), "ClientClick %d %d\n", - frame2index(c->frame.data[c->sel]) + 1, ev->button); + idx_of_frame(c->frame.data[c->sel]) + 1, ev->button); write_event(buf); } } @@ -100,13 +100,13 @@ handle_configurerequest(XEvent *e) XWindowChanges wc; Client *c; - c = win2client(ev->window); + c = client_of_win(ev->window); ev->value_mask &= ~CWSibling; if(c) { - gravitate(c, True); + gravitate_client(c, True); - if(c->frame.size && (area2index(c->frame.data[c->sel]->area) == 0)) { + if(c->frame.size && (idx_of_area(c->frame.data[c->sel]->area) == 0)) { if(ev->value_mask & CWX) c->rect.x = ev->x; if(ev->value_mask & CWY) @@ -119,15 +119,15 @@ handle_configurerequest(XEvent *e) if(ev->value_mask & CWBorderWidth) c->border = ev->border_width; - gravitate(c, False); + gravitate_client(c, False); if(c->frame.size) { Frame *f = c->frame.data[c->sel]; f->rect.x = wc.x = c->rect.x - def.border; - f->rect.y = wc.y = c->rect.y - bar_height(); + f->rect.y = wc.y = c->rect.y - height_of_bar(); f->rect.width = wc.width = c->rect.width + 2 * def.border; f->rect.height = wc.height = c->rect.height + def.border - + bar_height(); + + height_of_bar(); wc.border_width = 1; wc.sibling = None; wc.stack_mode = ev->detail; @@ -145,8 +145,8 @@ handle_configurerequest(XEvent *e) if(c && c->frame.size) { wc.x = def.border; - wc.y = bar_height(); - if(area2index(c->frame.data[c->sel]->area) > 0) { + wc.y = height_of_bar(); + if(idx_of_area(c->frame.data[c->sel]->area) > 0) { wc.width = c->rect.width; wc.height = c->rect.height; } @@ -167,7 +167,7 @@ handle_destroynotify(XEvent *e) Client *c; XDestroyWindowEvent *ev = &e->xdestroywindow; - if((c = win2client(ev->window))) + if((c = client_of_win(ev->window))) destroy_client(c); } @@ -179,7 +179,7 @@ handle_expose(XEvent *e) if(ev->count == 0) { if(ev->window == barwin) draw_bar(); - else if((c = win2clientframe(ev->window))) + else if((c = frame_of_win(ev->window))) draw_client(c); } } @@ -213,8 +213,8 @@ handle_maprequest(XEvent *e) } /* there're client which send map requests twice */ - if(!win2client(ev->window)) - manage_client(alloc_client(ev->window, &wa)); + if(!client_of_win(ev->window)) + manage_client(create_client(ev->window, &wa)); } static void @@ -226,8 +226,8 @@ handle_propertynotify(XEvent *e) if(ev->state == PropertyDelete) return; /* ignore */ - if((c = win2client(ev->window))) - update_client_property(c, ev); + if((c = client_of_win(ev->window))) + prop_client(c, ev); } static void @@ -236,6 +236,6 @@ handle_unmapnotify(XEvent *e) Client *c; XUnmapEvent *ev = &e->xunmap; - if((c = win2client(ev->window))) + if((c = client_of_win(ev->window))) destroy_client(c); } diff --git a/cmd/wm/frame.c b/cmd/wm/frame.c @@ -3,10 +3,53 @@ * See LICENSE file for license details. */ +#include <stdlib.h> + #include "wm.h" +static Vector * +frame2vector(FrameVector *fv) +{ + return (Vector *) fv; +} + +Frame * +create_frame(Area *a, Client *c) +{ + static unsigned short id = 1; + Frame *f = cext_emallocz(sizeof(Frame)); + + f->id = id++; + f->area = a; + f->client = c; + f->rect = c->rect; + f->rect.width += 2 * def.border; + f->rect.height += def.border + height_of_bar(); + cext_vattach(frame2vector(&c->frame), f); + c->sel = c->frame.size - 1; + cext_vattach(frame2vector(&a->frame),f); + a->sel = a->frame.size - 1; + + return f; +} + +void +destroy_frame(Frame *f) +{ + Client *c = f->client; + Area *a = f->area; + + cext_vdetach(frame2vector(&c->frame), f); + cext_vdetach(frame2vector(&a->frame), f); + free(f); + if(c->sel > 0) + c->sel--; + if(a->sel > 0) + a->sel--; +} + int -frid2index(Area *a, unsigned short id) +idx_of_frame_id(Area *a, unsigned short id) { int i; for(i = 0; i < a->frame.size; i++) @@ -16,7 +59,7 @@ frid2index(Area *a, unsigned short id) } int -frame2index(Frame *f) +idx_of_frame(Frame *f) { int i; Area *a = f->area; @@ -27,7 +70,7 @@ frame2index(Frame *f) } Client * -win2clientframe(Window w) +frame_of_win(Window w) { unsigned int i; for(i = 0; (i < client.size) && client.data[i]; i++) diff --git a/cmd/wm/fs.c b/cmd/wm/fs.c @@ -116,19 +116,19 @@ decode_qpath(Qid *qid, unsigned char *type, int *i1, int *i2, int *i3) if(i1id) { if(qid->dir_type == FsDGclient || qid->dir_type == FsDclients) - *i1 = cid2index(i1id); + *i1 = idx_of_client_id(i1id); else { switch(*type) { case FsFdata: case FsFcolors: - case FsDlabel: *i1 = lid2index(i1id); break; - default: *i1 = vid2index(i1id); break; + case FsDlabel: *i1 = idx_of_bar_id(i1id); break; + default: *i1 = idx_of_view_id(i1id); break; } } if(i2id && (*i1 != -1)) { - *i2 = aid2index(view.data[*i1], i2id); + *i2 = idx_of_area_id(view.data[*i1], i2id); if(i3id && (*i2 != -1)) - *i3 = frid2index(view.data[*i1]->area.data[*i2], i3id); + *i3 = idx_of_frame_id(view.data[*i1]->area.data[*i2], i3id); } } } @@ -271,7 +271,7 @@ name2type(char *name, unsigned char dir_type) return FsFdata; if(!strncmp(name, "mode", 5)) return FsFmode; - if((dir_type == FsDbar) && name2label(name)) + if((dir_type == FsDbar) && bar_of_name(name)) return FsDlabel; if(!strncmp(name, "sel", 4)) goto dyndir; @@ -366,8 +366,8 @@ mkqid(Qid *dir, char *wname, Qid *new) if(dir_type != FsDbar) return -1; { - Label *l; - if(!(l = name2label(wname))) + Bar *l; + if(!(l = bar_of_name(wname))) return -1; new->type = IXP_QTDIR; new->path = mkqpath(FsDlabel, l->id, 0, 0); @@ -528,7 +528,7 @@ type2stat(Stat *stat, char *wname, Qid *dir) IXP_DMREAD | IXP_DMWRITE); break; case FsFmode: - return mkstat(stat, dir, wname, strlen(mode2str(view.data[dir_i1]->area.data[dir_i2]->mode)), + return mkstat(stat, dir, wname, strlen(str_of_column_mode(view.data[dir_i1]->area.data[dir_i2]->mode)), IXP_DMREAD | IXP_DMWRITE); break; case FsFcolors: @@ -625,7 +625,7 @@ xcreate(IXPConn *c, Fcall *fcall) type = qpath_type(m->qid.path); switch(type) { case FsDbar: - get_label(fcall->name, False); + create_bar(fcall->name, False); break; default: return Enofile; @@ -675,11 +675,11 @@ xremove(IXPConn *c, Fcall *fcall) switch(type) { case FsDlabel: { - Label *l = label.data[i1]; + Bar *l = label.data[i1]; if(l->intern) return Enoperm; /* now detach the label */ - destroy_label(l); + destroy_bar(l); free(l); draw_bar(); } @@ -1095,7 +1095,7 @@ xread(IXPConn *c, Fcall *fcall) case FsFmode: if(!i2) return Enofile; - snprintf(buf, sizeof(buf), "%s", mode2str(view.data[i1]->area.data[i2]->mode)); + snprintf(buf, sizeof(buf), "%s", str_of_column_mode(view.data[i1]->area.data[i2]->mode)); fcall->count = strlen(buf); memcpy(p, buf, fcall->count); break; @@ -1164,8 +1164,8 @@ xwrite(IXPConn *c, Fcall *fcall) srv.running = 0; else if(!strncmp(buf, "view ", 5)) select_view(&buf[5]); - else if(!strncmp(buf, "retag", 6)) - retag(); + else if(!strncmp(buf, "reapply_rules", 6)) + reapply_rules(); else return Enocommand; break; @@ -1186,7 +1186,7 @@ xwrite(IXPConn *c, Fcall *fcall) if(!strncmp(buf, "kill", 5)) kill_client(f->client); else if(!strncmp(buf, "sendto ", 7)) - send2area_client(f->client, &buf[7]); + send_client_to(f->client, &buf[7]); else if(!strncmp(buf, "swap ", 5)) swap_client(f->client, &buf[5]); break; @@ -1233,7 +1233,7 @@ xwrite(IXPConn *c, Fcall *fcall) f = view.data[i1]->area.data[i2]->frame.data[i3]; blitz_strtorect(&rect, &f->rect, buf); if(i2) - resize_area(f->client, &f->rect, nil); + resize_column(f->client, &f->rect, nil); else resize_client(f->client, &f->rect, False); } @@ -1308,7 +1308,7 @@ xwrite(IXPConn *c, Fcall *fcall) memcpy(def.font, fcall->data, fcall->count); XFreeFont(dpy, xfont); xfont = blitz_getfont(dpy, def.font); - update_bar_geometry(); + resize_bar(); break; case FsFmode: if(!i2) @@ -1317,7 +1317,7 @@ xwrite(IXPConn *c, Fcall *fcall) return Ebadvalue; memcpy(buf, fcall->data, fcall->count); buf[fcall->count] = 0; - if((i = str2mode(buf)) == -1) + if((i = column_mode_of_str(buf)) == -1) return Ebadvalue; view.data[i1]->area.data[i2]->mode = i; arrange_column(view.data[i1]->area.data[i2], True); diff --git a/cmd/wm/kb.c b/cmd/wm/kb.c @@ -1,292 +0,0 @@ -/* - * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> - * See LICENSE file for license details. - */ - -#include <string.h> -#include <stdlib.h> -#include <X11/Xlib.h> -#include <X11/keysym.h> - -#include "wm.h" - -void -init_lock_modifiers() -{ - XModifierKeymap *modmap; - KeyCode num_lock; - static int masks[] = { - ShiftMask, LockMask, ControlMask, Mod1Mask, - Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask - }; - int i; - - num_lock_mask = 0; - modmap = XGetModifierMapping(dpy); - num_lock = XKeysymToKeycode(dpy, XStringToKeysym("Num_Lock")); - - if(modmap && modmap->max_keypermod > 0) { - int max = (sizeof(masks) / sizeof(int)) * modmap->max_keypermod; - for(i = 0; i < max; i++) - if(num_lock && (modmap->modifiermap[i] == num_lock)) - num_lock_mask = masks[i / modmap->max_keypermod]; - } - XFreeModifiermap(modmap); - - valid_mask = 255 & ~(num_lock_mask | LockMask); -} - -static unsigned long -blitz_strtomod(char *val) -{ - unsigned long mod = 0; - if (strstr(val, "Shift")) - mod |= ShiftMask; - if (strstr(val, "Control")) - mod |= ControlMask; - if (strstr(val, "Mod1")) - mod |= Mod1Mask; - if (strstr(val, "Mod2")) - mod |= Mod2Mask; - if (strstr(val, "Mod3")) - mod |= Mod3Mask; - if (strstr(val, "Mod4")) - mod |= Mod4Mask; - if (strstr(val, "Mod5")) - mod |= Mod5Mask; - return mod; -} - -static void -grab_key(Key *k) -{ - XGrabKey(dpy, k->key, k->mod, root, - True, GrabModeAsync, GrabModeAsync); - if(num_lock_mask) { - XGrabKey(dpy, k->key, k->mod | num_lock_mask, root, - True, GrabModeAsync, GrabModeAsync); - XGrabKey(dpy, k->key, k->mod | num_lock_mask | LockMask, root, - True, GrabModeAsync, GrabModeAsync); - } - XSync(dpy, False); -} - -static void -ungrab_key(Key *k) -{ - XUngrabKey(dpy, k->key, k->mod, root); - if(num_lock_mask) { - XUngrabKey(dpy, k->key, k->mod | num_lock_mask, root); - XUngrabKey(dpy, k->key, k->mod | num_lock_mask | LockMask, root); - } - XSync(dpy, False); -} - -static Key * -name2key(const char *name) -{ - unsigned int i; - for(i = 0; i < key.size; i++) - if(!strncmp(key.data[i]->name, name, sizeof(key.data[i]->name))) - return key.data[i]; - return nil; -} - -static Vector * -key2vector(KeyVector *kv) -{ - return (Vector *) kv; -} - -static Key * -get_key(const char *name) -{ - char buf[128]; - char *seq[8]; - char *kstr; - unsigned int i, toks; - static unsigned short id = 1; - Key *k = 0, *r = 0; - - if((k = name2key(name))) { - ungrab_key(k); - return k; - } - - cext_strlcpy(buf, name, sizeof(buf)); - toks = cext_tokenize(seq, 8, buf, ','); - - for(i = 0; i < toks; i++) { - if(!k) - r = k = cext_emallocz(sizeof(Key)); - else { - k->next = cext_emallocz(sizeof(Key)); - k = k->next; - } - cext_strlcpy(k->name, name, sizeof(k->name)); - kstr = strrchr(seq[i], '-'); - if(kstr) - kstr++; - else - kstr = seq[i]; - k->key = XKeysymToKeycode(dpy, XStringToKeysym(kstr)); - k->mod = blitz_strtomod(seq[i]); - } - if(r) { - r->id = id++; - cext_vattach(key2vector(&key), r); - } - - return r; -} - -void -destroy_key(Key *k) -{ - Key *n; - cext_vdetach(key2vector(&key), k); - while(k) { - n = k->next; - free(k); - k = n; - } -} - -static void -next_keystroke(unsigned long *mod, KeyCode *keyCode) -{ - XEvent e; - KeySym sym; - *mod = 0; - do { - XMaskEvent(dpy, KeyPressMask, &e); - *mod |= e.xkey.state & valid_mask; - *keyCode = (KeyCode) e.xkey.keycode; - sym = XKeycodeToKeysym(dpy, e.xkey.keycode, 0); - } while(IsModifierKey(sym)); -} - -static void -emulate_key_press(unsigned long mod, KeyCode key) -{ - XEvent e; - Window client_win; - int revert; - - XGetInputFocus(dpy, &client_win, &revert); - - e.xkey.type = KeyPress; - e.xkey.time = CurrentTime; - e.xkey.window = client_win; - e.xkey.display = dpy; - e.xkey.state = mod; - e.xkey.keycode = key; - XSendEvent(dpy, client_win, True, KeyPressMask, &e); - e.xkey.type = KeyRelease; - XSendEvent(dpy, client_win, True, KeyReleaseMask, &e); - XSync(dpy, False); -} - -static KeyVector -match_keys(KeyVector kv, unsigned long mod, KeyCode keycode, Bool seq) -{ - KeyVector result = {0}; - unsigned int i = 0; - for(i = 0; i < kv.size; i++) { - Key *k = kv.data[i]; - if(seq) - k = k->next; - if(k && (k->mod == mod) && (k->key == keycode)) - cext_vattach(key2vector(&result), k); - } - return result; -} - -static void -handle_key_seq(Window w, KeyVector done) -{ - unsigned long mod; - KeyCode key; - KeyVector found = {0}; - char buf[128]; - - next_keystroke(&mod, &key); - - found = match_keys(done, mod, key, True); - if((done.data[0]->mod == mod) && (done.data[0]->key == key)) - emulate_key_press(mod, key); /* double key */ - else { - switch(found.size) { - case 0: - XBell(dpy, 0); - break; /* grabbed but not found */ - case 1: - if(!found.data[0]->next) { - snprintf(buf, sizeof(buf), "Key %s\n", found.data[0]->name); - write_event(buf); - break; - } - default: - handle_key_seq(w, found); - break; - } - } - free(found.data); -} - -void -handle_key(Window w, unsigned long mod, KeyCode keycode) -{ - char buf[128]; - KeyVector found = match_keys(key, mod, keycode, False); - switch(found.size) { - case 0: - XBell(dpy, 0); - break; /* grabbed but not found */ - case 1: - if(!found.data[0]->next) { - snprintf(buf, sizeof(buf), "Key %s\n", found.data[0]->name); - write_event(buf); - break; - } - default: - XGrabKeyboard(dpy, w, True, GrabModeAsync, GrabModeAsync, CurrentTime); - handle_key_seq(w, found); - XUngrabKeyboard(dpy, CurrentTime); - XSync(dpy, False); - break; - } - free(found.data); -} - -void -update_keys() -{ - Key *k; - char *l, *p; - - init_lock_modifiers(); - - while(key.size) { - ungrab_key(key.data[0]); - destroy_key(key.data[0]); - } - - for(l = p = def.keys; p && *p;) { - if(*p == '\n') { - *p = 0; - if((k = get_key(l))) - grab_key(k); - *p = '\n'; - l = ++p; - } - else - p++; - } - if(l < p && strlen(l)) { - if((k = get_key(l))) - grab_key(k); - } - - XSync(dpy, False); -} diff --git a/cmd/wm/key.c b/cmd/wm/key.c @@ -0,0 +1,292 @@ +/* + * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> + * See LICENSE file for license details. + */ + +#include <string.h> +#include <stdlib.h> +#include <X11/Xlib.h> +#include <X11/keysym.h> + +#include "wm.h" + +void +init_lock_keys() +{ + XModifierKeymap *modmap; + KeyCode num_lock; + static int masks[] = { + ShiftMask, LockMask, ControlMask, Mod1Mask, + Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask + }; + int i; + + num_lock_mask = 0; + modmap = XGetModifierMapping(dpy); + num_lock = XKeysymToKeycode(dpy, XStringToKeysym("Num_Lock")); + + if(modmap && modmap->max_keypermod > 0) { + int max = (sizeof(masks) / sizeof(int)) * modmap->max_keypermod; + for(i = 0; i < max; i++) + if(num_lock && (modmap->modifiermap[i] == num_lock)) + num_lock_mask = masks[i / modmap->max_keypermod]; + } + XFreeModifiermap(modmap); + + valid_mask = 255 & ~(num_lock_mask | LockMask); +} + +static unsigned long +blitz_strtomod(char *val) +{ + unsigned long mod = 0; + if (strstr(val, "Shift")) + mod |= ShiftMask; + if (strstr(val, "Control")) + mod |= ControlMask; + if (strstr(val, "Mod1")) + mod |= Mod1Mask; + if (strstr(val, "Mod2")) + mod |= Mod2Mask; + if (strstr(val, "Mod3")) + mod |= Mod3Mask; + if (strstr(val, "Mod4")) + mod |= Mod4Mask; + if (strstr(val, "Mod5")) + mod |= Mod5Mask; + return mod; +} + +static void +grab_key(Key *k) +{ + XGrabKey(dpy, k->key, k->mod, root, + True, GrabModeAsync, GrabModeAsync); + if(num_lock_mask) { + XGrabKey(dpy, k->key, k->mod | num_lock_mask, root, + True, GrabModeAsync, GrabModeAsync); + XGrabKey(dpy, k->key, k->mod | num_lock_mask | LockMask, root, + True, GrabModeAsync, GrabModeAsync); + } + XSync(dpy, False); +} + +static void +ungrab_key(Key *k) +{ + XUngrabKey(dpy, k->key, k->mod, root); + if(num_lock_mask) { + XUngrabKey(dpy, k->key, k->mod | num_lock_mask, root); + XUngrabKey(dpy, k->key, k->mod | num_lock_mask | LockMask, root); + } + XSync(dpy, False); +} + +static Key * +name2key(const char *name) +{ + unsigned int i; + for(i = 0; i < key.size; i++) + if(!strncmp(key.data[i]->name, name, sizeof(key.data[i]->name))) + return key.data[i]; + return nil; +} + +static Vector * +key2vector(KeyVector *kv) +{ + return (Vector *) kv; +} + +static Key * +get_key(const char *name) +{ + char buf[128]; + char *seq[8]; + char *kstr; + unsigned int i, toks; + static unsigned short id = 1; + Key *k = 0, *r = 0; + + if((k = name2key(name))) { + ungrab_key(k); + return k; + } + + cext_strlcpy(buf, name, sizeof(buf)); + toks = cext_tokenize(seq, 8, buf, ','); + + for(i = 0; i < toks; i++) { + if(!k) + r = k = cext_emallocz(sizeof(Key)); + else { + k->next = cext_emallocz(sizeof(Key)); + k = k->next; + } + cext_strlcpy(k->name, name, sizeof(k->name)); + kstr = strrchr(seq[i], '-'); + if(kstr) + kstr++; + else + kstr = seq[i]; + k->key = XKeysymToKeycode(dpy, XStringToKeysym(kstr)); + k->mod = blitz_strtomod(seq[i]); + } + if(r) { + r->id = id++; + cext_vattach(key2vector(&key), r); + } + + return r; +} + +void +destroy_key(Key *k) +{ + Key *n; + cext_vdetach(key2vector(&key), k); + while(k) { + n = k->next; + free(k); + k = n; + } +} + +static void +next_keystroke(unsigned long *mod, KeyCode *keyCode) +{ + XEvent e; + KeySym sym; + *mod = 0; + do { + XMaskEvent(dpy, KeyPressMask, &e); + *mod |= e.xkey.state & valid_mask; + *keyCode = (KeyCode) e.xkey.keycode; + sym = XKeycodeToKeysym(dpy, e.xkey.keycode, 0); + } while(IsModifierKey(sym)); +} + +static void +emulate_key_press(unsigned long mod, KeyCode key) +{ + XEvent e; + Window client_win; + int revert; + + XGetInputFocus(dpy, &client_win, &revert); + + e.xkey.type = KeyPress; + e.xkey.time = CurrentTime; + e.xkey.window = client_win; + e.xkey.display = dpy; + e.xkey.state = mod; + e.xkey.keycode = key; + XSendEvent(dpy, client_win, True, KeyPressMask, &e); + e.xkey.type = KeyRelease; + XSendEvent(dpy, client_win, True, KeyReleaseMask, &e); + XSync(dpy, False); +} + +static KeyVector +match_keys(KeyVector kv, unsigned long mod, KeyCode keycode, Bool seq) +{ + KeyVector result = {0}; + unsigned int i = 0; + for(i = 0; i < kv.size; i++) { + Key *k = kv.data[i]; + if(seq) + k = k->next; + if(k && (k->mod == mod) && (k->key == keycode)) + cext_vattach(key2vector(&result), k); + } + return result; +} + +static void +handle_key_seq(Window w, KeyVector done) +{ + unsigned long mod; + KeyCode key; + KeyVector found = {0}; + char buf[128]; + + next_keystroke(&mod, &key); + + found = match_keys(done, mod, key, True); + if((done.data[0]->mod == mod) && (done.data[0]->key == key)) + emulate_key_press(mod, key); /* double key */ + else { + switch(found.size) { + case 0: + XBell(dpy, 0); + break; /* grabbed but not found */ + case 1: + if(!found.data[0]->next) { + snprintf(buf, sizeof(buf), "Key %s\n", found.data[0]->name); + write_event(buf); + break; + } + default: + handle_key_seq(w, found); + break; + } + } + free(found.data); +} + +void +handle_key(Window w, unsigned long mod, KeyCode keycode) +{ + char buf[128]; + KeyVector found = match_keys(key, mod, keycode, False); + switch(found.size) { + case 0: + XBell(dpy, 0); + break; /* grabbed but not found */ + case 1: + if(!found.data[0]->next) { + snprintf(buf, sizeof(buf), "Key %s\n", found.data[0]->name); + write_event(buf); + break; + } + default: + XGrabKeyboard(dpy, w, True, GrabModeAsync, GrabModeAsync, CurrentTime); + handle_key_seq(w, found); + XUngrabKeyboard(dpy, CurrentTime); + XSync(dpy, False); + break; + } + free(found.data); +} + +void +update_keys() +{ + Key *k; + char *l, *p; + + init_lock_keys(); + + while(key.size) { + ungrab_key(key.data[0]); + destroy_key(key.data[0]); + } + + for(l = p = def.keys; p && *p;) { + if(*p == '\n') { + *p = 0; + if((k = get_key(l))) + grab_key(k); + *p = '\n'; + l = ++p; + } + else + p++; + } + if(l < p && strlen(l)) { + if((k = get_key(l))) + grab_key(k); + } + + XSync(dpy, False); +} diff --git a/cmd/wm/mouse.c b/cmd/wm/mouse.c @@ -9,30 +9,6 @@ #include "wm.h" -Align -xy2align(XRectangle *rect, int x, int y) -{ - int w = x <= rect->x + rect->width / 2; - int n = y <= rect->y + rect->height / 2; - int e = x > rect->x + rect->width / 2; - int s = y > rect->y + rect->height / 2; - int nw = w && n; - int ne = e && n; - int sw = w && s; - int se = e && s; - - if(nw) - return NWEST; - else if(ne) - return NEAST; - else if(se) - return SEAST; - else if(sw) - return SWEST; - - return CENTER; -} - static int check_vert_match(XRectangle *r, XRectangle *neighbor) { @@ -223,7 +199,7 @@ draw_pseudo_border(XRectangle * r) } void -mouse_move(Client *c) +do_mouse_move(Client *c) { int px = 0, py = 0, wex, wey, ex, ey, first = 1, i; Window dummy; @@ -233,8 +209,8 @@ mouse_move(Client *c) int snaph = rect.height * def.snap / 1000; unsigned int num; unsigned int dmask; - XRectangle *rects = rectangles(c->frame.data[c->sel]->area->view, - area2index(c->frame.data[c->sel]->area) == 0, &num); + XRectangle *rects = rects_of_view(c->frame.data[c->sel]->area->view, + idx_of_area(c->frame.data[c->sel]->area) == 0, &num); XRectangle frect = c->frame.data[c->sel]->rect; XPoint pt; @@ -259,8 +235,8 @@ mouse_move(Client *c) case ButtonRelease: if(!first) { draw_pseudo_border(&frect); - if(area2index(c->frame.data[c->sel]->area)) - resize_area(c, &frect, &pt); + if(idx_of_area(c->frame.data[c->sel]->area)) + resize_column(c, &frect, &pt); else resize_client(c, &frect, False); } @@ -465,7 +441,7 @@ snap_resize(XRectangle * r, XRectangle * o, Align align, } void -mouse_resize(Client *c, Align align) +do_mouse_resize(Client *c, Align align) { int px = 0, py = 0, i, ox, oy, first = 1; Window dummy; @@ -475,8 +451,8 @@ mouse_resize(Client *c, Align align) int snaph = rect.height * def.snap / 1000; unsigned int dmask; unsigned int num; - XRectangle *rects = rectangles(c->frame.data[c->sel]->area->view, - area2index(c->frame.data[c->sel]->area) == 0, &num); + XRectangle *rects = rects_of_view(c->frame.data[c->sel]->area->view, + idx_of_area(c->frame.data[c->sel]->area) == 0, &num); XRectangle frect = c->frame.data[c->sel]->rect; XRectangle origin = frect; @@ -501,8 +477,8 @@ mouse_resize(Client *c, Align align) draw_pseudo_border(&frect); pt.x = px; pt.y = py; - if(area2index(c->frame.data[c->sel]->area)) - resize_area(c, &frect, &pt); + if(idx_of_area(c->frame.data[c->sel]->area)) + resize_column(c, &frect, &pt); else resize_client(c, &frect, False); } diff --git a/cmd/wm/rule.c b/cmd/wm/rule.c @@ -131,7 +131,7 @@ match(Client *c, const char *prop) } void -match_tags(Client *c) +apply_rules(Client *c) { if(!def.rules) goto Fallback; @@ -144,10 +144,10 @@ Fallback: } void -retag() +reapply_rules() { unsigned int i; for(i = 0; i < client.size; i++) - match_tags(client.data[i]); + apply_rules(client.data[i]); update_views(); } diff --git a/cmd/wm/view.c b/cmd/wm/view.c @@ -15,15 +15,15 @@ view2vector(ViewVector *vv) } View * -alloc_view(char *name) +create_view(char *name) { static unsigned short id = 1; View *v = cext_emallocz(sizeof(View)); v->id = id++; cext_strlcpy(v->name, name, sizeof(v->name)); - alloc_area(v); - alloc_area(v); + create_area(v); + create_area(v); sel = view.size; cext_vattach(view2vector(&view), v); return v; @@ -44,7 +44,7 @@ destroy_view(View *v) } int -view2index(View *v) +idx_of_view(View *v) { int i; for(i = 0; i < view.size; i++) @@ -72,7 +72,7 @@ focus_view(View *v) unsigned int i; XGrabServer(dpy); - sel = view2index(v); + sel = idx_of_view(v); update_frame_selectors(v); @@ -92,13 +92,13 @@ focus_view(View *v) XMoveWindow(dpy, client.data[i]->framewin, 2 * rect.width + f->rect.x, f->rect.y); } - update_bar_tags(); + update_view_bars(); XSync(dpy, False); XUngrabServer(dpy); } XRectangle * -rectangles(View *v, Bool isfloat, unsigned int *num) +rects_of_view(View *v, Bool isfloat, unsigned int *num) { XRectangle *result = nil; unsigned int i; @@ -129,7 +129,7 @@ rectangles(View *v, Bool isfloat, unsigned int *num) } int -vid2index(unsigned short id) +idx_of_view_id(unsigned short id) { int i; for(i = 0; i < view.size; i++) @@ -139,7 +139,7 @@ vid2index(unsigned short id) } View * -name2view(char *name) +view_of_name(char *name) { unsigned int i; @@ -150,15 +150,15 @@ name2view(char *name) return nil; } -View * +static View * get_view(char *name) { - View *v = name2view(name); - return v ? v : alloc_view(name); + View *v = view_of_name(name); + return v ? v : create_view(name); } static Bool -isempty(View *v) +is_empty(View *v) { unsigned int i; for(i = 0; i < v->area.size; i++) @@ -170,41 +170,41 @@ isempty(View *v) void select_view(char *arg) { - View *v = name2view(arg); + View *v = view_of_name(arg); if(!v) return; focus_view(v); } static Bool -isclientof(View *v, Client *c) +is_of_view(View *v, Client *c) { unsigned int i; for(i = 0; i < v->area.size; i++) - if(clientofarea(v->area.data[i], c)) + if(is_of_area(v->area.data[i], c)) return True; return False; } void -detach_fromview(View *v, Client *c) +detach_from_view(View *v, Client *c) { unsigned int i; for(i = 0; i < v->area.size; i++) { - if(clientofarea(v->area.data[i], c)) { - detach_fromarea(v->area.data[i], c); + if(is_of_area(v->area.data[i], c)) { + detach_from_area(v->area.data[i], c); XMoveWindow(dpy, c->framewin, 2 * rect.width, 0); } } } void -attach_toview(View *v, Client *c) +attach_to_view(View *v, Client *c) { Area *a; - if(isclientof(v, c)) + if(is_of_view(v, c)) return; if(c->trans || c->floating) @@ -212,7 +212,7 @@ attach_toview(View *v, Client *c) else a = v->area.data[v->sel]; - attach_toarea(a, c); + attach_to_area(a, c); map_client(c); XMapWindow(dpy, c->framewin); } @@ -313,7 +313,7 @@ update_client_views(Client *c) } static Bool -isviewof(Client *c, View *v) +is_view_of(Client *c, View *v) { unsigned int i; for(i = 0; i < c->view.size; i++) @@ -323,11 +323,11 @@ isviewof(Client *c, View *v) } static View * -emptyview() +next_empty_view() { unsigned int i; for(i = 0; i < view.size; i++) - if(isempty(view.data[i])) + if(is_empty(view.data[i])) return view.data[i]; return nil; } @@ -345,19 +345,19 @@ update_views() Client *c = client.data[i]; for(j = 0; j < view.size; j++) { if(strstr(c->tags, "*")) - attach_toview(view.data[j], c); - else if(isviewof(c, view.data[j])) { - if(!isclientof(view.data[j], c)) - attach_toview(view.data[j], c); + attach_to_view(view.data[j], c); + else if(is_view_of(c, view.data[j])) { + if(!is_of_view(view.data[j], c)) + attach_to_view(view.data[j], c); } else { - if(isclientof(view.data[j], c)) - detach_fromview(view.data[j], c); + if(is_of_view(view.data[j], c)) + detach_from_view(view.data[j], c); } } } - while((v = emptyview())) { + while((v = next_empty_view())) { if(v == old) old = nil; destroy_view(v); @@ -368,5 +368,5 @@ update_views() else if(view.size) focus_view(view.data[sel]); else - update_bar_tags(); + update_view_bars(); } diff --git a/cmd/wm/wm.c b/cmd/wm/wm.c @@ -28,17 +28,6 @@ usage() exit(1); } -Client * -win2client(Window w) -{ - unsigned int i; - - for(i = 0; (i < client.size) && client.data[i]; i++) - if(client.data[i]->win == w) - return client.data[i]; - return nil; -} - void scan_wins() { @@ -55,7 +44,7 @@ scan_wins() if(wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) continue; if(wa.map_state == IsViewable) - manage_client(alloc_client(wins[i], &wa)); + manage_client(create_client(wins[i], &wa)); } } if(wins) @@ -311,7 +300,7 @@ main(int argc, char *argv[]) init_atoms(); init_cursors(); xfont = blitz_getfont(dpy, def.font); - init_lock_modifiers(); + init_lock_keys(); init_screen(); wa.event_mask = SubstructureRedirectMask; diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h @@ -134,7 +134,7 @@ typedef struct { Color color; XRectangle rect; Bool intern; -} Label; +} Bar; /* default values */ typedef struct { @@ -154,14 +154,14 @@ typedef struct { /* global variables */ VECTOR(ClientVector, Client *); VECTOR(KeyVector, Key *); -VECTOR(LabelVector, Label *); +VECTOR(BarVector, Bar *); /* global variables */ ViewVector view; unsigned int sel; ClientVector client; KeyVector key; -LabelVector label; +BarVector label; Display *dpy; int screen; Window root; @@ -181,61 +181,66 @@ unsigned int valid_mask; unsigned int num_lock_mask; /* area.c */ -Area *alloc_area(View *t); +Area *create_area(View *t); void destroy_area(Area *a); -int area2index(Area *a); -int aid2index(View *t, unsigned short id); +int idx_of_area(Area *a); +int idx_of_area_id(View *t, unsigned short id); void select_area(Area *a, char *arg); -void send2area(Area *to, Area *from, Client *c); -void attach_toarea(Area *a, Client *c); -void detach_fromarea(Area *a, Client *c); -void arrange_column(Area *a, Bool dirty); -void resize_area(Client *c, XRectangle *r, XPoint *pt); -int str2mode(char *arg); -char *mode2str(int mode); -Bool clientofarea(Area *a, Client *c); +void send_to_area(Area *to, Area *from, Client *c); +void attach_to_area(Area *a, Client *c); +void detach_from_area(Area *a, Client *c); +Bool is_of_area(Area *a, Client *c); /* bar.c */ -Label *get_label(char *name, Bool intern); -void destroy_label(Label *l); +Bar *create_bar(char *name, Bool intern); +void destroy_bar(Bar *b); void draw_bar(); -int lid2index(unsigned short id); -void update_bar_geometry(); -unsigned int bar_height(); -Label *name2label(const char *name); -int label2index(Label *l); -void update_bar_tags(); +int idx_of_bar_id(unsigned short id); +void resize_bar(); +unsigned int height_of_bar(); +Bar *bar_of_name(const char *name); +int idx_of_bar(Bar *l); +void update_view_bars(); /* client.c */ -Client *alloc_client(Window w, XWindowAttributes *wa); +Client *create_client(Window w, XWindowAttributes *wa); +void destroy_client(Client *c); void configure_client(Client *c); -void update_client_property(Client *c, XPropertyEvent *e); +void prop_client(Client *c, XPropertyEvent *e); void kill_client(Client *c); void draw_client(Client *client); -void gravitate(Client *c, Bool invert); +void gravitate_client(Client *c, Bool invert); void unmap_client(Client *c); void map_client(Client *c); void reparent_client(Client *c, Window w, int x, int y); void manage_client(Client *c); -void destroy_client(Client *c); -Client *sel_client(); void focus_client(Client *c); +void focus(Client *c); void resize_client(Client *c, XRectangle *r, Bool ignore_xcall); void select_client(Client *c, char *arg); -void send2area_client(Client *c, char *arg); +void send_client_to(Client *c, char *arg); void resize_all_clients(); -void focus(Client *c); -int cid2index(unsigned short id); void swap_client(Client *c, char *arg); +Client *sel_client(); +int idx_of_client_id(unsigned short id); +Client *client_of_win(Window w); + +/* column.c */ +void arrange_column(Area *a, Bool dirty); +void resize_column(Client *c, XRectangle *r, XPoint *pt); +int column_mode_of_str(char *arg); +char *str_of_column_mode(int mode); /* event.c */ void init_x_event_handler(); void check_x_event(IXPConn *c); /* frame.c */ -int frid2index(Area *a, unsigned short id); -int frame2index(Frame *f); -Client *win2clientframe(Window w); +Frame *create_frame(Area *a, Client *c); +void destroy_frame(Frame *f); +int idx_of_frame_id(Area *a, unsigned short id); +int idx_of_frame(Frame *f); +Client *frame_of_win(Window w); /* fs.c */ unsigned long long mkqpath(unsigned char type, unsigned short pg, @@ -243,44 +248,40 @@ unsigned long long mkqpath(unsigned char type, unsigned short pg, void write_event(char *event); void new_ixp_conn(IXPConn *c); -/* kb.c */ +/* key.c */ void handle_key(Window w, unsigned long mod, KeyCode keycode); void update_keys(); -void init_lock_modifiers(); +void init_lock_keys(); /* mouse.c */ -void mouse_resize(Client *c, Align align); -void mouse_move(Client *c); -Align xy2align(XRectangle *rect, int x, int y); -void drop_move(Client *c, XRectangle *new, XPoint *pt); +void do_mouse_resize(Client *c, Align align); +void do_mouse_move(Client *c); void grab_mouse(Window w, unsigned long mod, unsigned int button); void ungrab_mouse(Window w, unsigned long mod, unsigned int button); /* rule.c */ void update_rules(); -void match_tags(Client *c); +void apply_rules(Client *c); +void reapply_rules(); /* view.c */ void arrange_view(View *v, Bool dirty); -View *alloc_view(char *name); +View *create_view(char *name); void focus_view(View *v); -XRectangle *rectangles(View *v, Bool isfloat, unsigned int *num); -int vid2index(unsigned short id); +XRectangle *rects_of_view(View *v, Bool isfloat, unsigned int *num); +int idx_of_view_id(unsigned short id); void select_view(char *arg); -int view2index(View *v); -void detach_fromview(View *v, Client *c); -void attach_toview(View *v, Client *c); +int idx_of_view(View *v); +void detach_from_view(View *v, Client *c); +void attach_to_view(View *v, Client *c); Client *sel_client_of_view(View *v); void restack_view(View *v); -View *name2view(char *name); +View *view_of_name(char *name); void destroy_view(View *v); -View *get_view(char *name); void update_views(); -void retag(); /* wm.c */ void scan_wins(); -Client *win2client(Window w); int win_proto(Window w); int win_state(Window w); int wmii_error_handler(Display *dpy, XErrorEvent *error); diff --git a/liblitz/blitz.h b/liblitz/blitz.h @@ -38,6 +38,7 @@ void blitz_drawlabel(Display *dpy, Draw *r); void blitz_drawborder(Display *dpy, Draw *r); /* geometry.c */ +Align blitz_align_of_rect(XRectangle *rect, int x, int y); int blitz_strtoalign(Align *result, char *val); int blitz_strtorect(XRectangle *root, XRectangle *r, char *val); Bool blitz_ispointinrect(int x, int y, XRectangle *r); diff --git a/liblitz/geometry.c b/liblitz/geometry.c @@ -10,6 +10,30 @@ #include "blitz.h" +Align +blitz_align_of_rect(XRectangle *rect, int x, int y) +{ + int w = x <= rect->x + rect->width / 2; + int n = y <= rect->y + rect->height / 2; + int e = x > rect->x + rect->width / 2; + int s = y > rect->y + rect->height / 2; + int nw = w && n; + int ne = e && n; + int sw = w && s; + int se = e && s; + + if(nw) + return NWEST; + else if(ne) + return NEAST; + else if(se) + return SEAST; + else if(sw) + return SWEST; + + return CENTER; +} + int blitz_strtoalign(Align *result, char *val) { /*