mirror of
https://github.com/0intro/wmii
synced 2025-01-06 02:22:01 +03:00
simplified tagging in Client
This commit is contained in:
parent
ae2d270f22
commit
3588e0909d
@ -220,7 +220,6 @@ void
|
||||
draw_client(Client *c)
|
||||
{
|
||||
Draw d = { 0 };
|
||||
char buf[512];
|
||||
|
||||
if(!c->frame.size)
|
||||
return; /* might not have been attached atm */
|
||||
@ -247,9 +246,8 @@ draw_client(Client *c)
|
||||
d.rect.height = bar_height();
|
||||
d.notch = nil;
|
||||
|
||||
tags2str(buf, sizeof(buf), c->tag, c->ntag);
|
||||
d.align = WEST;
|
||||
d.rect.x = d.rect.height + XTextWidth(xfont, buf, strlen(buf));
|
||||
d.rect.x = d.rect.height + XTextWidth(xfont, c->tags, strlen(c->tags));
|
||||
d.rect.width = c->frame.data[c->sel]->rect.width - d.rect.x;
|
||||
d.data = c->name;
|
||||
blitz_drawlabel(dpy, &d);
|
||||
@ -264,7 +262,7 @@ draw_client(Client *c)
|
||||
d.align = CENTER;
|
||||
d.rect.width = d.rect.x;
|
||||
d.rect.x = 0;
|
||||
d.data = buf;
|
||||
d.data = c->tags;
|
||||
blitz_drawlabel(dpy, &d);
|
||||
blitz_drawborder(dpy, &d);
|
||||
|
||||
@ -342,8 +340,8 @@ manage_client(Client *c)
|
||||
|
||||
if(c->trans && (trans = win2client(c->trans))) {
|
||||
for(i = 0; i < trans->ntag; i++)
|
||||
cext_strlcpy(c->tag[i], trans->tag[i], sizeof(c->tag[i]));
|
||||
c->ntag = trans->ntag;
|
||||
cext_strlcpy(c->tags, trans->tags, sizeof(c->tags));
|
||||
str2tagvector(&c->tag, c->tags);
|
||||
}
|
||||
else
|
||||
match_tags(c);
|
||||
@ -352,8 +350,8 @@ manage_client(Client *c)
|
||||
|
||||
v = view.size ? view.data[sel] : alloc_view(def.tag);
|
||||
if(!c->ntag) {
|
||||
cext_strlcpy(c->tag[0], v->name, sizeof(c->tag[0]));
|
||||
c->ntag++;
|
||||
cext_strlcpy(c->tags, v->name, sizeof(c->tags));
|
||||
str2tagvector(&c->tag, c->tags);
|
||||
}
|
||||
|
||||
update_tags();
|
||||
@ -646,9 +644,9 @@ Bool
|
||||
clienthastag(Client *c, const char *t)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; i < c->ntag; i++)
|
||||
if(!strncmp(c->tag[i], t, sizeof(c->tag[i]))
|
||||
|| !strncmp(c->tag[i], "*", 2))
|
||||
for(i = 0; i < c->tag.size; i++)
|
||||
if(!strncmp(c->tag.data[i], t, strlen(t))
|
||||
|| !strncmp(c->tag.data[i], "*", 2))
|
||||
return True;
|
||||
return False;
|
||||
}
|
||||
|
29
cmd/wm/fs.c
29
cmd/wm/fs.c
@ -512,12 +512,10 @@ type2stat(Stat *stat, char *wname, Qid *dir)
|
||||
switch(dir_type) {
|
||||
case FsDclient:
|
||||
f = view.data[dir_i1]->area.data[dir_i2]->frame.data[dir_i3];
|
||||
tags2str(buf, sizeof(buf), f->client->tag, f->client->ntag);
|
||||
return mkstat(stat, dir, wname, strlen(buf), IXP_DMREAD | IXP_DMWRITE);
|
||||
return mkstat(stat, dir, wname, strlen(f->client->tags), IXP_DMREAD | IXP_DMWRITE);
|
||||
break;
|
||||
case FsDGclient:
|
||||
tags2str(buf, sizeof(buf), client.data[dir_i1]->tag, client.data[dir_i1]->ntag);
|
||||
return mkstat(stat, dir, wname, strlen(buf), IXP_DMREAD | IXP_DMWRITE);
|
||||
return mkstat(stat, dir, wname, strlen(client.data[dir_i1]->tags), IXP_DMREAD | IXP_DMWRITE);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
@ -1033,15 +1031,13 @@ xread(IXPConn *c, Fcall *fcall)
|
||||
case FsDclient:
|
||||
{
|
||||
Client *c = view.data[i1]->area.data[i2]->frame.data[i3]->client;
|
||||
tags2str(buf, sizeof(buf), c->tag, c->ntag);
|
||||
if((fcall->count = strlen(buf)))
|
||||
memcpy(p, buf, fcall->count);
|
||||
if((fcall->count = strlen(c->tags)))
|
||||
memcpy(p, c->tags, fcall->count);
|
||||
}
|
||||
break;
|
||||
case FsDGclient:
|
||||
tags2str(buf, sizeof(buf), client.data[i1]->tag, client.data[i1]->ntag);
|
||||
if((fcall->count = strlen(buf)))
|
||||
memcpy(p, buf, fcall->count);
|
||||
if((fcall->count = strlen(client.data[i1]->tags)))
|
||||
memcpy(p, client.data[i1]->tags, fcall->count);
|
||||
break;
|
||||
default:
|
||||
for(i = 0; i < tag.size; i++) {
|
||||
@ -1153,6 +1149,7 @@ xwrite(IXPConn *c, Fcall *fcall)
|
||||
unsigned int len;
|
||||
int i, i1 = 0, i2 = 0, i3 = 0;
|
||||
Frame *f;
|
||||
Client *cl;
|
||||
|
||||
if(!m)
|
||||
return Enofile;
|
||||
@ -1222,14 +1219,14 @@ xwrite(IXPConn *c, Fcall *fcall)
|
||||
return Ebadvalue;
|
||||
memcpy(buf, fcall->data, fcall->count);
|
||||
buf[fcall->count] = 0;
|
||||
if(m->qid.dir_type == FsDclient) {
|
||||
f = view.data[i1]->area.data[i2]->frame.data[i3];
|
||||
f->client->ntag = str2tags(f->client->tag, buf);
|
||||
}
|
||||
if(m->qid.dir_type == FsDclient)
|
||||
cl = view.data[i1]->area.data[i2]->frame.data[i3]->client;
|
||||
else
|
||||
client.data[i1]->ntag = str2tags(client.data[i1]->tag, buf);
|
||||
cl = client.data[i1];
|
||||
cext_strlcpy(cl->tags, buf, sizeof(cl->tags));
|
||||
str2tagvector(&cl->tag, buf);
|
||||
update_tags();
|
||||
draw_client(client.data[i1]);
|
||||
draw_client(cl);
|
||||
break;
|
||||
case FsFgeom:
|
||||
if(fcall->count > sizeof(buf))
|
||||
|
@ -17,49 +17,43 @@
|
||||
* regex might contain POSIX regex syntax defined in regex(3)
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
regex_t regex;
|
||||
char tag[MAX_TAGS][MAX_TAGLEN];
|
||||
unsigned int ntag;
|
||||
Bool is_valid;
|
||||
} Rule;
|
||||
|
||||
static Rule *rule = nil;
|
||||
static unsigned int rulesz = 0;
|
||||
static unsigned int nrule = 0;
|
||||
|
||||
enum {
|
||||
IGNORE,
|
||||
REGEX,
|
||||
TAGS
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
regex_t regex;
|
||||
char tags[256];
|
||||
Bool is_valid;
|
||||
} Rule;
|
||||
VECTOR(RuleVector, Rule *);
|
||||
|
||||
static RuleVector rule;
|
||||
|
||||
static Vector *
|
||||
rule2vector(RuleVector *rv)
|
||||
{
|
||||
return (Vector *) rv;
|
||||
}
|
||||
|
||||
void
|
||||
update_rules()
|
||||
{
|
||||
unsigned int i;
|
||||
int mode = IGNORE;
|
||||
char *p, *r=nil, *t=nil, regex[256], tags[256];
|
||||
char *p, *r = nil, *t = nil, regex[256], tags[256];
|
||||
|
||||
if(!def.rules || !strlen(def.rules))
|
||||
return;
|
||||
|
||||
for(i = 0; i < nrule; i++)
|
||||
if(rule[i].is_valid) {
|
||||
regfree(&rule[i].regex);
|
||||
rule[i].is_valid = False;
|
||||
}
|
||||
|
||||
nrule = 0;
|
||||
for(p = def.rules; *p; p++)
|
||||
if(*p == '\n')
|
||||
nrule++;
|
||||
|
||||
if(nrule > rulesz) {
|
||||
if(rule)
|
||||
free(rule);
|
||||
rule = cext_emallocz(sizeof(Rule) * nrule);
|
||||
rulesz = nrule;
|
||||
while(rule.size) {
|
||||
Rule *r = rule.data[i];
|
||||
if(r->is_valid)
|
||||
regfree(&r->regex);
|
||||
cext_vdetach(rule2vector(&rule), r);
|
||||
free(r);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
@ -80,8 +74,6 @@ update_rules()
|
||||
if(*p == '/') {
|
||||
mode = IGNORE;
|
||||
*r = 0;
|
||||
rule[i].is_valid = !regcomp(&rule[i].regex, regex, 0);
|
||||
/* Is there a memory leak here if the rule is invalid? */
|
||||
}
|
||||
else {
|
||||
*r = *p;
|
||||
@ -90,10 +82,12 @@ update_rules()
|
||||
break;
|
||||
case TAGS:
|
||||
if(*p == '\n' || *(p + 1) == 0) {
|
||||
Rule *rul = cext_emallocz(sizeof(Rule));
|
||||
*t = 0;
|
||||
rule[i].ntag = str2tags(rule[i].tag, tags);
|
||||
rul->is_valid = !regcomp(&rul->regex, regex, 0);
|
||||
cext_strlcpy(rul->tags, tags, sizeof(rul->tags));
|
||||
mode = IGNORE;
|
||||
i++;
|
||||
cext_vattach(rule2vector(&rule), rul);
|
||||
}
|
||||
else {
|
||||
if((*p == ' ' || *p == '\t') && (tags[0] == 0))
|
||||
@ -109,21 +103,17 @@ update_rules()
|
||||
static void
|
||||
match(Client *c, const char *prop)
|
||||
{
|
||||
unsigned int i, j;
|
||||
unsigned int i;
|
||||
regmatch_t tmpregm;
|
||||
|
||||
c->ntag = 0;
|
||||
for(i = 0; i < nrule; i++) {
|
||||
Rule *r = &rule[i];
|
||||
c->tags[0] = 0;
|
||||
for(i = 0; i < rule.size; i++) {
|
||||
Rule *r = rule.data[i];
|
||||
if(r->is_valid && !regexec(&r->regex, prop, 1, &tmpregm, 0)) {
|
||||
for(j = 0; c->ntag < MAX_TAGS && j < r->ntag; j++) {
|
||||
if(!strncmp(r->tag[j], "~", 2))
|
||||
c->floating = True;
|
||||
else {
|
||||
cext_strlcpy(c->tag[c->ntag], r->tag[j], sizeof(c->tag[c->ntag]));
|
||||
c->ntag++;
|
||||
}
|
||||
}
|
||||
if(!strncmp(r->tags, "~", 2))
|
||||
c->floating = True;
|
||||
else
|
||||
cext_strlcat(c->tags, r->tags, sizeof(c->tags) - strlen(c->tags));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
42
cmd/wm/tag.c
42
cmd/wm/tag.c
@ -59,8 +59,8 @@ update_tags()
|
||||
tag.size = 0;
|
||||
|
||||
for(i = 0; i < client.size; i++) {
|
||||
for(j = 0; j < client.data[i]->ntag; j++)
|
||||
ensure_tag(client.data[i]->tag[j]);
|
||||
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++) {
|
||||
@ -87,35 +87,21 @@ update_tags()
|
||||
update_bar_tags();
|
||||
}
|
||||
|
||||
unsigned int
|
||||
str2tags(char tags[MAX_TAGS][MAX_TAGLEN], const char *stags)
|
||||
void
|
||||
str2tagvector(TagVector *tv, const char *tags)
|
||||
{
|
||||
unsigned int i, n;
|
||||
char buf[256];
|
||||
char *toks[MAX_TAGS];
|
||||
char *toks[16];
|
||||
char *p;
|
||||
|
||||
cext_strlcpy(buf, stags, sizeof(buf));
|
||||
n = cext_tokenize(toks, MAX_TAGS, buf, '+');
|
||||
for(i = 0; i < n; i++)
|
||||
cext_strlcpy(tags[i], toks[i], MAX_TAGLEN);
|
||||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
tags2str(char *stags, unsigned int stagsz,
|
||||
char tags[MAX_TAGS][MAX_TAGLEN], unsigned int ntags)
|
||||
{
|
||||
unsigned int i, len = 0, l;
|
||||
|
||||
stags[0] = 0;
|
||||
for(i = 0; i < ntags; i++) {
|
||||
l = strlen(tags[i]);
|
||||
if(len + l + 1 >= stagsz)
|
||||
return;
|
||||
if(len)
|
||||
stags[len++] = '+';
|
||||
memcpy(stags + len, tags[i], l);
|
||||
len += l;
|
||||
stags[len] = 0;
|
||||
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]));
|
||||
}
|
||||
|
15
cmd/wm/wm.h
15
cmd/wm/wm.h
@ -63,8 +63,6 @@ enum {
|
||||
FsFmode
|
||||
};
|
||||
|
||||
enum { MAX_TAGS = 8 };
|
||||
enum { MAX_TAGLEN = 32 };
|
||||
enum { MIN_COLWIDTH = 64 };
|
||||
enum { WM_PROTOCOL_DELWIN = 1 };
|
||||
|
||||
@ -75,7 +73,7 @@ typedef struct Client Client;
|
||||
|
||||
VECTOR(AreaVector, Area *);
|
||||
struct View {
|
||||
char name[MAX_TAGLEN];
|
||||
char name[256];
|
||||
unsigned short id;
|
||||
AreaVector area;
|
||||
unsigned int sel;
|
||||
@ -99,10 +97,12 @@ struct Frame {
|
||||
Client *client;
|
||||
};
|
||||
|
||||
VECTOR(TagVector, char *);
|
||||
struct Client {
|
||||
unsigned short id;
|
||||
char name[256];
|
||||
char tag[MAX_TAGS][MAX_TAGLEN];
|
||||
char tags[256];
|
||||
TagVector tag;
|
||||
unsigned int ntag;
|
||||
char classinst[256];
|
||||
int proto;
|
||||
@ -142,7 +142,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
char selcolor[24];
|
||||
char normcolor[24];
|
||||
char tag[MAX_TAGLEN];
|
||||
char tag[256];
|
||||
char *font;
|
||||
Color sel;
|
||||
Color norm;
|
||||
@ -159,7 +159,6 @@ VECTOR(ViewVector, View *);
|
||||
VECTOR(ClientVector, Client *);
|
||||
VECTOR(KeyVector, Key *);
|
||||
VECTOR(LabelVector, Label *);
|
||||
VECTOR(TagVector, char *);
|
||||
|
||||
/* global variables */
|
||||
ViewVector view;
|
||||
@ -268,12 +267,10 @@ void update_rules();
|
||||
void match_tags(Client *c);
|
||||
|
||||
/* tag.c */
|
||||
unsigned int str2tags(char tags[MAX_TAGS][MAX_TAGLEN], const char *stags);
|
||||
void tags2str(char *stags, unsigned int stagsz,
|
||||
char tags[MAX_TAGS][MAX_TAGLEN], unsigned int ntags);
|
||||
Bool istag(char *t);
|
||||
void ensure_tag(char *t);
|
||||
void update_tags();
|
||||
void str2tagvector(TagVector *tv, const char *tags);
|
||||
|
||||
/* view.c */
|
||||
void arrange_view(View *v, Bool updategeometry);
|
||||
|
10
doc/RELEASE
10
doc/RELEASE
@ -1,11 +1,11 @@
|
||||
Abbadon (9base-2)
|
||||
Abbadon (9base-2)
|
||||
Amare
|
||||
Andariel
|
||||
Andon
|
||||
ArchDean
|
||||
Beth
|
||||
Bethanel
|
||||
Boyd (wmii-2)
|
||||
Boyd (wmii-2)
|
||||
Camael
|
||||
Charon
|
||||
Duma
|
||||
@ -36,9 +36,9 @@ Sandalphon
|
||||
Sophia
|
||||
Sunya
|
||||
Thanatos
|
||||
Tothiel (wmii-2.5)
|
||||
Tothiel (wmii-2.5)
|
||||
Ultimus Maximus
|
||||
Uriel (wmii-1)
|
||||
Uriel (wmii-1)
|
||||
Yhprum
|
||||
Zaphkiel
|
||||
Zadkiel (wmii-1.1)
|
||||
Zadkiel (wmii-1.1)
|
||||
|
Loading…
Reference in New Issue
Block a user