Restructured tag/view/frame handling

This commit is contained in:
Kris Maglione 2006-06-25 09:16:03 -04:00
parent d0dcedf937
commit 76be3694d0
10 changed files with 295 additions and 382 deletions

View File

@ -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;
}

View File

@ -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(permit_tag(toks[i]))
apply[j++] = toks[i];
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;
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);
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];
}
}
toks[i] = nil;
update_client_views(c, toks);
if(!strlen(c->tags))
apply_tags(c, "nil");

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -9,26 +9,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)
{
@ -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;
cext_strlcpy(buf, c->tags, sizeof(buf));
n = cext_tokenize(toks, 16, buf, '+');
while((v = c->views)) {
c->views = v->next;
v->next = free_view_links;
free_view_links = v;
}
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]);
}
}
Client *
sel_client_of_view(View *v) {
return v->sel && v->sel->sel ? v->sel->sel->client : nil;
}
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];
}
/* 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);

View File

@ -350,6 +350,7 @@ main(int argc, char *argv[])
XMapRaised(blz.display, barwin);
draw_bar();
scan_wins();
update_views();
starting = False;

View File

@ -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);

View File

@ -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 *

View File

@ -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)