wmii

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

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:
cmd/wm/area.c | 243++++++++++++++++++++++++++++++++++++++++++-------------------------------------
cmd/wm/client.c | 123++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
cmd/wm/column.c | 20++++++++++----------
cmd/wm/frame.c | 44+++++---------------------------------------
cmd/wm/fs.c | 29+++++++++++++----------------
cmd/wm/view.c | 176+++++++++++++++++++++----------------------------------------------------------
cmd/wm/wm.c | 1+
cmd/wm/wm.h | 31++++++++++++++++++-------------
libixp/server.c | 8++++----
rc/wmiirc | 2+-
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)