commit e6caefcd581927b0cbdc497a64b8d66e2f643afb
parent b5f71fd3c72b5d8dc5518a3c68d6920019e36bc6
Author: Anselm R. Garbe <garbeam@wmii.de>
Date: Wed, 25 Jan 2006 19:39:08 +0200
began structural changes, don't pull yet
Diffstat:
13 files changed, 1321 insertions(+), 1425 deletions(-)
diff --git a/cmd/wm/Makefile b/cmd/wm/Makefile
@@ -3,13 +3,25 @@
include ../../config.mk
-all: layoutdef.c
- @${MAKE} -f Makefile.wm
- @echo built core wm
+CFLAGS += -I../../liblitz -I../../libixp -I../../libwmii \
+ -I../../libcext
+LDFLAGS += -L../../liblitz -llitz -L../../libixp -lixp \
+ -L../../libwmii -lwmii -L../../libcext -lcext
+# Solaris
+# LDFLAGS += -lsocket
-layoutdef.c:
- @echo SH mklayout.sh
- @sh mklayout.sh
+SRC = wm.c client.c event.c mouse.c page.c column.c
+OBJ = ${SRC:.c=.o}
+
+all: wmiiwm
+
+.c.o:
+ @echo CC $<
+ @${CC} -c ${CFLAGS} $<
+
+wmiiwm: ${OBJ}
+ @echo LD $@
+ @${CC} -o $@ ${OBJ} ${LDFLAGS}
clean:
rm -f wmiiwm *.o layoutdef.*
diff --git a/cmd/wm/Makefile.wm b/cmd/wm/Makefile.wm
@@ -1,27 +0,0 @@
-# wm - window manager improved 2
-# (C)opyright MMIV-MMVI Anselm R. Garbe
-
-include ../../config.mk
-
-CFLAGS += -I../../liblitz -I../../libixp -I../../libwmii \
- -I../../libcext
-LDFLAGS += -L../../liblitz -llitz -L../../libixp -lixp \
- -L../../libwmii -lwmii -L../../libcext -lcext
-# Solaris
-# LDFLAGS += -lsocket
-
-SRC = wm.c client.c event.c mouse.c frame.c page.c layoutdef.c layout.c
-
-include layoutdef.mk
-
-OBJ = ${SRC:.c=.o}
-
-all: wmiiwm
-
-.c.o:
- @echo CC $<
- @${CC} -c ${CFLAGS} $<
-
-wmiiwm: ${OBJ}
- @echo LD $@
- @${CC} -o $@ ${OBJ} ${LDFLAGS}
diff --git a/cmd/wm/client.c b/cmd/wm/client.c
@@ -10,18 +10,95 @@
#include "wm.h"
+static void handle_before_read_client(IXPServer * s, File * file);
+static void handle_after_write_client(IXPServer * s, File * file);
+
Client *
-alloc_client(Window w)
+alloc_client(Window w, XWindowAttributes *wa)
{
XTextProperty name;
Client *c = (Client *) cext_emallocz(sizeof(Client));
+ XSetWindowAttributes fwa;
+ size_t i;
+ static int id = 1;
+ char buf[MAX_BUF];
+ int bw, th;
+ long msize;
+ /* client itself */
c->win = w;
+ c->rect.x = wa->x;
+ c->rect.y = wa->y;
+ c->border = wa->border_width;
+ c->rect.width = wa->width + 2 * c->border;
+ c->rect.height = wa->height + 2 * c->border;
+ XSetWindowBorderWidth(dpy, c->win, 0);
+ c->proto = win_proto(c->win);
+ XGetTransientForHint(dpy, c->win, &c->trans);
+ if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize) || !c->size.flags)
+ c->size.flags = PSize;
+ XAddToSaveSet(dpy, c->win);
XGetWMName(dpy, c->win, &name);
if(name.value) {
cext_strlcpy(c->name, (char *)name.value, sizeof(c->name));
free(name.value);
}
+
+ snprintf(buf, MAX_BUF, "/detached/%d", id);
+ c->file[C_PREFIX] = ixp_create(ixps, buf);
+ snprintf(buf, MAX_BUF, "/detached/%d/name", id);
+ c->file[C_NAME] = ixp_create(ixps, buf);
+ c->file[C_NAME]->before_read = handle_before_read_client;
+ snprintf(buf, MAX_BUF, "/detached/%d/border", id);
+ c->file[C_BORDER] =
+ wmii_create_ixpfile(ixps, buf, def[WM_BORDER]->content);
+ c->file[C_BORDER]->after_write = handle_after_write_client;
+ snprintf(buf, MAX_BUF, "/detached/%d/tab", id);
+ c->file[C_TAB] = wmii_create_ixpfile(ixps, buf, def[WM_TAB]->content);
+ c->file[C_TAB]->after_write = handle_after_write_client;
+ snprintf(buf, MAX_BUF, "/detached/%d/handleinc", id);
+ c->file[C_HANDLE_INC] =
+ wmii_create_ixpfile(ixps, buf, def[WM_HANDLE_INC]->content);
+ c->file[C_HANDLE_INC]->after_write = handle_after_write_client;
+ snprintf(buf, MAX_BUF, "/detached/%d/geometry", id);
+ c->file[C_GEOMETRY] = ixp_create(ixps, buf);
+ c->file[C_GEOMETRY]->before_read = handle_before_read_client;
+ c->file[C_GEOMETRY]->after_write = handle_after_write_client;
+ id++;
+
+ /* client.frame */
+ fwa.override_redirect = 1;
+ fwa.background_pixmap = ParentRelative;
+ fwa.event_mask = SubstructureRedirectMask | ExposureMask | ButtonPressMask | PointerMotionMask;
+
+ bw = border_width(c);
+ th = tab_height(c);
+ c->frame.rect.width += 2 * bw;
+ c->frame.rect.height += bw + (th ? th : bw);
+ c->frame.win = XCreateWindow(dpy, root, c->frame.rect.x, c->frame.rect.y,
+ c->frame.rect.width, c->frame.rect.height, 0,
+ DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen),
+ CWOverrideRedirect | CWBackPixmap | CWEventMask, &fwa);
+ c->frame.cursor = normal_cursor;
+ XDefineCursor(dpy, c->frame.win, c->frame.cursor);
+ c->frame.gc = XCreateGC(dpy, c->frame.win, 0, 0);
+ XSync(dpy, False);
+
+ if(!clients) {
+ clientssz = 2;
+ clients = cext_emallocz(sizeof(Client *) * clientssz);
+ }
+ for(i = 0; (i < clientssz) && clients[i]; i++);
+ if(i >= clientssz) {
+ Client **tmp = clients;
+ clientssz *= 2;
+ clients = cext_emallocz(sizeof(Client *) * clientssz);
+ for(i = 0; tmp[i]; i++)
+ clients[i] = tmp[i];
+ free(tmp);
+ }
+ clients[i] = c;
+
return c;
}
@@ -135,23 +212,6 @@ close_client(Client * c)
}
void
-init_client(Client * c, XWindowAttributes * wa)
-{
- long msize;
- c->rect.x = wa->x;
- c->rect.y = wa->y;
- c->border = wa->border_width;
- c->rect.width = wa->width + 2 * c->border;
- c->rect.height = wa->height + 2 * c->border;
- XSetWindowBorderWidth(dpy, c->win, 0);
- c->proto = win_proto(c->win);
- XGetTransientForHint(dpy, c->win, &c->trans);
- if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize) || !c->size.flags)
- c->size.flags = PSize;
- XAddToSaveSet(dpy, c->win);
-}
-
-void
handle_client_property(Client * c, XPropertyEvent * e)
{
XTextProperty name;
@@ -196,7 +256,7 @@ destroy_client(Client * c)
void
draw_client(Client *c)
{
- Frame *f = c->frame;
+ Client *f = c->frame;
unsigned int tabh = tab_height(f);
Draw d = { 0 };
@@ -213,13 +273,13 @@ draw_client(Client *c)
d.font = font;
if(f == sel_frame()) {
- 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);
+ d.bg = blitz_loadcolor(dpy, screen, def[WM_SEL_BG_COLOR]->content);
+ d.fg = blitz_loadcolor(dpy, screen, def[WM_SEL_FG_COLOR]->content);
+ d.border = blitz_loadcolor(dpy, screen, 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.bg = blitz_loadcolor(dpy, screen, def[WM_NORM_BG_COLOR]->content);
+ d.fg = blitz_loadcolor(dpy, screen, def[WM_NORM_FG_COLOR]->content);
+ d.border = blitz_loadcolor(dpy, screen, def[WM_NORM_BORDER_COLOR]->content);
}
blitz_drawlabel(dpy, &d);
XSync(dpy, False);
@@ -310,7 +370,7 @@ attach_client(Client * c)
void
detach_client(Client * c, Bool unmap)
{
- Frame *f = c->frame;
+ Client *f = c->frame;
Layout *l = f ? f->layout : nil;
if(l)
l->def->detach(l, c, unmap);
@@ -362,3 +422,373 @@ attach_detached(Client * c)
detached = c;
ndetached++;
}
+
+
+
+Client *
+alloc_frame(XRectangle * r)
+{
+ XSetWindowAttributes wa;
+ static int id = 1;
+ char buf[MAX_BUF];
+ Client *f = (Client *) cext_emallocz(sizeof(Client));
+ int bw, th;
+
+ f->rect = *r;
+ f->cursor = normal_cursor;
+
+ snprintf(buf, MAX_BUF, "/detached/%d", id);
+ f->file[F_PREFIX] = ixp_create(ixps, buf);
+ snprintf(buf, MAX_BUF, "/detached/%d/name", id);
+ f->file[F_NAME] = ixp_create(ixps, buf);
+ f->file[F_NAME]->before_read = handle_before_read_frame;
+ snprintf(buf, MAX_BUF, "/detached/%d/border", id);
+ f->file[F_BORDER] =
+ wmii_create_ixpfile(ixps, buf, def[WM_BORDER]->content);
+ f->file[F_BORDER]->after_write = handle_after_write_frame;
+ snprintf(buf, MAX_BUF, "/detached/%d/tab", id);
+ f->file[F_TAB] = wmii_create_ixpfile(ixps, buf, def[WM_TAB]->content);
+ f->file[F_TAB]->after_write = handle_after_write_frame;
+ snprintf(buf, MAX_BUF, "/detached/%d/handleinc", id);
+ f->file[F_HANDLE_INC] =
+ wmii_create_ixpfile(ixps, buf, def[WM_HANDLE_INC]->content);
+ f->file[F_HANDLE_INC]->after_write = handle_after_write_frame;
+ snprintf(buf, MAX_BUF, "/detached/%d/geometry", id);
+ f->file[F_GEOMETRY] = ixp_create(ixps, buf);
+ f->file[F_GEOMETRY]->before_read = handle_before_read_frame;
+ f->file[F_GEOMETRY]->after_write = handle_after_write_frame;
+ id++;
+
+ wa.override_redirect = 1;
+ wa.background_pixmap = ParentRelative;
+ wa.event_mask = SubstructureRedirectMask | ExposureMask | ButtonPressMask | PointerMotionMask;
+
+ bw = border_width(c);
+ th = tab_height(c);
+ c->frame.rect.width += 2 * bw;
+ c->frame.rect.height += bw + (th ? th : bw);
+ c->frame.win = XCreateWindow(dpy, root, c->frame.rect.x, c->frame.rect.y,
+ c->frame.rect.width, c->frame.rect.height, 0,
+ DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen),
+ CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
+ c->frame.cursor = normal_cursor;
+ XDefineCursor(dpy, c->frame.win, c->frame.cursor);
+ c->frame.gc = XCreateGC(dpy, c->frame.win, 0, 0);
+ XSync(dpy, False);
+ return f;
+}
+
+Client *
+win_to_frame(Window w)
+{
+ Page *p;
+ for(p = pages; p; p = p->next) {
+ Client *f;
+ if(p->managed->def)
+ for(f = p->managed->def->frames(p->managed); f; f = f->next)
+ if(f->win == w)
+ return f;
+ for(f = p->floating->def->frames(p->floating); f; f = f->next)
+ if(f->win == w)
+ return f;
+ }
+ return nil;
+}
+
+void
+destroy_frame(Client * f)
+{
+ XFreeGC(dpy, f->gc);
+ XDestroyWindow(dpy, f->win);
+ ixp_remove_file(ixps, f->file[F_PREFIX]);
+ free(f);
+}
+
+unsigned int
+tab_height(Client * f)
+{
+ if(blitz_strtonum(f->file[F_TAB]->content, 0, 1))
+ return font->ascent + font->descent + 4;
+ return 0;
+}
+
+unsigned int
+border_width(Client * f)
+{
+ if(blitz_strtonum(f->file[F_BORDER]->content, 0, 1))
+ return BORDER_WIDTH;
+ return 0;
+}
+
+static void
+check_dimensions(Client * f, unsigned int tabh, unsigned int bw)
+{
+ Client *c = sel_client();
+ if(!c)
+ return;
+
+ if(c->size.flags & PMinSize) {
+ if(f->rect.width - 2 * bw < c->size.min_width) {
+ f->rect.width = c->size.min_width + 2 * bw;
+ }
+ if(f->rect.height - bw - (tabh ? tabh : bw) < c->size.min_height) {
+ f->rect.height = c->size.min_height + bw + (tabh ? tabh : bw);
+ }
+ }
+ if(c->size.flags & PMaxSize) {
+ if(f->rect.width - 2 * bw > c->size.max_width) {
+ f->rect.width = c->size.max_width + 2 * bw;
+ }
+ if(f->rect.height - bw - (tabh ? tabh : bw) > c->size.max_height) {
+ f->rect.height = c->size.max_height + bw + (tabh ? tabh : bw);
+ }
+ }
+}
+
+static void
+resize_incremental(Client * f, unsigned int tabh, unsigned int bw)
+{
+ Client *c = f->sel;
+ if(!c)
+ return;
+ /* increment stuff, see chapter 4.1.2.3 of the ICCCM Manual */
+ if(c->size.flags & PResizeInc) {
+ int base_width = 0, base_height = 0;
+
+ if(c->size.flags & PBaseSize) {
+ base_width = c->size.base_width;
+ base_height = c->size.base_height;
+ } else if(c->size.flags & PMinSize) {
+ /* base_{width,height} default to min_{width,height} */
+ base_width = c->size.min_width;
+ base_height = c->size.min_height;
+ }
+ /* client_width = base_width + i * c->size.width_inc for an integer i */
+ f->rect.width -=
+ (f->rect.width - 2 * bw - base_width) % c->size.width_inc;
+ f->rect.height -=
+ (f->rect.height - bw - (tabh ? tabh : bw) -
+ base_height) % c->size.height_inc;
+ }
+}
+
+void
+resize_frame(Client * f, XRectangle * r, XPoint * pt)
+{
+ Layout *l = f->layout;
+ unsigned int tabh = tab_height(f);
+ unsigned int bw = border_width(f);
+ Client *c = f->client;
+
+ l->def->resize(f, r, pt);
+
+ /* resize if client requests special size */
+ check_dimensions(f, tabh, bw);
+
+ if(f->file[F_HANDLE_INC]->content
+ && ((char *) f->file[F_HANDLE_INC]->content)[0] == '1')
+ resize_incremental(f, tabh, bw);
+
+ XMoveResizeWindow(dpy, f->win, f->rect.x, f->rect.y, f->rect.width,
+ f->rect.height);
+
+ if(f->client) {
+ 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);
+ }
+}
+
+/**
+ * Assumes following file:
+ *
+ * ./sel-style/text-font "<value>"
+ * ./sel-style/text-size "<int>"
+ * ./sel-style/text-color "#RRGGBBAA"
+ * ./sel-style/bg-color "#RRGGBBAA"
+ * ./sel-style/border-color "#RRGGBBAA [#RRGGBBAA [#RRGGBBAA [#RRGGBBAA]]]"
+ * ./norm-style/text-font "<value>"
+ * ./norm-style/text-size "<int>"
+ * ./norm-style/text-color "#RRGGBBAA"
+ * ./norm-style/bg-color "#RRGGBBAA"
+ * ./norm-style/border-color "#RRGGBBAA [#RRGGBBAA [#RRGGBBAA [#RRGGBBAA]]]"
+ */
+void
+draw_frame(Client * f)
+{
+ Draw d = { 0 };
+ int bw = border_width(f);
+ XRectangle notch;
+ if(bw) {
+ notch.x = bw;
+ notch.y = bw;
+ notch.width = f->rect.width - 2 * bw;
+ notch.height = f->rect.height - 2 * bw;
+ d.drawable = f->win;
+ d.font = font;
+ d.gc = f->gc;
+
+ /* define ground plate (i = 0) */
+ if(f == sel_frame()) {
+ d.bg = blitz_loadcolor(dpy, screen, def[WM_SEL_BG_COLOR]->content);
+ d.fg = blitz_loadcolor(dpy, screen, def[WM_SEL_FG_COLOR]->content);
+ d.border = blitz_loadcolor(dpy, screen, def[WM_SEL_BORDER_COLOR]->content);
+ } else {
+ d.bg = blitz_loadcolor(dpy, screen, def[WM_NORM_BG_COLOR]->content);
+ d.fg = blitz_loadcolor(dpy, screen, def[WM_NORM_FG_COLOR]->content);
+ d.border = blitz_loadcolor(dpy, screen, def[WM_NORM_BORDER_COLOR]->content);
+ }
+ d.rect = f->rect;
+ d.rect.x = d.rect.y = 0;
+ d.notch = ¬ch;
+
+ blitz_drawlabel(dpy, &d);
+ }
+ draw_client(f->client);
+ XSync(dpy, False);
+}
+
+void
+handle_frame_buttonpress(XButtonEvent * e, Client * f)
+{
+ Align align;
+ int bindex;
+ Layout *l = sel_layout();
+ if(l != f->layout)
+ focus_layout(f->layout);
+ l = f->layout;
+ l->def->focus(l, f->client, False);
+ if(e->button == Button1) {
+ align = cursor_to_align(f->cursor);
+ if(align == CENTER)
+ mouse_move(f);
+ else
+ mouse_resize(f, align);
+ return;
+ }
+ bindex = WM_EVENT_B2PRESS - 2 + e->button;
+ /* frame mouse handling */
+ if(def[bindex]->content)
+ wmii_spawn(dpy, def[bindex]->content);
+}
+
+void
+attach_client_to_frame(Client * f, Client * c)
+{
+ f->client = c;
+ c->frame = f;
+ resize_frame(f, &f->rect, 0);
+ reparent_client(c, f->win, c->rect.x, c->rect.y);
+ map_client(c);
+}
+
+void
+detach_client_from_frame(Client * c, Bool unmap)
+{
+ Client *f = c->frame;
+
+ c->frame = nil;
+ if(f->sel == c)
+ f->sel = nil;
+
+ f->client = nil;
+
+ if(!c->destroyed) {
+ if(!unmap) {
+ attach_detached(c);
+ unmap_client(c);
+ }
+ c->rect.x = f->rect.x;
+ c->rect.y = f->rect.y;
+ reparent_client(c, root, c->rect.x, c->rect.y);
+ }
+}
+
+static Client *
+handle_before_read_frames(IXPServer *s, File *file, Layout *l)
+{
+ Client *f;
+ char buf[32];
+ if(!l->def)
+ return nil;
+ for(f = l->def->frames(l); f; f = f->next) {
+ if(file == f->file[F_GEOMETRY]) {
+ snprintf(buf, sizeof(buf), "%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;
+ }
+ else if(file == f->file[F_NAME]) {
+ if(file->content)
+ free(file->content);
+ if(f->sel && f->sel->name) {
+ file->content = cext_estrdup(f->sel->name);
+ file->size = strlen(f->sel->name);
+ }
+ else {
+ file->content = nil;
+ file->size = 0;
+ }
+ return f;
+ }
+ }
+ return nil;
+}
+
+static void
+handle_before_read_frame(IXPServer * s, File * file)
+{
+ 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 Client *
+handle_after_write_frames(IXPServer *s, File *file, Layout *l)
+{
+ Client *f;
+ for(f = l->def->frames(l); f; f = f->next) {
+ if(file == f->file[F_TAB] || file == f->file[F_BORDER]
+ || file == f->file[F_HANDLE_INC]) {
+ f->layout->def->arrange(f->layout);
+ 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 * file)
+{
+ 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;
+ }
+}
+
+Client *
+sel_frame()
+{
+ Client *c = sel_client();
+ return c ? c->frame : nil;
+}
diff --git a/cmd/wm/column.c b/cmd/wm/column.c
@@ -0,0 +1,634 @@
+/*
+ * (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 <math.h>
+
+#include "wm.h"
+#include "layoutdef.h"
+
+typedef struct Acme Acme;
+typedef struct Column Column;
+typedef struct Cell Cell;
+
+struct Acme {
+ Column *sel;
+ Column *columns;
+ size_t ncolumns;
+ Frame *frames;
+ size_t nframes;
+};
+
+struct Cell {
+ Frame *frame;
+ Cell *next;
+ Cell *prev;
+ Column *column;
+};
+
+struct Column {
+ Cell *sel;
+ Cell *cells;
+ size_t ncells;
+ XRectangle rect;
+ Column *prev;
+ Column *next;
+};
+
+static void init_column(Layout *l, Client * clients);
+static Client *deinit_column(Layout *l);
+static void arrange_column(Layout *l);
+static Bool attach_column(Layout *l, Client * c);
+static void detach_column(Layout *l, Client * c, Bool unmap);
+static void resize_column(Frame * f, XRectangle * new, XPoint * pt);
+static void focus_column(Layout *l, Client *c, Bool raise);
+static Frame *frames_column(Layout *l);
+static Client *sel_column(Layout *l);
+static Action *actions_column(Layout *l);
+
+static void select_frame(void *obj, char *arg);
+static void max_frame(void *obj, char *arg);
+static void swap_frame(void *obj, char *arg);
+static void new_column(void *obj, char *arg);
+
+static Action lcol_acttbl[] = {
+ {"select", select_frame},
+ {"swap", swap_frame},
+ {"new", new_column},
+ {"max", max_frame},
+ {0, 0}
+};
+
+void
+init_layout_column()
+{
+ LayoutDef *lp, *l = cext_emallocz(sizeof(LayoutDef));
+ l->name = "column";
+ l->init = init_column;
+ l->deinit = deinit_column;
+ l->arrange = arrange_column;
+ l->attach = attach_column;
+ l->detach = detach_column;
+ l->resize = resize_column;
+ l->focus = focus_column;
+ l->frames = frames_column;
+ l->sel = sel_column;
+ l->actions = actions_column;
+
+ for(lp = layouts; lp && lp->next; lp = lp->next);
+ if(lp)
+ lp->next = l;
+ else
+ layouts = l;
+}
+
+static void
+xarrange_column(Column * column)
+{
+ Cell *cell;
+ unsigned int i = 0, h = layout_rect.height / column->ncells;
+ for(cell = column->cells; cell; cell = cell->next) {
+ Frame *f = cell->frame;
+ f->rect = column->rect;
+ f->rect.y = layout_rect.y + i * h;
+ if(!cell->next)
+ f->rect.height = layout_rect.height - f->rect.y + layout_rect.y;
+ else
+ f->rect.height = h;
+ resize_frame(f, &f->rect, 0);
+ i++;
+ }
+}
+
+static void
+arrange_column(Layout *l)
+{
+ Acme *acme = l->aux;
+ Column *column;
+ for(column = acme->columns; column; column = column->next)
+ xarrange_column(column);
+ XSync(dpy, False);
+}
+
+static void
+init_column(Layout *l, Client * clients)
+{
+ Client *n, *c = clients;
+
+ l->aux = cext_emallocz(sizeof(Acme));
+ while(c) {
+ n = c->next;
+ attach_column(l, c);
+ c = n;
+ }
+}
+
+static void
+attach_frame(Layout *l, Column * column, Frame * new)
+{
+ Acme *acme = l->aux;
+ Cell *c, *cell = cext_emallocz(sizeof(Cell));
+ Frame *f;
+
+ cell->frame = new;
+ cell->column = column;
+ new->aux = cell;
+ for(c = column->cells; c && c->next; c = c->next);
+ if(!c)
+ column->cells = cell;
+ else {
+ c->next = cell;
+ cell->prev = c;
+ }
+ column->ncells++;
+
+ for(f = acme->frames; f && f->next; f = f->next);
+ if(!f)
+ acme->frames = new;
+ else {
+ f->next = new;
+ new->prev = f;
+ }
+ attach_frame_to_layout(l, new);
+ acme->nframes++;
+}
+
+static void
+detach_frame(Layout *l, Frame * old)
+{
+ Acme *acme = l->aux;
+ Cell *cell = old->aux;
+ Column *column = cell->column;
+
+ if(cell->prev)
+ cell->prev->next = cell->next;
+ else
+ column->cells = cell->next;
+ if(cell->next)
+ cell->next->prev = cell->prev;
+
+ if(column->sel == cell)
+ column->sel = column->cells;
+
+ free(cell);
+ column->ncells--;
+
+ if(old->prev)
+ old->prev->next = old->next;
+ else
+ acme->frames = old->next;
+ if(old->next)
+ old->next->prev = old->prev;
+ old->prev = old->next = nil;
+ old->aux = nil;
+ detach_frame_from_layout(old);
+ acme->nframes--;
+}
+
+static Client *
+deinit_column(Layout *l)
+{
+ Acme *acme = l->aux;
+ Frame *f;
+ Client *cl, *res = nil, *c = nil;
+ Column *column = acme->columns;
+
+ while((f = acme->frames)) {
+ cl = f->client;
+ 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(l, f);
+ destroy_frame(f);
+ }
+ while((column = acme->columns)) {
+ acme->columns = column->next;
+ free(column);
+ }
+ free(acme);
+ l->aux = 0;
+ return res;
+}
+
+static Bool
+attach_column(Layout *l, Client * c)
+{
+ Acme *acme = l->aux;
+ Column *column = acme->sel;
+ Frame *f = nil;
+
+ if(!column) {
+ column = cext_emallocz(sizeof(Column));
+ column->rect = layout_rect;
+ acme->columns = acme->sel = column;
+ acme->ncolumns++;
+ }
+
+ f = alloc_frame(&c->rect);
+ attach_frame(l, column, f);
+ attach_client_to_frame(f, c);
+ xarrange_column(column);
+ if(l->page == selpage)
+ XMapWindow(dpy, f->win);
+ focus_column(l, c, True);
+ return True;
+}
+
+static void
+update_column_width(Layout *l)
+{
+ Acme *acme = l->aux;
+ unsigned int i = 0, width;
+ Column *column;
+
+ if(!acme->ncolumns)
+ return;
+
+ width = layout_rect.width / acme->ncolumns;
+ for(column = acme->columns; column; column = column->next) {
+ column->rect = layout_rect;
+ column->rect.x = i * width;
+ column->rect.width = width;
+ i++;
+ }
+ arrange_column(l);
+}
+
+static void
+detach_column(Layout *l, Client * c, Bool unmap)
+{
+ Acme *acme = l->aux;
+ Frame *f = c->frame;
+ Cell *old = f->aux;
+ Column *column = old->column;
+
+ detach_client_from_frame(c, unmap);
+ detach_frame(l, f);
+ destroy_frame(f);
+ if(column->cells) {
+ if(column->sel == old)
+ column->sel = column->cells;
+ xarrange_column(column);
+ }
+ else {
+ if(acme->sel == column) {
+ if(column->prev)
+ acme->sel = column->prev;
+ else
+ acme->sel = nil;
+ }
+ if(column->prev)
+ column->prev->next = column->next;
+ else
+ acme->columns = column->next;
+ if(column->next)
+ column->next->prev = column->prev;
+ if(!acme->sel)
+ acme->sel = acme->columns;
+ acme->ncolumns--;
+ free(column);
+ update_column_width(l);
+ }
+}
+
+static void
+match_frame_horiz(Column * column, XRectangle * r)
+{
+ Cell *cell;
+ for(cell = column->cells; cell; cell = cell->next) {
+ Frame *f = cell->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 = nil, *east = nil, *column = nil;
+ Cell *north = nil, *south = nil;
+ Cell *cell = f->aux;
+
+ column = cell->column;
+ west = column->prev;
+ east = column->next;
+ north = cell->prev;
+ south = cell->next;
+
+ /* horizontal resize */
+ if(west && (new->x != f->rect.x)) {
+ west->rect.width = new->x - west->rect.x;
+ column->rect.width += f->rect.x - new->x;
+ column->rect.x = new->x;
+ match_frame_horiz(west, &west->rect);
+ match_frame_horiz(column, &column->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;
+ column->rect.x = new->x;
+ column->rect.width = new->width;
+ match_frame_horiz(column, &column->rect);
+ match_frame_horiz(east, &east->rect);
+ }
+
+ /* vertical resize */
+ if(north && (new->y != f->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->frame, &north->frame->rect, nil);
+ resize_frame(f, &f->rect, nil);
+ }
+ if(south && (new->y + new->height != f->rect.y + f->rect.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->frame, &south->frame->rect, nil);
+ }
+}
+
+static void
+drop_moving(Frame * f, XRectangle * new, XPoint * pt)
+{
+ Layout *l = f->layout;
+ Cell *cell = f->aux;
+ Column *src = cell->column, *tgt = 0;
+ Acme *acme = l->aux;
+
+ if(!pt)
+ return;
+
+ for(tgt = acme->columns;
+ tgt && !blitz_ispointinrect(pt->x, pt->y, &tgt->rect);
+ tgt = tgt->next);
+ if(tgt) {
+ if(tgt != src) {
+ if(src->ncells < 2)
+ return;
+ detach_frame(l, f);
+ attach_frame(l, tgt, f);
+ xarrange_column(src);
+ xarrange_column(tgt);
+ focus_column(l, f->sel, True);
+ } else {
+ Cell *c;
+ for(c = src->cells;
+ c && !blitz_ispointinrect(pt->x, pt->y, &c->frame->rect);
+ c = c->next);
+ if(c && c != cell) {
+ Frame *tmp = c->frame;
+ c->frame = f;
+ cell->frame = tmp;
+ xarrange_column(src);
+ focus_column(l, f->sel, True);
+ }
+ }
+ }
+}
+
+static void
+resize_column(Frame * f, XRectangle * new, XPoint * pt)
+{
+ if((f->rect.width == new->width)
+ && (f->rect.height == new->height))
+ drop_moving(f, new, pt);
+ else
+ drop_resize(f, new);
+}
+
+static void
+focus_column(Layout *l, Client *c, Bool raise)
+{
+ Acme *acme = l->aux;
+ Cell *cell = c->frame->aux;
+ Client *old = sel_client();
+
+ c->frame->sel = c;
+ acme->sel = cell->column;
+ cell->column->sel = cell;
+ l->file[L_SEL_FRAME]->content = c->frame->file[F_PREFIX]->content;
+
+ if(raise)
+ XWarpPointer(dpy, None, c->win, 0, 0, 0, 0,
+ c->rect.width / 2, c->rect.height / 2);
+
+ focus_client(c, old);
+}
+
+static Frame *
+frames_column(Layout *l)
+{
+ Acme *acme = l->aux;
+ return acme->frames;
+}
+
+static Client *
+sel_column(Layout *l)
+{
+ Acme *acme = l->aux;
+ Column *column = acme->sel;
+
+ if(column && column->sel)
+ return column->sel->frame->sel;
+ return nil;
+}
+
+static Action *
+actions_column(Layout *l)
+{
+ return lcol_acttbl;
+}
+
+static void
+max_frame(void *obj, char *arg)
+{
+ Layout *l = obj;
+ Acme *acme = l->aux;
+ Column *c = acme->sel;
+ Cell *cell;
+ Frame *f;
+
+ if(!c)
+ return;
+
+ cell = c->sel;
+ if(!cell)
+ return;
+
+ f = cell->frame;
+ if(f->maximized) {
+ f->rect = f->old;
+ resize_frame(f, &f->old, nil);
+ f->maximized = False;
+ }
+ else {
+ f->old = f->rect;
+ f->rect = c->rect;
+ XRaiseWindow(dpy, f->win);
+ resize_frame(f, &c->rect, nil);
+ f->maximized = True;
+ }
+}
+
+static void
+select_frame(void *obj, char *arg)
+{
+ Layout *l = obj;
+ Acme *acme = l->aux;
+ Column *c, *column = acme->sel;
+ Cell *cell;
+
+ if(!column)
+ return;
+
+ cell = column->sel;
+ if(!cell || !arg)
+ return;
+ if(!strncmp(arg, "prev", 5)) {
+ if(cell->prev)
+ cell = cell->prev;
+ else
+ for(cell = column->cells; cell && cell->next; cell = cell->next);
+ } else if(!strncmp(arg, "next", 5)) {
+ if(cell->next)
+ cell = cell->next;
+ else
+ cell = column->cells;
+ } else if(!strncmp(arg, "west", 5)) {
+ if(column->prev)
+ cell = column->prev->sel;
+ else {
+ for(c = acme->columns; c && c->next; c = c->next);
+ cell = c->sel;
+ }
+ } else if(!strncmp(arg, "east", 5)) {
+ if(column->next)
+ cell = column->next->sel;
+ else
+ cell = acme->columns->sel;
+ } else {
+ unsigned int i = 0, idx = blitz_strtonum(arg, 0, column->ncells - 1);
+ for(cell = column->cells; cell && i != idx; cell = cell->next)
+ i++;
+ }
+ if(cell && cell != column->sel)
+ focus_column(l, cell->frame->sel, True);
+}
+
+static void
+swap_frame(void *obj, char *arg)
+{
+ Layout *l = obj;
+ Acme *acme = l->aux;
+ Column *west = nil, *east = nil, *column = acme->sel;
+ Cell *north = nil, *south = nil, *cell = column->sel;
+ Frame *f;
+ XRectangle r;
+
+ if(!column || !cell || !arg)
+ return;
+
+ west = column->prev;
+ east = column->next;
+ north = cell->prev;
+ south = cell->next;
+
+ if(!west)
+ west = east;
+ if(!east)
+ east = west;
+
+ if(!strncmp(arg, "north", 6) && north) {
+ r = north->frame->rect;
+ north->frame->rect = cell->frame->rect;
+ cell->frame->rect = r;
+ f = north->frame;
+ north->frame = cell->frame;
+ cell->frame = f;
+ cell->frame->aux = cell;
+ north->frame->aux = north;
+ resize_frame(cell->frame, &cell->frame->rect, nil);
+ resize_frame(north->frame, &north->frame->rect, nil);
+ focus_column(l, cell->frame->sel, True);
+ } else if(!strncmp(arg, "south", 6) && south) {
+ r = south->frame->rect;
+ south->frame->rect = cell->frame->rect;
+ cell->frame->rect = r;
+ f = south->frame;
+ south->frame = cell->frame;
+ cell->frame = f;
+ cell->frame->aux = cell;
+ south->frame->aux = south;
+ resize_frame(cell->frame, &cell->frame->rect, nil);
+ resize_frame(south->frame, &south->frame->rect, nil);
+ focus_column(l, cell->frame->sel, True);
+ } else if(!strncmp(arg, "west", 5) && west && column->ncells && west->ncells) {
+ Cell *other = west->sel;
+ r = other->frame->rect;
+ other->frame->rect = cell->frame->rect;
+ cell->frame->rect = r;
+ f = other->frame;
+ other->frame = cell->frame;
+ cell->frame = f;
+ other->frame->aux = other;
+ cell->frame->aux = cell;
+ resize_frame(cell->frame, &cell->frame->rect, nil);
+ resize_frame(other->frame, &other->frame->rect, nil);
+ focus_column(l, other->frame->sel, True);
+ } else if(!strncmp(arg, "east", 5) && east && column->ncells && east->ncells) {
+ Cell *other = east->sel;
+ r = other->frame->rect;
+ other->frame->rect = cell->frame->rect;
+ cell->frame->rect = r;
+ f = other->frame;
+ other->frame = cell->frame;
+ cell->frame = f;
+ other->frame->aux = other;
+ cell->frame->aux = cell;
+ resize_frame(cell->frame, &cell->frame->rect, nil);
+ resize_frame(other->frame, &other->frame->rect, nil);
+ focus_column(l, other->frame->sel, True);
+ }
+}
+
+static void
+new_column(void *obj, char *arg)
+{
+ Layout *l = obj;
+ Acme *acme = l->aux;
+ Column *c, *new, *column = acme->sel;
+ Frame *f;
+
+ if(!column || column->ncells < 2)
+ return;
+
+ f = column->sel->frame;
+ for(c = acme->columns; c && c->next; c = c->next);
+
+ new = cext_emallocz(sizeof(Column));
+ new->rect = layout_rect;
+ new->prev = c;
+ c->next = new;
+ acme->ncolumns++;
+ acme->sel = new;
+
+ detach_frame(l, f);
+ attach_frame(l, new, f);
+
+ update_column_width(l);
+ focus_column(l, f->sel, True);
+}
diff --git a/cmd/wm/event.c b/cmd/wm/event.c
@@ -208,7 +208,7 @@ handle_maprequest(XEvent * e)
/* attach heuristic support */
if(attachqueue && (attachqueue->page != selpage)) {
- AttachQueue *r = attachqueue;
+ MapQueue *r = attachqueue;
focus_page(r->page);
attachqueue = attachqueue->next;
free(r);
diff --git a/cmd/wm/frame.c b/cmd/wm/frame.c
@@ -1,384 +0,0 @@
-/*
- * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
- */
-
-#include <assert.h>
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "wm.h"
-
-static void handle_after_write_frame(IXPServer * s, File * file);
-static void handle_before_read_frame(IXPServer * s, File * file);
-
-Frame *
-alloc_frame(XRectangle * r)
-{
- XSetWindowAttributes wa;
- static int id = 1;
- char buf[MAX_BUF];
- Frame *f = (Frame *) cext_emallocz(sizeof(Frame));
- int bw, th;
-
- f->rect = *r;
- f->cursor = normal_cursor;
-
- snprintf(buf, MAX_BUF, "/detached/%d", id);
- f->file[F_PREFIX] = ixp_create(ixps, buf);
- snprintf(buf, MAX_BUF, "/detached/%d/name", id);
- f->file[F_NAME] = ixp_create(ixps, buf);
- f->file[F_NAME]->before_read = handle_before_read_frame;
- snprintf(buf, MAX_BUF, "/detached/%d/border", id);
- f->file[F_BORDER] =
- wmii_create_ixpfile(ixps, buf, def[WM_BORDER]->content);
- f->file[F_BORDER]->after_write = handle_after_write_frame;
- snprintf(buf, MAX_BUF, "/detached/%d/tab", id);
- f->file[F_TAB] = wmii_create_ixpfile(ixps, buf, def[WM_TAB]->content);
- f->file[F_TAB]->after_write = handle_after_write_frame;
- snprintf(buf, MAX_BUF, "/detached/%d/handleinc", id);
- f->file[F_HANDLE_INC] =
- wmii_create_ixpfile(ixps, buf, def[WM_HANDLE_INC]->content);
- f->file[F_HANDLE_INC]->after_write = handle_after_write_frame;
- snprintf(buf, MAX_BUF, "/detached/%d/geometry", id);
- f->file[F_GEOMETRY] = ixp_create(ixps, buf);
- f->file[F_GEOMETRY]->before_read = handle_before_read_frame;
- f->file[F_GEOMETRY]->after_write = handle_after_write_frame;
- id++;
-
- wa.override_redirect = 1;
- wa.background_pixmap = ParentRelative;
- wa.event_mask =
- SubstructureRedirectMask | ExposureMask | ButtonPressMask |
- PointerMotionMask;
-
- bw = border_width(f);
- th = tab_height(f);
- f->rect.width += 2 * bw;
- f->rect.height += bw + (th ? th : bw);
- f->win = XCreateWindow(dpy, root, f->rect.x, f->rect.y, f->rect.width,
- f->rect.height, 0, DefaultDepth(dpy, screen_num),
- CopyFromParent, DefaultVisual(dpy, screen_num),
- CWOverrideRedirect | CWBackPixmap | CWEventMask,
- &wa);
- XDefineCursor(dpy, f->win, f->cursor);
- f->gc = XCreateGC(dpy, f->win, 0, 0);
- XSync(dpy, False);
- return f;
-}
-
-Frame *
-win_to_frame(Window w)
-{
- Page *p;
- for(p = pages; p; p = p->next) {
- Frame *f;
- if(p->managed->def)
- for(f = p->managed->def->frames(p->managed); f; f = f->next)
- if(f->win == w)
- return f;
- for(f = p->floating->def->frames(p->floating); f; f = f->next)
- if(f->win == w)
- return f;
- }
- return nil;
-}
-
-void
-destroy_frame(Frame * f)
-{
- XFreeGC(dpy, f->gc);
- XDestroyWindow(dpy, f->win);
- ixp_remove_file(ixps, f->file[F_PREFIX]);
- free(f);
-}
-
-unsigned int
-tab_height(Frame * f)
-{
- if(blitz_strtonum(f->file[F_TAB]->content, 0, 1))
- return font->ascent + font->descent + 4;
- return 0;
-}
-
-unsigned int
-border_width(Frame * f)
-{
- if(blitz_strtonum(f->file[F_BORDER]->content, 0, 1))
- return BORDER_WIDTH;
- return 0;
-}
-
-static void
-check_dimensions(Frame * f, unsigned int tabh, unsigned int bw)
-{
- Client *c = sel_client();
- if(!c)
- return;
-
- if(c->size.flags & PMinSize) {
- if(f->rect.width - 2 * bw < c->size.min_width) {
- f->rect.width = c->size.min_width + 2 * bw;
- }
- if(f->rect.height - bw - (tabh ? tabh : bw) < c->size.min_height) {
- f->rect.height = c->size.min_height + bw + (tabh ? tabh : bw);
- }
- }
- if(c->size.flags & PMaxSize) {
- if(f->rect.width - 2 * bw > c->size.max_width) {
- f->rect.width = c->size.max_width + 2 * bw;
- }
- if(f->rect.height - bw - (tabh ? tabh : bw) > c->size.max_height) {
- f->rect.height = c->size.max_height + bw + (tabh ? tabh : bw);
- }
- }
-}
-
-static void
-resize_incremental(Frame * f, unsigned int tabh, unsigned int bw)
-{
- Client *c = f->sel;
- if(!c)
- return;
- /* increment stuff, see chapter 4.1.2.3 of the ICCCM Manual */
- if(c->size.flags & PResizeInc) {
- int base_width = 0, base_height = 0;
-
- if(c->size.flags & PBaseSize) {
- base_width = c->size.base_width;
- base_height = c->size.base_height;
- } else if(c->size.flags & PMinSize) {
- /* base_{width,height} default to min_{width,height} */
- base_width = c->size.min_width;
- base_height = c->size.min_height;
- }
- /* client_width = base_width + i * c->size.width_inc for an integer i */
- f->rect.width -=
- (f->rect.width - 2 * bw - base_width) % c->size.width_inc;
- f->rect.height -=
- (f->rect.height - bw - (tabh ? tabh : bw) -
- base_height) % c->size.height_inc;
- }
-}
-
-void
-resize_frame(Frame * f, XRectangle * r, XPoint * pt)
-{
- Layout *l = f->layout;
- unsigned int tabh = tab_height(f);
- unsigned int bw = border_width(f);
- Client *c = f->client;
-
- l->def->resize(f, r, pt);
-
- /* resize if client requests special size */
- check_dimensions(f, tabh, bw);
-
- if(f->file[F_HANDLE_INC]->content
- && ((char *) f->file[F_HANDLE_INC]->content)[0] == '1')
- resize_incremental(f, tabh, bw);
-
- XMoveResizeWindow(dpy, f->win, f->rect.x, f->rect.y, f->rect.width,
- f->rect.height);
-
- if(f->client) {
- 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);
- }
-}
-
-/**
- * Assumes following file:
- *
- * ./sel-style/text-font "<value>"
- * ./sel-style/text-size "<int>"
- * ./sel-style/text-color "#RRGGBBAA"
- * ./sel-style/bg-color "#RRGGBBAA"
- * ./sel-style/border-color "#RRGGBBAA [#RRGGBBAA [#RRGGBBAA [#RRGGBBAA]]]"
- * ./norm-style/text-font "<value>"
- * ./norm-style/text-size "<int>"
- * ./norm-style/text-color "#RRGGBBAA"
- * ./norm-style/bg-color "#RRGGBBAA"
- * ./norm-style/border-color "#RRGGBBAA [#RRGGBBAA [#RRGGBBAA [#RRGGBBAA]]]"
- */
-void
-draw_frame(Frame * f)
-{
- Draw d = { 0 };
- int bw = border_width(f);
- XRectangle notch;
- if(bw) {
- notch.x = bw;
- notch.y = bw;
- notch.width = f->rect.width - 2 * bw;
- notch.height = f->rect.height - 2 * bw;
- d.drawable = f->win;
- d.font = font;
- d.gc = f->gc;
-
- /* define ground plate (i = 0) */
- if(f == sel_frame()) {
- 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.rect = f->rect;
- d.rect.x = d.rect.y = 0;
- d.notch = ¬ch;
-
- blitz_drawlabel(dpy, &d);
- }
- draw_client(f->client);
- XSync(dpy, False);
-}
-
-void
-handle_frame_buttonpress(XButtonEvent * e, Frame * f)
-{
- Align align;
- int bindex;
- Layout *l = sel_layout();
- if(l != f->layout)
- focus_layout(f->layout);
- l = f->layout;
- l->def->focus(l, f->client, False);
- if(e->button == Button1) {
- align = cursor_to_align(f->cursor);
- if(align == CENTER)
- mouse_move(f);
- else
- mouse_resize(f, align);
- return;
- }
- bindex = WM_EVENT_B2PRESS - 2 + e->button;
- /* frame mouse handling */
- if(def[bindex]->content)
- wmii_spawn(dpy, def[bindex]->content);
-}
-
-void
-attach_client_to_frame(Frame * f, Client * c)
-{
- f->client = c;
- c->frame = f;
- resize_frame(f, &f->rect, 0);
- reparent_client(c, f->win, c->rect.x, c->rect.y);
- map_client(c);
-}
-
-void
-detach_client_from_frame(Client * c, Bool unmap)
-{
- Frame *f = c->frame;
-
- c->frame = nil;
- if(f->sel == c)
- f->sel = nil;
-
- f->client = nil;
-
- if(!c->destroyed) {
- if(!unmap) {
- attach_detached(c);
- unmap_client(c);
- }
- c->rect.x = f->rect.x;
- c->rect.y = f->rect.y;
- reparent_client(c, root, c->rect.x, c->rect.y);
- }
-}
-
-static Frame *
-handle_before_read_frames(IXPServer *s, File *file, Layout *l)
-{
- Frame *f;
- char buf[32];
- if(!l->def)
- return nil;
- for(f = l->def->frames(l); f; f = f->next) {
- if(file == f->file[F_GEOMETRY]) {
- snprintf(buf, sizeof(buf), "%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;
- }
- else if(file == f->file[F_NAME]) {
- if(file->content)
- free(file->content);
- if(f->sel && f->sel->name) {
- file->content = cext_estrdup(f->sel->name);
- file->size = strlen(f->sel->name);
- }
- else {
- file->content = nil;
- file->size = 0;
- }
- return f;
- }
- }
- return nil;
-}
-
-static void
-handle_before_read_frame(IXPServer * s, File * file)
-{
- 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 Frame *
-handle_after_write_frames(IXPServer *s, File *file, Layout *l)
-{
- Frame *f;
- for(f = l->def->frames(l); f; f = f->next) {
- if(file == f->file[F_TAB] || file == f->file[F_BORDER]
- || file == f->file[F_HANDLE_INC]) {
- f->layout->def->arrange(f->layout);
- 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 * file)
-{
- 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 *
-sel_frame()
-{
- Client *c = sel_client();
- return c ? c->frame : nil;
-}
diff --git a/cmd/wm/layout_column.c b/cmd/wm/layout_column.c
@@ -1,634 +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 <math.h>
-
-#include "wm.h"
-#include "layoutdef.h"
-
-typedef struct Acme Acme;
-typedef struct Column Column;
-typedef struct Cell Cell;
-
-struct Acme {
- Column *sel;
- Column *columns;
- size_t ncolumns;
- Frame *frames;
- size_t nframes;
-};
-
-struct Cell {
- Frame *frame;
- Cell *next;
- Cell *prev;
- Column *column;
-};
-
-struct Column {
- Cell *sel;
- Cell *cells;
- size_t ncells;
- XRectangle rect;
- Column *prev;
- Column *next;
-};
-
-static void init_column(Layout *l, Client * clients);
-static Client *deinit_column(Layout *l);
-static void arrange_column(Layout *l);
-static Bool attach_column(Layout *l, Client * c);
-static void detach_column(Layout *l, Client * c, Bool unmap);
-static void resize_column(Frame * f, XRectangle * new, XPoint * pt);
-static void focus_column(Layout *l, Client *c, Bool raise);
-static Frame *frames_column(Layout *l);
-static Client *sel_column(Layout *l);
-static Action *actions_column(Layout *l);
-
-static void select_frame(void *obj, char *arg);
-static void max_frame(void *obj, char *arg);
-static void swap_frame(void *obj, char *arg);
-static void new_column(void *obj, char *arg);
-
-static Action lcol_acttbl[] = {
- {"select", select_frame},
- {"swap", swap_frame},
- {"new", new_column},
- {"max", max_frame},
- {0, 0}
-};
-
-void
-init_layout_column()
-{
- LayoutDef *lp, *l = cext_emallocz(sizeof(LayoutDef));
- l->name = "column";
- l->init = init_column;
- l->deinit = deinit_column;
- l->arrange = arrange_column;
- l->attach = attach_column;
- l->detach = detach_column;
- l->resize = resize_column;
- l->focus = focus_column;
- l->frames = frames_column;
- l->sel = sel_column;
- l->actions = actions_column;
-
- for(lp = layouts; lp && lp->next; lp = lp->next);
- if(lp)
- lp->next = l;
- else
- layouts = l;
-}
-
-static void
-xarrange_column(Column * column)
-{
- Cell *cell;
- unsigned int i = 0, h = layout_rect.height / column->ncells;
- for(cell = column->cells; cell; cell = cell->next) {
- Frame *f = cell->frame;
- f->rect = column->rect;
- f->rect.y = layout_rect.y + i * h;
- if(!cell->next)
- f->rect.height = layout_rect.height - f->rect.y + layout_rect.y;
- else
- f->rect.height = h;
- resize_frame(f, &f->rect, 0);
- i++;
- }
-}
-
-static void
-arrange_column(Layout *l)
-{
- Acme *acme = l->aux;
- Column *column;
- for(column = acme->columns; column; column = column->next)
- xarrange_column(column);
- XSync(dpy, False);
-}
-
-static void
-init_column(Layout *l, Client * clients)
-{
- Client *n, *c = clients;
-
- l->aux = cext_emallocz(sizeof(Acme));
- while(c) {
- n = c->next;
- attach_column(l, c);
- c = n;
- }
-}
-
-static void
-attach_frame(Layout *l, Column * column, Frame * new)
-{
- Acme *acme = l->aux;
- Cell *c, *cell = cext_emallocz(sizeof(Cell));
- Frame *f;
-
- cell->frame = new;
- cell->column = column;
- new->aux = cell;
- for(c = column->cells; c && c->next; c = c->next);
- if(!c)
- column->cells = cell;
- else {
- c->next = cell;
- cell->prev = c;
- }
- column->ncells++;
-
- for(f = acme->frames; f && f->next; f = f->next);
- if(!f)
- acme->frames = new;
- else {
- f->next = new;
- new->prev = f;
- }
- attach_frame_to_layout(l, new);
- acme->nframes++;
-}
-
-static void
-detach_frame(Layout *l, Frame * old)
-{
- Acme *acme = l->aux;
- Cell *cell = old->aux;
- Column *column = cell->column;
-
- if(cell->prev)
- cell->prev->next = cell->next;
- else
- column->cells = cell->next;
- if(cell->next)
- cell->next->prev = cell->prev;
-
- if(column->sel == cell)
- column->sel = column->cells;
-
- free(cell);
- column->ncells--;
-
- if(old->prev)
- old->prev->next = old->next;
- else
- acme->frames = old->next;
- if(old->next)
- old->next->prev = old->prev;
- old->prev = old->next = nil;
- old->aux = nil;
- detach_frame_from_layout(old);
- acme->nframes--;
-}
-
-static Client *
-deinit_column(Layout *l)
-{
- Acme *acme = l->aux;
- Frame *f;
- Client *cl, *res = nil, *c = nil;
- Column *column = acme->columns;
-
- while((f = acme->frames)) {
- cl = f->client;
- 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(l, f);
- destroy_frame(f);
- }
- while((column = acme->columns)) {
- acme->columns = column->next;
- free(column);
- }
- free(acme);
- l->aux = 0;
- return res;
-}
-
-static Bool
-attach_column(Layout *l, Client * c)
-{
- Acme *acme = l->aux;
- Column *column = acme->sel;
- Frame *f = nil;
-
- if(!column) {
- column = cext_emallocz(sizeof(Column));
- column->rect = layout_rect;
- acme->columns = acme->sel = column;
- acme->ncolumns++;
- }
-
- f = alloc_frame(&c->rect);
- attach_frame(l, column, f);
- attach_client_to_frame(f, c);
- xarrange_column(column);
- if(l->page == selpage)
- XMapWindow(dpy, f->win);
- focus_column(l, c, True);
- return True;
-}
-
-static void
-update_column_width(Layout *l)
-{
- Acme *acme = l->aux;
- unsigned int i = 0, width;
- Column *column;
-
- if(!acme->ncolumns)
- return;
-
- width = layout_rect.width / acme->ncolumns;
- for(column = acme->columns; column; column = column->next) {
- column->rect = layout_rect;
- column->rect.x = i * width;
- column->rect.width = width;
- i++;
- }
- arrange_column(l);
-}
-
-static void
-detach_column(Layout *l, Client * c, Bool unmap)
-{
- Acme *acme = l->aux;
- Frame *f = c->frame;
- Cell *old = f->aux;
- Column *column = old->column;
-
- detach_client_from_frame(c, unmap);
- detach_frame(l, f);
- destroy_frame(f);
- if(column->cells) {
- if(column->sel == old)
- column->sel = column->cells;
- xarrange_column(column);
- }
- else {
- if(acme->sel == column) {
- if(column->prev)
- acme->sel = column->prev;
- else
- acme->sel = nil;
- }
- if(column->prev)
- column->prev->next = column->next;
- else
- acme->columns = column->next;
- if(column->next)
- column->next->prev = column->prev;
- if(!acme->sel)
- acme->sel = acme->columns;
- acme->ncolumns--;
- free(column);
- update_column_width(l);
- }
-}
-
-static void
-match_frame_horiz(Column * column, XRectangle * r)
-{
- Cell *cell;
- for(cell = column->cells; cell; cell = cell->next) {
- Frame *f = cell->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 = nil, *east = nil, *column = nil;
- Cell *north = nil, *south = nil;
- Cell *cell = f->aux;
-
- column = cell->column;
- west = column->prev;
- east = column->next;
- north = cell->prev;
- south = cell->next;
-
- /* horizontal resize */
- if(west && (new->x != f->rect.x)) {
- west->rect.width = new->x - west->rect.x;
- column->rect.width += f->rect.x - new->x;
- column->rect.x = new->x;
- match_frame_horiz(west, &west->rect);
- match_frame_horiz(column, &column->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;
- column->rect.x = new->x;
- column->rect.width = new->width;
- match_frame_horiz(column, &column->rect);
- match_frame_horiz(east, &east->rect);
- }
-
- /* vertical resize */
- if(north && (new->y != f->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->frame, &north->frame->rect, nil);
- resize_frame(f, &f->rect, nil);
- }
- if(south && (new->y + new->height != f->rect.y + f->rect.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->frame, &south->frame->rect, nil);
- }
-}
-
-static void
-drop_moving(Frame * f, XRectangle * new, XPoint * pt)
-{
- Layout *l = f->layout;
- Cell *cell = f->aux;
- Column *src = cell->column, *tgt = 0;
- Acme *acme = l->aux;
-
- if(!pt)
- return;
-
- for(tgt = acme->columns;
- tgt && !blitz_ispointinrect(pt->x, pt->y, &tgt->rect);
- tgt = tgt->next);
- if(tgt) {
- if(tgt != src) {
- if(src->ncells < 2)
- return;
- detach_frame(l, f);
- attach_frame(l, tgt, f);
- xarrange_column(src);
- xarrange_column(tgt);
- focus_column(l, f->sel, True);
- } else {
- Cell *c;
- for(c = src->cells;
- c && !blitz_ispointinrect(pt->x, pt->y, &c->frame->rect);
- c = c->next);
- if(c && c != cell) {
- Frame *tmp = c->frame;
- c->frame = f;
- cell->frame = tmp;
- xarrange_column(src);
- focus_column(l, f->sel, True);
- }
- }
- }
-}
-
-static void
-resize_column(Frame * f, XRectangle * new, XPoint * pt)
-{
- if((f->rect.width == new->width)
- && (f->rect.height == new->height))
- drop_moving(f, new, pt);
- else
- drop_resize(f, new);
-}
-
-static void
-focus_column(Layout *l, Client *c, Bool raise)
-{
- Acme *acme = l->aux;
- Cell *cell = c->frame->aux;
- Client *old = sel_client();
-
- c->frame->sel = c;
- acme->sel = cell->column;
- cell->column->sel = cell;
- l->file[L_SEL_FRAME]->content = c->frame->file[F_PREFIX]->content;
-
- if(raise)
- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0,
- c->rect.width / 2, c->rect.height / 2);
-
- focus_client(c, old);
-}
-
-static Frame *
-frames_column(Layout *l)
-{
- Acme *acme = l->aux;
- return acme->frames;
-}
-
-static Client *
-sel_column(Layout *l)
-{
- Acme *acme = l->aux;
- Column *column = acme->sel;
-
- if(column && column->sel)
- return column->sel->frame->sel;
- return nil;
-}
-
-static Action *
-actions_column(Layout *l)
-{
- return lcol_acttbl;
-}
-
-static void
-max_frame(void *obj, char *arg)
-{
- Layout *l = obj;
- Acme *acme = l->aux;
- Column *c = acme->sel;
- Cell *cell;
- Frame *f;
-
- if(!c)
- return;
-
- cell = c->sel;
- if(!cell)
- return;
-
- f = cell->frame;
- if(f->maximized) {
- f->rect = f->old;
- resize_frame(f, &f->old, nil);
- f->maximized = False;
- }
- else {
- f->old = f->rect;
- f->rect = c->rect;
- XRaiseWindow(dpy, f->win);
- resize_frame(f, &c->rect, nil);
- f->maximized = True;
- }
-}
-
-static void
-select_frame(void *obj, char *arg)
-{
- Layout *l = obj;
- Acme *acme = l->aux;
- Column *c, *column = acme->sel;
- Cell *cell;
-
- if(!column)
- return;
-
- cell = column->sel;
- if(!cell || !arg)
- return;
- if(!strncmp(arg, "prev", 5)) {
- if(cell->prev)
- cell = cell->prev;
- else
- for(cell = column->cells; cell && cell->next; cell = cell->next);
- } else if(!strncmp(arg, "next", 5)) {
- if(cell->next)
- cell = cell->next;
- else
- cell = column->cells;
- } else if(!strncmp(arg, "west", 5)) {
- if(column->prev)
- cell = column->prev->sel;
- else {
- for(c = acme->columns; c && c->next; c = c->next);
- cell = c->sel;
- }
- } else if(!strncmp(arg, "east", 5)) {
- if(column->next)
- cell = column->next->sel;
- else
- cell = acme->columns->sel;
- } else {
- unsigned int i = 0, idx = blitz_strtonum(arg, 0, column->ncells - 1);
- for(cell = column->cells; cell && i != idx; cell = cell->next)
- i++;
- }
- if(cell && cell != column->sel)
- focus_column(l, cell->frame->sel, True);
-}
-
-static void
-swap_frame(void *obj, char *arg)
-{
- Layout *l = obj;
- Acme *acme = l->aux;
- Column *west = nil, *east = nil, *column = acme->sel;
- Cell *north = nil, *south = nil, *cell = column->sel;
- Frame *f;
- XRectangle r;
-
- if(!column || !cell || !arg)
- return;
-
- west = column->prev;
- east = column->next;
- north = cell->prev;
- south = cell->next;
-
- if(!west)
- west = east;
- if(!east)
- east = west;
-
- if(!strncmp(arg, "north", 6) && north) {
- r = north->frame->rect;
- north->frame->rect = cell->frame->rect;
- cell->frame->rect = r;
- f = north->frame;
- north->frame = cell->frame;
- cell->frame = f;
- cell->frame->aux = cell;
- north->frame->aux = north;
- resize_frame(cell->frame, &cell->frame->rect, nil);
- resize_frame(north->frame, &north->frame->rect, nil);
- focus_column(l, cell->frame->sel, True);
- } else if(!strncmp(arg, "south", 6) && south) {
- r = south->frame->rect;
- south->frame->rect = cell->frame->rect;
- cell->frame->rect = r;
- f = south->frame;
- south->frame = cell->frame;
- cell->frame = f;
- cell->frame->aux = cell;
- south->frame->aux = south;
- resize_frame(cell->frame, &cell->frame->rect, nil);
- resize_frame(south->frame, &south->frame->rect, nil);
- focus_column(l, cell->frame->sel, True);
- } else if(!strncmp(arg, "west", 5) && west && column->ncells && west->ncells) {
- Cell *other = west->sel;
- r = other->frame->rect;
- other->frame->rect = cell->frame->rect;
- cell->frame->rect = r;
- f = other->frame;
- other->frame = cell->frame;
- cell->frame = f;
- other->frame->aux = other;
- cell->frame->aux = cell;
- resize_frame(cell->frame, &cell->frame->rect, nil);
- resize_frame(other->frame, &other->frame->rect, nil);
- focus_column(l, other->frame->sel, True);
- } else if(!strncmp(arg, "east", 5) && east && column->ncells && east->ncells) {
- Cell *other = east->sel;
- r = other->frame->rect;
- other->frame->rect = cell->frame->rect;
- cell->frame->rect = r;
- f = other->frame;
- other->frame = cell->frame;
- cell->frame = f;
- other->frame->aux = other;
- cell->frame->aux = cell;
- resize_frame(cell->frame, &cell->frame->rect, nil);
- resize_frame(other->frame, &other->frame->rect, nil);
- focus_column(l, other->frame->sel, True);
- }
-}
-
-static void
-new_column(void *obj, char *arg)
-{
- Layout *l = obj;
- Acme *acme = l->aux;
- Column *c, *new, *column = acme->sel;
- Frame *f;
-
- if(!column || column->ncells < 2)
- return;
-
- f = column->sel->frame;
- for(c = acme->columns; c && c->next; c = c->next);
-
- new = cext_emallocz(sizeof(Column));
- new->rect = layout_rect;
- new->prev = c;
- c->next = new;
- acme->ncolumns++;
- acme->sel = new;
-
- detach_frame(l, f);
- attach_frame(l, new, f);
-
- update_column_width(l);
- focus_column(l, f->sel, True);
-}
diff --git a/cmd/wm/mklayout.sh b/cmd/wm/mklayout.sh
@@ -1,12 +0,0 @@
-#!/bin/sh
-rm -f layoutdef.h layoutdef.c layout.mk
-echo "#include \"layoutdef.h\"" > layoutdef.c
-echo "#include \"wm.h\"" >> layoutdef.c
-echo "void init_layouts() {" >> layoutdef.c
-for i in `ls layout_*.c`; do
- FUNC="`echo \`basename $i\` | sed 's/\.c//g'`"
- echo "void init_$FUNC();" >> layoutdef.h
- echo " init_$FUNC();" >> layoutdef.c;
- echo "SRC += $i" >>layoutdef.mk
-done
-echo "}" >> layoutdef.c
diff --git a/cmd/wm/mouse.c b/cmd/wm/mouse.c
@@ -290,7 +290,7 @@ draw_pseudo_border(XRectangle * r)
pseudo.y += 2;
pseudo.width -= 4;
pseudo.height -= 4;
- XDrawRectangles(dpy, root, xorgc, &pseudo, 1);
+ XDrawRectangles(dpy, root, gc_xor, &pseudo, 1);
XSync(dpy, False);
}
diff --git a/cmd/wm/page.c b/cmd/wm/page.c
@@ -72,7 +72,7 @@ destroy_page(Page * p)
return;
Page *newselpage;
- AttachQueue *o, *n;
+ MapQueue *o, *n;
while(attachqueue && (attachqueue->page == p)) {
n = attachqueue->next;
@@ -235,13 +235,13 @@ handle_after_write_page(IXPServer * s, File * file)
static void
xexec(void *obj, char *arg)
{
- AttachQueue *r;
+ MapQueue *r;
if(!attachqueue)
- r = attachqueue = cext_emallocz(sizeof(AttachQueue));
+ r = attachqueue = cext_emallocz(sizeof(MapQueue));
else {
for(r = attachqueue; r && r->next; r = r->next);
- r->next = cext_emallocz(sizeof(AttachQueue));
+ r->next = cext_emallocz(sizeof(MapQueue));
r = r->next;
}
r->page = obj;
@@ -258,13 +258,3 @@ toggle_layout(void *obj, char *arg)
else
focus_layout(p->managed);
}
-
-Page *
-pageat(unsigned int idx)
-{
- unsigned int i = 0;
- Page *p;
- for(p = pages; p && i != idx; p = p->next)
- i++;
- return p;
-}
diff --git a/cmd/wm/wm.c b/cmd/wm/wm.c
@@ -116,73 +116,69 @@ scale_rect(XRectangle * from_dim, XRectangle * to_dim,
}
static void
-draw_pager_layout(Layout *l, Draw * d)
-{
- Frame *f;
- Frame *sel = sel_frame();
- if(!l->def)
- return;
- for(f = l->def->frames(l); f; f = f->next) {
- 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->name;
- scale_rect(&rect, &initial_rect, &f->rect, &d->rect);
- blitz_drawlabel(dpy, d);
- XSync(dpy, False); /* do not clear upwards */
+draw_pager_client(Client *c, Draw *d)
+{
+ if(c == sel_client()) {
+ d->bg = blitz_loadcolor(dpy, screen, def[WM_SEL_BG_COLOR]->content);
+ d->fg = blitz_loadcolor(dpy, screen, def[WM_SEL_FG_COLOR]->content);
+ d->border = blitz_loadcolor(dpy, screen, def[WM_SEL_BORDER_COLOR]->content);
+ } else {
+ d->bg = blitz_loadcolor(dpy, screen, def[WM_NORM_BG_COLOR]->content);
+ d->fg = blitz_loadcolor(dpy, screen, def[WM_NORM_FG_COLOR]->content);
+ d->border = blitz_loadcolor(dpy, screen, def[WM_NORM_BORDER_COLOR]->content);
}
+ d->data = c->name;
+ scale_rect(&rect, &initial_rect, &c->frame.rect, &d->rect);
+ blitz_drawlabel(dpy, d);
+ XSync(dpy, False); /* do not clear upwards */
}
static void
-draw_pager_page(Page * p, Draw * d)
+draw_pager_page(size_t idx, Draw *d)
{
- unsigned int idx = 1;
+ size_t i, j;
char name[4];
initial_rect = d->rect;
- 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);
+ if(idx == sel_page) {
+ d->bg = blitz_loadcolor(dpy, screen, def[WM_SEL_BG_COLOR]->content);
+ d->fg = blitz_loadcolor(dpy, screen, def[WM_SEL_FG_COLOR]->content);
+ d->border = blitz_loadcolor(dpy, screen, 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->bg = blitz_loadcolor(dpy, screen, def[WM_NORM_BG_COLOR]->content);
+ d->fg = blitz_loadcolor(dpy, screen, def[WM_NORM_FG_COLOR]->content);
+ d->border = blitz_loadcolor(dpy, screen, def[WM_NORM_BORDER_COLOR]->content);
}
- for(page = pages; page && page != p; page = page->next)
- idx++;
- snprintf(name, sizeof(name), "%d", idx);
+ snprintf(name, sizeof(name), "%d", idx + 1);
d->data = name;
blitz_drawlabel(dpy, d);
XSync(dpy, False);
- if(p->managed)
- draw_pager_layout(p->managed, d);
- draw_pager_layout(p->floating, d);
+
+ for(i = 0; (i < pages[idx]->managedsz) && pages[idx]->managed[i]; i++) {
+ Column *col = pages[idx]->managed[i];
+ for(j = 0; (i < col->clientssz) && col->clients[j]; j++)
+ draw_pager_client(col->clients[j], d);
+ }
+ for(i = 0; (i < pages[idx]->floatingsz) && pages[idx]->floating[i]; i++)
+ draw_pager_client(pages[idx]->floating[i], d);
}
static void
draw_pager()
{
Draw d = { 0 };
- unsigned int ic, ir, tw, th, rows, cols;
+ unsigned int i, ic, ir, tw, th, rows, cols;
int dx;
- Page *p;
- blitz_getbasegeometry(npages, &cols, &rows);
+ for(i = 0; (i < pagessz) && pages[i]; i++);
+ blitz_getbasegeometry(i, &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.gc = gc_transient;
d.font = font;
- p = pages;
+ i = 0;
for(ir = 0; ir < rows; ir++) {
for(ic = 0; ic < cols; ic++) {
d.rect.x = ic * tw + (ic * GAP);
@@ -192,28 +188,27 @@ draw_pager()
else
d.rect.y = ir * (rect.height - th) / (rows - 1);
d.rect.height = th;
- draw_pager_page(p, &d);
- if(!p->next)
+ draw_pager_page(i++, &d);
+ if(!pages[i])
return;
- p = p->next;
}
}
}
-static Page *
+static int
xy_to_pager_page(int x, int y)
{
- unsigned int ic, ir, tw, th, rows, cols;
+ unsigned int i, ic, ir, tw, th, rows, cols;
int dx;
XRectangle r;
- Page *p;
- blitz_getbasegeometry(npages, &cols, &rows);
+ for(i = 0; (i < pagessz) && pages[i]; i++);
+ blitz_getbasegeometry(i, &cols, &rows);
dx = (cols - 1) * GAP; /* GAPpx space */
tw = (rect.width - dx) / cols;
th = ((double) tw / rect.width) * rect.height;
- p = pages;
+ i = 0;
for(ir = 0; ir < rows; ir++) {
for(ic = 0; ic < cols; ic++) {
r.x = ic * tw + (ic * GAP);
@@ -224,13 +219,13 @@ xy_to_pager_page(int x, int y)
r.y = ir * (rect.height - th) / (rows - 1);
r.height = th;
if(blitz_ispointinrect(x, y, &r))
- return p;
- if(!p->next)
- return nil;
- p = p->next;
+ return i;
+ i++;
+ if(!pages[i])
+ return -1;
}
}
- return nil;
+ return -1;
}
static int
@@ -253,10 +248,13 @@ pager(void *obj, char *arg)
{
XEvent ev;
int i;
+ size_t j;
if(!pages)
return;
+ for(j = 0; (j < pagessz) && pages[j]; j++);
+
XClearWindow(dpy, transient);
XMapRaised(dpy, transient);
draw_pager();
@@ -282,8 +280,8 @@ pager(void *obj, char *arg)
case KeyPress:
XUnmapWindow(dpy, transient);
if((i = handle_kpress(&ev.xkey)) != -1)
- if(i < npages)
- focus_page(pageat(i));
+ if(i < j)
+ focus_page(i);
XUngrabKeyboard(dpy, CurrentTime);
XUngrabPointer(dpy, CurrentTime /* ev.xbutton.time */ );
return;
@@ -303,12 +301,12 @@ pager(void *obj, char *arg)
static void
map_detached_clients()
{
- unsigned int ic, ir, tw, th, rows, cols;
+ unsigned int i, ic, ir, tw, th, rows, cols;
int dx, dy;
- Client *c = detached;
XRectangle cr;
- blitz_getbasegeometry(ndetached, &cols, &rows);
+ for(i = 0; detached && detached[i]; i++);
+ blitz_getbasegeometry(i, &cols, &rows);
if(!cols)
cols = 1;
if(!rows)
@@ -318,21 +316,21 @@ map_detached_clients()
tw = (rect.width - dx) / cols;
th = (rect.height - dy) / rows;
+ i = 0;
for(ir = 0; ir < rows; ir++) {
for(ic = 0; ic < cols; ic++) {
- if(!c)
+ if(!detached[i++])
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);
- configure_client(c);
- map_client(c);
- grab_client(c, AnyModifier, Button1);
- XRaiseWindow(dpy, c->win);
+ XMoveResizeWindow(dpy, detached[i]->win, cr.x, cr.y, cr.width, cr.height);
+ configure_client(detached[i]);
+ map_client(detached[i]);
+ grab_client(detached[i], AnyModifier, Button1);
+ XRaiseWindow(dpy, detached[i]->win);
XSync(dpy, False);
- c = c->next;
}
}
}
@@ -342,9 +340,11 @@ detached_clients(void *obj, char *arg)
{
XEvent ev;
int n;
- Client *c = detached;
+ size_t i, nc;
+ Client *c;
- if(!c)
+ for(nc = 0; detached && detached[nc]; nc++);
+ if(!nc)
return;
XClearWindow(dpy, transient);
XMapRaised(dpy, transient);
@@ -362,12 +362,12 @@ detached_clients(void *obj, char *arg)
switch (ev.type) {
case KeyPress:
XUnmapWindow(dpy, transient);
- for(c = detached; c; c = c->next)
- unmap_client(c);
+ for(i = 0; detached[i]; i++)
+ unmap_client(detached[i]);
if((n = handle_kpress(&ev.xkey)) != -1) {
- if((c = clientat(detached, n))) {
- detach_detached(c);
- attach_client(c);
+ if(n < nc) {
+ detach_detached(detached[n]);
+ attach_client(detached[n]);
}
}
XUngrabKeyboard(dpy, CurrentTime);
@@ -375,8 +375,8 @@ detached_clients(void *obj, char *arg)
break;
case ButtonPress:
XUnmapWindow(dpy, transient);
- for(c = detached; c; c = c->next)
- unmap_client(c);
+ for(i = 0; detached[i]; i++)
+ unmap_client(detached[i]);
if((ev.xbutton.button == Button1)
&& (c = win_to_client(ev.xbutton.window))) {
detach_detached(c);
@@ -400,7 +400,7 @@ xclose_client(void *obj, char *arg)
static void
xattach_client(void *obj, char *arg)
{
- Client *c = detached;
+ Client *c = detached ? detached[0] : nil;
if(c) {
detach_detached(c);
attach_client(c);
@@ -418,34 +418,32 @@ xdetach_client(void *obj, char *arg)
static void
xselect_page(void *obj, char *arg)
{
- Page *p = selpage;
- if(!p || !arg)
+ size_t np;
+
+ for(np = 0; (np < pagessz) && pages[np]; np++);
+ if(!np || !arg)
return;
if(!strncmp(arg, "prev", 5)) {
- if(p->prev)
- p = p->prev;
- else
- for(p = pages; p && p->next; p = p->next);
+ if(sel_page > 0)
+ for(sel_page = 0; pages[sel_page]; sel_page++);
+ sel_page--;
} else if(!strncmp(arg, "next", 5)) {
- if(p->next)
- p = p->next;
- else
- p = pages;
- } else {
- int idx = blitz_strtonum(arg, 0, pageid);
- if(idx)
- idx--;
+ if(pages[sel_page + 1])
+ sel_page++;
else
- idx = 9;
- p = pageat(idx);
+ sel_page = 0;
+ } else {
+ int idx = blitz_strtonum(arg, 0, np);
+ if(idx < np)
+ sel_page = idx;
}
- focus_page(p);
+ focus_page(sel_page);
}
static void
xdestroy_page(void *obj, char *arg)
{
- destroy_page(selpage);
+ destroy_page(sel_page);
}
static void
@@ -457,24 +455,12 @@ new_page(void *obj, char *arg)
Client *
win_to_client(Window w)
{
- 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;
- if(p->managed->def)
- for(f = p->managed->def->frames(p->managed); f; f = f->next) {
- if(f->client->win == w)
- return f->client;
- }
- for(f = p->floating->def->frames(p->floating); f; f = f->next) {
- if(f->client->win == w)
- return f->client;
- }
- }
- return nil;
+ size_t i;
+
+ for(i = 0; clients && clients[i]; i++)
+ if(clients[i]->win == w)
+ return clients[i];
+ return nil;
}
void
@@ -495,8 +481,7 @@ scan_wins()
|| XGetTransientForHint(dpy, wins[i], &d1))
continue;
if(wa.map_state == IsViewable) {
- c = alloc_client(wins[i]);
- init_client(c, &wa);
+ c = alloc_client(wins[i], &wa);
attach_client(c);
c->ignore_unmap++; /* was viewable already */
}
@@ -563,31 +548,6 @@ win_state(Window w)
return res;
}
-static void
-update_pages()
-{
- Page *p;
-
- for(p = pages; p; p = p->next) {
- p->floating->def->arrange(p->floating);
- p->managed->def->arrange(p->managed);
- }
-}
-
-void
-handle_before_read(IXPServer * s, File * f)
-{
- char buf[64];
- if(f == def[WM_MANAGED_GEOMETRY]) {
- snprintf(buf, 64, "%d %d %d %d", layout_rect.x, layout_rect.y,
- layout_rect.width, layout_rect.height);
- if(f->content)
- free(f->content);
- f->content = cext_estrdup(buf);
- f->size = strlen(buf);
- }
-}
-
void
handle_after_write(IXPServer * s, File * f)
{
@@ -595,22 +555,15 @@ handle_after_write(IXPServer * s, File * f)
run_action(f, 0, wm_acttbl);
else if(f == def[WM_TRANS_COLOR]) {
unsigned long col[1];
- col[0] = xorcolor.pixel;
- XFreeColors(dpy, DefaultColormap(dpy, screen_num), col, 1, 0);
- XAllocNamedColor(dpy, DefaultColormap(dpy, screen_num),
+ col[0] = color_xor.pixel;
+ XFreeColors(dpy, DefaultColormap(dpy, screen), col, 1, 0);
+ XAllocNamedColor(dpy, DefaultColormap(dpy, screen),
def[WM_TRANS_COLOR]->content,
- &xorcolor, &xorcolor);
- XSetForeground(dpy, xorgc, xorcolor.pixel);
+ &color_xor, &color_xor);
+ XSetForeground(dpy, gc_xor, color_xor.pixel);
} else if(f == def[WM_FONT]) {
XFreeFont(dpy, font);
font = blitz_getfont(dpy, def[WM_FONT]->content);
- } else if(f == def[WM_MANAGED_GEOMETRY]) {
- char *geom = def[WM_MANAGED_GEOMETRY]->content;
- if(geom && strrchr(geom, ' ')) {
- layout_rect = rect;
- blitz_strtorect(&rect, &layout_rect, geom);
- update_pages();
- }
}
check_event(0);
}
@@ -653,11 +606,7 @@ init_default()
wmii_create_ixpfile(ixps, "/default/transcolor",
BLITZ_SEL_FG_COLOR);
def[WM_TRANS_COLOR]->after_write = handle_after_write;
- def[WM_MANAGED_GEOMETRY] =
- wmii_create_ixpfile(ixps, "/default/geometry",
- BLITZ_SEL_FG_COLOR);
- def[WM_MANAGED_GEOMETRY]->after_write = handle_after_write;
- def[WM_MANAGED_GEOMETRY]->before_read = handle_before_read;
+ def[WM_MANAGED_GEOMETRY] = wmii_create_ixpfile(ixps, "/default/geometry", BLITZ_SEL_FG_COLOR);
def[WM_SEL_BG_COLOR] =
wmii_create_ixpfile(ixps, "/default/sstyle/bgcolor",
BLITZ_SEL_BG_COLOR);
@@ -673,17 +622,14 @@ init_default()
def[WM_NORM_FG_COLOR] =
wmii_create_ixpfile(ixps, "/default/nstyle/fgcolor",
BLITZ_NORM_FG_COLOR);
- def[WM_NORM_BORDER_COLOR] =
- wmii_create_ixpfile(ixps, "/default/nstyle/bordercolor",
+ def[WM_NORM_BORDER_COLOR] = wmii_create_ixpfile(ixps, "/default/nstyle/bordercolor",
BLITZ_NORM_BORDER_COLOR);
def[WM_FONT] = wmii_create_ixpfile(ixps, "/default/font", BLITZ_FONT);
def[WM_FONT]->after_write = handle_after_write;
def[WM_SNAP_VALUE] = wmii_create_ixpfile(ixps, "/default/snapvalue", "20"); /* 0..1000 */
def[WM_BORDER] = wmii_create_ixpfile(ixps, "/default/border", "1");
def[WM_TAB] = wmii_create_ixpfile(ixps, "/default/tab", "1");
- def[WM_HANDLE_INC] =
- wmii_create_ixpfile(ixps, "/default/handleinc", "1");
- def[WM_LAYOUT] = wmii_create_ixpfile(ixps, "/default/layout", LAYOUT);
+ def[WM_HANDLE_INC] = wmii_create_ixpfile(ixps, "/default/handleinc", "1");
def[WM_SEL_PAGE] = ixp_create(ixps, "/sel");
def[WM_EVENT_PAGE_UPDATE] = ixp_create(ixps, "/event/pageupdate");
def[WM_EVENT_CLIENT_UPDATE] = ixp_create(ixps, "/event/clientupdate");
@@ -700,34 +646,33 @@ init_screen()
XGCValues gcv;
XSetWindowAttributes wa;
- XAllocNamedColor(dpy, DefaultColormap(dpy, screen_num),
- def[WM_TRANS_COLOR]->content, &xorcolor, &xorcolor);
+ XAllocNamedColor(dpy, DefaultColormap(dpy, screen),
+ def[WM_TRANS_COLOR]->content, &color_xor, &color_xor);
gcv.subwindow_mode = IncludeInferiors;
gcv.function = GXxor;
- gcv.foreground = xorcolor.pixel;
+ gcv.foreground = color_xor.pixel;
gcv.line_width = 4;
gcv.plane_mask = AllPlanes;
gcv.graphics_exposures = False;
- xorgc = XCreateGC(dpy, root, GCForeground | GCGraphicsExposures
+ gc_xor = XCreateGC(dpy, root, GCForeground | GCGraphicsExposures
| GCFunction | GCSubwindowMode | GCLineWidth
| GCPlaneMask, &gcv);
rect.x = rect.y = 0;
- rect.width = DisplayWidth(dpy, screen_num);
- rect.height = DisplayHeight(dpy, screen_num);
- layout_rect = rect;
+ rect.width = DisplayWidth(dpy, screen);
+ rect.height = DisplayHeight(dpy, screen);
wa.override_redirect = 1;
wa.background_pixmap = ParentRelative;
wa.event_mask = ExposureMask | ButtonPressMask;
transient =
XCreateWindow(dpy, root, 0, 0, rect.width, rect.height, 0,
- DefaultDepth(dpy, screen_num), CopyFromParent,
- DefaultVisual(dpy, screen_num),
+ DefaultDepth(dpy, screen), CopyFromParent,
+ DefaultVisual(dpy, screen),
CWOverrideRedirect | CWBackPixmap | CWEventMask,
&wa);
XSync(dpy, False);
- transient_gc = XCreateGC(dpy, transient, 0, 0);
+ gc_transient = XCreateGC(dpy, transient, 0, 0);
XDefineCursor(dpy, transient, normal_cursor);
XDefineCursor(dpy, root, normal_cursor);
}
@@ -771,14 +716,12 @@ startup_error_handler(Display * dpy, XErrorEvent * error)
static void
cleanup()
{
- Page *p;
- for(p = pages; p; p = p->next) {
- Frame *f;
- for(f = p->managed->def->frames(p->managed); f; f = f->next)
- detach_client_from_frame(f->client, False);
- for(f = p->floating->def->frames(p->floating); f; f = f->next)
- detach_client_from_frame(f->client, False);
- }
+ size_t i;
+ Client *c;
+ for(i = 0; clients && clients[i]; i++) {
+ c = clients[i];
+ reparent_client(c, root, c->frame.rect.x + c->rect.x, c->frame.rect.y + c->rect.y);
+ }
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
XSync(dpy, False);
}
@@ -818,8 +761,8 @@ main(int argc, char *argv[])
fprintf(stderr, "%s", "wmiiwm: cannot open display\n");
exit(1);
}
- screen_num = DefaultScreen(dpy);
- root = RootWindow(dpy, screen_num);
+ screen = DefaultScreen(dpy);
+ root = RootWindow(dpy, screen);
/* check if another WM is already running */
other_wm_running = 0;
@@ -850,20 +793,18 @@ main(int argc, char *argv[])
}
def[WM_CTL]->after_write = handle_after_write;
- pages = selpage = nil;
- ndetached = npages = 0;
- pageid = 1;
- detached = nil;
- layouts = nil;
+ detachedsz = pagessz = clientssz = sel_page = 0;
+ pages = nil;
+ clients = detached = nil;
attachqueue = nil;
+
init_atoms();
init_cursors();
init_default();
font = blitz_getfont(dpy, def[WM_FONT]->content);
wmii_init_lock_modifiers(dpy, &valid_mask, &num_lock_mask);
init_screen();
- init_layouts();
scan_wins();
/* main event loop */
diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h
@@ -13,32 +13,24 @@
enum {
P_PREFIX,
P_NAME,
- P_LAYOUT_PREFIX,
- P_SEL_LAYOUT,
- P_LAYOUT_NAME,
+ P_MANAGED_PREFIX,
+ P_FLOATING_PREFIX,
+ P_SEL_PREFIX,
+ P_SEL_MANAGED_CLIENT,
+ P_SEL_FLOATING_CLIENT,
P_CTL,
P_LAST
};
-/* array indexes of layout file pointers */
-enum {
- L_PREFIX,
- L_FRAME_PREFIX,
- L_SEL_FRAME,
- L_NAME,
- L_CTL,
- L_LAST
-};
-
/* array indexes of frame file pointers */
enum {
- F_PREFIX,
- F_NAME,
- F_GEOMETRY,
- F_BORDER,
- F_TAB,
- F_HANDLE_INC,
- F_LAST
+ C_PREFIX,
+ C_NAME,
+ C_GEOMETRY,
+ C_BORDER,
+ C_TAB,
+ C_HANDLE_INC,
+ C_LAST
};
/* array indexes of wm file pointers */
@@ -58,7 +50,6 @@ enum {
WM_HANDLE_INC,
WM_SNAP_VALUE,
WM_SEL_PAGE,
- WM_LAYOUT,
WM_EVENT_PAGE_UPDATE,
WM_EVENT_CLIENT_UPDATE,
WM_EVENT_B1PRESS,
@@ -81,110 +72,80 @@ enum {
#define PROTO_DEL 1
#define BORDER_WIDTH 3
-#define LAYOUT "column"
-#define LAYOUT_FLOAT "float"
#define GAP 5
#define ROOT_MASK SubstructureRedirectMask
#define CLIENT_MASK (StructureNotifyMask | PropertyChangeMask)
+typedef struct MapQueue MapQueue;
+typedef struct Column Column;
typedef struct Page Page;
-typedef struct AttachQueue AttachQueue;
-typedef struct LayoutDef LayoutDef;
-typedef struct Layout Layout;
-typedef struct Frame Frame;
typedef struct Client Client;
-struct AttachQueue {
+struct MapQueue {
Page *page;
- AttachQueue *next;
-};
-
-struct Page {
- Layout *managed;
- Layout *floating;
- Layout *sel;
- File *file[P_LAST];
- Page *next;
- Page *prev;
- size_t index;
+ MapQueue *next;
};
-struct LayoutDef {
- char *name;
- void (*init) (Layout *, Client *); /* called when layout is initialized */
- Client *(*deinit) (Layout *); /* called when layout is uninitialized */
- void (*arrange) (Layout *); /* called when layout is resized */
- Bool(*attach) (Layout *, Client *); /* called on attach */
- void (*detach) (Layout *, Client *, Bool unmap); /* called on detach */
- void (*resize) (Frame *, XRectangle *, XPoint *); /* called after resize */
- void (*focus) (Layout *, Client *, Bool raise); /* focussing a client */
- Frame *(*frames) (Layout *); /* called for drawing */
- Client *(*sel) (Layout *); /* returns selected client */
- Action *(*actions) (Layout *); /* local action table */
- LayoutDef *next;
+struct Column {
+ Client **clients;
+ size_t clientssz;
+ size_t sel;
};
-struct Layout {
- Page *page;
- LayoutDef *def;
- void *aux; /* auxillary pointer */
- File *file[L_LAST];
-};
-
-struct Frame {
- Layout *layout;
- Window win;
- Client *sel;
- Client *client;
- Bool maximized;
- XRectangle old;
- GC gc;
- XRectangle rect;
- Cursor cursor;
- void *aux; /* auxillary pointer */
- File *file[F_LAST];
- Frame *next;
- Frame *prev;
+struct Page {
+ Client **floating;
+ Column **managed;
+ size_t floatingsz;
+ size_t managedsz;
+ size_t sel_float;
+ size_t sel_managed;
+ Bool is_managed;
+ XRectangle rect_managed;
+ File *file[P_LAST];
};
struct Client {
+ char name[256];
int proto;
unsigned int border;
unsigned int ignore_unmap;
- char name[256];
Bool destroyed;
+ Bool maximized;
Window win;
Window trans;
XRectangle rect;
XSizeHints size;
- Frame *frame;
- Client *next;
- Client *prev;
+ struct Frame {
+ Window win;
+ XRectangle rect;
+ XRectangle revert;
+ GC gc;
+ Cursor cursor;
+ } frame;
+ File *file[C_LAST];
};
-
/* global variables */
-Page *pages;
-Page *selpage;
-AttachQueue *attachqueue;
-size_t npages;
-int pageid;
-Client *detached;
-size_t ndetached;
-LayoutDef *layouts;
+Page **pages;
+size_t pagessz;
+size_t sel_page;
+MapQueue *attachqueue;
+Client **detached;
+size_t detachedsz;
+Client **clients;
+size_t clientssz;
Display *dpy;
IXPServer *ixps;
-int screen_num;
+int screen;
Window root;
-Window transient;
+Window transient; /* pager / attach */
XRectangle rect;
-XRectangle layout_rect;
XFontStruct *font;
-XColor xorcolor;
-GC xorgc;
-GC transient_gc;
+XColor color_xor;
+GC gc_xor;
+GC gc_transient;
Atom wm_state; /* TODO: Maybe replace with wm_atoms[WM_ATOM_COUNT]? */
Atom wm_change_state;
@@ -213,8 +174,7 @@ unsigned int valid_mask, num_lock_mask;
/* client.c */
-Client *alloc_client(Window w);
-void init_client(Client * c, XWindowAttributes * wa);
+Client *alloc_client(Window w, XWindowAttributes *wa);
void destroy_client(Client * c);
void configure_client(Client * c);
void handle_client_property(Client * c, XPropertyEvent * e);
@@ -233,52 +193,38 @@ Client *clientat(Client * clients, size_t idx);
void detach_detached(Client * c);
void attach_detached(Client * c);
void focus_client(Client *new, Client *old);
-
-/* frame.c */
-Frame *win_to_frame(Window w);
-Frame *alloc_frame(XRectangle * r);
-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);
+Client *win_to_frame(Window w);
+Client *alloc_frame(XRectangle * r);
+void destroy_frame(Client * f);
+void resize_frame(Client * f, XRectangle * r, XPoint * pt);
+void draw_frame(Client * f);
+void handle_frame_buttonpress(XButtonEvent * e, Client * f);
+void attach_client_to_frame(Client * f, Client * c);
void detach_client_from_frame(Client * client, Bool unmap);
-unsigned int tab_height(Frame * f);
-unsigned int border_width(Frame * f);
-Frame *sel_frame();
+unsigned int tab_height(Client * f);
+unsigned int border_width(Client * f);
+Client *sel_frame();
/* event.c */
void init_event_hander();
void check_event(Connection * c);
/* mouse.c */
-void mouse_resize(Frame * f, Align align);
-void mouse_move(Frame * f);
-Cursor cursor_for_motion(Frame * f, int x, int y);
+void mouse_resize(Client * f, Align align);
+void mouse_move(Client * f);
+Cursor cursor_for_motion(Client * f, int x, int y);
Align cursor_to_align(Cursor cursor);
Align xy_to_align(XRectangle * rect, int x, int y);
-void drop_move(Frame * f, XRectangle * new, XPoint * pt);
+void drop_move(Client * f, XRectangle * new, XPoint * pt);
/* page.c */
-Page *pageat(unsigned int idx);
-Page *alloc_page();
-void destroy_page(Page * p);
-void focus_page(Page * p);
+size_t alloc_page();
+void destroy_page(size_t idx);
+void focus_page(size_t idx);
XRectangle *rectangles(unsigned int *num);
-/* layout.c */
-Layout *alloc_layout(Page * p, char *layout);
-void destroy_layout(Layout *l);
-void focus_layout(Layout *l);
-void unmap_layout(Layout *l);
-void map_layout(Layout *l, Bool raise);
-Layout *sel_layout();
-void attach_frame_to_layout(Layout *l, Frame * f);
-void detach_frame_from_layout(Frame * f);
-LayoutDef *match_layout_def(char *name);
-
-/* layoutdef.c */
-void init_layouts();
+/* column.c */
+void arrange_column(Page *p);
/* wm.c */
void invoke_wm_event(File * f);
@@ -288,5 +234,5 @@ Client *win_to_client(Window w);
int win_proto(Window w);
int win_state(Window w);
void handle_after_write(IXPServer * s, File * f);
-void detach(Frame * f, int client_destroyed);
+void detach(Client * f, int client_destroyed);
void set_client_state(Client * c, int state);
diff --git a/doc/RELEASE b/doc/RELEASE
@@ -1,11 +1,11 @@
-Abbadon
+Abbadon (9base-2)
Amare
Andariel
Andon
ArchDean
Beth
Bethanel
-Boyd * (2)
+Boyd (wmii-2)
Camael
Charon
Duma
@@ -36,9 +36,9 @@ Sandalphon
Sophia
Sunya
Thanatos
-Tothiel * (wmii-2.5, 9base-1)
+Tothiel (wmii-2.5)
Ultimus Maximus
-Uriel * (1)
+Uriel (wmii-1)
Yhprum
Zaphkiel
-Zadkiel * (1.1)
+Zadkiel (wmii-1.1)