[hackers] [wmii] Add experimental regex tag support.

From: Kris Maglione <jg_AT_suckless.org>
Date: Fri Jan 25 05:00:46 2008

changeset: 2260:487d96a8c4d2
tag: tip
user: Kris Maglione <jg_AT_suckless.org>
date: Thu Jan 24 22:55:45 2008 -0500
summary: Add experimental regex tag support.

diff -r 0b003cc0cc07 -r 487d96a8c4d2 cmd/wmii/Makefile
--- a/cmd/wmii/Makefile Thu Jan 24 20:03:44 2008 -0500
+++ b/cmd/wmii/Makefile Thu Jan 24 22:55:45 2008 -0500
@@ -30,6 +30,7 @@ OBJ = area \
         rule \
         printevent\
         utf \
+ _util \
         view \
         xdnd \
         x11 \
diff -r 0b003cc0cc07 -r 487d96a8c4d2 cmd/wmii/_util.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cmd/wmii/_util.c Thu Jan 24 22:55:45 2008 -0500
@@ -0,0 +1,115 @@
+/* Copyright ©2008 Kris Maglione <fbsdaemon_AT_gmail.com>
+ * See LICENSE file for license details.
+ */
+#include "dat.h"
+#include "fns.h"
+
+/* Blech. */
+#define VECTOR(type, nam, c) \
+void \
+vector_##c##init(Vector_##nam *v) { \
+ memset(v, 0, sizeof *v); \
+} \
+ \
+void \
+vector_##c##free(Vector_##nam *v) { \
+ free(v->ary); \
+ memset(v, 0, sizeof *v); \
+} \
+ \
+void \
+vector_##c##push(Vector_##nam *v, type val) { \
+ if(v->n == v->size) { \
+ if(v->size == 0) \
+ v->size = 2; \
+ v->size <<= 2; \
+ v->ary = erealloc(v->ary, v->size * sizeof *v->ary); \
+ } \
+ v->ary[v->n++] = val; \
+} \
+
+VECTOR(long, long, l)
+VECTOR(Rectangle, rect, r)
+VECTOR(void*, ptr, p)
+
+void
+reinit(Regex *r, char *regx) {
+
+ refree(r);
+
+ r->regex = estrdup(regx);
+ r->regc = regcomp(regx);
+}
+
+void
+refree(Regex *r) {
+
+ free(r->regex);
+ free(r->regc);
+ r->regex = nil;
+ r->regc = nil;
+}
+
+void
+uniq(char **toks) {
+ char **p, **q;
+
+ q = toks;
+ if(*q == nil)
+ return;
+ for(p=q+1; *p; p++)
+ if(strcmp(*q, *p))
+ *++q = *p;
+ *++q = nil;
+}
+
+char**
+comm(int cols, char **toka, char **tokb) {
+ Vector_ptr vec;
+ char **ret;
+ char *p;
+ int cmp, len, i;
+
+ len = 0;
+ vector_pinit(&vec);
+ while(*toka || *tokb) {
+ if(!*toka)
+ cmp = 1;
+ else if(!*tokb)
+ cmp = -1;
+ else
+ cmp = strcmp(*toka, *tokb);
+ if(cmp < 0) {
+ if(cols & CLeft) {
+ vector_ppush(&vec, *toka);
+ len += strlen(*toka) + 1;
+ }
+ toka++;
+ }else if(cmp > 0) {
+ if(cols & CRight) {
+ vector_ppush(&vec, *tokb);
+ len += strlen(*tokb) + 1;
+ }
+ tokb++;
+ }else {
+ if(cols & CCenter) {
+ vector_ppush(&vec, *toka);
+ len += strlen(*toka) + 1;
+ }
+ toka++;
+ tokb++;
+ }
+ }
+ ret = emalloc((vec.n+1) * sizeof(char*) + len);
+ ret[vec.n] = nil;
+ p = (char*)&ret[vec.n+1];
+ for(i=0; i < vec.n; i++) {
+ len = strlen(vec.ary[i]) + 1;
+ memcpy(p, vec.ary[i], len);
+ ret[i] = p;
+ p += len;
+ }
+ free(vec.ary);
+ return ret;
+}
+
diff -r 0b003cc0cc07 -r 487d96a8c4d2 cmd/wmii/client.c
--- a/cmd/wmii/client.c Thu Jan 24 20:03:44 2008 -0500
+++ b/cmd/wmii/client.c Thu Jan 24 22:55:45 2008 -0500
@@ -245,6 +245,8 @@ client_destroy(Client *c) {
         none = nil;
         client_setviews(c, &none);
         sethandler(&c->w, nil);
+ refree(&c->tagre);
+ free(c->retags);
 
         if(hide)
                 reparentwindow(&c->w, &scr.root, screen->r.max);
@@ -910,6 +912,7 @@ client_setviews(Client *c, char **tags)
                                 f = frame_create(c, view_create(*tags));
                                 if(f->view == screen->sel || !c->sel)
                                         c->sel = f;
+ kludge = c;
                                 view_attach(f->view, f);
                                 f->cnext = *fp;
                                 *fp = f;
@@ -918,7 +921,8 @@ client_setviews(Client *c, char **tags)
                         tags++;
                 }
         }
- view_update_all();
+ if(c->sel == nil)
+ c->sel = c->frame;
 }
 
 static int
@@ -943,10 +947,13 @@ static char *badtags[] = {
 
 void
 apply_tags(Client *c, const char *tags) {
+ View *v;
         uint i, j, k, n;
         bool add;
         char buf[512], last;
- char *toks[32], *cur;
+ char *toks[32], *vtags[32];
+ char **p;
+ char *cur;
 
         buf[0] = 0;
 
@@ -958,7 +965,6 @@ apply_tags(Client *c, const char *tags)
                 utflcpy(buf, c->tags, sizeof(c->tags));
 
         strlcat(buf, &tags[n], sizeof(buf));
- trim(buf, " \t/");
 
         n = 0;
         add = True;
@@ -971,6 +977,27 @@ apply_tags(Client *c, const char *tags)
 
         j = 0;
         while(buf[n] && n < sizeof(buf) && j < 32) {
+ if(buf[n] == '/') {
+ for(i=n+1; i < sizeof(buf) - 1; i++)
+ if(buf[i] == '/')
+ break;
+ if(buf[i] != '/')
+ goto ifnot;
+ i++;
+ if(buf[i] != '+'
+ && buf[i] != '-'
+ && buf[i] != '\0') /* Don't be lenient */
+ goto ifnot;
+ buf[i-1] = '\0';
+ if(add)
+ reinit(&c->tagre, buf+n+1);
+ else
+ refree(&c->tagre);
+ last = buf[i];
+ buf[i] = '\0';
+ goto next;
+ }
+ ifnot:
                 for(i = n; i < sizeof(buf) - 1; i++)
                         if(buf[i] == '+'
                         || buf[i] == '-'
@@ -978,6 +1005,8 @@ apply_tags(Client *c, const char *tags)
                                 break;
                 last = buf[i];
                 buf[i] = '\0';
+
+ trim(buf+n, " \t/");
 
                 cur = nil;
                 if(!strcmp(buf+n, "~"))
@@ -990,7 +1019,7 @@ apply_tags(Client *c, const char *tags)
                         cur = buf+n;
 
                 n = i + 1;
- if(cur) {
+ if(cur && j < nelem(toks)-1) {
                         if(add)
                                 toks[j++] = cur;
                         else {
@@ -1001,6 +1030,7 @@ apply_tags(Client *c, const char *tags)
                         }
                 }
 
+ next:
                 if(last == '+')
                         add = True;
                 if(last == '-')
@@ -1009,20 +1039,33 @@ apply_tags(Client *c, const char *tags)
                         buf[n] = '\0';
         }
 
- if(!j)
- return;
-
+ toks[j] = nil;
         qsort(toks, j, sizeof *toks, strpcmp);
-
+ uniq(toks);
         c->tags[0] = '\0';
- for(i=0, n=0; i < j; i++)
- if(n == 0 || strcmp(toks[i], toks[n-1])) {
- if(i > 0)
- strlcat(c->tags, "+", sizeof c->tags);
- strlcat(c->tags, toks[i], sizeof c->tags);
- toks[n++] = toks[i];
- }
- toks[n] = nil;
+ for(p=toks; *p; p++) {
+ if(p > toks)
+ strlcat(c->tags, "+", sizeof c->tags);
+ strlcat(c->tags, *p, sizeof c->tags);
+ }
+
+ i = 0;
+ if(c->tagre.regex)
+ for(v=view; v; v=v->next)
+ if(regexec(c->tagre.regc, v->name, nil, 0))
+ if(i < nelem(vtags)-1)
+ vtags[i++] = v->name;
+ vtags[i] = nil;
+
+ free(c->retags);
+ c->retags = comm(CRight, toks, vtags);
+
+ for(p=vtags; *p; p++)
+ if(j < nelem(toks)-1)
+ toks[j++] = *p;
+ toks[j] = nil;
+ qsort(toks, j, sizeof *toks, strpcmp);
+ uniq(toks);
 
         client_setviews(c, toks);
 
diff -r 0b003cc0cc07 -r 487d96a8c4d2 cmd/wmii/dat.h
--- a/cmd/wmii/dat.h Thu Jan 24 20:03:44 2008 -0500
+++ b/cmd/wmii/dat.h Thu Jan 24 22:55:45 2008 -0500
@@ -26,6 +26,12 @@ enum {
 };
 
 enum {
+ CLeft = 1<<0,
+ CCenter = 1<<1,
+ CRight = 1<<2,
+};
+
+enum {
         UrgManager,
         UrgClient,
 };
@@ -93,6 +99,7 @@ typedef struct Key Key;
 typedef struct Key Key;
 typedef struct Map Map;
 typedef struct MapEnt MapEnt;
+typedef struct Regex Regex;
 typedef struct Rule Rule;
 typedef struct Ruleset Ruleset;
 typedef struct Strut Strut;
@@ -124,6 +131,11 @@ struct Bar {
         CTuple col;
 };
 
+struct Regex {
+ char* regex;
+ Reprog* regc;
+};
+
 struct Client {
         Client* next;
         Frame* frame;
@@ -131,10 +143,12 @@ struct Client {
         Window w;
         Window* framewin;
         XWindow trans;
+ Regex tagre;
         Group* group;
         Strut* strut;
         Cursor cursor;
         Rectangle r;
+ char** retags;
         char name[256];
         char tags[256];
         char props[512];
@@ -212,6 +226,7 @@ struct Rule {
         Rule* next;
         Reprog* regex;
         char value[256];
+
 };
 
 struct Ruleset {
@@ -253,6 +268,7 @@ void vector_##c##push(Vector_##nam*, typ
 
 VECTOR(long, long, l)
 VECTOR(Rectangle, rect, r)
+VECTOR(void*, ptr, p)
 #undef VECTOR
 
 #ifndef EXTERN
@@ -334,6 +350,8 @@ EXTERN int debugfile;
 EXTERN int debugfile;
 EXTERN long xtime;
 
+EXTERN Client* kludge;
+
 extern char* debugtab[];
 
 #define Debug(x) if((debugflag|debugfile)&(x) && setdebug(x))
diff -r 0b003cc0cc07 -r 487d96a8c4d2 cmd/wmii/fns.h
--- a/cmd/wmii/fns.h Thu Jan 24 20:03:44 2008 -0500
+++ b/cmd/wmii/fns.h Thu Jan 24 22:55:45 2008 -0500
@@ -216,6 +216,12 @@ void view_update_rect(View*);
 void view_update_rect(View*);
 Rectangle* view_rects(View*, uint *num, Frame *ignore);
 
+/* util.c */
+void refree(Regex*);
+void reinit(Regex*, char*);
+char** comm(int, char**, char**);
+void uniq(char**);
+
 /* utf.c */
 char* toutf8(const char*);
 char* toutf8n(const char*, size_t);
diff -r 0b003cc0cc07 -r 487d96a8c4d2 cmd/wmii/frame.c
--- a/cmd/wmii/frame.c Thu Jan 24 20:03:44 2008 -0500
+++ b/cmd/wmii/frame.c Thu Jan 24 22:55:45 2008 -0500
@@ -301,6 +301,9 @@ frame_resize(Frame *f, Rectangle r) {
                 return;
         }
 
+ if(f->area->floating)
+ f->collapsed = false;
+
         stickycorner = get_sticky(f->r, r);
         f->crect = frame_hints(f, r, stickycorner);
 
diff -r 0b003cc0cc07 -r 487d96a8c4d2 cmd/wmii/geom.c
--- a/cmd/wmii/geom.c Thu Jan 24 20:03:44 2008 -0500
+++ b/cmd/wmii/geom.c Thu Jan 24 22:55:45 2008 -0500
@@ -89,31 +89,3 @@ get_sticky(Rectangle src, Rectangle dst)
         return stickycorner;
 }
 
-/* XXX: These don't belong here. */
-/* Blech. */
-#define VECTOR(type, nam, c) \
-void \
-vector_##c##init(Vector_##nam *v) { \
- memset(v, 0, sizeof *v); \
-} \
- \
-void \
-vector_##c##free(Vector_##nam *v) { \
- free(v->ary); \
- memset(v, 0, sizeof *v); \
-} \
- \
-void \
-vector_##c##push(Vector_##nam *v, type val) { \
- if(v->n == v->size) { \
- if(v->size == 0) \
- v->size = 2; \
- v->size <<= 2; \
- v->ary = erealloc(v->ary, v->size * sizeof *v->ary); \
- } \
- v->ary[v->n++] = val; \
-} \
-
-VECTOR(long, long, l)
-VECTOR(Rectangle, rect, r)
-
diff -r 0b003cc0cc07 -r 487d96a8c4d2 cmd/wmii/mouse.c
--- a/cmd/wmii/mouse.c Thu Jan 24 20:03:44 2008 -0500
+++ b/cmd/wmii/mouse.c Thu Jan 24 22:55:45 2008 -0500
@@ -408,6 +408,8 @@ mouse_resizecolframe(Frame *f, Align ali
         assert((align&(East|West)) != (East|West));
         assert((align&(North|South)) != (North|South));
 
+ f->collapsed = false;
+
         v = screen->sel;
         d = divs;
         for(a=v->area->next; a != f->area; a=a->next)
@@ -681,8 +683,10 @@ static void
 static void
 trampoline(int fn, Frame *f) {
 
- while(fn > 0)
+ while(fn > 0) {
+ f->collapsed = false;
                 fn = tramp[fn](f);
+ }
         ungrabpointer();
 
         warppointer(grabboxcenter(f));
diff -r 0b003cc0cc07 -r 487d96a8c4d2 cmd/wmii/view.c
--- a/cmd/wmii/view.c Thu Jan 24 20:03:44 2008 -0500
+++ b/cmd/wmii/view.c Thu Jan 24 22:55:45 2008 -0500
@@ -7,11 +7,25 @@
 
 static bool
 empty_p(View *v) {
- Area *a;
+ Frame *f;
+ Area *a;
+ char **p;
+ int cmp;
+
         for(a=v->area; a; a=a->next)
- if(a->frame)
- return False;
- return True;
+ for(f=a->frame; f; f=f->anext) {
+ for(p=f->client->retags; *p; p++) {
+ cmp = strcmp(*p, v->name);
+ if(cmp == 0)
+ goto nextframe;
+ if(cmp > 0)
+ return false;
+ }
+ return false;
+ nextframe:
+ continue;
+ }
+ return true;
 }
 
 static void
@@ -43,11 +57,17 @@ View*
 View*
 view_create(const char *name) {
         static ushort id = 1;
- View **i, *v;
+ View **vp;
+ Client *c;
+ View *v;
 
         for(v=view; v; v=v->next)
                 if(!strcmp(name, v->name))
                         return v;
+
+ print("xviews:\n");
+ for(View *q=view; q; q=q->next)
+ print("view: %d %s\n", !strcmp(name, q->name), q->name);
 
         v = emallocz(sizeof(View));
         v->id = id++;
@@ -62,11 +82,17 @@ view_create(const char *name) {
         
         area_focus(v->area->next);
 
- for(i=&view; *i; i=&(*i)->next)
- if(strcmp((*i)->name, name) >= 0)
+ for(vp=&view; *vp; vp=&(*vp)->next)
+ if(strcmp((*vp)->name, name) >= 0)
                         break;
- v->next = *i;
- *i = v;
+ v->next = *vp;
+ *vp = v;
+
+ /* FIXME: Belongs elsewhere */
+ /* FIXME: Can do better. */
+ for(c=client; c; c=c->next)
+ if(c != kludge)
+ apply_tags(c, c->tags);
 
         view_arrange(v);
         if(!screen->sel)
@@ -77,22 +103,29 @@ view_create(const char *name) {
 
 void
 view_destroy(View *v) {
- Area *a;
- View **i, *tv;
+ View **vp;
+ Frame *f;
+ View *tv;
+ Area *a;
+
+ for(vp=&view; *vp; vp=&(*vp)->next)
+ if(*vp == v) break;
+ *vp = v->next;
+
+ /* FIXME: Can do better */
+ for(a=v->area; a; a=a->next)
+ for(f=a->frame; f; f=f->anext)
+ apply_tags(f->client, f->client->tags);
 
         while((a = v->area->next))
                 area_destroy(a);
         area_destroy(v->area);
 
- for(i=&view; *i; i=&(*i)->next)
- if(*i == v) break;
- *i = v->next;
-
         event("DestroyTag %s\n", v->name);
 
         if(v == screen->sel) {
                 for(tv=view; tv; tv=tv->next)
- if(tv->next == *i) break;
+ if(tv->next == *vp) break;
                 if(tv == nil)
                         tv = view;
                 if(tv)
@@ -259,6 +292,9 @@ view_attach(View *v, Frame *f) {
                 a = v->area->next;
 
         area_attach(a, f);
+
+ if(c->sel == nil)
+ c->sel = f;
 }
 
 void
@@ -429,7 +465,7 @@ view_newcolw(View *v, int num) {
                         char buf[sizeof r->value];
                         char *toks[16];
 
- strcpy(buf, r->value);
+ utflcpy(buf, r->value, sizeof buf);
 
                         n = tokenize(toks, 16, buf, '+');
                         if(num < n)
Received on Fri Jan 25 2008 - 05:00:46 UTC

This archive was generated by hypermail 2.2.0 : Sun Jul 13 2008 - 15:59:09 UTC