commit 76be3694d071a82863abe4a09f3d1ba128636eee
parent d0dcedf937558b584ef2e2c11c0291262e49a6fa
Author: Kris Maglione <bsdaemon@wmii.de>
Date: Sun, 25 Jun 2006 09:16:03 -0400
Restructured tag/view/frame handling
Diffstat:
10 files changed, 295 insertions(+), 382 deletions(-)
diff --git a/cmd/wm/area.c b/cmd/wm/area.c
@@ -9,6 +9,40 @@
#include "wm.h"
+Bool
+is_of_area(Area *a, Client *c)
+{
+ Frame *f;
+ for(f=a->frame; f; f=f->anext)
+ if(f->client == c)
+ return True;
+ return False;
+}
+
+int
+idx_of_area(Area *a)
+{
+ Area *t;
+ int i = 0;
+ for(t=a->view->area; t && t != a; t=t->next)
+ i++;
+ return t ? i : -1;
+}
+
+Area *
+area_of_id(View *v, unsigned short id)
+{
+ Area *a;
+ for(a=v->area; a && a->id != id; a=a->next);
+ return a;
+}
+
+Client *
+sel_client_of_area(Area *a)
+{
+ return a && a->sel ? a->sel->client : nil;
+}
+
Area *
create_area(View *v, Area *pos, unsigned int w)
{
@@ -76,6 +110,101 @@ destroy_area(Area *a)
free(a);
}
+void
+send_to_area(Area *to, Area *from, Frame *f)
+{
+ f->client->revert = from;
+ detach_from_area(from, f);
+ attach_to_area(to, f, True);
+ focus_client(f->client, True);
+}
+
+void
+attach_to_area(Area *a, Frame *f, Bool send)
+{
+ unsigned int h, n_frame;
+ Frame **fa, *ft;
+ View *v = a->view;
+ Client *c = f->client;
+
+ for(ft=a->frame, n_frame=1; ft; ft=ft->anext, n_frame++);
+
+ h = 0;
+ c->floating = a->floating;
+ if(!c->floating) {
+ h = a->rect.height / n_frame;
+ if(a->frame)
+ scale_column(a, a->rect.height - h);
+ }
+
+ if(!send && !c->floating) { /* column */
+ unsigned int w = newcolw_of_view(v);
+ if(v->area->next->frame && w) {
+ a = new_column(v, a, w);
+ arrange_view(v);
+ }
+ }
+
+ fa = a->sel ? &a->sel->anext : &a->frame;
+ f->anext = *fa;
+ *fa = f;
+
+ f->area = a;
+ a->sel = f;
+
+ if(!c->floating) { /* column */
+ f->rect.height = h;
+ arrange_column(a, False);
+ }
+ else { /* floating */
+ place_client(a, c);
+ resize_client(c, &f->rect, True);
+ }
+}
+
+void
+detach_from_area(Area *a, Frame *f)
+{
+ Frame **ft, *pr = nil;
+ Client *c = f->client;
+ View *v = a->view;
+
+ for(ft=&a->frame; *ft; ft=&(*ft)->anext) {
+ if(*ft == f) break;
+ pr = *ft;
+ }
+ cext_assert(*ft == f);
+ *ft = f->anext;
+
+ if(a->sel == f)
+ a->sel = pr ? pr : *ft;
+
+ if(!a->floating) {
+ if(a->frame)
+ arrange_column(a, False);
+ else {
+ if(v->area->next->next)
+ destroy_area(a);
+ else if(!a->frame && v->area->frame)
+ v->sel = v->area; /* focus floating area if it contains something */
+ arrange_view(v);
+ }
+ }
+ else if(!a->frame) {
+ if(c->trans) {
+ /* focus area of transient, if possible */
+ Client *cl = client_of_win(c->trans);
+ if(cl && cl->frame) {
+ a = cl->sel->area;
+ if(a->view == v)
+ v->sel = a;
+ }
+ }
+ else if(v->area->next->frame)
+ v->sel = v->area->next; /* focus first col as fallback */
+ }
+}
+
char *
select_area(Area *a, char *arg)
{
@@ -139,15 +268,6 @@ select_area(Area *a, char *arg)
return nil;
}
-void
-send_to_area(Area *to, Area *from, Client *c)
-{
- c->revert = from;
- detach_from_area(from, c);
- attach_to_area(to, c, True);
- focus_client(c, True);
-}
-
static void
place_client(Area *a, Client *c)
{
@@ -244,108 +364,3 @@ place_client(Area *a, Client *c)
if(rects)
free(rects);
}
-
-void
-attach_to_area(Area *a, Client *c, Bool send)
-{
- View *v = a->view;
- unsigned int h = 0, i;
- Frame *f;
- for(f=a->frame, i=1; f; f=f->anext, i++);
-
- c->floating = a->floating;
- if(!c->floating) {
- h = a->rect.height / i;
- if(a->frame)
- scale_column(a, a->rect.height - h);
- }
-
- if(!send && !c->floating) { /* column */
- unsigned int w = newcolw_of_view(v);
- if(v->area->next->frame && w) {
- a = new_column(v, a, w);
- arrange_view(v);
- }
- }
-
- f = create_frame(a, c);
-
- if(!c->floating) { /* column */
- f->rect.height = h;
- arrange_column(a, False);
- }
- else { /* floating */
- place_client(a, c);
- resize_client(c, &f->rect, False);
- }
-}
-
-void
-detach_from_area(Area *a, Client *c)
-{
- View *v = a->view;
- Frame *f;
-
- for(f=c->frame; f && f->area != a; f=f->cnext);
- cext_assert(f->area == a);
- destroy_frame(f);
-
- if(!a->floating) {
- if(a->frame)
- arrange_column(a, False);
- else {
- if(v->area->next->next)
- destroy_area(a);
- else if(!a->frame && v->area->frame)
- v->sel = v->area; /* focus floating area if it contains something */
- arrange_view(v);
- }
- }
- else if(!a->frame) {
- if(c->trans) {
- /* focus area of transient, if possible */
- Client *cl = client_of_win(c->trans);
- if(cl && cl->frame) {
- a = cl->sel->area;
- if(a->view == v)
- v->sel = a;
- }
- }
- else if(v->area->next->frame)
- v->sel = v->area->next; /* focus first col as fallback */
- }
-}
-
-Bool
-is_of_area(Area *a, Client *c)
-{
- Frame *f;
- for(f=a->frame; f; f=f->anext)
- if(f->client == c)
- return True;
- return False;
-}
-
-int
-idx_of_area(Area *a)
-{
- Area *t;
- int i = 0;
- for(t=a->view->area; t && t != a; t=t->next)
- i++;
- return t ? i : -1;
-}
-
-Area *
-area_of_id(View *v, unsigned short id)
-{
- Area *a;
- for(a=v->area; a && a->id != id; a=a->next);
- return a;
-}
-
-Client *
-sel_client_of_area(Area *a)
-{
- return a && a->sel ? a->sel->client : nil;
-}
diff --git a/cmd/wm/client.c b/cmd/wm/client.c
@@ -347,14 +347,16 @@ manage_client(Client *c)
cext_strlcpy(c->tags, trans->tags, sizeof(c->tags));
else if(tags.nitems)
cext_strlcpy(c->tags, (char *)tags.value, sizeof(c->tags));
-
XFree(tags.value);
if(!strlen(c->tags))
apply_rules(c);
+ apply_tags(c, c->tags);
+
reparent_client(c, c->framewin, c->rect.x, c->rect.y);
- update_views();
+ if(!starting)
+ update_views();
map_client(c);
XMapWindow(blz.display, c->framewin);
XSync(blz.display, False);
@@ -372,7 +374,7 @@ dummy_error_handler(Display *dpy, XErrorEvent *error)
void
destroy_client(Client *c)
{
- View *v;
+ char *dummy = nil;
Client **tc;
XGrabServer(blz.display);
@@ -383,10 +385,7 @@ destroy_client(Client *c)
c->rect.y = c->sel->rect.y;
}
- for(v=view; v; v=v->next)
- detach_from_view(v, c);
- *c->tags = '\0';
- update_client_views(c);
+ update_client_views(c, &dummy);
unmap_client(c);
@@ -523,9 +522,11 @@ resize_client(Client *c, XRectangle *r, Bool ignore_xcall)
c->rect.width = f->rect.width - 2 * def.border;
c->rect.height = f->rect.height - def.border - height_of_bar();
}
- XMoveResizeWindow(blz.display, c->win, c->rect.x, c->rect.y,
+ if(!ignore_xcall) {
+ XMoveResizeWindow(blz.display, c->win, c->rect.x, c->rect.y,
c->rect.width, c->rect.height);
- configure_client(c);
+ configure_client(c);
+ }
}
void
@@ -543,11 +544,11 @@ newcol_client(Client *c, char *arg)
if(!strncmp(arg, "prev", 5)) {
for(to=v->area; to && to->next != a; to=to->next);
to = new_column(v, to, 0);
- send_to_area(to, a, c);
+ send_to_area(to, a, f);
}
else if(!strncmp(arg, "next", 5)) {
to = new_column(v, a, 0);
- send_to_area(to, a, c);
+ send_to_area(to, a, f);
}
else
return;
@@ -615,7 +616,7 @@ send_client(Frame *f, char *arg)
to=new_column(v, v->area, 0);
if(!to)
return Ebadvalue;
- send_to_area(to, a, c);
+ send_to_area(to, a, f);
}
else if(i && !strncmp(arg, "right", 5)) {
if(a->floating)
@@ -624,7 +625,7 @@ send_client(Frame *f, char *arg)
to = new_column(v, a, 0);
if(!to)
return Ebadvalue;
- send_to_area(to, a, c);
+ send_to_area(to, a, f);
}
else if(!strncmp(arg, "toggle", 7)) {
if(!a->floating)
@@ -633,7 +634,7 @@ send_client(Frame *f, char *arg)
to = c->revert;
else
to = v->area->next;
- send_to_area(to, a, c);
+ send_to_area(to, a, f);
}
else if(i && !strncmp(arg, "up", 3)) {
for(tf=a->frame; tf && tf->anext != f; tf=tf->anext);
@@ -656,29 +657,15 @@ send_client(Frame *f, char *arg)
if(sscanf(arg, "%d", &j) != 1)
return Ebadvalue;
for(to=v->area; to && j; to=to->next, j--);
- send_to_area(to, a, c);
+ send_to_area(to, a, f);
}
else
return Ebadvalue;
flush_masked_events(EnterWindowMask);
+ update_views();
return nil;
}
-void
-resize_all_clients()
-{
- Client *c;
- for(c = client; c; c=c->next) {
- if(c->frame && c->sel->area) {
- if(idx_of_area(c->sel->area))
- resize_column(c, &c->sel->rect, nil);
- else
- resize_client(c, &c->sel->rect, False);
- }
- }
- flush_masked_events(EnterWindowMask);
-}
-
/* convenience function */
void
focus(Client *c, Bool restack)
@@ -716,20 +703,44 @@ Client *
client_of_win(Window w)
{
Client *c;
-
for(c=client; c && c->win != w; c=c->next);
return c;
}
-static Bool
-permit_tag(const char *tag)
+static int
+compare_tags(const void **a, const void **b) {
+ return strcmp(*a, *b);
+}
+
+void
+update_client_views(Client *c, char **tags)
{
- static char *exclude[] = { "sel", "status" };
- unsigned int i;
- for(i = 0; i < (sizeof(exclude) / sizeof(exclude[0])); i++)
- if(!strcmp(exclude[i], tag))
- return False;
- return True;
+ int cmp;
+ Frame *f;
+ Frame **fp = &c->frame;
+ while(*fp || *tags) {
+ while(*fp && (!*tags || (cmp=strcmp((*fp)->view->name, *tags)) < 0)) {
+ f = *fp;
+ detach_from_area(f->area, f);
+ *fp = f->cnext;
+ free(f);
+ if(c->sel == f)
+ c->sel = *fp;
+ }
+
+ if(*tags) {
+ if(!*fp || cmp > 0) {
+ f = create_frame(c, get_view(*tags));
+ if(f->view == sel || !c->sel)
+ c->sel = f;
+ attach_to_view(f->view, f);
+ f->cnext = *fp;
+ *fp = f;
+ }
+ if(*fp) fp=&(*fp)->cnext;
+ tags++;
+ }
+ }
}
void
@@ -737,31 +748,33 @@ apply_tags(Client *c, const char *tags)
{
unsigned int i, j = 0, n;
char buf[256];
- char *toks[16], *apply[16];
+ char *toks[32];
cext_strlcpy(buf, tags, sizeof(buf));
- if(!(n = cext_tokenize(toks, 16, buf, '+')))
+ if(!(n = cext_tokenize(toks, 31, buf, '+')))
return;
for(i = 0; i < n; i++) {
if(!strncmp(toks[i], "~", 2))
c->floating = True;
- else if(!strncmp(toks[i], "!", 2)) {
- if(view)
- apply[j++] = sel->name;
- else
- apply[j++] = "nil";
+ else if(!strncmp(toks[i], "!", 2))
+ toks[j++] = view ? sel->name : "nil";
+ else if(strncmp(toks[i], "sel", 4))
+ toks[j++] = toks[i];
+ }
+
+ c->tags[0] = '\0';
+ qsort(toks, j, sizeof(char *), (void *)compare_tags);
+ for(i=0, n=0; i < j; i++) {
+ if(!n || strcmp(toks[i], toks[n-1])) {
+ if(n)
+ cext_strlcat(c->tags, "+", sizeof(c->tags) - strlen(c->tags) - 1);
+ cext_strlcat(c->tags, toks[i], sizeof(c->tags) - strlen(c->tags) - 1);
+ toks[n++] = toks[i];
}
- else if(permit_tag(toks[i]))
- apply[j++] = toks[i];
- }
-
- c->tags[0] = 0;
- for(i = 0; i < j; i++) {
- cext_strlcat(c->tags, apply[i], sizeof(c->tags) - strlen(c->tags) - 1);
- if(i + 1 < j)
- cext_strlcat(c->tags, "+", sizeof(c->tags) - strlen(c->tags) - 1);
}
+ toks[i] = nil;
+ update_client_views(c, toks);
if(!strlen(c->tags))
apply_tags(c, "nil");
diff --git a/cmd/wm/column.c b/cmd/wm/column.c
@@ -64,7 +64,7 @@ relax_column(Area *a)
for(f=a->frame; f; f=f->anext) {
f->rect.x = a->rect.x + (a->rect.width - f->rect.width) / 2;
f->rect.y = a->rect.y + (a->rect.height - f->rect.height) / 2;
- resize_client(f->client, &f->rect, False);
+ resize_client(f->client, &f->rect, True);
}
return;
}
@@ -101,7 +101,7 @@ relax_column(Area *a)
f->rect.y = yoff;
if(a->mode != Colmax)
yoff = f->rect.y + f->rect.height + hdiff;
- resize_client(f->client, &f->rect, False);
+ resize_client(f->client, &f->rect, True);
}
}
@@ -212,11 +212,10 @@ match_horiz(Area *a, XRectangle *r)
for(f=a->frame; f; f=f->anext) {
f->rect.x = r->x;
f->rect.width = r->width;
- resize_client(f->client, &f->rect, False);
+ resize_client(f->client, &f->rect, True);
}
}
-
static void
drop_resize(Frame *f, XRectangle *new)
{
@@ -304,8 +303,8 @@ AfterHorizontal:
north->rect.height = new->y - north->rect.y;
f->rect.height += f->rect.y - new->y;
f->rect.y = new->y;
- resize_client(north->client, &north->rect, False);
- resize_client(f->client, &f->rect, False);
+ resize_client(north->client, &north->rect, True);
+ resize_client(f->client, &f->rect, True);
}
if(south && (new->y + new->height != f->rect.y + f->rect.height)) {
south->rect.height -= new->y + new->height - south->rect.y;
@@ -313,11 +312,12 @@ AfterHorizontal:
f->rect.y = new->y;
f->rect.height = new->height;
resize_client(f->client, &f->rect, False);
- resize_client(south->client, &south->rect, False);
+ resize_client(south->client, &south->rect, True);
}
AfterVertical:
relax_column(a);
+ focus_view(v);
}
static Frame *
@@ -354,14 +354,14 @@ drop_move(Frame *f, XRectangle *new, XPoint *pt)
if(pt->x < 16) {
if((src->frame && src->frame->anext) || (src != v->area->next)) {
tgt = new_column(v, v->area->next, 0);
- send_to_area(tgt, src, f->client);
+ send_to_area(tgt, src, f);
}
}
else if(pt->x >= rect.width - 16) {
if((src->frame && src->frame->anext) || src->next) {
for(tgt=src; tgt->next; tgt=tgt->next);
tgt = new_column(v, tgt, 0);
- send_to_area(tgt, src, f->client);
+ send_to_area(tgt, src, f);
}
}
else if(src != tgt) {
@@ -370,7 +370,7 @@ drop_move(Frame *f, XRectangle *new, XPoint *pt)
if(!(ft = frame_of_point(pt)) || (f == ft))
return;
before = pt->y < (ft->rect.y + ft->rect.height / 2);
- send_to_area(tgt, src, c);
+ send_to_area(tgt, src, f);
f = c->sel;
remove_frame(f);
diff --git a/cmd/wm/frame.c b/cmd/wm/frame.c
@@ -9,16 +9,14 @@
#include "wm.h"
Frame *
-create_frame(Area *a, Client *c)
+create_frame(Client *c, View *v)
{
static unsigned short id = 1;
Frame *f = cext_emallocz(sizeof(Frame));
- Frame **fa = a->sel ? &a->sel->anext : &a->frame;
- Frame **fc = c->sel ? &c->sel->cnext : &c->frame;
f->id = id++;
- f->area = a;
f->client = c;
+ f->view = v;
f->revert = f->rect = c->rect;
f->rect.width += 2 * def.border;
f->rect.height += def.border + height_of_bar();
@@ -40,14 +38,6 @@ create_frame(Area *a, Client *c)
f->tagbar.font = &def.font;
f->tagbar.color = def.normcolor;
- a->sel = f;
- c->sel = f;
-
- f->anext = *fa;
- *fa = f;
- f->cnext = *fc;
- *fc = f;
-
return f;
}
@@ -76,28 +66,6 @@ insert_frame(Frame *pos, Frame *f, Bool before)
*p = f;
}
-void
-destroy_frame(Frame *f)
-{
- Client *c = f->client;
- Area *a = f->area;
- Frame **ft, *pr = nil;
-
- for(ft=&c->frame; *ft && *ft != f; pr = *ft, ft=&(*ft)->cnext);
- cext_assert(*ft == f);
- *ft = f->cnext;
- if(c->sel == f)
- c->sel = pr ? pr : *ft;
-
- for(ft=&a->frame; *ft && *ft != f; pr = *ft, ft=&(*ft)->anext);
- cext_assert(*ft == f);
- *ft = f->anext;
- if(a->sel == f)
- a->sel = pr ? pr : *ft;
-
- free(f);
-}
-
Frame *
frame_of_id(Area *a, unsigned short id)
{
@@ -140,10 +108,8 @@ update_frame_widget_colors(Frame *f)
void
draw_frame(Frame *f)
{
-
Frame *p;
unsigned int fidx, size, w;
- char buf[256];
for(fidx=0, p=f->area->frame; p && p != f; p=p->anext, fidx++);
for(size=fidx; p; p=p->anext, size++);
@@ -156,11 +122,11 @@ draw_frame(Frame *f)
f->posbar.rect = f->tile.rect;
f->posbar.rect.height = height_of_bar();
- snprintf(buf, sizeof(buf), "%s%d/%d",
+ snprintf(buffer, BUFFER_SIZE, "%s%d/%d",
f->area->floating ? "~" : "", fidx + 1, size);
w = f->posbar.rect.width =
- f->posbar.rect.height + blitz_textwidth(&def.font, buf);
+ f->posbar.rect.height + blitz_textwidth(&def.font, buffer);
f->posbar.rect.x = f->rect.width - f->posbar.rect.width;
@@ -182,7 +148,7 @@ draw_frame(Frame *f)
f->tagbar.text = def.testtags ? def.testtags : f->client->tags;
blitz_draw_input(&f->tagbar);
blitz_draw_label(&f->titlebar, f->client->name);
- blitz_draw_label(&f->posbar, buf);
+ blitz_draw_label(&f->posbar, buffer);
XCopyArea(blz.display, pmap, f->client->framewin, f->tagbar.gc,
0, 0, f->rect.width, f->rect.height, 0, 0);
XSync(blz.display, False);
diff --git a/cmd/wm/fs.c b/cmd/wm/fs.c
@@ -71,9 +71,6 @@ static char
/* Global Vars */
/***************/
-enum { BUF_SIZE = 2048 };
-static char buf[BUF_SIZE];
-
FileId *free_fileid = nil;
P9Req *pending_event_reads = nil;
FidLink *pending_event_fids;
@@ -255,8 +252,8 @@ message_root(char *message)
unsigned int n;
if(!strchr(message, ' ')) {
- snprintf(buf, BUF_SIZE, "%s ", message);
- message = buf;
+ snprintf(buffer, BUFFER_SIZE, "%s ", message);
+ message = buffer;
}
if(!strncmp(message, "quit ", 5))
@@ -308,15 +305,15 @@ read_root_ctl()
{
unsigned int i = 0;
if(sel)
- i += snprintf(&buf[i], (BUF_SIZE - i), "view %s\n", sel->name);
- i += snprintf(&buf[i], (BUF_SIZE - i), "selcolors %s\n", def.selcolor.colstr);
- i += snprintf(&buf[i], (BUF_SIZE - i), "normcolors %s\n", def.normcolor.colstr);
- i += snprintf(&buf[i], (BUF_SIZE - i), "font %s\n", def.font.fontstr);
- i += snprintf(&buf[i], (BUF_SIZE - i), "grabmod %s\n", def.grabmod);
- i += snprintf(&buf[i], (BUF_SIZE - i), "border %d\n", def.border);
+ i += snprintf(&buffer[i], (BUFFER_SIZE - i), "view %s\n", sel->name);
+ i += snprintf(&buffer[i], (BUFFER_SIZE - i), "selcolors %s\n", def.selcolor.colstr);
+ i += snprintf(&buffer[i], (BUFFER_SIZE - i), "normcolors %s\n", def.normcolor.colstr);
+ i += snprintf(&buffer[i], (BUFFER_SIZE - i), "font %s\n", def.font.fontstr);
+ i += snprintf(&buffer[i], (BUFFER_SIZE - i), "grabmod %s\n", def.grabmod);
+ i += snprintf(&buffer[i], (BUFFER_SIZE - i), "border %d\n", def.border);
if(def.testtags)
- i += snprintf(&buf[i], (BUF_SIZE - i), "testtags %s\n", def.testtags);
- return buf;
+ i += snprintf(&buffer[i], (BUFFER_SIZE - i), "testtags %s\n", def.testtags);
+ return buffer;
}
@@ -343,17 +340,17 @@ write_event(char *format, ...) {
P9Req *aux;
va_start(ap, format);
- vsnprintf(buf, BUF_SIZE, format, ap);
+ vsnprintf(buffer, BUFFER_SIZE, format, ap);
va_end(ap);
- if(!(len = strlen(buf)))
+ if(!(len = strlen(buffer)))
return;
for(f=pending_event_fids; f; f=f->next) {
fi = f->fid->aux;
slen = fi->buf ? strlen(fi->buf) : 0;
fi->buf = realloc(fi->buf, slen + len + 1);
fi->buf[slen] = '\0';
- strcat(fi->buf, buf);
+ strcat(fi->buf, buffer);
}
while((aux = pending_event_reads)) {
pending_event_reads = pending_event_reads->aux;
diff --git a/cmd/wm/view.c b/cmd/wm/view.c
@@ -10,26 +10,6 @@
#include "wm.h"
static Bool
-is_of_view(View *v, Client *c)
-{
- Area *a;
- for(a=v->area; a; a=a->next)
- if(is_of_area(a, c))
- return True;
- return False;
-}
-
-static Bool
-is_view_of(Client *c, View *v)
-{
- ViewLink *l;
- for(l=c->views; l; l=l->next)
- if(l->view == v)
- return True;
- return False;
-}
-
-static Bool
is_empty(View *v)
{
Area *a;
@@ -51,12 +31,16 @@ View *
view_of_name(const char *name)
{
View *v;
+ int cmp;
for(v = view; v; v=v->next)
- if(!strcmp(v->name, name)) break;
+ if(!(cmp=strcmp(name, v->name)))
+ break;
+ else if(cmp > 0)
+ return nil;
return v;
}
-static View *
+View *
get_view(const char *name)
{
View *v = view_of_name(name);
@@ -124,25 +108,19 @@ destroy_view(View *v)
static void
update_frame_selectors(View *v)
{
- Client *c;
+ Area *a;
Frame *f;
-
- /* select correct frames of clients */
- for(c=client; c; c=c->next)
- for(f=c->frame; f; f=f->cnext)
- if(f->area->view == v) {
- c->sel = f;
- break;
- }
+ for(a=v->area; a; a=a->next)
+ for(f=a->frame; f; f=f->anext)
+ f->client->sel = f;
}
void
focus_view(View *v)
{
+ Frame *f;
Client *c;
- cext_assert(v);
-
XGrabServer(blz.display);
assign_sel_view(v);
@@ -150,13 +128,11 @@ focus_view(View *v)
/* gives all(!) clients proper geometry (for use of different tags) */
for(c=client; c; c=c->next)
- if(c->sel) {
- Frame *f = c->sel;
- if(f && f->area->view == v) {
+ if((f = c->sel)) {
+ if(f->view == v) {
XMoveWindow(blz.display, c->framewin, f->rect.x, f->rect.y);
resize_client(c, &f->rect, False);
- }
- else
+ }else
XMoveWindow(blz.display, c->framewin, 2 * rect.width + f->rect.x, f->rect.y);
}
@@ -169,24 +145,6 @@ focus_view(View *v)
flush_masked_events(EnterWindowMask);
}
-XRectangle *
-rects_of_view(View *v, unsigned int *num)
-{
- XRectangle *result = nil;
- Frame *f;
-
- *num = 2;
- for(f=v->area->frame; f; f=f->anext, (*num)++);
-
- result = cext_emallocz(*num * sizeof(XRectangle));
- for(f=v->area->frame; f; f=f->anext)
- *result++ = f->rect;
- *result++ = rect;
- *result++ = brect;
-
- return &result[-*num];
-}
-
void
select_view(const char *arg)
{
@@ -200,23 +158,10 @@ select_view(const char *arg)
}
void
-detach_from_view(View *v, Client *c)
-{
- Area *a, *next;
-
- for(a=v->area; a; a=next) {
- next=a->next;
- if(is_of_area(a, c)) {
- detach_from_area(a, c);
- XMoveWindow(blz.display, c->framewin, 2 * rect.width, 0);
- }
- }
-}
-
-void
-attach_to_view(View *v, Client *c)
+attach_to_view(View *v, Frame *f)
{
Area *a;
+ Client *c = f->client;
c->revert = nil;
@@ -227,7 +172,7 @@ attach_to_view(View *v, Client *c)
a = v->area->next;
else
a = v->sel;
- attach_to_area(a, c, False);
+ attach_to_area(a, f, False);
v->sel = a;
}
@@ -322,72 +267,56 @@ arrange_view(View *v)
}
}
-void
-update_client_views(Client *c)
-{
- static ViewLink *free_view_links = nil;
- ViewLink *v;
- char buf[256];
- char *toks[16];
- unsigned int i, n;
+Client *
+sel_client_of_view(View *v) {
+ return v->sel && v->sel->sel ? v->sel->sel->client : nil;
+}
- cext_strlcpy(buf, c->tags, sizeof(buf));
- n = cext_tokenize(toks, 16, buf, '+');
+XRectangle *
+rects_of_view(View *v, unsigned int *num)
+{
+ XRectangle *result = nil;
+ Frame *f;
- while((v = c->views)) {
- c->views = v->next;
- v->next = free_view_links;
- free_view_links = v;
- }
+ *num = 2;
+ for(f=v->area->frame; f; f=f->anext, (*num)++);
- for(i = 0; i < n; i++) {
- if(free_view_links) {
- v = free_view_links;
- free_view_links = v->next;
- }
- else
- v = cext_emallocz(sizeof(ViewLink));
-
- v->next = c->views;
- c->views = v;
- v->view = get_view(toks[i]);
- }
-}
+ result = cext_emallocz(*num * sizeof(XRectangle));
+ for(f=v->area->frame; f; f=f->anext)
+ *result++ = f->rect;
+ *result++ = rect;
+ *result++ = brect;
-Client *
-sel_client_of_view(View *v) {
- return v->sel && v->sel->sel ? v->sel->sel->client : nil;
+ return &result[-*num];
}
/* XXX: This will need cleanup */
unsigned char *
view_index(View *v) {
- enum { BUF_MAX = 8092 };
- static unsigned char buf[BUF_MAX];
unsigned int a_i, buf_i, n;
int len;
Frame *f;
Area *a;
- len = BUF_MAX;
+ len = BUFFER_SIZE;
buf_i = 0;
for((a = v->area), (a_i = 0); a; (a=a->next), (a_i++)) {
for(f=a->frame; f && len > 0; f=f->anext) {
XRectangle *r = &f->rect;
if(a_i == 0)
- n = snprintf((char *)&buf[buf_i], len, "~ %d %d %d %d %d %s\n",
+ n = snprintf(&buffer[buf_i], len, "~ %d %d %d %d %d %s\n",
idx_of_client(f->client),
r->x, r->y, r->width, r->height,
f->client->props);
else
- n = snprintf((char *)&buf[buf_i], len, "%d %d %d %s\n",
+ n = snprintf(&buffer[buf_i], len, "%d %d %d %s\n",
a_i, idx_of_client(f->client),
r->width, f->client->props);
buf_i += n;
len -= n;
}
}
- return buf;
+ return buffer;
}
Client *
@@ -415,9 +344,8 @@ area_of_message(View *v, char *message, unsigned int *next) {
*next = 4;
return v->sel;
}
- if(!strncmp(message, "~ ", 2)) {
+ if(!strncmp(message, "~ ", 2))
return v->area;
- }
if(1 != sscanf(message, "%d %n", &i, next) || i == 0)
return nil;
for(a=v->area; i && a; a=a->next, i--);
@@ -472,30 +400,18 @@ message_view(View *v, char *message) {
void
update_views()
{
- View **i, *v, *old = sel;
- Client *c;
+ View *n, *v;
+ View *old = sel;
- for(c=client; c; c=c->next)
- update_client_views(c);
-
- for(c=client; c; c=c->next) {
- for(v=view; v; v=v->next) {
- update_frame_selectors(v);
- if(is_view_of(c, v)) {
- if(!is_of_view(v, c))
- attach_to_view(v, c);
- }else
- if(is_of_view(v, c))
- detach_from_view(v, c);
- }
- }
+ for(v=view; v; v=v->next)
+ update_frame_selectors(v);
if(old && !strncmp(old->name, "nil", 4))
old = nil;
- for(i=&view; *i; *i && (i=&(*i)->next))
- if((*i != old) && is_empty(*i))
- destroy_view(*i);
+ for((v=view) && (n=v->next); v; (v=n) && (n=v->next))
+ if((v != old) && is_empty(v))
+ destroy_view(v);
if(old)
focus_view(old);
diff --git a/cmd/wm/wm.c b/cmd/wm/wm.c
@@ -350,6 +350,7 @@ main(int argc, char *argv[])
XMapRaised(blz.display, barwin);
draw_bar();
scan_wins();
+ update_views();
starting = False;
diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h
@@ -49,6 +49,12 @@ typedef struct Area Area;
typedef struct Frame Frame;
typedef struct Client Client;
+typedef struct ViewLink ViewLink;
+struct ViewLink {
+ ViewLink *next;
+ View *view;
+};
+
struct View {
View *next;
char name[256];
@@ -58,12 +64,6 @@ struct View {
Area *revert;
};
-typedef struct ViewLink ViewLink;
-struct ViewLink {
- ViewLink *next;
- View *view;
-};
-
struct Area {
Area *next;
Frame *frame;
@@ -78,6 +78,7 @@ struct Area {
struct Frame {
Frame *cnext;
Frame *anext;
+ View *view;
Area *area;
unsigned short id;
XRectangle rect;
@@ -170,6 +171,9 @@ Key *key;
Bar *lbar;
Bar *rbar;
+enum { BUFFER_SIZE = 8092 };
+char buffer[BUFFER_SIZE];
+
View *sel;
P9Srv p9srv;
Blitz blz;
@@ -200,9 +204,9 @@ Area *create_area(View *v, Area *pos, unsigned int w);
void destroy_area(Area *a);
Area *area_of_id(View *t, unsigned short id);
char *select_area(Area *a, char *arg);
-void send_to_area(Area *to, Area *from, Client *c);
-void attach_to_area(Area *a, Client *c, Bool send);
-void detach_from_area(Area *a, Client *c);
+void send_to_area(Area *to, Area *from, Frame *f);
+void attach_to_area(Area *a, Frame *f, Bool send);
+void detach_from_area(Area *a, Frame *f);
Bool is_of_area(Area *a, Client *c);
int idx_of_area(Area *a);
Client *sel_client_of_area(Area *a);
@@ -259,8 +263,8 @@ void check_x_event(IXPConn *c);
unsigned int flush_masked_events(long even_mask);
/* frame.c */
-Frame *create_frame(Area *a, Client *c);
-void destroy_frame(Frame *f);
+Frame *create_frame(Client *c, View *v);
+void destroy_frame(Frame **f);
void remove_frame(Frame *f);
void insert_frame(Frame *pos, Frame *f, Bool before);
int idx_of_frame(Frame *f);
@@ -309,14 +313,15 @@ void update_rules(Rule **rule, const char *data);
/* view.c */
void arrange_view(View *v);
void scale_view(View *v, float w);
+View *get_view(const char *name);
View *create_view(const char *name);
void focus_view(View *v);
-void update_client_views(Client *c);
+void update_client_views(Client *c, char **tags);
XRectangle *rects_of_view(View *v, unsigned int *num);
View *view_of_id(unsigned short id);
void select_view(const char *arg);
void detach_from_view(View *v, Client *c);
-void attach_to_view(View *v, Client *c);
+void attach_to_view(View *v, Frame *f);
Client *sel_client_of_view(View *v);
char *message_view(View *v, char *message);
void restack_view(View *v);
diff --git a/libixp/server.c b/libixp/server.c
@@ -66,10 +66,10 @@ prepare_select(IXPServer *s)
static void
handle_conns(IXPServer *s)
{
- IXPConn **c;
- for(c=&s->conn; *c; *c && (c=&(*c)->next))
- if(FD_ISSET((*c)->fd, &s->rd) && (*c)->read)
- (*c)->read(*c);
+ IXPConn *c, *n;
+ for((c=s->conn) && (n=c->next); c; (c=n) && (n=c->next))
+ if(FD_ISSET(c->fd, &s->rd) && c->read)
+ c->read(c);
}
char *
diff --git a/rc/wmiirc b/rc/wmiirc
@@ -188,7 +188,7 @@ do
$MODKEY-[0-9])
xwrite /ctl view `echo $1 | sed 's/.*-//'`;;
$MODKEY-Return)
- PATH="$OLD_PATH" xterm &;;
+ xterm &;;
$MODKEY-Shift-$LEFT)
xwrite /tag/sel/ctl send sel left;;
$MODKEY-Shift-$RIGHT)