mirror of https://github.com/0intro/wmii
Restructured tag/view/frame handling
This commit is contained in:
parent
d0dcedf937
commit
76be3694d0
243
cmd/wm/area.c
243
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;
|
||||
}
|
||||
|
|
121
cmd/wm/client.c
121
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(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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
29
cmd/wm/fs.c
29
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;
|
||||
|
|
178
cmd/wm/view.c
178
cmd/wm/view.c
|
@ -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);
|
||||
|
|
|
@ -350,6 +350,7 @@ main(int argc, char *argv[])
|
|||
XMapRaised(blz.display, barwin);
|
||||
draw_bar();
|
||||
scan_wins();
|
||||
update_views();
|
||||
|
||||
starting = False;
|
||||
|
||||
|
|
31
cmd/wm/wm.h
31
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);
|
||||
|
|
|
@ -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 *
|
||||
|
|
Loading…
Reference in New Issue