mirror of https://github.com/0intro/wmii
added /view/X/capacity (though some corner cases might crash the wm if you use it)
This commit is contained in:
parent
c7cba3c123
commit
b42643433e
119
cmd/wm/area.c
119
cmd/wm/area.c
|
@ -116,11 +116,58 @@ void
|
|||
send2area(Area *to, Area *from, Client *c)
|
||||
{
|
||||
c->revert = from;
|
||||
detach_fromarea(from, c);
|
||||
detach_fromarea(from, c, True);
|
||||
attach_toarea(to, c);
|
||||
focus_client(c);
|
||||
}
|
||||
|
||||
void
|
||||
pre_attach(Area *a)
|
||||
{
|
||||
Area *new = nil;
|
||||
Client *c;
|
||||
View *v = a->view;
|
||||
unsigned int i, j;
|
||||
|
||||
if(!a->capacity || (a->nframe < a->capacity))
|
||||
return;
|
||||
i = area2index(a);
|
||||
for(j = i + 1; j < v->narea; j++)
|
||||
if(!v->area[j]->capacity
|
||||
|| (v->area[j]->capacity > v->area[j]->nframe))
|
||||
{
|
||||
new = v->area[j];
|
||||
break;
|
||||
}
|
||||
if(!new) {
|
||||
new = alloc_area(v);
|
||||
arrange_view(v, True);
|
||||
}
|
||||
c = a->frame[a->sel]->client;
|
||||
detach_fromarea(a, c, False);
|
||||
attach_toarea(new, c);
|
||||
arrange_area(new);
|
||||
}
|
||||
|
||||
void
|
||||
post_detach(Area *a)
|
||||
{
|
||||
Client *c;
|
||||
Area *det;
|
||||
View *v = a->view;
|
||||
unsigned int i = area2index(a);
|
||||
|
||||
if(!a->capacity || i + 1 >= v->narea)
|
||||
return;
|
||||
det = v->area[i + 1];
|
||||
if(!det->nframe)
|
||||
return;
|
||||
c = det->frame[det->sel]->client;
|
||||
detach_fromarea(det, c, True);
|
||||
attach_toarea(a, c);
|
||||
arrange_area(a);
|
||||
}
|
||||
|
||||
void
|
||||
attach_toarea(Area *a, Client *c)
|
||||
{
|
||||
|
@ -129,6 +176,7 @@ attach_toarea(Area *a, Client *c)
|
|||
|
||||
if(clientofview(a->view, c))
|
||||
return;
|
||||
pre_attach(a);
|
||||
f = cext_emallocz(sizeof(Frame));
|
||||
f->id = id++;
|
||||
f->area = a;
|
||||
|
@ -150,7 +198,7 @@ attach_toarea(Area *a, Client *c)
|
|||
}
|
||||
|
||||
void
|
||||
detach_fromarea(Area *a, Client *c)
|
||||
detach_fromarea(Area *a, Client *c, Bool postarrange)
|
||||
{
|
||||
Frame *f;
|
||||
View *v = a->view;
|
||||
|
@ -171,6 +219,12 @@ detach_fromarea(Area *a, Client *c)
|
|||
a->nframe--;
|
||||
if(a->sel > 0)
|
||||
a->sel--;
|
||||
|
||||
if(!postarrange)
|
||||
return;
|
||||
|
||||
post_detach(a);
|
||||
|
||||
i = area2index(a);
|
||||
if(i && a->nframe)
|
||||
arrange_area(a);
|
||||
|
@ -180,7 +234,7 @@ detach_fromarea(Area *a, Client *c)
|
|||
destroy_area(a);
|
||||
else if(!a->nframe && v->area[0]->nframe)
|
||||
v->sel = 0; /* focus floating area if it contains something */
|
||||
arrange_tag(v, True);
|
||||
arrange_view(v, True);
|
||||
}
|
||||
else if(!i && !a->nframe) {
|
||||
if(c->trans) {
|
||||
|
@ -351,27 +405,6 @@ Fallthrough:
|
|||
relax_area(a);
|
||||
}
|
||||
|
||||
void
|
||||
arrange_tag(View *v, Bool updategeometry)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int width;
|
||||
|
||||
if(v->narea == 1)
|
||||
return;
|
||||
|
||||
width = rect.width / (v->narea - 1);
|
||||
for(i = 1; i < v->narea; i++) {
|
||||
Area *a = v->area[i];
|
||||
if(updategeometry) {
|
||||
a->rect.height = rect.height - brect.height;
|
||||
a->rect.x = (i - 1) * width;
|
||||
a->rect.width = width;
|
||||
}
|
||||
arrange_area(a);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
match_horiz(Area *a, XRectangle *r)
|
||||
{
|
||||
|
@ -393,6 +426,7 @@ drop_resize(Frame *f, XRectangle *new)
|
|||
Frame *north = nil, *south = nil;
|
||||
unsigned int i;
|
||||
unsigned int min = 2 * bar_height();
|
||||
Bool horiz_resize = False;
|
||||
|
||||
for(i = 1; (i < v->narea) && (v->area[i] != a); i++);
|
||||
/* first managed area is indexed 1, thus (i > 1) ? ... */
|
||||
|
@ -403,47 +437,36 @@ drop_resize(Frame *f, XRectangle *new)
|
|||
north = i ? a->frame[i - 1] : nil;
|
||||
south = i + 1 < a->nframe ? a->frame[i + 1] : nil;
|
||||
|
||||
/* validate (and trim if necessary) horizontal resize */
|
||||
if(new->width < MIN_COLWIDTH) {
|
||||
if(new->x + new->width == f->rect.x + f->rect.width)
|
||||
new->x = a->rect.x + a->rect.width - MIN_COLWIDTH;
|
||||
new->width = MIN_COLWIDTH;
|
||||
}
|
||||
/* horizontal resize */
|
||||
if(west && (new->x != f->rect.x)) {
|
||||
horiz_resize = True;
|
||||
if(new->x < 0 || new->x < (west->rect.x + MIN_COLWIDTH)) {
|
||||
new->width -= (west->rect.x + MIN_COLWIDTH) - new->x;
|
||||
new->x = west->rect.x + MIN_COLWIDTH;
|
||||
} else if(new->width < MIN_COLWIDTH) {
|
||||
new->x -= MIN_COLWIDTH - new->width;
|
||||
new->width = MIN_COLWIDTH;
|
||||
}
|
||||
} else {
|
||||
new->width += new->x - a->rect.x;
|
||||
new->x = a->rect.x;
|
||||
}
|
||||
if(east && (new->x + new->width != f->rect.x + f->rect.width)) {
|
||||
if((new->x + new->width) > (east->rect.x + east->rect.width - MIN_COLWIDTH))
|
||||
new->width = (east->rect.x + east->rect.width - MIN_COLWIDTH) - new->x;
|
||||
} else
|
||||
new->width = (a->rect.x + a->rect.width) - new->x;
|
||||
if(new->width < MIN_COLWIDTH)
|
||||
goto AfterHorizontal;
|
||||
|
||||
/* horizontal resize */
|
||||
if(west && (new->x != a->rect.x)) {
|
||||
west->rect.width = new->x - west->rect.x;
|
||||
a->rect.width += a->rect.x - new->x;
|
||||
a->rect.x = new->x;
|
||||
match_horiz(a, &a->rect);
|
||||
match_horiz(west, &west->rect);
|
||||
relax_area(west);
|
||||
}
|
||||
if(east && (new->x + new->width != a->rect.x + a->rect.width)) {
|
||||
if(east && (new->x + new->width != f->rect.x + f->rect.width)) {
|
||||
horiz_resize = True;
|
||||
if((new->x + new->width) > (east->rect.x + east->rect.width - MIN_COLWIDTH))
|
||||
new->width = (east->rect.x + east->rect.width - MIN_COLWIDTH) - new->x;
|
||||
else if(new->width < MIN_COLWIDTH)
|
||||
new->width = MIN_COLWIDTH;
|
||||
east->rect.width -= new->x + new->width - east->rect.x;
|
||||
east->rect.x = new->x + new->width;
|
||||
a->rect.width = (new->x + new->width) - a->rect.x;
|
||||
match_horiz(a, &a->rect);
|
||||
match_horiz(east, &east->rect);
|
||||
relax_area(east);
|
||||
}
|
||||
AfterHorizontal:
|
||||
if(horiz_resize)
|
||||
match_horiz(a, &a->rect);
|
||||
|
||||
if(a->mode == Colstack || a->mode == Colmax)
|
||||
goto AfterVertical;
|
||||
|
|
|
@ -94,7 +94,7 @@ void
|
|||
draw_bar()
|
||||
{
|
||||
unsigned int i = 0, w = 0;
|
||||
int exp = 0;
|
||||
int exp = -1;
|
||||
Draw d = { 0 };
|
||||
Label *l = nil;
|
||||
|
||||
|
|
|
@ -519,10 +519,10 @@ send2area_client(Client *c, char *arg)
|
|||
if(i == -1)
|
||||
return;
|
||||
if(!strncmp(arg, "new", 4) && i) {
|
||||
if(a->nframe == 1 || v->narea - 1 >= rect.width / MIN_COLWIDTH)
|
||||
if(a->nframe == 1 || v->narea - 1 >= rect.width / (2 * MIN_COLWIDTH))
|
||||
return;
|
||||
to = alloc_area(v);
|
||||
arrange_tag(v, True);
|
||||
arrange_view(v, True);
|
||||
}
|
||||
else if(!strncmp(arg, "prev", 5) && i) {
|
||||
if(i == 1)
|
||||
|
|
55
cmd/wm/fs.c
55
cmd/wm/fs.c
|
@ -55,6 +55,7 @@ static char Ebadvalue[] = "bad value";
|
|||
* /view/1/ FsDarea
|
||||
* /view/1/ctl FsFctl command interface (area)
|
||||
* /view/1/mode FsFmode column mode
|
||||
* /view/1/capacity FsFcapacity capacity of column
|
||||
* /view/1/sel/ FsDclient
|
||||
* /view/1/1/class FsFclass class:instance of client
|
||||
* /view/1/1/name FsFname name of client
|
||||
|
@ -217,6 +218,11 @@ qid2name(Qid *qid)
|
|||
return nil;
|
||||
return "tags";
|
||||
break;
|
||||
case FsFcapacity:
|
||||
if(i1 == -1 || i2 == -1)
|
||||
return nil;
|
||||
return "capacity";
|
||||
break;
|
||||
case FsFmode:
|
||||
if(i1 == -1 || i2 == -1)
|
||||
return nil;
|
||||
|
@ -269,6 +275,8 @@ name2type(char *name, unsigned char dir_type)
|
|||
return FsFrules;
|
||||
if(!strncmp(name, "data", 5))
|
||||
return FsFdata;
|
||||
if(!strncmp(name, "capacity", 9))
|
||||
return FsFcapacity;
|
||||
if(!strncmp(name, "mode", 5))
|
||||
return FsFmode;
|
||||
if(!strncmp(name, "tag", 4))
|
||||
|
@ -381,6 +389,7 @@ mkqid(Qid *dir, char *wname, Qid *new)
|
|||
return -1;
|
||||
goto Mkfile;
|
||||
break;
|
||||
case FsFcapacity:
|
||||
case FsFmode:
|
||||
if(dir_i1 == -1 || dir_i2 == -1 || dir_type != FsDarea)
|
||||
return -1;
|
||||
|
@ -536,6 +545,10 @@ type2stat(Stat *stat, char *wname, Qid *dir)
|
|||
case FsFdata:
|
||||
return mkstat(stat, dir, wname, (dir_i1 == nlabel) ? 0 : strlen(label[dir_i1]->data), DMREAD | DMWRITE);
|
||||
break;
|
||||
case FsFcapacity:
|
||||
snprintf(buf, sizeof(buf), "%u", view[dir_i1]->area[dir_i2]->capacity);
|
||||
return mkstat(stat, dir, wname, strlen(buf), DMREAD | DMWRITE);
|
||||
break;
|
||||
case FsFmode:
|
||||
return mkstat(stat, dir, wname, strlen(mode2str(view[dir_i1]->area[dir_i2]->mode)), DMREAD | DMWRITE);
|
||||
break;
|
||||
|
@ -789,8 +802,10 @@ xread(IXPConn *c, Fcall *fcall)
|
|||
case FsDarea:
|
||||
/* jump to offset */
|
||||
len = type2stat(&stat, "ctl", &m->qid);
|
||||
if(i2)
|
||||
if(i2) {
|
||||
len += type2stat(&stat, "mode", &m->qid);
|
||||
len += type2stat(&stat, "capacity", &m->qid);
|
||||
}
|
||||
if(view[i1]->area[i2]->nframe)
|
||||
len += type2stat(&stat, "sel", &m->qid);
|
||||
for(i = 0; i < view[i1]->area[i2]->nframe; i++) {
|
||||
|
@ -956,6 +971,8 @@ xread(IXPConn *c, Fcall *fcall)
|
|||
if(i2) {
|
||||
fcall->count += type2stat(&stat, "mode", &m->qid);
|
||||
p = ixp_enc_stat(p, &stat);
|
||||
fcall->count += type2stat(&stat, "capacity", &m->qid);
|
||||
p = ixp_enc_stat(p, &stat);
|
||||
}
|
||||
if(view[i1]->area[i2]->nframe) {
|
||||
fcall->count += type2stat(&stat, "sel", &m->qid);
|
||||
|
@ -1103,6 +1120,13 @@ xread(IXPConn *c, Fcall *fcall)
|
|||
if((fcall->count = strlen(def.font)))
|
||||
memcpy(p, def.font, fcall->count);
|
||||
break;
|
||||
case FsFcapacity:
|
||||
if(!i2)
|
||||
return Enofile;
|
||||
snprintf(buf, sizeof(buf), "%u", view[i1]->area[i2]->capacity);
|
||||
fcall->count = strlen(buf);
|
||||
memcpy(p, buf, fcall->count);
|
||||
break;
|
||||
case FsFmode:
|
||||
if(!i2)
|
||||
return Enofile;
|
||||
|
@ -1319,6 +1343,35 @@ xwrite(IXPConn *c, Fcall *fcall)
|
|||
xfont = blitz_getfont(dpy, def.font);
|
||||
update_bar_geometry();
|
||||
break;
|
||||
case FsFcapacity:
|
||||
if(!i2)
|
||||
return Enofile;
|
||||
if(fcall->count > sizeof(buf))
|
||||
return Ebadvalue;
|
||||
memcpy(buf, fcall->data, fcall->count);
|
||||
buf[fcall->count] = 0;
|
||||
i = cext_strtonum(buf, 0, 0xffff, &err);
|
||||
if(err)
|
||||
return Ebadvalue;
|
||||
view[i1]->area[i2]->capacity = i;
|
||||
if(i) {
|
||||
Area *a = view[i1]->area[i2];
|
||||
len = 0;
|
||||
while(a->nframe > a->capacity)
|
||||
pre_attach(a);
|
||||
for(i = 1; i < view[i1]->narea; i++)
|
||||
len += view[i1]->area[i]->nframe;
|
||||
if(len > a->capacity) {
|
||||
while(a->nframe < a->capacity) {
|
||||
i = a->nframe;
|
||||
post_detach(a);
|
||||
if(i == a->nframe)
|
||||
break;
|
||||
}
|
||||
}
|
||||
arrange_area(a);
|
||||
}
|
||||
break;
|
||||
case FsFmode:
|
||||
if(!i2)
|
||||
return Enofile;
|
||||
|
|
|
@ -234,7 +234,7 @@ detach_fromview(View *v, Client *c)
|
|||
Client *cl;
|
||||
for(i = 0; i < v->narea; i++) {
|
||||
if(clientofarea(v->area[i], c)) {
|
||||
detach_fromarea(v->area[i], c);
|
||||
detach_fromarea(v->area[i], c, True);
|
||||
XMoveWindow(dpy, c->framewin, 2 * rect.width, 0);
|
||||
}
|
||||
}
|
||||
|
@ -297,3 +297,24 @@ restack_view(View *v)
|
|||
if(n)
|
||||
XRestackWindows(dpy, wins, n);
|
||||
}
|
||||
|
||||
void
|
||||
arrange_view(View *v, Bool updategeometry)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int width;
|
||||
|
||||
if(v->narea == 1)
|
||||
return;
|
||||
|
||||
width = rect.width / (v->narea - 1);
|
||||
for(i = 1; i < v->narea; i++) {
|
||||
Area *a = v->area[i];
|
||||
if(updategeometry) {
|
||||
a->rect.height = rect.height - brect.height;
|
||||
a->rect.x = (i - 1) * width;
|
||||
a->rect.width = width;
|
||||
}
|
||||
arrange_area(a);
|
||||
}
|
||||
}
|
||||
|
|
14
cmd/wm/wm.h
14
cmd/wm/wm.h
|
@ -60,13 +60,14 @@ enum {
|
|||
FsFtags,
|
||||
FsFclass,
|
||||
FsFtag,
|
||||
FsFcapacity,
|
||||
FsFmode
|
||||
};
|
||||
|
||||
#define MAX_TAGS 8
|
||||
#define MAX_TAGLEN 32
|
||||
#define MAX_TAGS 8
|
||||
#define MAX_TAGLEN 32
|
||||
#define WM_PROTOCOL_DELWIN 1
|
||||
#define MIN_COLWIDTH 64
|
||||
#define MIN_COLWIDTH 32
|
||||
|
||||
typedef struct View View;
|
||||
typedef struct Area Area;
|
||||
|
@ -91,6 +92,7 @@ struct Area {
|
|||
unsigned int framesz;
|
||||
unsigned int sel;
|
||||
unsigned int nframe;
|
||||
unsigned int capacity;
|
||||
int mode;
|
||||
XRectangle rect;
|
||||
};
|
||||
|
@ -205,13 +207,14 @@ int aid2index(View *t, unsigned short id);
|
|||
void select_area(Area *a, char *arg);
|
||||
void send2area(Area *to, Area *from, Client *c);
|
||||
void attach_toarea(Area *a, Client *c);
|
||||
void detach_fromarea(Area *a, Client *c);
|
||||
void arrange_tag(View *t, Bool updategeometry);
|
||||
void detach_fromarea(Area *a, Client *c, Bool postarrange);
|
||||
void arrange_area(Area *a);
|
||||
void resize_area(Client *c, XRectangle *r, XPoint *pt);
|
||||
int str2mode(char *arg);
|
||||
char *mode2str(int mode);
|
||||
Bool clientofarea(Area *a, Client *c);
|
||||
void pre_attach(Area *a);
|
||||
void post_detach(Area *a);
|
||||
|
||||
/* bar.c */
|
||||
Label *get_label(char *name);
|
||||
|
@ -286,6 +289,7 @@ Bool istag(char *t);
|
|||
void update_tags();
|
||||
|
||||
/* view.c */
|
||||
void arrange_view(View *v, Bool updategeometry);
|
||||
View *alloc_view(char *name);
|
||||
void focus_view(View *v);
|
||||
XRectangle *rectangles(View *v, Bool isfloat, unsigned int *num);
|
||||
|
|
Loading…
Reference in New Issue