commit 8ece4071aefdaaa810227669fbbbfd38b5a44b03
parent eb09a51b8bc39159abf4c7ec0ae5ea7cbc44a64e
Author: garbeam <garbeam@mmv.wmii.de>
Date: Fri, 16 Dec 2005 03:59:27 +0200
removing container, not finished yet, fixed a bunch of other nasty bugs reported so far
Diffstat:
15 files changed, 758 insertions(+), 887 deletions(-)
diff --git a/cmd/wm/area.c b/cmd/wm/area.c
@@ -9,84 +9,55 @@
#include "wm.h"
-static void handle_after_write_area(IXPServer * s, File * f);
+static void handle_after_write_area(IXPServer *s, File *file);
Area *alloc_area(Page *p, char *layout)
{
char buf[MAX_BUF];
Area *a = (Area *) cext_emallocz(sizeof(Area));
- size_t id = cext_sizeof_container(&p->areas);
a->page = p;
- snprintf(buf, MAX_BUF, "/%s/layout/%d", p->file[P_PREFIX]->name, id);
+ snprintf(buf, MAX_BUF, "/%s/layout/%s", p->file[P_PREFIX]->name, layout);
a->file[A_PREFIX] = ixp_create(ixps, buf);
- snprintf(buf, MAX_BUF, "/%s/layout/%d/frame", p->file[P_PREFIX]->name, id);
+ snprintf(buf, MAX_BUF, "/%s/layout/%s/frame", p->file[P_PREFIX]->name, layout);
a->file[A_FRAME_PREFIX] = ixp_create(ixps, buf);
- snprintf(buf, MAX_BUF, "/%s/layout/%d/frame/sel", p->file[P_PREFIX]->name, id);
+ snprintf(buf, MAX_BUF, "/%s/layout/%s/frame/sel", p->file[P_PREFIX]->name, layout);
a->file[A_SEL_FRAME] = ixp_create(ixps, buf);
a->file[A_SEL_FRAME]->bind = 1;
- snprintf(buf, MAX_BUF, "/%s/layout/%d/ctl", p->file[P_PREFIX]->name, id);
+ snprintf(buf, MAX_BUF, "/%s/layout/%s/ctl", p->file[P_PREFIX]->name, layout);
a->file[A_CTL] = ixp_create(ixps, buf);
a->file[A_CTL]->after_write = handle_after_write_area;
- snprintf(buf, MAX_BUF, "/%s/layout/%d/name", p->file[P_PREFIX]->name, id);
+ snprintf(buf, MAX_BUF, "/%s/layout/%s/name", p->file[P_PREFIX]->name, layout);
a->file[A_LAYOUT] = wmii_create_ixpfile(ixps, buf, layout);
a->file[A_LAYOUT]->after_write = handle_after_write_area;
- a->layout = get_layout(layout);
- a->layout->init(a);
- cext_attach_item(&p->areas, a);
- cext_attach_item(areas, a);
+ a->layout = match_layout(layout);
+ a->layout->init(a, nil);
p->file[P_SEL_AREA]->content = a->file[A_PREFIX]->content;
return a;
}
void destroy_area(Area *a)
{
- Client *c;
a->layout->deinit(a);
- while ((c = cext_stack_get_top_item(&a->clients))) {
- cext_detach_item(&a->clients, c);
- cext_attach_item(detached, c);
- }
ixp_remove_file(ixps, a->file[A_PREFIX]);
- cext_detach_item(areas, a);
free(a);
}
-void sel_area(Area *a)
-{
- Page *p = a->page;
- Frame *f;
- cext_stack_top_item(&p->areas, a);
- p->file[P_SEL_AREA]->content = a->file[A_PREFIX]->content;
- if ((f = get_sel_frame_of_area(a)))
- a->layout->select(f, False);
-}
-
-static void iter_hide_area(void *item, void *aux)
-{
- XUnmapWindow(dpy, ((Frame *)item)->win);
-}
-
void hide_area(Area * a)
{
- cext_list_iterate(a->layout->get_frames(a), nil, iter_hide_area);
-}
-
-static void iter_show_area(void *item, void *aux)
-{
- XMapWindow(dpy, ((Frame *)item)->win);
-}
-
-void show_area(Area * a)
-{
- cext_list_iterate(a->layout->get_frames(a), nil, iter_show_area);
+ Frame *f;
+ for (f = a->layout->frames(a); f; f = f->next)
+ XUnmapWindow(dpy, f->win);
}
-Area *get_sel_area()
+void show_area(Area *a, Bool raise)
{
- Page *p = get_sel_page();
-
- return p ? cext_stack_get_top_item(&p->areas) : nil;
+ Frame *f;
+ for (f = a->layout->frames(a); f; f = f->next)
+ if (raise)
+ XMapRaised(dpy, f->win);
+ else
+ XMapWindow(dpy, f->win);
}
void attach_frame_to_area(Area *a, Frame *f)
@@ -101,29 +72,25 @@ void detach_frame_from_area(Frame *f) {
f->area = 0;
}
-static void iter_after_write_area(void *item, void *aux)
-{
- Area *a = item;
- File *file = aux;
- if (file == a->file[A_CTL]) {
- run_action(file, a, a->layout->get_actions(a));
- return;
- }
- if (file == a->file[A_LAYOUT]) {
- Layout *l = get_layout(file->content);
- if (l) {
- a->layout->deinit(a);
- a->layout = l;
- a->layout->init(a);
- invoke_wm_event(def[WM_EVENT_PAGE_UPDATE]);
+static void handle_after_write_area(IXPServer *s, File *file) {
+ Page *p;
+ for (p = pages; p; p = p->next) {
+ if (file == p->managed->file[A_CTL]) {
+ run_action(file, p->managed, p->managed->layout->actions(p->managed));
+ return;
+ }
+ else if (file == p->floating->file[A_CTL]) {
+ run_action(file, p->floating, p->floating->layout->actions(p->floating));
+ return;
+ }
+ else if (file == p->managed->file[A_LAYOUT]) {
+ Layout *l = match_layout(file->content);
+ if (l) {
+ Client *clients = p->managed->layout->deinit(p->managed);
+ p->managed->layout = l;
+ p->managed->layout->init(p->managed, clients);
+ invoke_wm_event(def[WM_EVENT_PAGE_UPDATE]);
+ }
}
- return;
}
}
-
-static void handle_after_write_area(IXPServer *s, File *f) {
- cext_list_iterate(areas, f, iter_after_write_area);
-}
-
-
-
diff --git a/cmd/wm/client.c b/cmd/wm/client.c
@@ -25,16 +25,15 @@ Client *alloc_client(Window w)
c->file[C_NAME] = wmii_create_ixpfile(ixps, buf, (char *)name.value);
free(name.value);
id++;
- cext_attach_item(clients, c);
return c;
}
-void sel_client(Client * c)
+void focus_client(Client * c)
{
Frame *f = 0;
/* sel client */
f = c->frame;
- cext_stack_top_item(&f->clients, c);
+ f->sel = c;
f->file[F_SEL_CLIENT]->content = c->file[C_PREFIX]->content;
XRaiseWindow(dpy, c->win);
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
@@ -161,7 +160,7 @@ void handle_client_property(Client *c, XPropertyEvent *e)
}
free(name.value);
if (c->frame)
- draw_client(c, nil);
+ draw_client(c);
invoke_wm_event(def[WM_EVENT_CLIENT_UPDATE]);
break;
case XA_WM_TRANSIENT_FOR:
@@ -178,43 +177,38 @@ void handle_client_property(Client *c, XPropertyEvent *e)
void destroy_client(Client * c)
{
- cext_detach_item(detached, c);
- cext_detach_item(clients, c);
+ detach_detached(c);
ixp_remove_file(ixps, c->file[C_PREFIX]);
free(c);
}
/* speed reasoned function for client property change */
-void draw_client(void *item, void *aux)
+void draw_client(Client *client)
{
- Client *c = item;
- Frame *f = c->frame;
- unsigned int tw, tabh = tab_height(f);
- size_t size;
- int i;
+ Frame *f = client->frame;
+ unsigned int i = 0, tw, tabh = tab_height(f);
Draw d = { 0 };
+ Client *c;
if (!tabh)
return;
- size = cext_sizeof_container(&f->clients);
- tw = f->rect.width;
- if (size)
- tw /= size;
- i = cext_list_get_item_index(&f->clients, c);
+ tw = f->rect.width / f->nclients;
+ for (c = f->clients; c && c != client; c = c->next)
+ i++;
d.drawable = f->win;
d.gc = f->gc;
d.rect.x = i * tw;
d.rect.y = 0;
d.rect.width = tw;
- if (i && (i == size - 1))
+ if (i && (i == f->nclients - 1))
d.rect.width = f->rect.width - d.rect.x;
d.rect.height = tabh;
d.data = c->file[C_NAME]->content;
d.font = font;
- if ((f == get_sel_frame()) && (c == get_sel_client())) {
+ if ((f == sel_frame()) && (c == f->sel)) {
d.bg = blitz_loadcolor(dpy, screen_num, f->file[F_SEL_BG_COLOR]->content);
d.fg = blitz_loadcolor(dpy, screen_num, f->file[F_SEL_FG_COLOR]->content);
d.border = blitz_loadcolor(dpy, screen_num, f->file[F_SEL_BORDER_COLOR]->content);
@@ -229,7 +223,9 @@ void draw_client(void *item, void *aux)
void draw_clients(Frame * f)
{
- cext_list_iterate(&f->clients, 0, draw_client);
+ Client *c;
+ for (c = f->clients; c; c = c->next)
+ draw_client(c);
}
void gravitate(Client * c, unsigned int tabh, unsigned int bw, int invert)
@@ -295,36 +291,66 @@ void gravitate(Client * c, unsigned int tabh, unsigned int bw, int invert)
void attach_client(Client * c)
{
Area *a = 0;
- if (!cext_sizeof_container(pages))
- alloc_page();
+ Page *p = pages;
+ if (!p)
+ p = alloc_page();
/* transient stuff */
- a = get_sel_area();
+ a = p->sel;
if (c && c->trans) {
Client *t = win_to_client(c->trans);
if (t && t->frame)
- a = cext_list_get_item(&t->frame->area->page->areas, 0);
+ a = p->floating;
}
- cext_attach_item(&a->clients, c);
a->layout->attach(a, c);
invoke_wm_event(def[WM_EVENT_PAGE_UPDATE]);
}
void detach_client(Client *c, Bool unmap) {
- Page *p;
Frame *f = c->frame;
Area *a = f ? f->area : nil;
if (a) {
a->layout->detach(a, c, unmap);
- cext_detach_item(&a->clients, c);
}
if (c->destroyed)
destroy_client(c);
- if ((p = get_sel_page()))
- sel_page(p);
+ if (selpage)
+ focus_page(selpage);
+}
+
+Client *sel_client()
+{
+ Frame *f = sel_frame();
+ return f ? f->sel : nil;
+}
+
+Client *clientat(Client *clients, size_t idx)
+{
+ size_t i = 0;
+ Client *c = clients;
+ for (; c && i != idx ; c = c->next) i++;
+ return c;
+}
+
+void detach_detached(Client *c)
+{
+ if (detached == c) {
+ if (c->next)
+ c->next->prev = nil;
+ detached = c->next;
+ }
+ else {
+ if (c->next)
+ c->next->prev = c->prev;
+ c->prev->next = c->next;
+ }
+ ndetached--;
}
-Client *get_sel_client()
+void attach_detached(Client *c)
{
- Frame *f = get_sel_frame();
- return f ? cext_stack_get_top_item(&f->clients) : nil;
+ c->prev = nil;
+ c->next = detached;
+ if (detached)
+ detached->prev = c;
+ detached = c;
}
diff --git a/cmd/wm/event.c b/cmd/wm/event.c
@@ -116,10 +116,9 @@ static void handle_configurerequest(XEvent * e)
if (f) {
Page *p = f->area->page;
- if (cext_list_get_item_index(&p->areas, f->area)) {
- Area *a = cext_list_get_item(&p->areas, 0);
+ if (f->area == p->managed) {
f->area->layout->detach(f->area, c, False);
- a->layout->attach(a, c);
+ p->floating->layout->attach(p->floating, c);
f = c->frame;
}
bw = border_width(f);
@@ -274,7 +273,7 @@ static void handle_enternotify(XEvent * e)
c = win_to_client(ev->window);
if (c && c->frame) {
sel_area(c->frame->area);
- c->frame->area->layout->select(c->frame, False);
+ c->frame->area->layout->focus(c->frame, False);
}
}
diff --git a/cmd/wm/frame.c b/cmd/wm/frame.c
@@ -11,8 +11,8 @@
#include "wm.h"
static void select_client(void *obj, char *arg);
-static void handle_after_write_frame(IXPServer * s, File * f);
-static void handle_before_read_frame(IXPServer * s, File * f);
+static void handle_after_write_frame(IXPServer *s, File *file);
+static void handle_before_read_frame(IXPServer *s, File *file);
/* action table for /frame/?/ namespace */
Action frame_acttbl[] = {
@@ -93,26 +93,26 @@ Frame *alloc_frame(XRectangle * r)
XDefineCursor(dpy, f->win, f->cursor);
f->gc = XCreateGC(dpy, f->win, 0, 0);
XSync(dpy, False);
- cext_attach_item(frames, f);
return f;
}
-static int comp_frame_win(void *pattern, void *frame)
-{
- Window w = *(Window *)pattern;
- Frame *f = frame;
-
- return w == f->win;
-}
-
Frame *win_to_frame(Window w)
{
- return cext_find_item(frames, &w, comp_frame_win);
+ Page *p;
+ for (p = pages; p; p = p->next) {
+ Frame *f;
+ for (f = p->managed->layout->frames(p->managed); f; f = f->next)
+ if (f->win == w)
+ return f;
+ for (f = p->floating->layout->frames(p->floating); f; f = f->next)
+ if (f->win == w)
+ return f;
+ }
+ return nil;
}
void destroy_frame(Frame * f)
{
- cext_detach_item(frames, f);
XFreeGC(dpy, f->gc);
XDestroyWindow(dpy, f->win);
ixp_remove_file(ixps, f->file[F_PREFIX]);
@@ -133,32 +133,9 @@ unsigned int border_width(Frame * f)
return 0;
}
-typedef struct {
- unsigned int tabh;
- unsigned int bw;
-} Twouint;
-
-static void iter_resize_client(void *item, void *aux)
-{
- Client *c = item;
- Twouint *v = aux;
- c->rect.x = v->bw;
- c->rect.y = v->tabh ? v->tabh : v->bw;
- c->rect.width = c->frame->rect.width - 2 * v->bw;
- c->rect.height = c->frame->rect.height - v->bw - (v->tabh ? v->tabh : v->bw);
- XMoveResizeWindow(dpy, c->win, c->rect.x, c->rect.y, c->rect.width, c->rect.height);
- configure_client(c);
-}
-
-static void resize_clients(Frame * f, int tabh, int bw)
-{
- Twouint aux = { tabh, bw };
- cext_list_iterate(&f->clients, &aux, iter_resize_client);
-}
-
static void check_dimensions(Frame * f, unsigned int tabh, unsigned int bw)
{
- Client *c = get_sel_client();
+ Client *c = sel_client();
if (!c)
return;
@@ -182,7 +159,7 @@ static void check_dimensions(Frame * f, unsigned int tabh, unsigned int bw)
static void resize_incremental(Frame * f, unsigned int tabh, unsigned int bw)
{
- Client *c = get_sel_client();
+ Client *c = f->sel;
if (!c)
return;
/* increment stuff, see chapter 4.1.2.3 of the ICCCM Manual */
@@ -211,6 +188,7 @@ void resize_frame(Frame * f, XRectangle * r, XPoint * pt)
Area *a = f->area;
unsigned int tabh = tab_height(f);
unsigned int bw = border_width(f);
+ Client *c;
a->layout->resize(f, r, pt);
@@ -221,7 +199,15 @@ void resize_frame(Frame * f, XRectangle * r, XPoint * pt)
resize_incremental(f, tabh, bw);
XMoveResizeWindow(dpy, f->win, f->rect.x, f->rect.y, f->rect.width, f->rect.height);
- resize_clients(f, (tabh ? tabh : bw), bw);
+
+ for (c = f->clients; c; c = c->next) {
+ c->rect.x = bw;
+ c->rect.y = tabh ? tabh : bw;
+ c->rect.width = c->frame->rect.width - 2 * bw;
+ c->rect.height = c->frame->rect.height - bw - (tabh ? tabh : bw);
+ XMoveResizeWindow(dpy, c->win, c->rect.x, c->rect.y, c->rect.width, c->rect.height);
+ configure_client(c);
+ }
}
/**
@@ -253,7 +239,7 @@ void draw_frame(Frame *f)
d.gc = f->gc;
/* define ground plate (i = 0) */
- if (f == get_sel_frame()) {
+ if (f == sel_frame()) {
d.bg = blitz_loadcolor(dpy, screen_num, f->file[F_SEL_BG_COLOR]->content);
d.fg = blitz_loadcolor(dpy, screen_num, f->file[F_SEL_FG_COLOR]->content);
d.border = blitz_loadcolor(dpy, screen_num, f->file[F_SEL_BORDER_COLOR]->content);
@@ -275,59 +261,88 @@ void draw_frame(Frame *f)
void handle_frame_buttonpress(XButtonEvent *e, Frame *f)
{
Align align;
- size_t size = cext_sizeof_container(&f->clients);
- int bindex, cindex = e->x / (f->rect.width / size);
- /*fprintf(stderr, "%d (x) / %d (w) / %d (size) = %d (#c)\n", e->x, f->rect.width, size, cindex);*/
- /*sel_client(cext_list_get_item(&f->clients, cindex));*/
- cext_stack_top_item(&f->clients, cext_list_get_item(&f->clients, cindex));
+ int bindex, cindex = e->x / (f->rect.width / f->nclients);
+ f->sel = clientat(f->clients, cindex);
if (e->button == Button1) {
align = cursor_to_align(f->cursor);
if (align == CENTER)
mouse_move(f);
else
mouse_resize(f, align);
- f->area->layout->select(f, False);
+ f->area->layout->focus(f, False);
return;
}
- f->area->layout->select(f, False);
+ f->area->layout->focus(f, False);
bindex = F_EVENT_B2PRESS - 2 + e->button;
/* frame mouse handling */
if (f->file[bindex]->content)
wmii_spawn(dpy, f->file[bindex]->content);
}
-void attach_client_to_frame(Frame *f, Client *c)
+void attach_client_to_frame(Frame *f, Client *client)
{
+ Client *c;
wmii_move_ixpfile(c->file[C_PREFIX], f->file[F_CLIENT_PREFIX]);
- f->file[F_SEL_CLIENT]->content = c->file[C_PREFIX]->content;
- cext_attach_item(&f->clients, c);
- c->frame = f;
+ f->file[F_SEL_CLIENT]->content = client->file[C_PREFIX]->content;
+ for (c = f->clients; c && c->next; c = c->next);
+ if (!c) {
+ f->clients = client;
+ client->prev = client->next = nil;
+ }
+ else {
+ client->prev = c;
+ client->next = nil;
+ c->next = client;
+ }
+ f->sel = client;
+ client->frame = f;
resize_frame(f, &f->rect, 0);
- reparent_client(c, f->win, c->rect.x, c->rect.y);
- show_client(c);
- sel_client(c);
+ reparent_client(client, f->win, client->rect.x, client->rect.y);
+ show_client(client);
+ sel_client(client);
}
void detach_client_from_frame(Client *c, Bool unmap)
{
Frame *f = c->frame;
- Client *client;
+
c->frame = nil;
f->file[F_SEL_CLIENT]->content = nil;
wmii_move_ixpfile(c->file[C_PREFIX], def[WM_DETACHED_CLIENT]);
- cext_detach_item(&f->clients, c);
+
+ if (f->sel == c) {
+ if (c->prev)
+ f->sel = c->prev;
+ else
+ f->sel = nil;
+ }
+
+ if (f->clients == c) {
+ if (c->next)
+ c->next->prev = nil;
+ f->clients = c->next;
+ }
+ else {
+ c->prev->next = c->next;
+ if (c->next)
+ c->next->prev = c->prev;
+ }
+
+ if (!f->sel)
+ f->sel = f->clients;
+
if (!c->destroyed) {
if (!unmap) {
- cext_attach_item(detached, c);
+ attach_detached(c);
hide_client(c);
}
c->rect.x = f->rect.x;
c->rect.y = f->rect.y;
reparent_client(c, root, c->rect.x, c->rect.y);
}
- if ((client = cext_stack_get_top_item(&f->clients))) {
- sel_client(client);
- f->area->layout->select(f, False);
+ if (f->sel) {
+ focus_client(f->sel);
+ f->area->layout->focus(f, False);
}
}
@@ -335,74 +350,89 @@ static void select_client(void *obj, char *arg)
{
Client *c;
Frame *f = obj;
- size_t size = cext_sizeof_container(&f->clients);
- if (!f || !arg || size == 1)
+ if (!f || !arg || !f->clients->next)
return;
- c = cext_stack_get_top_item(&f->clients);
if (!strncmp(arg, "prev", 5))
- c = cext_list_get_prev_item(&f->clients, c);
+ c = f->sel->prev;
else if (!strncmp(arg, "next", 5))
- c = cext_list_get_next_item(&f->clients, c);
+ c = f->sel->next;
else
- c = cext_list_get_item(&f->clients, blitz_strtonum(arg, 0, cext_sizeof_container(&f->clients) - 1));
- sel_client(c);
- f->area->layout->select(f, False);
+ c = clientat(f->clients, blitz_strtonum(arg, 0, f->nclients - 1));
+ focus_client(c);
+ f->area->layout->focus(f, False);
}
-static void iter_before_read_frame(void *item, void *aux)
+static Frame *handle_before_read_frames(IXPServer *s, File *file, Area *a)
{
- Frame *f = item;
- File *file = aux;
- if (file == f->file[F_GEOMETRY]) {
- char buf[64];
- snprintf(buf, 64, "%d,%d,%d,%d", f->rect.x, f->rect.y, f->rect.width, f->rect.height);
- if (file->content)
- free(file->content);
- file->content = cext_estrdup(buf);
- file->size = strlen(buf);
- }
+ Frame *f;
+ char buf[64];
+ for (f = a->layout->frames(a); f; f = f->next)
+ if (file == f->file[F_GEOMETRY]) {
+ snprintf(buf, 64, "%d,%d,%d,%d", f->rect.x, f->rect.y, f->rect.width, f->rect.height);
+ if (file->content)
+ free(file->content);
+ file->content = cext_estrdup(buf);
+ file->size = strlen(buf);
+ return f;
+ }
+ return nil;
}
-static void handle_before_read_frame(IXPServer *s, File *f)
+static void handle_before_read_frame(IXPServer *s, File *file)
{
- cext_list_iterate(frames, f, iter_before_read_frame);
+ Page *p;
+ for (p = pages; p; p = p->next) {
+ if (handle_before_read_frames(s, file, p->managed)
+ || handle_before_read_frames(s, file, p->floating))
+ return;
+ }
}
-static void iter_after_write_frame(void *item, void *aux)
+static Frame *handle_after_write_frames(IXPServer *s, File *file, Area *a)
{
- Frame *f = item;
- File *file = aux;
- if (file == f->file[F_CTL]) {
- run_action(file, f, frame_acttbl);
- return;
- }
- if (file == f->file[F_TAB] || file == f->file[F_BORDER] || file == f->file[F_HANDLE_INC]) {
- f->area->layout->arrange(f->area);
- return;
- } else if (file == f->file[F_GEOMETRY]) {
- char *geom = f->file[F_GEOMETRY]->content;
- if (geom && strrchr(geom, ',')) {
- XRectangle frect = f->rect;
- blitz_strtorect(&rect, &frect, geom);
- resize_frame(f, &frect, 0);
+ Frame *f;
+ for (f = a->layout->frames(a); f; f = f->next) {
+ if (file == f->file[F_CTL]) {
+ run_action(file, f, frame_acttbl);
+ return f;
+ }
+ if (file == f->file[F_TAB] || file == f->file[F_BORDER] || file == f->file[F_HANDLE_INC]) {
+ f->area->layout->arrange(f->area);
+ return f;
+ } else if (file == f->file[F_GEOMETRY]) {
+ char *geom = f->file[F_GEOMETRY]->content;
+ if (geom && strrchr(geom, ',')) {
+ XRectangle frect = f->rect;
+ blitz_strtorect(&rect, &frect, geom);
+ resize_frame(f, &frect, 0);
+ }
+ return f;
}
}
+ return nil;
}
-static void handle_after_write_frame(IXPServer * s, File * f)
+static void handle_after_write_frame(IXPServer *s, File *file)
{
- cext_list_iterate(frames, f, iter_after_write_frame);
+ Page *p;
+ for (p = pages; p; p = p->next) {
+ if (handle_after_write_frames(s, file, p->managed)
+ || handle_after_write_frames(s, file, p->floating))
+ return;
+ }
}
-Frame *get_sel_frame_of_area(Area *a)
+Frame *sel_frame()
{
- return cext_stack_get_top_item(a->layout->get_frames(a));
+ Area *a = sel_area();
+ if (!a)
+ return nil;
+ return a->layout->sel(a);
}
-Frame *get_sel_frame()
+Frame *get_bottom_frame(Frame *frames)
{
- Page *p = get_sel_page();
- if (!p)
- return nil;
- return get_sel_frame_of_area(get_sel_area(p));
+ Frame *f;
+ for (f = frames; f && f->next; f = f->next);
+ return f;
}
diff --git a/cmd/wm/layout.c b/cmd/wm/layout.c
@@ -7,15 +7,11 @@
#include "wm.h"
-static int comp_layout_name(void *name, void *layout)
+Layout *match_layout(char *name)
{
- Layout *l = layout;
- size_t len = strlen(l->name);
-
- return !strncmp(name, l->name, len);
-}
-
-Layout *get_layout(char *name)
-{
- return cext_find_item(layouts, name, comp_layout_name);
+ Layout *l;
+ for (l = layouts; l; l = l->next)
+ if (!strncmp(name, l->name, strlen(l->name)))
+ return l;
+ return nil;
}
diff --git a/cmd/wm/layout_column.c b/cmd/wm/layout_column.c
@@ -12,26 +12,42 @@
typedef struct Acme Acme;
typedef struct Column Column;
+typedef struct ColFrame ColFrame;
struct Acme {
- Container columns;
- Container frames;
+ Column *sel;
+ Column *columns;
+ size_t ncolumns;
+ Frame *frames;
+ size_t nframes;
+};
+
+struct ColFrame {
+ Frame *frame;
+ ColFrame *next;
+ ColFrame *prev;
+ Column *col;
};
struct Column {
- Container frames;
+ ColFrame *sel;
+ ColFrame *frames;
+ size_t nframes;
XRectangle rect;
+ Column *prev;
+ Column *next;
};
-static void init_col(Area * a);
-static void deinit_col(Area * a);
-static void arrange_col(Area * a);
-static Bool attach_col(Area * a, Client * c);
-static void detach_col(Area * a, Client * c, Bool unmap);
-static void resize_col(Frame *f, XRectangle * new, XPoint * pt);
-static void select_col(Frame *f, Bool raise);
-static Container *get_frames_col(Area *a);
-static Action *get_actions_col(Area *a);
+static void init_col(Area *a, Client *clients);
+static Client *deinit_col(Area *a);
+static void arrange_col(Area *a);
+static Bool attach_col(Area *a, Client *c);
+static void detach_col(Area *a, Client *c, Bool unmap);
+static void resize_col(Frame *f, XRectangle *new, XPoint *pt);
+static void focus_col(Frame *f, Bool raise);
+static Frame *frames_col(Area *a);
+static Frame *sel_col(Area *a);
+static Action *actions_col(Area *a);
static void select_frame(void *obj, char *arg);
static void swap_frame(void *obj, char *arg);
@@ -44,98 +60,176 @@ static Action lcol_acttbl[] = {
{0, 0}
};
-static Layout lcol = { "col", init_col, deinit_col, arrange_col, attach_col, detach_col,
- resize_col, select_col, get_frames_col, get_actions_col };
-
void init_layout_column()
{
- cext_attach_item(layouts, &lcol);
-}
-
-static Column *get_sel_column(Acme *acme)
-{
- return cext_stack_get_top_item(&acme->columns);
-}
-
-static void iter_arrange_column_frame(void *frame, void *height)
-{
- Frame *f = frame;
- Column *col = f->aux;
- size_t size = cext_sizeof_container(&col->frames);
- unsigned int h = *(unsigned int *)height;
- int idx = cext_list_get_item_index(&col->frames, f) ;
-
- f->rect = col->rect;
- f->rect.y = area_rect.y + idx * h;
- if (idx + 1 == size)
- f->rect.height = area_rect.height - f->rect.y + area_rect.y;
+ Layout *lp, *l = cext_emallocz(sizeof(Layout));
+ l->name = "column";
+ l->init = init_col;
+ l->deinit = deinit_col;
+ l->arrange = arrange_col;
+ l->attach = attach_col;
+ l->detach = detach_col;
+ l->resize = resize_col;
+ l->focus = focus_col;
+ l->frames = frames_col;
+ l->sel = sel_col;
+ l->actions = actions_col;
+
+ for (lp = layouts; lp && lp->next; lp = lp->next);
+ if (lp)
+ lp->next = l;
else
- f->rect.height = h;
-
- resize_frame(f, &f->rect, 0);
+ layouts = l;
}
-static void iter_arrange_column(void *column, void *area)
+static void arrange_column(Column *col)
{
- Column *col = column;
- size_t size = cext_sizeof_container(&col->frames);
- unsigned int height;
-
- if (size) {
- height= area_rect.height / size;
- cext_list_iterate(&col->frames, &height, iter_arrange_column_frame);
+ ColFrame *cf;
+ unsigned int i = 0, h = area_rect.height / col->nframes;
+ for (cf = col->frames; cf; cf = cf->next) {
+ Frame *f = cf->frame;
+ f->rect = col->rect;
+ f->rect.y = area_rect.y + i * h;
+ if (!cf->next)
+ f->rect.height = area_rect.height - f->rect.y + area_rect.y;
+ else
+ f->rect.height = h;
+ resize_frame(f, &f->rect, 0);
+ i++;
}
}
static void arrange_col(Area *a)
{
Acme *acme = a->aux;
- cext_list_iterate(&acme->columns, a, iter_arrange_column);
+ Column *col;
+ for (col = acme->columns; col; col = col->next)
+ arrange_column(col);
XSync(dpy, False);
}
-static void iter_attach_col(void *client, void *area)
+static void init_col(Area *a, Client *clients)
{
- attach_col(area, client);
+ Client *n, *c = clients;
+
+ a->aux = cext_emallocz(sizeof(Acme));
+ while (c) {
+ n = c->next;
+ attach_col(a, c);
+ c = n;
+ }
}
-static void init_col(Area *a)
+static void attach_frame(Area *a, Column *col, Frame *f)
{
- Acme *acme = cext_emallocz(sizeof(Acme));
- a->aux = acme;
- cext_list_iterate(&a->clients, a, iter_attach_col);
+ Acme *acme = a->aux;
+ ColFrame *c, *cf = cext_emallocz(sizeof(ColFrame));
+ Frame *fr;
+
+ cf->frame = f;
+ cf->col = col;
+ f->aux = cf;
+ for (c = col->frames; c && c->next; c = c->next);
+ if (!c)
+ col->frames = cf;
+ else {
+ c->next = cf;
+ cf->prev = c;
+ }
+ col->sel = cf;
+ col->nframes++;
+
+ for (fr = acme->frames; fr && fr->next; fr = fr->next);
+ if (!fr)
+ acme->frames = f;
+ else {
+ fr->next = f;
+ f->prev = fr;
+ }
+ attach_frame_to_area(a, f);
+ acme->nframes++;
+
}
-static void iter_detach_client(void *client, void *area)
+static void detach_frame(Area *a, Frame *f)
{
- Area *a = area;
- detach_col(a, (Client *)client, a->page != get_sel_page());
+ Acme *acme = a->aux;
+ ColFrame *cf = f->aux;
+ Column *col = cf->col;
+
+ if (col->sel == cf) {
+ if (cf->prev)
+ col->sel = cf->prev;
+ else
+ col->sel = nil;
+ }
+ if (cf->prev)
+ cf->prev->next = cf->next;
+ else
+ col->frames = cf->next;
+ if (cf->next)
+ cf->next->prev = cf->prev;
+ if (!col->sel)
+ col->sel = col->frames;
+ free(cf);
+ col->nframes--;
+
+ if (f->prev)
+ f->prev->next = f->next;
+ else
+ acme->frames = f->next;
+ if (f->next)
+ f->next->prev = f->prev;
+ f->aux = nil;
+ detach_frame_from_area(f);
+ acme->nframes--;
}
-static void deinit_col(Area *a)
+static Client *deinit_col(Area *a)
{
Acme *acme = a->aux;
- Column *col;
- cext_list_iterate(&a->clients, a, iter_detach_client);
- while ((col = get_sel_column(acme)))
- {
- cext_detach_item(&acme->columns, col);
+ Frame *f;
+ Client *cl, *res = nil, *c = nil;
+ Column *col = acme->columns;
+
+ while ((f = acme->frames)) {
+ while ((cl = f->clients)) {
+ detach_client_from_frame(cl, False);
+ cl->prev = cl->next = 0;
+ if (!c)
+ res = c = cl;
+ else {
+ c->next = cl;
+ cl->prev = c;
+ c = cl;
+ }
+ }
+ detach_frame(a, f);
+ destroy_frame(f);
+ }
+ while ((col = acme->columns)) {
+ acme->columns = col->next;
free(col);
}
free(acme);
a->aux = 0;
+ return res;
}
static Bool attach_col(Area *a, Client *c)
{
Acme *acme = a->aux;
- Column *col = get_sel_column(acme);
- Frame *f = get_sel_frame_of_area(a);
+ Column *col = acme->sel;
+ Frame *f = nil;
+
+ if (col && col->sel)
+ f = col->sel->frame;
if (!col) {
col = cext_emallocz(sizeof(Column));
col->rect = area_rect;
- cext_attach_item(&acme->columns, col);
+ acme->columns = acme->sel = col;
+ acme->ncolumns++;
}
/* check for tabbing? */
@@ -143,34 +237,31 @@ static Bool attach_col(Area *a, Client *c)
f = 0;
if (!f) {
f = alloc_frame(&c->rect);
- attach_frame_to_area(a, f);
- f->aux = col;
- cext_attach_item(&acme->frames, f);
- cext_attach_item(&col->frames, f);
+ attach_frame(a, col, f);
}
attach_client_to_frame(f, c);
- iter_arrange_column(col, a);
- if (a->page == get_sel_page())
+ arrange_column(col);
+ if (a->page == selpage)
XMapWindow(dpy, f->win);
- select_col(f, True);
+ focus_col(f, True);
return True;
}
static void update_column_width(Area *a)
{
Acme *acme = a->aux;
- size_t size = cext_sizeof_container(&acme->columns);
- unsigned int i, width;
+ unsigned int i = 0, width;
+ Column *col;
- if (!size)
+ if (!acme->ncolumns)
return;
- width = area_rect.width / size;
- for (i = 0; i < size; i++) {
- Column *col = cext_list_get_item(&acme->columns, i);
+ width = area_rect.width / acme->ncolumns;
+ for (col = acme->columns; col; col = col->next) {
col->rect = area_rect;
col->rect.x = i * width;
col->rect.width = width;
+ i++;
}
arrange_col(a);
}
@@ -182,128 +273,121 @@ static void detach_col(Area *a, Client *c, Bool unmap)
Column *col = f->aux;
detach_client_from_frame(c, unmap);
- if (!cext_sizeof_container(&f->clients)) {
- detach_frame_from_area(f);
- cext_detach_item(&acme->frames, f);
- cext_detach_item(&col->frames, f);
+ if (!f->clients) {
+ detach_frame(a, f);
destroy_frame(f);
}
else return;
- if (cext_sizeof_container(&col->frames))
- iter_arrange_column(col, a);
+ if (col->frames)
+ arrange_column(col);
else {
- cext_detach_item(&acme->columns, col);
+ if (acme->sel == col) {
+ if (col->prev)
+ acme->sel = col->prev;
+ else
+ acme->sel = nil;
+ }
+ if (col->prev)
+ col->prev->next = col->next;
+ else
+ acme->columns = col->next;
+ if (col->next)
+ col->next->prev = col->prev;
+ if (!acme->sel)
+ acme->sel = acme->columns;
+ acme->ncolumns--;
free(col);
update_column_width(a);
}
}
-static void iter_match_frame_horiz(void *frame, void *rect)
+static void match_frame_horiz(Column *col, XRectangle *r)
{
- Frame *f = frame;
- XRectangle *r = rect;
- f->rect.x = r->x;
- f->rect.width = r->width;
- resize_frame(f, &f->rect, nil);
+ ColFrame *cf;
+ for (cf = col->frames; cf; cf = cf->next) {
+ Frame *f = cf->frame;
+ f->rect.x = r->x;
+ f->rect.width = r->width;
+ resize_frame(f, &f->rect, nil);
+ }
}
static void drop_resize(Frame *f, XRectangle *new)
{
Column *west = 0, *east = 0, *col = f->aux;
- Frame *north = 0, *south = 0;
- Acme *acme = f->area->aux;
- size_t ncol = cext_sizeof_container(&acme->columns);
- size_t nfr = cext_sizeof_container(&col->frames);
- int colidx = cext_list_get_item_index(&acme->columns, col);
- int fidx = cext_list_get_item_index(&col->frames, f);
+ ColFrame *north = 0, *south = 0;
+ ColFrame *cf = f->aux;
- if (colidx > 0)
- west = cext_list_get_item(&acme->columns, colidx - 1);
- if (colidx + 1 < ncol)
- east = cext_list_get_item(&acme->columns, colidx + 1);
- if (fidx > 0)
- north = cext_list_get_item(&col->frames, fidx - 1);
- if (fidx + 1 < nfr)
- south = cext_list_get_item(&col->frames, fidx + 1);
+ west = col->prev;
+ east = col->next;
+ north = cf->prev;
+ south = cf->next;
/* horizontal resize */
if (west && (new->x != f->rect.x)) {
west->rect.width = new->x - west->rect.x;
col->rect.width += f->rect.x - new->x;
col->rect.x = new->x;
- cext_list_iterate(&west->frames, &west->rect, iter_match_frame_horiz);
- cext_list_iterate(&col->frames, &col->rect, iter_match_frame_horiz);
+ match_frame_horiz(west, &west->rect);
+ match_frame_horiz(col, &col->rect);
}
if (east && (new->x + new->width != f->rect.x + f->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;
- cext_list_iterate(&col->frames, &col->rect, iter_match_frame_horiz);
- cext_list_iterate(&east->frames, &east->rect, iter_match_frame_horiz);
+ match_frame_horiz(col, &col->rect);
+ match_frame_horiz(east, &east->rect);
}
/* vertical resize */
if (north && (new->y != f->rect.y)) {
- north->rect.height = new->y - north->rect.y;
+ north->frame->rect.height = new->y - north->frame->rect.y;
f->rect.height += f->rect.y - new->y;
f->rect.y = new->y;
- resize_frame(north, &north->rect, nil);
+ resize_frame(north->frame, &north->frame->rect, nil);
resize_frame(f, &f->rect, nil);
}
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;
+ south->frame->rect.height -= new->y + new->height - south->frame->rect.y;
+ south->frame->rect.y = new->y + new->height;
f->rect.y = new->y;
f->rect.height = new->height;
resize_frame(f, &f->rect, nil);
- resize_frame(south, &south->rect, nil);
+ resize_frame(south->frame, &south->frame->rect, nil);
}
}
-static int comp_pointer_frame(void *point, void *frame)
-{
- Frame *f = frame;
- XPoint *pt = point;
-
- fprintf(stderr, "frame: %d,%d in %d,%d,%d,%d ?\n", pt->x, pt->y, f->rect.x, f->rect.y, f->rect.width, f->rect.height);
- return blitz_ispointinrect(pt->x, pt->y, &f->rect);
-}
-
-static int comp_pointer_col(void *point, void *column)
-{
- Column *col = column;
- XPoint *pt = point;
-
- fprintf(stderr, "col: %d,%d in %d,%d,%d,%d ?\n", pt->x, pt->y, col->rect.x, col->rect.y, col->rect.width, col->rect.height);
- return blitz_ispointinrect(pt->x, pt->y, &col->rect);
-}
-
static void drop_moving(Frame *f, XRectangle *new, XPoint *pt)
{
- Acme *acme = f->area->aux;
- Column *src = f->aux, *tgt = 0;
+ Area *a = f->area;
+ ColFrame *fcf = f->aux;
+ Column *src = fcf->col, *tgt = 0;
+ Acme *acme = a->aux;
if (!pt)
return;
- if ((tgt = cext_find_item(&acme->columns, pt, comp_pointer_col))) {
+ for (tgt = acme->columns; tgt && !blitz_ispointinrect(pt->x, pt->y, &tgt->rect); tgt = tgt->next);
+ if (tgt) {
if (tgt != src) {
- if (cext_sizeof_container(&src->frames) < 2)
+ if (src->nframes < 2)
return;
- cext_detach_item(&src->frames, f);
- cext_attach_item(&tgt->frames, f);
- f->aux = tgt;
- iter_arrange_column(tgt, f->area);
- iter_arrange_column(src, f->area);
- select_col(f, True);
+ detach_frame(a, f);
+ attach_frame(a, tgt, f);
+ arrange_column(src);
+ arrange_column(tgt);
+ focus_col(f, True);
}
else {
- Frame *other = cext_find_item(&tgt->frames, pt, comp_pointer_frame);
- if (other && other != f) {
- cext_swap_items(&tgt->frames, f, other);
- iter_arrange_column(tgt, f->area);
- select_col(f, True);
+ ColFrame *cf;
+ for (cf = src->frames; cf && !blitz_ispointinrect(pt->x, pt->y, &cf->frame->rect); cf = cf->next);
+ if (cf && cf != fcf) {
+ Frame *tmp = cf->frame;
+ cf->frame = f;
+ fcf->frame = tmp;
+ arrange_column(src);
+ focus_col(f, True);
}
}
}
@@ -318,32 +402,41 @@ static void resize_col(Frame *f, XRectangle *new, XPoint *pt)
drop_resize(f, new);
}
-static void select_col(Frame *f, Bool raise)
+static void focus_col(Frame *f, Bool raise)
{
Area *a = f->area;
Acme *acme = a->aux;
- Column *col = f->aux;
- Frame *old = get_sel_frame();
+ ColFrame *old, *fcf = f->aux;
+ Column *col = fcf->col;
- cext_stack_top_item(&acme->columns, col);
- sel_client(cext_stack_get_top_item(&f->clients));
- cext_stack_top_item(&col->frames, f);
- cext_stack_top_item(&acme->frames, f);
+ old = col->sel;
+ acme->sel = col;
+ col->sel = fcf;
+ sel_client(f->sel);
a->file[A_SEL_FRAME]->content = f->file[F_PREFIX]->content;
if (raise)
center_pointer(f);
- if (old && old != f)
- draw_frame(old);
+ if (old && old != fcf)
+ draw_frame(old->frame);
draw_frame(f);
}
-static Container *get_frames_col(Area *a)
+static Frame *frames_col(Area *a)
{
Acme *acme = a->aux;
- return &acme->frames;
+ return acme->frames;
}
-static Action *get_actions_col(Area *a)
+static Frame *sel_col(Area *a) {
+ Acme *acme = a->aux;
+ Column *col = acme->sel;
+
+ if (col && col->sel)
+ return col->sel->frame;
+ return nil;
+}
+
+static Action *actions_col(Area *a)
{
return lcol_acttbl;
}
@@ -381,7 +474,7 @@ static void select_frame(void *obj, char *arg)
}
else
f = cext_list_get_item(&col->frames, blitz_strtonum(arg, 0, cext_sizeof_container(&col->frames) - 1));
- select_col(f, True);
+ focus_col(f, True);
}
static void swap_frame(void *obj, char *arg)
@@ -423,7 +516,7 @@ static void swap_frame(void *obj, char *arg)
cext_swap_items(&col->frames, f, north);
resize_frame(f, &f->rect, nil);
resize_frame(north, &north->rect, nil);
- select_col(f, True);
+ focus_col(f, True);
}
else if (!strncmp(arg, "south", 6) && south) {
r = south->rect;
@@ -432,7 +525,7 @@ static void swap_frame(void *obj, char *arg)
cext_swap_items(&col->frames, f, south);
resize_frame(f, &f->rect, nil);
resize_frame(south, &south->rect, nil);
- select_col(f, True);
+ focus_col(f, True);
}
else if (!strncmp(arg, "west", 5) && west && (ncol > 1)) {
Frame *other = cext_stack_get_top_item(&west->frames);
@@ -447,7 +540,7 @@ static void swap_frame(void *obj, char *arg)
other->aux = col;
resize_frame(f, &f->rect, nil);
resize_frame(other, &other->rect, nil);
- select_col(f, True);
+ focus_col(f, True);
}
else if (!strncmp(arg, "east", 5) && east && (ncol > 1)) {
Frame *other = cext_stack_get_top_item(&east->frames);
@@ -462,7 +555,7 @@ static void swap_frame(void *obj, char *arg)
other->aux = col;
resize_frame(f, &f->rect, nil);
resize_frame(other, &other->rect, nil);
- select_col(f, True);
+ focus_col(f, True);
}
}
@@ -482,5 +575,6 @@ static void new_col(void *obj, char *arg)
cext_attach_item(&col->frames, f);
cext_attach_item(&acme->columns, col);
update_column_width(a);
- select_col(f, True);
+ focus_col(f, True);
}
+
diff --git a/cmd/wm/page.c b/cmd/wm/page.c
@@ -9,74 +9,90 @@
#include "wm.h"
-static void handle_after_write_page(IXPServer * s, File * f);
+static void handle_after_write_page(IXPServer *s, File *file);
-static void select_area(void *obj, char *arg);
+static void toggle_area(void *obj, char *arg);
/* action table for /?/ namespace */
Action page_acttbl[] = {
- {"select", select_area},
+ {"toggle", toggle_area},
{0, 0}
};
Page *alloc_page()
{
- Page *p = cext_emallocz(sizeof(Page));
+ Page *p, *new = cext_emallocz(sizeof(Page));
char buf[MAX_BUF], buf2[16];
- size_t id = cext_sizeof_container(pages);
-
- snprintf(buf2, sizeof(buf2), "%d", id);
- snprintf(buf, sizeof(buf), "/%d", id);
- p->file[P_PREFIX] = ixp_create(ixps, buf);
- snprintf(buf, sizeof(buf), "/%d/name", id);
- p->file[P_NAME] = wmii_create_ixpfile(ixps, buf, buf2);
- snprintf(buf, sizeof(buf), "/%d/layout/", id);
- p->file[P_AREA_PREFIX] = ixp_create(ixps, buf);
- snprintf(buf, sizeof(buf), "/%d/layout/sel", id);
- p->file[P_SEL_AREA] = ixp_create(ixps, buf);
- p->file[P_SEL_AREA]->bind = 1; /* mount point */
- snprintf(buf, sizeof(buf), "/%d/ctl", id);
- p->file[P_CTL] = ixp_create(ixps, buf);
- p->file[P_CTL]->after_write = handle_after_write_page;
- alloc_area(p, "float");
- alloc_area(p, def[WM_LAYOUT]->content);
- cext_attach_item(pages, p);
+
+ snprintf(buf2, sizeof(buf2), "%d", npages);
+ snprintf(buf, sizeof(buf), "/%d", npages);
+ new->file[P_PREFIX] = ixp_create(ixps, buf);
+ snprintf(buf, sizeof(buf), "/%d/name", npages);
+ new->file[P_NAME] = wmii_create_ixpfile(ixps, buf, buf2);
+ snprintf(buf, sizeof(buf), "/%d/layout/", npages);
+ new->file[P_AREA_PREFIX] = ixp_create(ixps, buf);
+ snprintf(buf, sizeof(buf), "/%d/layout/sel", npages);
+ new->file[P_SEL_AREA] = ixp_create(ixps, buf);
+ new->file[P_SEL_AREA]->bind = 1; /* mount point */
+ snprintf(buf, sizeof(buf), "/%d/ctl", npages);
+ new->file[P_CTL] = ixp_create(ixps, buf);
+ new->file[P_CTL]->after_write = handle_after_write_page;
+ new->floating = alloc_area(new, "float");
+ new->sel = new->managed = alloc_area(new, def[WM_LAYOUT]->content);
+ for (p = pages; p && p->next; p = p->next);
+ if (!p)
+ pages = new;
+ else {
+ new->prev = p;
+ p->next = new;
+ }
+ selpage = new;
def[WM_SEL_PAGE]->content = p->file[P_PREFIX]->content;
invoke_wm_event(def[WM_EVENT_PAGE_UPDATE]);
return p;
}
-static void iter_destroy_area(void *area, void *aux)
+void destroy_page(Page *p)
{
- destroy_area((Area *)area);
-}
-
-void destroy_page(Page * p)
-{
- cext_list_iterate(&p->areas, nil, iter_destroy_area);
+ destroy_area(p->floating);
+ destroy_area(p->managed);
def[WM_SEL_PAGE]->content = 0;
ixp_remove_file(ixps, p->file[P_PREFIX]);
- cext_detach_item(pages, p);
+ if (p == selpage) {
+ if (p->prev)
+ selpage = p->prev;
+ else
+ selpage = nil;
+ }
+
+ if (p == pages) {
+ if (p->next)
+ p->next->prev = nil;
+ pages = p->next;
+ }
+ else {
+ p->prev->next = p->next;
+ if (p->next)
+ p->next->prev = p->prev;
+ }
+
free(p);
- if ((p = get_sel_page()))
- sel_page(p);
- else
- invoke_wm_event(def[WM_EVENT_PAGE_UPDATE]);
+ if (!selpage)
+ selpage = pages;
+
+ if (selpage)
+ focus_page(selpage);
}
-void sel_page(Page * p)
+void focus_page(Page *p)
{
- Page *sel = get_sel_page();
- if (!sel)
- return;
- if (p != sel) {
- hide_page(sel);
- cext_stack_top_item(pages, p);
- show_page(p);
- }
+ if (selpage != p)
+ hide_page(selpage);
+ selpage = p;
+ show_page(p);
def[WM_SEL_PAGE]->content = p->file[P_PREFIX]->content;
invoke_wm_event(def[WM_EVENT_PAGE_UPDATE]);
- sel_area(get_sel_area());
+ focus_area(sel_area());
}
XRectangle *rectangles(unsigned int *num)
@@ -109,57 +125,46 @@ XRectangle *rectangles(unsigned int *num)
return result;
}
-static void iter_hide_page(void *item, void *aux)
-{
- hide_area((Area *)item);
-}
-
-void hide_page(Page * p)
-{
- cext_list_iterate(&p->areas, nil, iter_hide_page);
-}
-
-static void iter_show_page(void *item, void *aux)
+void hide_page(Page *p)
{
- show_area((Area *)item);
+ hide_area(p->managed);
+ hide_area(p->floating);
}
-void show_page(Page * p)
+void show_page(Page *p)
{
- cext_list_iterate(&p->areas, nil, iter_show_page);
+ show_area(p->managed, False);
+ show_area(p->floating, False);
}
-static void iter_after_write_page(void *item, void *aux)
+static void handle_after_write_page(IXPServer *s, File *file)
{
- Page *p = (Page *)item;
- File *file = aux;
- if (file == p->file[P_CTL]) {
- run_action(file, p, page_acttbl);
- return;
+ Page *p;
+ for (p = pages; p; p = p->next) {
+ if (file == p->file[P_CTL]) {
+ run_action(file, p, page_acttbl);
+ return;
+ }
}
}
-static void handle_after_write_page(IXPServer *s, File *f)
+static void toggle_area(void *obj, char *arg)
{
- cext_list_iterate(pages, f, iter_after_write_page);
-}
+ Page *p = obj;
-Page *get_sel_page()
-{
- return cext_stack_get_top_item(pages);
+ if (p->sel == p->managed)
+ p->sel = p->floating;
+ else
+ p->sel = p->managed;
+
+ sel_area(p->sel);
+ invoke_wm_event(def[WM_EVENT_PAGE_UPDATE]);
}
-static void select_area(void *obj, char *arg)
+Page *get_page(unsigned int idx)
{
- Page *p = obj;
- Area *a = cext_stack_get_top_item(&p->areas);
-
- if (!strncmp(arg, "prev", 5))
- a = cext_list_get_prev_item(&p->areas, a);
- else if (!strncmp(arg, "next", 5))
- a = cext_list_get_next_item(&p->areas, a);
- else
- a = cext_list_get_item(&p->areas, blitz_strtonum(arg, 0, cext_sizeof_container(&p->areas) - 1));
- sel_area(a);
- invoke_wm_event(def[WM_EVENT_PAGE_UPDATE]);
+ unsigned int i = 0;
+ Page *p = pages;
+ for (; p && i != idx; p = p->next);
+ return p;
}
diff --git a/cmd/wm/wm.c b/cmd/wm/wm.c
@@ -113,36 +113,35 @@ scale_rect(XRectangle * from_dim, XRectangle * to_dim,
tgt->height = 1;
}
-static void iter_draw_pager_frame(void *item, void *aux)
-{
- Draw *d = aux;
- Frame *f = (Frame *)item;
- if (f == get_sel_frame_of_area(f->area)) {
- d->bg = blitz_loadcolor(dpy, screen_num, def[WM_SEL_BG_COLOR]->content);
- d->fg = blitz_loadcolor(dpy, screen_num, def[WM_SEL_FG_COLOR]->content);
- d->border = blitz_loadcolor(dpy, screen_num, def[WM_SEL_BORDER_COLOR]->content);
- } else {
- d->bg = blitz_loadcolor(dpy, screen_num, def[WM_NORM_BG_COLOR]->content);
- d->fg = blitz_loadcolor(dpy, screen_num, def[WM_NORM_FG_COLOR]->content);
- d->border = blitz_loadcolor(dpy, screen_num, def[WM_NORM_BORDER_COLOR]->content);
+static void draw_pager_area(Area *a, Draw *d)
+{
+ Frame *f;
+ Frame *sel = sel_frame();
+ for (f = bottom_frame(a->layout->frames(a)); f; f = f->prev) {
+ if (f == sel) {
+ d->bg = blitz_loadcolor(dpy, screen_num, def[WM_SEL_BG_COLOR]->content);
+ d->fg = blitz_loadcolor(dpy, screen_num, def[WM_SEL_FG_COLOR]->content);
+ d->border = blitz_loadcolor(dpy, screen_num, def[WM_SEL_BORDER_COLOR]->content);
+ } else {
+ d->bg = blitz_loadcolor(dpy, screen_num, def[WM_NORM_BG_COLOR]->content);
+ d->fg = blitz_loadcolor(dpy, screen_num, def[WM_NORM_FG_COLOR]->content);
+ d->border = blitz_loadcolor(dpy, screen_num, def[WM_NORM_BORDER_COLOR]->content);
+ }
+ d->data = f->sel->file[C_NAME]->content;
+ scale_rect(&rect, &initial_rect, &f->rect, &d->rect);
+ blitz_drawlabel(dpy, d);
+ XSync(dpy, False); /* do not clear upwards */
}
- d->data = ((Client *)cext_stack_get_top_item(&f->clients))->file[C_NAME]->content;
- scale_rect(&rect, &initial_rect, &f->rect, &d->rect);
- blitz_drawlabel(dpy, d);
- XSync(dpy, False); /* do not clear upwards */
-}
-
-static void draw_pager_area(void *item, void *aux)
-{
- Area *a = (Area *)item;
- cext_stack_iterate_up(a->layout->get_frames(a), aux, iter_draw_pager_frame);
}
static void draw_pager_page(Page *p, Draw *d)
{
+ unsigned int idx = 0;
char name[4];
initial_rect = d->rect;
- if (p == cext_stack_get_top_item(pages)) {
+ Page *page;
+
+ if (p == selpage) {
d->bg = blitz_loadcolor(dpy, screen_num, def[WM_SEL_BG_COLOR]->content);
d->fg = blitz_loadcolor(dpy, screen_num, def[WM_SEL_FG_COLOR]->content);
d->border = blitz_loadcolor(dpy, screen_num, def[WM_SEL_BORDER_COLOR]->content);
@@ -151,28 +150,31 @@ static void draw_pager_page(Page *p, Draw *d)
d->fg = blitz_loadcolor(dpy, screen_num, def[WM_NORM_FG_COLOR]->content);
d->border = blitz_loadcolor(dpy, screen_num, def[WM_NORM_BORDER_COLOR]->content);
}
- snprintf(name, sizeof(name), "%d", cext_list_get_item_index(pages, p));
+ for (page = pages; page && page != p; page = page->next) idx++;
+ snprintf(name, sizeof(name), "%d", idx);
d->data = name;
blitz_drawlabel(dpy, d);
XSync(dpy, False);
- cext_stack_iterate_up(&p->areas, d, draw_pager_area);
+ if (p->managed)
+ draw_pager_area(p->managed, d);
+ draw_pager_area(p->floating, d);
}
static void draw_pager()
{
Draw d = { 0 };
- unsigned int ic, ir, tw, th, rows, cols, size;
- int i = 0;
+ unsigned int ic, ir, tw, th, rows, cols;
int dx;
Page *p;
- blitz_getbasegeometry(pages, &size, &cols, &rows);
+ blitz_getbasegeometry(npages, &cols, &rows);
dx = (cols - 1) * GAP; /* GAPpx space */
tw = (rect.width - dx) / cols;
th = ((double) tw / rect.width) * rect.height;
d.drawable = transient;
d.gc = transient_gc;
d.font = font;
+ p = pages;
for (ir = 0; ir < rows; ir++) {
for (ic = 0; ic < cols; ic++) {
d.rect.x = ic * tw + (ic * GAP);
@@ -182,29 +184,26 @@ static void draw_pager()
else
d.rect.y = ir * (rect.height - th) / (rows - 1);
d.rect.height = th;
- if (!(p = cext_list_get_item(pages, i)))
+ if (!p->next)
return;
draw_pager_page(p, &d);
- i++;
}
}
}
static Page *xy_to_pager_page(int x, int y)
{
- unsigned int ic, ir, tw, th, rows, cols, size;
- int i = 0;
+ unsigned int ic, ir, tw, th, rows, cols;
int dx;
XRectangle r;
Page *p;
- if (!cext_sizeof_container(pages))
- return nil;
- blitz_getbasegeometry(pages, &size, &cols, &rows);
+ blitz_getbasegeometry(npages, &cols, &rows);
dx = (cols - 1) * GAP; /* GAPpx space */
tw = (rect.width - dx) / cols;
th = ((double) tw / rect.width) * rect.height;
+ p = pages;
for (ir = 0; ir < rows; ir++) {
for (ic = 0; ic < cols; ic++) {
r.x = ic * tw + (ic * GAP);
@@ -214,11 +213,10 @@ static Page *xy_to_pager_page(int x, int y)
else
r.y = ir * (rect.height - th) / (rows - 1);
r.height = th;
- if (!(p = cext_list_get_item(pages, i)))
+ if (!p->next)
return nil;
if (blitz_ispointinrect(x, y, &r))
return p;
- i++;
}
}
return nil;
@@ -241,7 +239,7 @@ static void pager(void *obj, char *arg)
XEvent ev;
int i;
- if (!cext_sizeof_container(pages))
+ if (!pages)
return;
XClearWindow(dpy, transient);
@@ -265,8 +263,8 @@ static void pager(void *obj, char *arg)
case KeyPress:
XUnmapWindow(dpy, transient);
if ((i = handle_kpress(&ev.xkey)) != -1)
- if (i < cext_sizeof_container(pages))
- sel_page(cext_list_get_item(pages, i));
+ if (i < npages)
+ focus_page(pageat(i));
XUngrabKeyboard(dpy, CurrentTime);
XUngrabPointer(dpy, CurrentTime /* ev.xbutton.time */ );
return;
@@ -276,7 +274,7 @@ static void pager(void *obj, char *arg)
if (ev.xbutton.button == Button1) {
Page *p = xy_to_pager_page(ev.xbutton.x, ev.xbutton.y);
if (p)
- sel_page(p);
+ focus_page(p);
}
XUngrabKeyboard(dpy, CurrentTime);
XUngrabPointer(dpy, CurrentTime /* ev.xbutton.time */ );
@@ -288,12 +286,14 @@ static void pager(void *obj, char *arg)
static void draw_detached_clients()
{
- unsigned int i, ic, ir, tw, th, rows, cols, size;
+ unsigned int ic, ir, tw, th, rows, cols;
int dx, dy;
+ Client *c = detached;
+ XRectangle cr;
- if (!cext_sizeof_container(detached))
+ if (!c)
return;
- blitz_getbasegeometry(detached, &size, &cols, &rows);
+ blitz_getbasegeometry(ndetached, &cols, &rows);
dx = (cols - 1) * GAP; /* GAPpx space */
dy = (rows - 1) * GAP; /* GAPpx space */
tw = (rect.width - dx) / cols;
@@ -301,24 +301,21 @@ static void draw_detached_clients()
XClearWindow(dpy, transient);
XMapRaised(dpy, transient);
- i = 0;
for (ir = 0; ir < rows; ir++) {
for (ic = 0; ic < cols; ic++) {
- Client *c = cext_list_get_item(detached, i++);
- XRectangle cr;
if (!c)
return;
cr.x = ic * tw + (ic * GAP);
cr.y = ir * th + (ir * GAP);
cr.width = tw;
cr.height = th;
- XMoveResizeWindow(dpy, c->win, cr.x, cr.y, cr.width,
- cr.height);
+ XMoveResizeWindow(dpy, c->win, cr.x, cr.y, cr.width, cr.height);
configure_client(c);
show_client(c);
XRaiseWindow(dpy, c->win);
grab_client(c, AnyModifier, AnyButton);
XSync(dpy, False);
+ c = c->next;
}
}
}
@@ -334,13 +331,9 @@ static void reserve_area(void *obj, char *arg)
static void detached_clients(void *obj, char *arg)
{
XEvent ev;
- int i, n;
- size_t size = cext_sizeof_container(detached);
+ int n;
Client *c;
- if (!size)
- return;
-
XClearWindow(dpy, transient);
XMapRaised(dpy, transient);
draw_detached_clients();
@@ -355,30 +348,25 @@ static void detached_clients(void *obj, char *arg)
switch (ev.type) {
case KeyPress:
XUnmapWindow(dpy, transient);
+ for (c = detached; c; c = c->next)
+ hide_client(c);
if ((n = handle_kpress(&ev.xkey)) != -1) {
- for (i = 0; i < size; i++)
- hide_client(cext_list_get_item(detached, i));
- if (n - 1 < i) {
- c = cext_list_get_item(detached, n);
- cext_detach_item(detached, c);
+ if (n - 1 < ndetached) {
+ c = clientat(detached, n);
+ detach_detached(c);
attach_client(c);
}
- } else {
- for (i = 0; i < size; i++)
- hide_client(cext_list_get_item(detached, i));
}
XUngrabKeyboard(dpy, CurrentTime);
return;
break;
case ButtonPress:
- if (ev.xbutton.button == Button1) {
- XUnmapWindow(dpy, transient);
- for (i = 0; i < size; i++)
- hide_client(cext_list_get_item(detached, i));
- if ((c = win_to_client(ev.xbutton.window))) {
- cext_detach_item(detached, c);
- attach_client(c);
- }
+ XUnmapWindow(dpy, transient);
+ for (c = detached; c; c = c->next)
+ hide_client(c);
+ if ((ev.xbutton.button == Button1) && (c = win_to_client(ev.xbutton.window))) {
+ detach_detached(c);
+ attach_client(c);
}
XUngrabKeyboard(dpy, CurrentTime);
return;
@@ -389,70 +377,80 @@ static void detached_clients(void *obj, char *arg)
static void _close_client(void *obj, char *arg)
{
- Frame *f = get_sel_frame();
- if (f)
- close_client(cext_stack_get_top_item(&f->clients));
+ Client *c = sel_client();
+ if (c)
+ close_client(c);
}
static void _attach_client(void *obj, char *arg)
{
- if (cext_sizeof_container(detached)) {
- Client *c = cext_stack_get_top_item(detached);
- cext_detach_item(detached, c);
+ Client *c = detached;
+ if (c) {
+ detach_detached(c);
attach_client(c);
}
}
static void _detach_client(void *obj, char *arg)
{
- Client *c = get_sel_client();
+ Client *c = sel_client();
if (c)
detach_client(c, False);
}
static void _select_page(void *obj, char *arg)
{
- Page *p = get_sel_page();
+ Page *p = selpage;
if (!p || !arg)
return;
if (!strncmp(arg, "prev", 5))
- p = cext_list_get_prev_item(pages, p);
+ p = p->prev;
else if (!strncmp(arg, "next", 5))
- p = cext_list_get_next_item(pages, p);
+ p = p->next;
else
- p = cext_list_get_item(pages, blitz_strtonum(arg, 0, cext_sizeof_container(pages) - 1));
- sel_page(p);
+ p = pageat(blitz_strtonum(arg, 0, npages - 1));
+ if (p)
+ focus_page(p);
}
static void _destroy_page(void *obj, char *arg)
{
- Page *p = get_sel_page();
+ Page *p = selpage;
if (p)
destroy_page(p);
- p = get_sel_page();
- if (p)
- sel_page(p);
+ if (selpage)
+ focus_page(selpage);
}
static void new_page(void *obj, char *arg)
{
- Page *p = get_sel_page();
+ Page *p = selpage;
if (p)
hide_page(p);
alloc_page();
}
-static int comp_client_win(void *pattern, void *client)
-{
- Window w = *(Window *)pattern;
- Client *c = client;
-
- return c->win == w;
-}
-
Client *win_to_client(Window w)
{
- return cext_find_item(clients, &w, comp_client_win);
+ Page *p;
+ Client *c;
+ for (c = detached; c; c = c->next)
+ if (c->win == w)
+ return c;
+ for (p = pages; p; p = p->next) {
+ Frame *f;
+ for (f = p->managed->layout->frames(p->managed); f; f = f->next) {
+ for (c = f->clients; c; c = c->next)
+ if (c->win == w)
+ return c;
+ }
+ for (f = p->floating->layout->frames(p->floating); f; f = f->next) {
+ for (c = f->clients; c; c = c->next)
+ if (c->win == w)
+ return c;
+ }
+ }
+ return nil;
}
void scan_wins()
@@ -533,16 +531,14 @@ int win_state(Window w)
return res;
}
-static void iter_update_area(void *area, void *aux)
+static void update_pages()
{
- Area *a = area;
- a->layout->arrange(a);
-}
+ Page *p;
-static void iter_update_page(void *page, void *aux)
-{
- Page *p = page;
- cext_list_iterate(&p->areas, nil, iter_update_area);
+ for (p = pages; p; p = p->next) {
+ p->floating->layout->arrange(p->floating);
+ p->managed->layout->arrange(p->managed);
+ }
}
void handle_before_read(IXPServer *s, File *f)
@@ -579,7 +575,7 @@ void handle_after_write(IXPServer * s, File * f)
if (geom && strrchr(geom, ',')) {
area_rect = rect;
blitz_strtorect(&rect, &area_rect, geom);
- cext_list_iterate(pages, nil, iter_update_page);
+ update_pages();
}
}
check_event(0);
@@ -708,14 +704,21 @@ static int startup_error_handler(Display * dpy, XErrorEvent * error)
return -1;
}
-static void clean_client_up(void *item, void *aux)
-{
- detach_client(item, False);
-}
-
static void cleanup()
{
- cext_list_iterate(clients, nil, clean_client_up);
+ Page *p;
+ Client *c;
+ for (p = pages; p; p = p->next) {
+ Frame *f;
+ for (f = p->managed->layout->frames(p->managed); f; f = f->next) {
+ while ((c = f->clients))
+ detach_client_from_frame(c, False);
+ }
+ for (f = p->floating->layout->frames(p->floating); f; f = f->next) {
+ while ((c = f->clients))
+ detach_client_from_frame(c, False);
+ }
+ }
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
}
@@ -785,12 +788,10 @@ int main(int argc, char *argv[])
}
def[WM_CTL]->after_write = handle_after_write;
- detached = cext_emallocz(sizeof(Container));
- pages = cext_emallocz(sizeof(Container));
- areas = cext_emallocz(sizeof(Container));
- frames = cext_emallocz(sizeof(Container));
- clients = cext_emallocz(sizeof(Container));
- layouts = cext_emallocz(sizeof(Container));
+ pages = selpage = nil;
+ ndetached = npages = 0;
+ detached = nil;
+ layouts = nil;
init_atoms();
init_cursors();
diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h
@@ -105,27 +105,32 @@ typedef struct Frame Frame;
typedef struct Client Client;
struct Page {
- Container areas;
+ Area *managed;
+ Area *floating;
+ Area *sel;
File *file[P_LAST];
+ Page *next;
+ Page *prev;
};
struct Layout {
char *name;
- void (*init) (Area *); /* called when layout is initialized */
- void (*deinit) (Area *); /* called when layout is uninitialized */
- void (*arrange) (Area *); /* called when area is resized */
- Bool (*attach) (Area *, Client *); /* called on attach */
- void (*detach) (Area *, Client *, Bool unmap); /* called on detach */
- void (*resize) (Frame *, XRectangle *, XPoint *); /* called after resize */
- void (*select) (Frame *, Bool raise); /* selection */
- Container *(*get_frames) (Area *); /* called for drawing */
- Action *(*get_actions) (Area *); /* local action table */
+ void (*init) (Area *, Client *); /* called when layout is initialized */
+ Client *(*deinit) (Area *); /* called when layout is uninitialized */
+ void (*arrange) (Area *); /* called when area is resized */
+ Bool (*attach) (Area *, Client *); /* called on attach */
+ void (*detach) (Area *, Client *, Bool unmap); /* called on detach */
+ void (*resize) (Frame *, XRectangle *, XPoint *); /* called after resize */
+ void (*focus) (Frame *, Bool raise); /* focussing a frame */
+ Frame *(*frames) (Area *); /* called for drawing */
+ Frame *(*sel) (Area *); /* returns selected frame */
+ Action *(*actions) (Area *); /* local action table */
+ Layout *next;
};
struct Area {
Page *page;
Layout *layout;
- Container clients;
void *aux; /* free pointer */
File *file[A_LAST];
};
@@ -133,16 +138,19 @@ struct Area {
struct Frame {
Area *area;
Window win;
- Container clients;
+ Client *sel;
+ Client *clients;
+ size_t nclients;
GC gc;
XRectangle rect;
Cursor cursor;
void *aux; /* free pointer */
File *file[F_LAST];
+ Frame *next;
+ Frame *prev;
};
struct Client {
- Area *area;
int proto;
unsigned int border;
unsigned int ignore_unmap;
@@ -153,10 +161,19 @@ struct Client {
XSizeHints size;
Frame *frame;
File *file[C_LAST];
+ Client *next;
+ Client *prev;
};
/* global variables */
+Page *pages;
+Page *selpage;
+size_t npages;
+Client *detached;
+size_t ndetached;
+Layout *layouts;
+
Display *dpy;
IXPServer *ixps;
int screen_num;
@@ -164,12 +181,6 @@ Window root;
Window transient;
XRectangle rect;
XRectangle area_rect;
-Container *detached;
-Container *pages;
-Container *areas;
-Container *frames;
-Container *clients;
-Container *layouts;
XFontStruct *font;
XColor xorcolor;
GC xorgc;
@@ -202,11 +213,11 @@ unsigned int valid_mask, num_lock_mask;
/* area.c */
Area *alloc_area(Page *p, char *layout);
-void destroy_area(Area * a);
-void sel_area(Area * a);
-void hide_area(Area * a);
-void show_area(Area * a);
-Area *get_sel_area();
+void destroy_area(Area *a);
+void focus_area(Area *a);
+void hide_area(Area *a);
+void show_area(Area *a, Bool raise);
+Area *sel_area();
void attach_frame_to_area(Area *a, Frame *f);
void detach_frame_from_area(Frame *f);
@@ -217,7 +228,7 @@ void destroy_client(Client * c);
void configure_client(Client * c);
void handle_client_property(Client * c, XPropertyEvent * e);
void close_client(Client * c);
-void draw_client(void *item, void *aux);
+void draw_client(Client *client);
void draw_clients(Frame * f);
void gravitate(Client * c, unsigned int tabh, unsigned int bw, int invert);
void grab_client(Client * c, unsigned long mod, unsigned int button);
@@ -225,10 +236,13 @@ void ungrab_client(Client * c, unsigned long mod, unsigned int button);
void hide_client(Client * c);
void show_client(Client * c);
void reparent_client(Client * c, Window w, int x, int y);
-void sel_client(Client *c);
+void focus_client(Client *c);
void attach_client(Client *c);
void detach_client(Client *c, Bool unmap);
-Client *get_sel_client();
+Client *sel_client();
+Client *clientat(Client *clients, size_t idx);
+void detach_detached(Client *c);
+void attach_detached(Client *c);
/* frame.c */
Frame *win_to_frame(Window w);
@@ -237,12 +251,12 @@ void destroy_frame(Frame * f);
void resize_frame(Frame *f, XRectangle *r, XPoint *pt);
void draw_frame(Frame *f);
void handle_frame_buttonpress(XButtonEvent *e, Frame *f);
-void attach_client_to_frame(Frame *f, Client *c);
-void detach_client_from_frame(Client *c, Bool unmap);
+void attach_client_to_frame(Frame *f, Client *client);
+void detach_client_from_frame(Client *client, Bool unmap);
unsigned int tab_height(Frame * f);
unsigned int border_width(Frame * f);
-Frame *get_sel_frame();
-Frame *get_sel_frame_of_area(Area *a);
+Frame *sel_frame();
+Frame *bottom_frame(Frame *frames);
/* event.c */
void init_event_hander();
@@ -258,17 +272,17 @@ void drop_move(Frame * f, XRectangle * new, XPoint * pt);
void center_pointer(Frame * f);
/* page.c */
-Page *get_sel_page();
+Page *pageat(unsigned int idx);
Page *alloc_page();
void free_page(Page * p);
void destroy_page(Page * p);
-void sel_page(Page *p);
+void focus_page(Page *p);
XRectangle *rectangles(unsigned int *num);
void hide_page(Page * p);
void show_page(Page * p);
/* layout.c */
-Layout *get_layout(char *name);
+Layout *match_layout(char *name);
/* layoutdef.c */
void init_layouts();
diff --git a/config.mk b/config.mk
@@ -11,7 +11,7 @@ LIBDIR = ${PREFIX}/lib
X11INC = /usr/X11R6/include
X11LIB = /usr/X11R6/lib
-VERSION = 20051215
+VERSION = 3-current
# includes and libs
INCLUDES = -I. -I${INCDIR} -I/usr/include -I${X11INC}
diff --git a/libcext/Makefile b/libcext/Makefile
@@ -3,7 +3,7 @@
include ../config.mk
-SRC = container.c emallocz.c estrdup.c strlcat.c strlcpy.c strtonum.c tokenize.c
+SRC = emallocz.c estrdup.c strlcat.c strlcpy.c strtonum.c tokenize.c
OBJ = ${SRC:.c=.o}
diff --git a/libcext/cext.h b/libcext/cext.h
@@ -15,39 +15,6 @@
#define TRUE 1
#endif
-/* container.c */
-typedef struct Container Container;
-typedef struct CItem CItem;
-
-struct CItem {
- void *item;
- CItem *next;
- CItem *up;
- CItem *down;
-};
-
-struct Container {
- CItem *list;
- CItem *stack;
-};
-
-void cext_attach_item(Container *c, void *item);
-void cext_detach_item(Container *c, void *item);
-void *cext_find_item(Container *c, void *pattern, int (*comp)(void *pattern, void *item));
-void cext_swap_items(Container *c, void *item1, void *item2);
-size_t cext_sizeof_container(Container *c);
-void cext_stack_top_item(Container *c, void *item);
-void *cext_stack_get_top_item(Container *c);
-void *cext_stack_get_down_item(Container *c, void *item);
-void *cext_stack_get_up_item(Container *c, void *item);
-void cext_stack_iterate_down(Container *c, void *aux, void (*iter)(void *, void *aux));
-void cext_stack_iterate_up(Container *c, void *aux, void (*iter)(void *, void *aux));
-void cext_list_iterate(Container *c, void *aux, void (*iter)(void *, void *aux));
-void *cext_list_get_item(Container *c, size_t index);
-int cext_list_get_item_index(Container *c, void *item);
-void *cext_list_get_next_item(Container *c, void *item);
-void *cext_list_get_prev_item(Container *c, void *item);
-
/* emallocz.c */
void *cext_emallocz(size_t size);
diff --git a/libcext/container.c b/libcext/container.c
@@ -1,227 +0,0 @@
-/*
- * (C)opyright MMIV-MMV Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
- */
-
-#include <assert.h>
-#include <stdlib.h>
-
-#include "cext.h"
-
-static int comp_ptr(void *p1, void *p2)
-{
- return p1 == p2;
-}
-
-static void detach_from_stack(Container *c, CItem *i)
-{
- /* remove from stack */
- if (i == c->stack) {
- c->stack = i->down;
- if (c->stack)
- c->stack->up = 0;
- }
- else {
- if (i->up)
- i->up->down = i->down;
- if (i->down)
- i->down->up = i->up;
- }
- i->up = 0;
- i->down = 0;
-}
-
-static void attach_to_stack(Container *c, CItem *i)
-{
- i->up = 0;
- i->down = 0;
- if (!c->stack)
- c->stack = i;
- else {
- i->down = c->stack;
- c->stack->up = i;
- c->stack = i;
- }
-}
-
-void cext_attach_item(Container *c, void *item)
-{
- CItem *i, *new = cext_emallocz(sizeof(CItem));
- new->item = item;
- if (!c->list)
- c->list = new;
- else {
- for (i = c->list; i->next; i = i->next);
- i->next = new;
- }
- attach_to_stack(c, new);
-}
-
-void cext_detach_item(Container *c, void *item)
-{
- CItem *i = c->list;
- if (!i)
- return;
-
- /* remove from list */
- if (i->item == item)
- c->list = i->next;
- else {
- CItem *tmp;
- for (; i->next && (i->next->item != item); i = i->next);
- if (!i->next)
- return;
- tmp = i;
- i = i->next;
- tmp->next = tmp->next->next;
- }
- detach_from_stack(c, i);
- free(i);
-}
-
-static CItem *cext_find_citem(Container *c, void *pattern, int (*comp)(void *pattern, void *item))
-{
- CItem *i;
- for (i = c->list; i && !comp(pattern, i->item); i = i->next);
- return i;
-}
-
-void *cext_find_item(Container *c, void *pattern, int (*comp)(void *pattern, void *item))
-{
- CItem *i = cext_find_citem(c, pattern, comp);
- return i ? i->item : nil;
-}
-
-size_t cext_sizeof_container(Container *c)
-{
- size_t idx = 0;
- CItem *i;
-
- for (i = c->list; i; i = i->next)
- idx++;
-
- return idx;
-}
-
-void cext_swap_items(Container *c, void *item1, void *item2)
-{
- CItem *i1 = cext_find_citem(c, item1, comp_ptr);
- CItem *i2 = cext_find_citem(c, item2, comp_ptr);
-
- i1->item = item2;
- i2->item = item1;
-}
-
-void cext_stack_top_item(Container *c, void *item)
-{
- CItem *i = cext_find_citem(c, item, comp_ptr);
- if (!i)
- return;
- detach_from_stack(c, i);
- attach_to_stack(c, i);
-}
-
-void *cext_stack_get_top_item(Container *c)
-{
- return c->stack ? c->stack->item : nil;
-}
-
-void *cext_stack_get_down_item(Container *c, void *item)
-{
- CItem *i = cext_find_citem(c, item, comp_ptr);
- if (!i)
- return nil;
- return i->down ? i->down->item : c->stack->item;
-}
-
-void *cext_stack_get_up_item(Container *c, void *item)
-{
- CItem *i = cext_find_citem(c, item, comp_ptr);
- CItem *bottom;
- if (!i)
- return nil;
- for (bottom = c->stack; bottom && bottom->down; bottom = bottom->down);
- return i->up ? i->up->item : bottom->item;
-}
-
-void cext_stack_iterate_down(Container *c, void *aux, void (*iter)(void *, void *aux))
-{
- CItem *i;
- for (i = c->stack; i; i = i->down)
- {
- assert(c);
- assert(i->item);
- iter(i->item, aux);
- }
-}
-
-void cext_stack_iterate_up(Container *c, void *aux, void (*iter)(void *, void *aux))
-{
- CItem *i;
- for (i = c->stack; i && i->down; i = i->down);
- for (; i; i = i->up)
- {
- assert(c);
- assert(i->item);
- iter(i->item, aux);
- }
-}
-
-void cext_list_iterate(Container *c, void *aux, void (*iter)(void *, void *aux))
-{
- CItem *i;
- for (i = c->list; i; i = i->next)
- {
- assert(c);
- assert(i->item);
- iter(i->item, aux);
- }
-}
-
-void *cext_list_get_item(Container *c, size_t index)
-{
- size_t idx = 0;
- CItem *i;
-
- for (i = c->list; i && index != idx; i = i->next)
- idx++;
-
- return i ? i->item : nil;
-}
-
-int cext_list_get_item_index(Container *c, void *item)
-{
- int idx = 0;
- CItem *i;
-
- for (i = c->list; i && i->item != item; i = i->next)
- idx++;
-
- return i ? idx : -1;
-}
-
-void *cext_list_get_next_item(Container *c, void *item)
-{
- size_t size = cext_sizeof_container(c);
- int idx = cext_list_get_item_index(c, item);
- if (idx == -1)
- return nil;
-
- if (idx + 1 < size)
- return cext_list_get_item(c, idx + 1);
- else
- return cext_list_get_item(c, 0);
-}
-
-void *cext_list_get_prev_item(Container *c, void *item)
-{
- size_t size = cext_sizeof_container(c);
- int idx = cext_list_get_item_index(c, item);
- if (idx == -1)
- return nil;
-
- if (idx - 1 < 0)
- return cext_list_get_item(c, size - 1);
- else
- return cext_list_get_item(c, idx - 1);
-}
diff --git a/liblitz/blitz.h b/liblitz/blitz.h
@@ -45,7 +45,7 @@ void blitz_drawlabelnoborder(Display * dpy, Draw * r);
int blitz_strtorect(XRectangle * root, XRectangle * r, char *val);
Bool blitz_ispointinrect(int x, int y, XRectangle * r);
int blitz_distance(XRectangle * origin, XRectangle * target);
-void blitz_getbasegeometry(Container *c, unsigned int *size, unsigned int *cols, unsigned int *rows);
+void blitz_getbasegeometry(unsigned int size, unsigned int *cols, unsigned int *rows);
/* mouse.c */
char *blitz_buttontostr(unsigned int button);
diff --git a/liblitz/geometry.c b/liblitz/geometry.c
@@ -198,15 +198,14 @@ int blitz_distance(XRectangle * origin, XRectangle * target)
return (int) sqrt((double) (((ox - tx) * (ox - tx)) + ((oy - ty) * (oy - ty))));
}
-void blitz_getbasegeometry(Container *c, unsigned int *size, unsigned int *cols, unsigned int *rows)
+void blitz_getbasegeometry(unsigned int size, unsigned int *cols, unsigned int *rows)
{
float sq, dummy;
- *size = cext_sizeof_container(c);
- sq = sqrt(*size);
+ sq = sqrt(size);
if (modff(sq, &dummy) < 0.5)
*rows = floor(sq);
else
*rows = ceil(sq);
- *cols = ((*rows) * (*rows)) < (*size) ? *rows + 1 : *rows;
+ *cols = ((*rows) * (*rows)) < (size) ? *rows + 1 : *rows;
}