simplified tagging data structures internally, though not finished yet, don't use this exessively ;)

This commit is contained in:
Anselm R. Garbe 2006-04-10 17:43:13 +02:00
parent 45f0284ab0
commit c087c64dd2
9 changed files with 77 additions and 165 deletions

View File

@ -215,8 +215,6 @@ attach_toarea(Area *a, Client *c)
unsigned int aidx = area2index(a);
Frame *f;
if(clientofview(a->view, c))
return;
c->floating = !aidx;
f = cext_emallocz(sizeof(Frame));
f->id = id++;

View File

@ -207,14 +207,14 @@ update_bar_tags()
for(i = 0; (i < label.size) && label.data[i]->intern; i++) {
l = label.data[i];
if(!istag(l->name) && !name2view(l->name)) {
if(!name2view(l->name)) {
destroy_label(l);
i--;
}
}
for(i = 0; i < tag.size; i++) {
l = get_label(tag.data[i], True);
cext_strlcpy(l->data, tag.data[i], sizeof(l->data));
for(i = 0; i < view.size; i++) {
l = get_label(view.data[i]->name, True);
cext_strlcpy(l->data, view.data[i]->name, sizeof(l->data));
}
draw_bar();

View File

@ -330,15 +330,13 @@ manage_client(Client *c)
{
Client *trans;
if(c->trans && (trans = win2client(c->trans))) {
if(c->trans && (trans = win2client(c->trans)))
cext_strlcpy(c->tags, trans->tags, sizeof(c->tags));
str2tagvector(&c->tag, c->tags);
}
else
match_tags(c, True);
reparent_client(c, c->framewin, c->rect.x, c->rect.y);
update_tags();
update_tags(c);
}
static int
@ -350,8 +348,7 @@ dummy_error_handler(Display *dpy, XErrorEvent *error)
void
destroy_client(Client *c)
{
int i;
Client *cl;
unsigned int i;
XGrabServer(dpy);
XSetErrorHandler(dummy_error_handler);
@ -370,12 +367,9 @@ destroy_client(Client *c)
XFreeGC(dpy, c->gc);
XDestroyWindow(dpy, c->framewin);
cext_vdetach(client2vector(&client), c);
update_tags();
update_tags(nil);
free(c);
if(view.size && (cl = sel_client_of_view(view.data[sel])))
focus_client(cl);
XSync(dpy, False);
XSetErrorHandler(wmii_error_handler);
XUngrabServer(dpy);
@ -631,9 +625,9 @@ Bool
clienthastag(Client *c, const char *t)
{
unsigned int i;
for(i = 0; i < c->tag.size; i++)
if(!strncmp(c->tag.data[i], t, strlen(t))
|| !strncmp(c->tag.data[i], "*", 2))
for(i = 0; i < c->view.size; i++)
if(!strncmp(c->view.data[i]->name, t, strlen(t))
|| !strncmp(c->tags, "*", 2))
return True;
return False;
}

View File

@ -512,8 +512,8 @@ type2stat(Stat *stat, char *wname, Qid *dir)
default:
{
unsigned int i, len = 0;
for(i = 0; i < tag.size; i++)
len += strlen(tag.data[i]) + 1;
for(i = 0; i < view.size; i++)
len += strlen(view.data[i]->name) + 1;
return mkstat(stat, dir, wname, len, IXP_DMREAD);
}
break;
@ -833,17 +833,17 @@ xread(IXPConn *c, Fcall *fcall)
if(m->qid.dir_type == FsDroot) {
len = 0;
/* jump to offset */
for(i = 0; i < tag.size; i++) {
len += strlen(tag.data[i]) + 1;
for(i = 0; i < view.size; i++) {
len += strlen(view.data[i]->name) + 1;
if(len <= fcall->offset)
continue;
}
/* offset found, proceeding */
for(; i < tag.size; i++) {
len = strlen(tag.data[i]) + 1;
for(; i < view.size; i++) {
len = strlen(view.data[i]->name) + 1;
if(fcall->count + len > fcall->iounit)
break;
memcpy(p + fcall->count, tag.data[i], len - 1);
memcpy(p + fcall->count, view.data[i]->name, len - 1);
memcpy(p + fcall->count + len - 1, "\n", 1);
fcall->count += len;
}
@ -864,7 +864,7 @@ xread(IXPConn *c, Fcall *fcall)
p = ixp_enc_stat(p, &stat);
fcall->count += type2stat(&stat, "bar", &m->qid);
p = ixp_enc_stat(p, &stat);
if(tag.size) {
if(view.size) {
fcall->count += type2stat(&stat, "tags", &m->qid);
p = ixp_enc_stat(p, &stat);
}
@ -1028,11 +1028,11 @@ xread(IXPConn *c, Fcall *fcall)
memcpy(p, client.data[i1]->tags, fcall->count);
break;
default:
for(i = 0; i < tag.size; i++) {
len = strlen(tag.data[i]) + 1;
for(i = 0; i < view.size; i++) {
len = strlen(view.data[i]->name) + 1;
if(fcall->count + len > fcall->iounit)
break;
memcpy(p + fcall->count, tag.data[i], len - 1);
memcpy(p + fcall->count, view.data[i]->name, len - 1);
memcpy(p + fcall->count + len - 1, "\n", 1);
fcall->count += len;
}
@ -1210,8 +1210,7 @@ xwrite(IXPConn *c, Fcall *fcall)
else
cl = client.data[i1];
cext_strlcpy(cl->tags, buf, sizeof(cl->tags));
str2tagvector(&cl->tag, buf);
update_tags();
update_tags(cl);
draw_client(cl);
break;
case FsFgeom:

View File

@ -110,15 +110,11 @@ match(Client *c, const char *prop, Bool newclient)
if(!strncmp(r->tags, "~", 2))
c->floating = True;
else if(!strncmp(r->tags, "!", 2)) {
if(view.size && newclient) {
if(view.size && newclient)
cext_strlcpy(c->tags, view.data[sel]->name, sizeof(c->tags));
str2tagvector(&c->tag, c->tags);
}
}
else {
else
cext_strlcpy(c->tags, r->tags, sizeof(c->tags));
str2tagvector(&c->tag, c->tags);
}
}
}
}

View File

@ -8,107 +8,56 @@
#include "wm.h"
Bool
istag(char *t)
void
update_tags(Client *c)
{
unsigned int i;
for(i = 0; i < tag.size; i++)
if(!strncmp(tag.data[i], t, strlen(t)))
return True;
return False;
}
static void
organize_client(View *v, Client *c)
{
if(clienthastag(c, v->name)) {
if(!clientofview(v, c)) {
/*fprintf(stderr, "org attach %s?\n", c->name);*/
attach_toview(v, c);
if(c) {
char buf[256];
char *toks[16];
unsigned int j, n;
Bool match;
fprintf(stderr, "tags: %s\n", c->tags);
cext_strlcpy(buf, c->tags, sizeof(buf));
n = cext_tokenize(toks, 16, buf, '+');
for(i = 0; i < n; i++) {
View *v = get_view(toks[i]);
if(!clientofview(v, c))
attach_toview(v, c);
}
for(i = 0; i < c->view.size; i++) {
View *v = c->view.data[i];
match = False;
for(j = 0; j < n; j++) {
if(!strncmp(v->name, toks[j], sizeof(v->name)))
match = True;
}
if(!match)
detach_fromview(v, c);
}
}
else {
if(clientofview(v, c)) {
/*fprintf(stderr, "org detach %s?\n", c->name);*/
detach_fromview(v, c);
}
}
}
static Vector *
tag2vector(TagVector *tv)
{
return (Vector *) tv;
}
void
ensure_tag(char *arg)
{
if(!istag(arg) && strncmp(arg, "*", 2))
cext_vattach(tag2vector(&tag), strdup(arg));
}
void
update_tags()
{
unsigned int i, j;
while(tag.size) {
char *p = tag.data[0];
cext_vdetach(tag2vector(&tag), p);
free(p);
}
for(i = 0; i < client.size; i++) {
for(j = 0; j < client.data[i]->tag.size; j++)
ensure_tag(client.data[i]->tag.data[j]);
}
for(i = 0; view.size && (i < client.size); i++) {
for(j = 0; j < view.size; j++) {
View *v = view.data[j];
if(j == sel)
continue;
organize_client(v, client.data[i]);
}
organize_client(view.data[sel], client.data[i]);
}
if(view.size && !hasclient(view.data[sel]))
destroy_view(view.data[sel]);
for(i = 0; i < view.size; i++)
if(!hasclient(view.data[i]))
destroy_view(view.data[i]);
if(view.size)
focus_view(view.data[sel]);
else if(tag.size)
select_view(tag.data[0]);
else
update_bar_tags();
}
void
str2tagvector(TagVector *tv, const char *tags)
{
unsigned int i, n;
char buf[256];
char *toks[16];
char *p;
while(tv->size) {
p = tv->data[0];
cext_vdetach(tag2vector(tv), p);
free(p);
}
cext_strlcpy(buf, tags, sizeof(buf));
n = cext_tokenize(toks, 16, buf, '+');
for(i = 0; i < n; i++)
cext_vattach(tag2vector(tv), strdup(toks[i]));
}
void
retag()
{
unsigned int i;
for(i = 0; i < client.size; i++)
for(i = 0; i < client.size; i++) {
match_tags(client.data[i], False);
update_tags();
update_tags(client.data[i]);
}
}

View File

@ -8,7 +8,7 @@
#include "wm.h"
static Vector *
Vector *
view2vector(ViewVector *vv)
{
return (Vector *) vv;
@ -32,6 +32,7 @@ alloc_view(char *name)
void
destroy_view(View *v)
{
fprintf(stderr, "destroy_view: %s\n", v->name);
while(v->area.size)
destroy_area(v->area.data[0]);
@ -70,13 +71,6 @@ focus_view(View *v)
Client *c;
unsigned int i;
/* cleanup other empty views */
for(i = 0; i < view.size; i++)
if(!hasclient(view.data[i])) {
destroy_view(view.data[i]);
i--;
}
XGrabServer(dpy);
sel = view2index(v);
@ -158,23 +152,8 @@ name2view(char *name)
View *
get_view(char *name)
{
unsigned int i;
View *v = name2view(name);
if(v)
return v;
for(i = 0; i < client.size; i++)
if(clienthastag(client.data[i], name))
goto Createview;
return nil;
Createview:
v = alloc_view(name);
for(i = 0; i < client.size; i++)
if(clienthastag(client.data[i], name) && !clientofview(v, client.data[i]))
attach_toview(v, client.data[i]);
return v;
return v ? v : alloc_view(name);
}
Bool
@ -190,7 +169,7 @@ hasclient(View *v)
void
select_view(char *arg)
{
View *v = get_view(arg);
View *v = name2view(arg);
if(!v)
return;
focus_view(v);
@ -200,8 +179,8 @@ Bool
clientofview(View *v, Client *c)
{
unsigned int i;
for(i = 0; i < v->area.size; i++)
if(clientofarea(v->area.data[i], c))
for(i = 0; i < c->view.size; i++)
if(v == c->view.data[i])
return True;
return False;
}
@ -209,16 +188,16 @@ clientofview(View *v, Client *c)
void
detach_fromview(View *v, Client *c)
{
int i;
Client *cl;
unsigned int i;
fprintf(stderr, "detach_fromview: %s\n", c->name);
cext_vdetach(view2vector(&c->view), v);
for(i = 0; i < v->area.size; i++) {
if(clientofarea(v->area.data[i], c)) {
detach_fromarea(v->area.data[i], c);
XMoveWindow(dpy, c->framewin, 2 * rect.width, 0);
}
}
if((cl = sel_client_of_view(v)))
focus_client(cl);
}
void
@ -226,6 +205,8 @@ attach_toview(View *v, Client *c)
{
Area *a;
fprintf(stderr, "attach_toview: %s\n", c->name);
if(c->trans || c->floating)
a = v->area.data[0];
else
@ -234,8 +215,7 @@ attach_toview(View *v, Client *c)
attach_toarea(a, c);
map_client(c);
XMapWindow(dpy, c->framewin);
if(v == view.data[sel])
focus_client(c);
cext_vattach(view2vector(&c->view), v);
}
Client *

View File

@ -289,9 +289,8 @@ main(int argc, char *argv[])
ixp_server_open_conn(&srv, ConnectionNumber(dpy), check_x_event, nil);
init_x_event_handler();
tag.size = view.size = client.size = sel = 0;
view.size = client.size = sel = 0;
view.data = nil;
tag.data = nil;
client.data = nil;
key.data = nil;

View File

@ -96,12 +96,12 @@ struct Frame {
Client *client;
};
VECTOR(TagVector, char *);
VECTOR(ViewVector, View *);
struct Client {
unsigned short id;
char name[256];
char tags[256];
TagVector tag;
ViewVector view;
char classinst[256];
int proto;
unsigned int border;
@ -152,7 +152,6 @@ typedef struct {
} Default;
/* global variables */
VECTOR(ViewVector, View *);
VECTOR(ClientVector, Client *);
VECTOR(KeyVector, Key *);
VECTOR(LabelVector, Label *);
@ -161,7 +160,6 @@ VECTOR(LabelVector, Label *);
ViewVector view;
unsigned int sel;
ClientVector client;
TagVector tag;
KeyVector key;
LabelVector label;
Display *dpy;
@ -264,13 +262,11 @@ void update_rules();
void match_tags(Client *c, Bool newclient);
/* tag.c */
Bool istag(char *t);
void ensure_tag(char *t);
void update_tags();
void str2tagvector(TagVector *tv, const char *tags);
void update_tags(Client *c);
void retag();
/* view.c */
Vector *view2vector(ViewVector *vv);
void arrange_view(View *v, Bool dirty);
View *alloc_view(char *name);
void focus_view(View *v);
@ -286,6 +282,7 @@ void restack_view(View *v);
Bool hasclient(View *v);
View *name2view(char *name);
void destroy_view(View *v);
View *get_view(char *name);
/* wm.c */
void scan_wins();