commit e23ca5ca5924f543150d17c1c45cf7fa5dc26195
parent ea20f48ed0426c9a0ce1de2aadf3f426dd9f12e2
Author: Anselm R. Garbe <garbeam@wmii.de>
Date: Thu, 2 Mar 2006 15:28:55 +0100
proceeded with sendtopage fixes
Diffstat:
7 files changed, 311 insertions(+), 320 deletions(-)
diff --git a/cmd/wm/Makefile b/cmd/wm/Makefile
@@ -9,7 +9,7 @@ LDFLAGS += -L../../liblitz -llitz -L../../libixp -lixp -L../../libcext -lcext
# Solaris
# LDFLAGS += -lsocket
-SRC = area.c bar.c fs.c wm.c kb.c client.c event.c mouse.c page.c column.c
+SRC = area.c bar.c fs.c wm.c kb.c client.c event.c mouse.c page.c
OBJ = ${SRC:.c=.o}
all: wmiiwm
diff --git a/cmd/wm/area.c b/cmd/wm/area.c
@@ -97,13 +97,7 @@ select_area(Area *a, char *arg)
void
sendto_area(Area *to, Client *c)
{
- Area *a = c->area;
-
- cext_array_detach((void **)a->client, c, &a->clientsz);
- a->nclient--;
- if(a->sel >= a->nclient)
- a->sel = 0;
-
+ detach_client_area(c);
attach_client2area(to, c);
focus_client(c);
}
@@ -134,8 +128,8 @@ attach_client2area(Area *a, Client *c)
(void **)a->client, c, sizeof(Client *), &a->clientsz);
a->nclient++;
c->area = a;
- if(p->sel > 0) /* column mode */
- arrange_column(a);
+ if(p->sel > 0) /* area mode */
+ arrange_area(a);
else /* normal mode */
resize_client(c, &c->frame.rect, nil, False);
}
@@ -150,7 +144,7 @@ detach_client_area(Client *c)
a->nclient--;
if(a->sel >= a->nclient)
a->sel = 0;
- if(i) { /* column */
+ if(i) { /* area */
if(a->capacity && (a->nclient < a->capacity)) {
for(++i; i < p->narea; i++) {
Area *tmp = p->area[i];
@@ -171,6 +165,295 @@ detach_client_area(Client *c)
}
}
else
- arrange_column(a);
+ arrange_area(a);
+ }
+}
+
+void
+match_capacity(Area *a)
+{
+ while(a->nclient > a->capacity) {
+ Client *c = a->client[a->nclient - 1];
+ detach_client_area(c);
+ attach_client(c);
+ }
+}
+
+char *
+colmode2str(ColumnMode mode)
+{
+ switch(mode) {
+ case COL_EQUAL: return "equal"; break;
+ case COL_STACK: return "stack"; break;
+ case COL_MAX: return "max"; break;
+ default: break;
+ }
+ return nil;
+}
+
+ColumnMode
+str2colmode(char *arg)
+{
+ if(!strncmp("equal", arg, 6))
+ return COL_EQUAL;
+ if(!strncmp("stack", arg, 6))
+ return COL_STACK;
+ if(!strncmp("max", arg, 4))
+ return COL_MAX;
+ return -1;
+}
+
+static void
+relax_area(Area *a)
+{
+ unsigned int i, yoff, h, w, hdiff, wdiff;
+
+ if(!a->nclient)
+ return;
+
+ /* some relaxing from potential increment gaps */
+ h = w = 0;
+ for(i = 0; i < a->nclient; i++) {
+ Client *c = a->client[i];
+ if(a->mode == COL_MAX) {
+ if(h < c->frame.rect.height)
+ h = c->frame.rect.height;
+ }
+ else
+ h += c->frame.rect.height;
+ if(w < c->frame.rect.width)
+ w = c->frame.rect.width;
+ }
+ wdiff = (a->rect.width - w) / 2;
+
+ /* try to add rest space to all clients if not COL_STACK mode */
+ if(a->mode != COL_STACK) {
+ for(i = 0; (h < a->rect.height) && (i < a->nclient); i++) {
+ Client *c = a->client[i];
+ unsigned int tmp = c->frame.rect.height;
+ c->frame.rect.height += (a->rect.height - h);
+ resize_client(c, &c->frame.rect, 0, True);
+ h += (c->frame.rect.height - tmp);
+ }
+ }
+
+ hdiff = (a->rect.height - h) / a->nclient;
+ yoff = a->rect.y + hdiff / 2;
+ for(i = 0; i < a->nclient; i++) {
+ Client *c = a->client[i];
+ c->frame.rect.x = a->rect.x + wdiff;
+ c->frame.rect.y = yoff;
+ if(a->mode != COL_MAX)
+ yoff = c->frame.rect.y + c->frame.rect.height + hdiff;
+ resize_client(c, &c->frame.rect, 0, False);
+ }
+}
+
+void
+arrange_area(Area *a)
+{
+ unsigned int i, yoff, h;
+
+ if(!a->nclient)
+ return;
+
+ switch(a->mode) {
+ case COL_EQUAL:
+ h = a->rect.height;
+ h /= a->nclient;
+ for(i = 0; i < a->nclient; i++) {
+ Client *c = a->client[i];
+ c->frame.rect = a->rect;
+ c->frame.rect.y += i * h;
+ if(i + 1 < a->nclient)
+ c->frame.rect.height = h;
+ else
+ c->frame.rect.height =
+ a->rect.height - c->frame.rect.y + a->rect.y;
+ resize_client(c, &c->frame.rect, 0, True);
+ }
+ break;
+ case COL_STACK:
+ yoff = a->rect.y;
+ h = a->rect.height - (a->nclient - 1) * bar_height();
+ for(i = 0; i < a->nclient; i++) {
+ Client *c = a->client[i];
+ c->frame.rect = a->rect;
+ c->frame.rect.y = yoff;
+ if(i == a->sel)
+ c->frame.rect.height = h;
+ else
+ c->frame.rect.height = bar_height();
+ yoff += c->frame.rect.height;
+ resize_client(c, &c->frame.rect, 0, True);
+ }
+ break;
+ case COL_MAX:
+ for(i = 0; i < a->nclient; i++) {
+ Client *c = a->client[i];
+ c->frame.rect = a->rect;
+ resize_client(c, &c->frame.rect, 0, True);
+ }
+ break;
+ default:
+ break;
+ }
+
+ relax_area(a);
+}
+
+void
+arrange_page(Page *p, Bool update_areas)
+{
+ unsigned int i;
+ unsigned int width;
+
+ if(p->narea == 1)
+ return;
+
+ width = rect.width / (p->narea - 1);
+ for(i = 1; i < p->narea; i++) {
+ Area *a = p->area[i];
+ if(update_areas) {
+ update_area_geometry(a);
+ a->rect.x = (i - 1) * width;
+ a->rect.width = width;
+ }
+ arrange_area(a);
}
}
+
+static void
+match_horiz(Area *a, XRectangle *r)
+{
+ unsigned int i;
+
+ for(i = 0; i < a->nclient; i++) {
+ Client *c = a->client[i];
+ c->frame.rect.x = r->x;
+ c->frame.rect.width = r->width;
+ resize_client(c, &c->frame.rect, nil, False);
+ }
+}
+
+static void
+drop_resize(Client *c, XRectangle *new)
+{
+ Area *west = nil, *east = nil, *a = c->area;
+ Page *p = a->page;
+ Client *north = nil, *south = nil;
+ unsigned int i;
+
+ for(i = 1; (i < p->narea) && (p->area[i] != a); i++);
+ /* first managed area is indexed 1, thus (i > 1) ? ... */
+ west = (i > 1) ? p->area[i - 1] : nil;
+ east = i + 1 < p->narea ? p->area[i + 1] : nil;
+
+ for(i = 1; (i < a->nclient) && (a->client[i] != c); i++);
+ north = i ? a->client[i - 1] : nil;
+ south = i + 1 < a->nclient ? a->client[i + 1] : nil;
+
+ /* horizontal resize */
+ if(west && (new->x != c->frame.rect.x)) {
+ west->rect.width = new->x - west->rect.x;
+ a->rect.width += c->frame.rect.x - new->x;
+ a->rect.x = new->x;
+ match_horiz(west, &west->rect);
+ match_horiz(a, &a->rect);
+ relax_area(west);
+ }
+ if(east && (new->x + new->width != c->frame.rect.x + c->frame.rect.width)) {
+ east->rect.width -= new->x + new->width - east->rect.x;
+ east->rect.x = new->x + new->width;
+ a->rect.x = new->x;
+ a->rect.width = new->width;
+ match_horiz(a, &a->rect);
+ match_horiz(east, &east->rect);
+ relax_area(east);
+ }
+
+ /* vertical resize */
+ if(north && (new->y != c->frame.rect.y)) {
+ north->frame.rect.height = new->y - north->frame.rect.y;
+ c->frame.rect.height += c->frame.rect.y - new->y;
+ c->frame.rect.y = new->y;
+ resize_client(north, &north->frame.rect, nil, False);
+ resize_client(c, &c->frame.rect, nil, False);
+ }
+ if(south && (new->y + new->height != c->frame.rect.y + c->frame.rect.height)) {
+ south->frame.rect.height -= new->y + new->height - south->frame.rect.y;
+ south->frame.rect.y = new->y + new->height;
+ c->frame.rect.y = new->y;
+ c->frame.rect.height = new->height;
+ resize_client(c, &c->frame.rect, nil, False);
+ resize_client(south, &south->frame.rect, nil, False);
+ }
+ relax_area(a);
+}
+
+static void
+drop_moving(Client *c, XRectangle *new, XPoint * pt)
+{
+ Area *tgt = nil, *src = c->area;
+ Page *p = src->page;
+ unsigned int i;
+
+ if(!pt || src->nclient < 2)
+ return;
+
+ for(i = 1; (i < p->narea) &&
+ !blitz_ispointinrect(pt->x, pt->y, &p->area[i]->rect); i++);
+ if((tgt = ((i < p->narea) ? p->area[i] : nil))) {
+ if(tgt != src) {
+ sendto_area(tgt, c);
+ arrange_area(tgt);
+ }
+ else {
+ for(i = 0; (i < src->nclient) &&
+ !blitz_ispointinrect(pt->x, pt->y, &src->client[i]->frame.rect); i++);
+ if((i < src->nclient) && (c != src->client[i])) {
+ unsigned int j = client2index(c);
+ Client *tmp = src->client[j];
+ src->client[j] = src->client[i];
+ src->client[i] = tmp;
+ arrange_area(src);
+ focus_client(c);
+ }
+ }
+ }
+}
+
+void
+resize_area(Client *c, XRectangle *r, XPoint *pt)
+{
+ if((c->frame.rect.width == r->width)
+ && (c->frame.rect.height == r->height))
+ drop_moving(c, r, pt);
+ else
+ drop_resize(c, r);
+}
+
+Area *
+new_area(Area *old)
+{
+ Page *p = old->page;
+ Client *c = sel_client_of_page(p);
+ Area *a;
+
+ if(!area2index(old) || (old->nclient < 2))
+ return nil;
+
+ a = alloc_area(p);
+ cext_array_detach((void **)old->client, c, &old->clientsz);
+ old->nclient--;
+ if(old->sel == old->nclient)
+ old->sel = 0;
+ a->client = (Client **)cext_array_attach((void **)a->client, c,
+ sizeof(Client *), &a->clientsz);
+ a->nclient++;
+
+ c->area = a;
+ arrange_page(p, True);
+ focus_client(c);
+ return a;
+}
diff --git a/cmd/wm/bar.c b/cmd/wm/bar.c
@@ -49,7 +49,7 @@ update_bar_geometry()
for(i = 0; i < npage; i++)
for(j = 1; j < page[i]->narea; j++) {
update_area_geometry(page[i]->area[j]);
- arrange_column(page[i]->area[j]);
+ arrange_area(page[i]->area[j]);
}
}
diff --git a/cmd/wm/client.c b/cmd/wm/client.c
@@ -115,7 +115,7 @@ focus_client(Client *c)
client_name_event(c);
client_focus_event(c);
if(i > 0 && c->area->mode == COL_STACK)
- arrange_column(c->area);
+ arrange_area(c->area);
}
void
@@ -473,7 +473,7 @@ resize_client(Client *c, XRectangle *r, XPoint *pt, Bool ignore_xcall)
if(area2index(c->area) > 0)
- resize_column(c, r, pt);
+ resize_area(c, r, pt);
else
c->frame.rect = *r;
@@ -599,8 +599,8 @@ sendtoarea_client(Client *c, char *arg) {
arrange_page(p, True);
}
else {
- arrange_column(a);
- arrange_column(to);
+ arrange_area(a);
+ arrange_area(to);
}
}
diff --git a/cmd/wm/column.c b/cmd/wm/column.c
@@ -1,288 +0,0 @@
-/*
- * (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 *
-colmode2str(ColumnMode mode)
-{
- switch(mode) {
- case COL_EQUAL: return "equal"; break;
- case COL_STACK: return "stack"; break;
- case COL_MAX: return "max"; break;
- default: break;
- }
- return nil;
-}
-
-ColumnMode
-str2colmode(char *arg)
-{
- if(!strncmp("equal", arg, 6))
- return COL_EQUAL;
- if(!strncmp("stack", arg, 6))
- return COL_STACK;
- if(!strncmp("max", arg, 4))
- return COL_MAX;
- return -1;
-}
-
-static void
-relax_column(Area *col)
-{
- unsigned int i, yoff, h, w, hdiff, wdiff;
-
- if(!col->nclient)
- return;
-
- /* some relaxing from potential increment gaps */
- h = w = 0;
- for(i = 0; i < col->nclient; i++) {
- Client *c = col->client[i];
- if(col->mode == COL_MAX) {
- if(h < c->frame.rect.height)
- h = c->frame.rect.height;
- }
- else
- h += c->frame.rect.height;
- if(w < c->frame.rect.width)
- w = c->frame.rect.width;
- }
- wdiff = (col->rect.width - w) / 2;
-
- /* try to add rest space to all clients if not COL_STACK mode */
- if(col->mode != COL_STACK) {
- for(i = 0; (h < col->rect.height) && (i < col->nclient); i++) {
- Client *c = col->client[i];
- unsigned int tmp = c->frame.rect.height;
- c->frame.rect.height += (col->rect.height - h);
- resize_client(c, &c->frame.rect, 0, True);
- h += (c->frame.rect.height - tmp);
- }
- }
-
- hdiff = (col->rect.height - h) / col->nclient;
- yoff = col->rect.y + hdiff / 2;
- for(i = 0; i < col->nclient; i++) {
- Client *c = col->client[i];
- c->frame.rect.x = col->rect.x + wdiff;
- c->frame.rect.y = yoff;
- if(col->mode != COL_MAX)
- yoff = c->frame.rect.y + c->frame.rect.height + hdiff;
- resize_client(c, &c->frame.rect, 0, False);
- }
-}
-
-void
-arrange_column(Area *col)
-{
- unsigned int i, yoff, h;
-
- if(!col->nclient)
- return;
-
- switch(col->mode) {
- case COL_EQUAL:
- h = col->rect.height;
- h /= col->nclient;
- for(i = 0; i < col->nclient; i++) {
- Client *c = col->client[i];
- c->frame.rect = col->rect;
- c->frame.rect.y += i * h;
- if(i + 1 < col->nclient)
- c->frame.rect.height = h;
- else
- c->frame.rect.height =
- col->rect.height - c->frame.rect.y + col->rect.y;
- resize_client(c, &c->frame.rect, 0, True);
- }
- break;
- case COL_STACK:
- yoff = col->rect.y;
- h = col->rect.height - (col->nclient - 1) * bar_height();
- for(i = 0; i < col->nclient; i++) {
- Client *c = col->client[i];
- c->frame.rect = col->rect;
- c->frame.rect.y = yoff;
- if(i == col->sel)
- c->frame.rect.height = h;
- else
- c->frame.rect.height = bar_height();
- yoff += c->frame.rect.height;
- resize_client(c, &c->frame.rect, 0, True);
- }
- break;
- case COL_MAX:
- for(i = 0; i < col->nclient; i++) {
- Client *c = col->client[i];
- c->frame.rect = col->rect;
- resize_client(c, &c->frame.rect, 0, True);
- }
- break;
- default:
- break;
- }
-
- relax_column(col);
-}
-
-void
-arrange_page(Page *p, Bool update_colums)
-{
- unsigned int i;
- unsigned int width;
-
- if(p->narea == 1)
- return;
-
- width = rect.width / (p->narea - 1);
- for(i = 1; i < p->narea; i++) {
- Area *a = p->area[i];
- if(update_colums) {
- update_area_geometry(a);
- a->rect.x = (i - 1) * width;
- a->rect.width = width;
- }
- arrange_column(a);
- }
-}
-
-static void
-match_horiz(Area *col, XRectangle *r)
-{
- unsigned int i;
-
- for(i = 0; i < col->nclient; i++) {
- Client *c = col->client[i];
- c->frame.rect.x = r->x;
- c->frame.rect.width = r->width;
- resize_client(c, &c->frame.rect, nil, False);
- }
-}
-
-static void
-drop_resize(Client *c, XRectangle *new)
-{
- Area *west = nil, *east = nil, *col = c->area;
- Page *p = col->page;
- Client *north = nil, *south = nil;
- unsigned int i;
-
- for(i = 1; (i < p->narea) && (p->area[i] != col); i++);
- /* first managed area is indexed 1, thus (i > 1) ? ... */
- west = (i > 1) ? p->area[i - 1] : nil;
- east = i + 1 < p->narea ? p->area[i + 1] : nil;
-
- for(i = 1; (i < col->nclient) && (col->client[i] != c); i++);
- north = i ? col->client[i - 1] : nil;
- south = i + 1 < col->nclient ? col->client[i + 1] : nil;
-
- /* horizontal resize */
- if(west && (new->x != c->frame.rect.x)) {
- west->rect.width = new->x - west->rect.x;
- col->rect.width += c->frame.rect.x - new->x;
- col->rect.x = new->x;
- match_horiz(west, &west->rect);
- match_horiz(col, &col->rect);
- relax_column(west);
- }
- if(east && (new->x + new->width != c->frame.rect.x + c->frame.rect.width)) {
- east->rect.width -= new->x + new->width - east->rect.x;
- east->rect.x = new->x + new->width;
- col->rect.x = new->x;
- col->rect.width = new->width;
- match_horiz(col, &col->rect);
- match_horiz(east, &east->rect);
- relax_column(east);
- }
-
- /* vertical resize */
- if(north && (new->y != c->frame.rect.y)) {
- north->frame.rect.height = new->y - north->frame.rect.y;
- c->frame.rect.height += c->frame.rect.y - new->y;
- c->frame.rect.y = new->y;
- resize_client(north, &north->frame.rect, nil, False);
- resize_client(c, &c->frame.rect, nil, False);
- }
- if(south && (new->y + new->height != c->frame.rect.y + c->frame.rect.height)) {
- south->frame.rect.height -= new->y + new->height - south->frame.rect.y;
- south->frame.rect.y = new->y + new->height;
- c->frame.rect.y = new->y;
- c->frame.rect.height = new->height;
- resize_client(c, &c->frame.rect, nil, False);
- resize_client(south, &south->frame.rect, nil, False);
- }
- relax_column(col);
-}
-
-static void
-drop_moving(Client *c, XRectangle *new, XPoint * pt)
-{
- Area *tgt = nil, *src = c->area;
- Page *p = src->page;
- unsigned int i;
-
- if(!pt || src->nclient < 2)
- return;
-
- for(i = 1; (i < p->narea) &&
- !blitz_ispointinrect(pt->x, pt->y, &p->area[i]->rect); i++);
- if((tgt = ((i < p->narea) ? p->area[i] : nil))) {
- if(tgt != src) {
- sendto_area(tgt, c);
- arrange_column(tgt);
- }
- else {
- for(i = 0; (i < src->nclient) &&
- !blitz_ispointinrect(pt->x, pt->y, &src->client[i]->frame.rect); i++);
- if((i < src->nclient) && (c != src->client[i])) {
- unsigned int j = client2index(c);
- Client *tmp = src->client[j];
- src->client[j] = src->client[i];
- src->client[i] = tmp;
- arrange_column(src);
- focus_client(c);
- }
- }
- }
-}
-
-void
-resize_column(Client *c, XRectangle *r, XPoint *pt)
-{
- if((c->frame.rect.width == r->width)
- && (c->frame.rect.height == r->height))
- drop_moving(c, r, pt);
- else
- drop_resize(c, r);
-}
-
-Area *
-new_column(Area *old)
-{
- Page *p = old->page;
- Client *c = sel_client_of_page(p);
- Area *col;
-
- if(!area2index(old) || (old->nclient < 2))
- return nil;
-
- col = alloc_area(p);
- cext_array_detach((void **)old->client, c, &old->clientsz);
- old->nclient--;
- if(old->sel == old->nclient)
- old->sel = 0;
- col->client = (Client **)cext_array_attach((void **)col->client, c,
- sizeof(Client *), &col->clientsz);
- col->nclient++;
-
- c->area = col;
- arrange_page(p, True);
- focus_client(c);
- return col;
-}
diff --git a/cmd/wm/fs.c b/cmd/wm/fs.c
@@ -340,7 +340,7 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk)
new->type = IXP_QTDIR;
if(!strncmp(wname, "new", 4)) {
if(iswalk) {
- Area *a = new_column(p->area[p->sel]);
+ Area *a = new_area(p->area[p->sel]);
if(!a)
return -1;
new->path = mkqpath(Darea, p->id, a->id, 0);
@@ -1191,7 +1191,7 @@ xwrite(IXPConn *c, Fcall *fcall)
if(err)
return "max value out of range 0x0000..0xffff";
page[i1]->area[i2]->capacity = i;
- /* TODO: detach to many clients/attach */
+ match_capacity(page[i1]->area[i2]);
break;
case Fmode:
{
@@ -1202,9 +1202,9 @@ xwrite(IXPConn *c, Fcall *fcall)
buf[fcall->count] = 0;
mode = str2colmode(buf);
if(mode == -1)
- return "invalid column mode";
+ return "invalid area mode";
page[i1]->area[i2]->mode = mode;
- arrange_column(page[i1]->area[i2]);
+ arrange_area(page[i1]->area[i2]);
}
break;
case Fkey:
diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h
@@ -198,6 +198,13 @@ void select_area(Area *a, char *arg);
void sendto_area(Area *to, Client *c);
void attach_client2area(Area *a, Client *c);
void detach_client_area(Client *c);
+void arrange_page(Page *p, Bool update_area_geometry);
+void arrange_area(Area *a);
+void resize_area(Client *c, XRectangle *r, XPoint *pt);
+Area *new_area(Area *old);
+ColumnMode str2colmode(char *arg);
+char *colmode2str(ColumnMode mode);
+void match_capacity(Area *a);
/* bar.c */
Label *new_label();
@@ -274,17 +281,6 @@ int pid2index(unsigned short id);
void select_page(char *arg);
int page2index(Page *p);
-/* spawn.c */
-void spawn(char *cmd);
-
-/* column.c */
-void arrange_page(Page *p, Bool update_colums);
-void arrange_column(Area *col);
-void resize_column(Client *c, XRectangle *r, XPoint *pt);
-Area *new_column(Area *old);
-ColumnMode str2colmode(char *arg);
-char *colmode2str(ColumnMode mode);
-
/* wm.c */
void scan_wins();
Client *win2client(Window w);