proceeded, though we still miss a real Tag struct
00ca643b
2 file(s) · +39 −25
| 12 | 12 | #define SELFGCOLOR "#ffffff" |
|
| 13 | 13 | ||
| 14 | 14 | /* tagging */ |
|
| 15 | - | const char tags[][MAXTAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "www" }; |
|
| 16 | - | int initags[LENGTH(tags)] = { [0] = 1 }; |
|
| 15 | + | const char tags[][MAXTAGLEN] = { "1", "2", "3", "4", "nil", "6", "7", "8", "www" }; |
|
| 16 | + | unsigned int vtags[LENGTH(tags)] = { 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 }; |
|
| 17 | + | Bool initags[LENGTH(tags)] = { [0] = True, [5] = True }; |
|
| 18 | + | ||
| 17 | 19 | Rule rules[] = { |
|
| 18 | 20 | /* class:instance:title substr tags ref isfloating */ |
|
| 19 | 21 | { "Firefox", tags[8], False }, |
| 67 | 67 | int x, y, w, h; |
|
| 68 | 68 | int basew, baseh, incw, inch, maxw, maxh, minw, minh; |
|
| 69 | 69 | int minax, maxax, minay, maxay; |
|
| 70 | - | int *tags; |
|
| 71 | 70 | long flags; |
|
| 72 | 71 | unsigned int border, oldborder; |
|
| 73 | 72 | Bool isbanned, isfixed, isfloating, isurgent; |
|
| 73 | + | Bool *tags; |
|
| 74 | 74 | Client *next; |
|
| 75 | 75 | Client *prev; |
|
| 76 | 76 | Client *snext; |
|
| 110 | 110 | Bool isfloating; |
|
| 111 | 111 | } Rule; |
|
| 112 | 112 | ||
| 113 | + | typedef struct { |
|
| 114 | + | const char name[MAXTAGLEN]; |
|
| 115 | + | unsigned int view; |
|
| 116 | + | } Tag; |
|
| 117 | + | ||
| 113 | 118 | struct View { |
|
| 114 | - | int id; |
|
| 115 | 119 | int x, y, w, h, wax, way, wah, waw; |
|
| 116 | 120 | double mwfact; |
|
| 117 | 121 | Layout *layout; |
|
| 119 | 123 | }; |
|
| 120 | 124 | ||
| 121 | 125 | /* function declarations */ |
|
| 126 | + | void addtag(Client *c, const char *t); |
|
| 122 | 127 | void applyrules(Client *c); |
|
| 123 | 128 | void arrange(void); |
|
| 124 | 129 | void attach(Client *c); |
|
| 153 | 158 | Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); |
|
| 154 | 159 | void grabbuttons(Client *c, Bool focused); |
|
| 155 | 160 | void grabkeys(void); |
|
| 156 | - | unsigned int idxoftag(const char *tag); |
|
| 161 | + | unsigned int idxoftag(const char *t); |
|
| 157 | 162 | void initfont(const char *fontstr); |
|
| 158 | 163 | Bool isoccupied(unsigned int t); |
|
| 159 | 164 | Bool isprotodel(Client *c); |
|
| 208 | 213 | int nviews = 1; |
|
| 209 | 214 | View *selview; |
|
| 210 | 215 | int screen; |
|
| 211 | - | int *seltags; |
|
| 212 | - | int *prevtags; |
|
| 213 | 216 | int (*xerrorxlib)(Display *, XErrorEvent *); |
|
| 214 | 217 | unsigned int bh, bpos; |
|
| 215 | 218 | unsigned int blw = 0; |
|
| 234 | 237 | Bool dozoom = True; |
|
| 235 | 238 | Bool otherwm, readin; |
|
| 236 | 239 | Bool running = True; |
|
| 240 | + | Bool *prevtags; |
|
| 241 | + | Bool *seltags; |
|
| 237 | 242 | Client *clients = NULL; |
|
| 238 | 243 | Client *sel = NULL; |
|
| 239 | 244 | Client *stack = NULL; |
|
| 248 | 253 | ||
| 249 | 254 | /* function implementations */ |
|
| 250 | 255 | void |
|
| 256 | + | addtag(Client *c, const char *t) { |
|
| 257 | + | unsigned int i, tidx = idxoftag(t); |
|
| 258 | + | ||
| 259 | + | for(i = 0; i < LENGTH(tags); i++) |
|
| 260 | + | if(c->tags[i] && vtags[i] != vtags[tidx]) |
|
| 261 | + | return; /* conflict */ |
|
| 262 | + | c->tags[tidx] = True; |
|
| 263 | + | } |
|
| 264 | + | ||
| 265 | + | void |
|
| 251 | 266 | applyrules(Client *c) { |
|
| 252 | 267 | unsigned int i; |
|
| 253 | - | Bool matched_tag = False; |
|
| 268 | + | Bool matched = False; |
|
| 254 | 269 | Rule *r; |
|
| 255 | 270 | XClassHint ch = { 0 }; |
|
| 256 | 271 | ||
| 257 | 272 | /* rule matching */ |
|
| 258 | 273 | XGetClassHint(dpy, c->win, &ch); |
|
| 259 | - | snprintf(buf, sizeof buf, "%s:%s:%s", |
|
| 260 | - | ch.res_class ? ch.res_class : "", |
|
| 261 | - | ch.res_name ? ch.res_name : "", c->name); |
|
| 262 | 274 | for(i = 0; i < LENGTH(rules); i++) { |
|
| 263 | 275 | r = &rules[i]; |
|
| 264 | 276 | if(strstr(c->name, r->prop) |
|
| 267 | 279 | { |
|
| 268 | 280 | c->isfloating = r->isfloating; |
|
| 269 | 281 | if(r->tag) { |
|
| 270 | - | matched_tag = True; |
|
| 271 | - | c->tags[idxoftag(r->tag)] = selview->id; |
|
| 282 | + | addtag(c, r->tag); |
|
| 283 | + | matched = True; |
|
| 272 | 284 | } |
|
| 273 | 285 | } |
|
| 274 | 286 | } |
|
| 276 | 288 | XFree(ch.res_class); |
|
| 277 | 289 | if(ch.res_name) |
|
| 278 | 290 | XFree(ch.res_name); |
|
| 279 | - | if(!matched_tag) |
|
| 291 | + | if(!matched) |
|
| 280 | 292 | memcpy(c->tags, seltags, sizeof initags); |
|
| 281 | 293 | } |
|
| 282 | 294 | ||
| 532 | 544 | for(c = stack; c && (!isvisible(c) || getview(c) != v); c = c->snext); |
|
| 533 | 545 | for(i = 0; i < LENGTH(tags); i++) { |
|
| 534 | 546 | dc.w = textw(tags[i]); |
|
| 535 | - | if(seltags[i] && seltags[i] == v->id) { |
|
| 547 | + | if(seltags[i]) { |
|
| 536 | 548 | drawtext(v, tags[i], dc.sel, isurgent(i)); |
|
| 537 | 549 | drawsquare(v, c && c->tags[i], isoccupied(i), isurgent(i), dc.sel); |
|
| 538 | 550 | } |
|
| 902 | 914 | } |
|
| 903 | 915 | ||
| 904 | 916 | unsigned int |
|
| 905 | - | idxoftag(const char *tag) { |
|
| 917 | + | idxoftag(const char *t) { |
|
| 906 | 918 | unsigned int i; |
|
| 907 | 919 | ||
| 908 | - | for(i = 0; (i < LENGTH(tags)) && (tags[i] != tag); i++); |
|
| 920 | + | for(i = 0; (i < LENGTH(tags)) && (tags[i] != t); i++); |
|
| 909 | 921 | return (i < LENGTH(tags)) ? i : 0; |
|
| 910 | 922 | } |
|
| 911 | 923 | ||
| 1559 | 1571 | for(i = 0; i < nviews; i++) { |
|
| 1560 | 1572 | /* init geometry */ |
|
| 1561 | 1573 | v = &views[i]; |
|
| 1562 | - | v->id = i + 1; |
|
| 1563 | 1574 | ||
| 1564 | 1575 | if(nviews != 1 && isxinerama) { |
|
| 1565 | 1576 | ||
| 1653 | 1664 | if(!sel) |
|
| 1654 | 1665 | return; |
|
| 1655 | 1666 | for(i = 0; i < LENGTH(tags); i++) |
|
| 1656 | - | sel->tags[i] = (NULL == arg) ? selview->id : 0; |
|
| 1657 | - | sel->tags[idxoftag(arg)] = selview->id; |
|
| 1667 | + | sel->tags[i] = (NULL == arg); |
|
| 1668 | + | sel->tags[idxoftag(arg)] = True; |
|
| 1658 | 1669 | arrange(); |
|
| 1659 | 1670 | } |
|
| 1660 | 1671 | ||
| 1750 | 1761 | sel->tags[i] = !sel->tags[i]; |
|
| 1751 | 1762 | for(j = 0; j < LENGTH(tags) && !sel->tags[j]; j++); |
|
| 1752 | 1763 | if(j == LENGTH(tags)) |
|
| 1753 | - | sel->tags[i] = selview->id; /* at least one tag must be enabled */ |
|
| 1764 | + | sel->tags[i] = True; /* at least one tag must be enabled */ |
|
| 1754 | 1765 | arrange(); |
|
| 1755 | 1766 | } |
|
| 1756 | 1767 | ||
| 1762 | 1773 | seltags[i] = !seltags[i]; |
|
| 1763 | 1774 | for(j = 0; j < LENGTH(tags) && !seltags[j]; j++); |
|
| 1764 | 1775 | if(j == LENGTH(tags)) |
|
| 1765 | - | seltags[i] = selview->id; /* at least one tag must be viewed */ |
|
| 1776 | + | seltags[i] = True; /* at least one tag must be viewed */ |
|
| 1766 | 1777 | arrange(); |
|
| 1767 | 1778 | } |
|
| 1768 | 1779 | ||
| 1903 | 1914 | void |
|
| 1904 | 1915 | view(const char *arg) { |
|
| 1905 | 1916 | unsigned int i; |
|
| 1906 | - | int tmp[LENGTH(tags)]; |
|
| 1917 | + | Bool tmp[LENGTH(tags)]; |
|
| 1907 | 1918 | ||
| 1908 | 1919 | for(i = 0; i < LENGTH(tags); i++) |
|
| 1909 | - | tmp[i] = (NULL == arg) ? selview->id : 0; |
|
| 1910 | - | tmp[idxoftag(arg)] = selview->id; |
|
| 1920 | + | tmp[i] = (NULL == arg); |
|
| 1921 | + | tmp[idxoftag(arg)] = True; |
|
| 1922 | + | ||
| 1911 | 1923 | if(memcmp(seltags, tmp, sizeof initags) != 0) { |
|
| 1912 | 1924 | memcpy(prevtags, seltags, sizeof initags); |
|
| 1913 | 1925 | memcpy(seltags, tmp, sizeof initags); |
|