comparison dwm.c @ 755:cdd895c163bd

tag and seltag is now only bool removed unnecessary functions cleanups
author meillo@marmaro.de
date Fri, 30 May 2008 00:07:26 +0200
parents 4c12dccc288d
children bff1012527b3
comparison
equal deleted inserted replaced
754:4c12dccc288d 755:cdd895c163bd
88 int basew, baseh, incw, inch, maxw, maxh, minw, minh; 88 int basew, baseh, incw, inch, maxw, maxh, minw, minh;
89 int minax, minay, maxax, maxay; 89 int minax, minay, maxax, maxay;
90 long flags; 90 long flags;
91 unsigned int border; 91 unsigned int border;
92 Bool isfixed, isfloat, ismax; 92 Bool isfixed, isfloat, ismax;
93 Bool *tags; 93 Bool tag;
94 Client *next; 94 Client *next;
95 Client *prev; 95 Client *prev;
96 Client *snext; 96 Client *snext;
97 Window win; 97 Window win;
98 }; 98 };
99 99
100 typedef struct { 100 typedef struct {
101 const char *clpattern; 101 const char *clpattern;
102 const char *tpattern; 102 int tag;
103 Bool isfloat; 103 Bool isfloat;
104 } Rule; 104 } Rule;
105 105
106 typedef struct { 106 typedef struct {
107 regex_t *clregex; 107 regex_t *clregex;
108 regex_t *tregex;
109 } RReg; 108 } RReg;
110 109
111 110
112 typedef struct { 111 typedef struct {
113 unsigned long mod; 112 unsigned long mod;
130 unsigned int nmaster; /* number of master clients */ 129 unsigned int nmaster; /* number of master clients */
131 unsigned int ntags, numlockmask; /* number of tags, dynamic lock mask */ 130 unsigned int ntags, numlockmask; /* number of tags, dynamic lock mask */
132 void (*handler[LASTEvent])(XEvent *); /* event handler */ 131 void (*handler[LASTEvent])(XEvent *); /* event handler */
133 void (*arrange)(void); /* arrange function, indicates mode */ 132 void (*arrange)(void); /* arrange function, indicates mode */
134 Atom wmatom[WMLast], netatom[NetLast]; 133 Atom wmatom[WMLast], netatom[NetLast];
135 Bool running, selscreen, *seltag; /* seltag is array of Bool */ 134 Bool running, selscreen, seltag; /* seltag is array of Bool */
136 Client *clients, *sel, *stack; /* global client list and stack */ 135 Client *clients, *sel, *stack; /* global client list and stack */
137 Cursor cursor[CurLast]; 136 Cursor cursor[CurLast];
138 DC dc; /* global draw context */ 137 DC dc; /* global draw context */
139 Display *dpy; 138 Display *dpy;
140 Window root, barwin; 139 Window root, barwin;
184 int xerror(Display *dsply, XErrorEvent *ee); /* dwm's X error handler */ 183 int xerror(Display *dsply, XErrorEvent *ee); /* dwm's X error handler */
185 184
186 /* tag.c */ 185 /* tag.c */
187 void initrregs(void); /* initialize regexps of rules defined in config.h */ 186 void initrregs(void); /* initialize regexps of rules defined in config.h */
188 Client *getnext(Client *c); /* returns next visible client */ 187 Client *getnext(Client *c); /* returns next visible client */
189 Client *getprev(Client *c); /* returns previous visible client */
190 void settags(Client *c, Client *trans); /* sets tags of c */ 188 void settags(Client *c, Client *trans); /* sets tags of c */
191 void tag(Arg *arg); /* tags c with arg's index */
192 void toggletag(Arg *arg); /* toggles c tags with arg's index */ 189 void toggletag(Arg *arg); /* toggles c tags with arg's index */
193 void viewnext(Arg *arg); /* view next tag(s) */
194 190
195 /* util.c */ 191 /* util.c */
196 void *emallocz(unsigned int size); /* allocates zero-initialized memory, exits on error */ 192 void *emallocz(unsigned int size); /* allocates zero-initialized memory, exits on error */
197 void eprint(const char *errstr, ...); /* prints errstr and exits with 1 */ 193 void eprint(const char *errstr, ...); /* prints errstr and exits with 1 */
198 void spawn(Arg *arg); /* forks a new subprocess with to arg's cmd */ 194 void spawn(Arg *arg); /* forks a new subprocess with to arg's cmd */
206 void incnmaster(Arg *arg); /* increments nmaster with arg's index value */ 202 void incnmaster(Arg *arg); /* increments nmaster with arg's index value */
207 Bool isvisible(Client *c); /* returns True if client is visible */ 203 Bool isvisible(Client *c); /* returns True if client is visible */
208 void restack(void); /* restores z layers of all clients */ 204 void restack(void); /* restores z layers of all clients */
209 void togglefloat(Arg *arg); /* toggles focusesd client between floating/non-floating state */ 205 void togglefloat(Arg *arg); /* toggles focusesd client between floating/non-floating state */
210 void togglemode(Arg *arg); /* toggles global arrange function (dotile/dofloat) */ 206 void togglemode(Arg *arg); /* toggles global arrange function (dotile/dofloat) */
211 void view(Arg *arg); /* views the tag with arg's index */ 207 void toggleview(); /* views the tag with arg's index */
212 void zoom(Arg *arg); /* zooms the focused client to master area, arg is ignored */ 208 void zoom(Arg *arg); /* zooms the focused client to master area, arg is ignored */
213 209
214 210
215 211
216 212
402 drawstatus(); 398 drawstatus();
403 } 399 }
404 400
405 Bool 401 Bool
406 isvisible(Client *c) { 402 isvisible(Client *c) {
407 unsigned int i; 403 if((c->tag && seltag) || (!c->tag && !seltag)) {
408 404 return True;
409 for(i = 0; i < ntags; i++) 405 }
410 if(c->tags[i] && seltag[i])
411 return True;
412 return False; 406 return False;
413 } 407 }
414 408
415 void 409 void
416 restack(void) { 410 restack(void) {
462 else 456 else
463 drawstatus(); 457 drawstatus();
464 } 458 }
465 459
466 void 460 void
467 view(Arg *arg) { 461 toggleview() {
468 unsigned int i; 462 seltag = !seltag;
469
470 for(i = 0; i < ntags; i++)
471 seltag[i] = (arg->i == -1) ? True : False;
472 if(arg->i >= 0 && arg->i < ntags)
473 seltag[arg->i] = True;
474 arrange(); 463 arrange();
475 } 464 }
476 465
477 void 466 void
478 zoom(Arg *arg) { 467 zoom(Arg *arg) {
581 getnext(Client *c) { 570 getnext(Client *c) {
582 for(; c && !isvisible(c); c = c->next); 571 for(; c && !isvisible(c); c = c->next);
583 return c; 572 return c;
584 } 573 }
585 574
586 Client *
587 getprev(Client *c) {
588 for(; c && !isvisible(c); c = c->prev);
589 return c;
590 }
591
592 void 575 void
593 initrregs(void) { 576 initrregs(void) {
594 unsigned int i; 577 unsigned int i;
595 regex_t *reg; 578 regex_t *reg;
596 579
604 if(regcomp(reg, rule[i].clpattern, REG_EXTENDED)) 587 if(regcomp(reg, rule[i].clpattern, REG_EXTENDED))
605 free(reg); 588 free(reg);
606 else 589 else
607 rreg[i].clregex = reg; 590 rreg[i].clregex = reg;
608 } 591 }
609 if(rule[i].tpattern) {
610 reg = emallocz(sizeof(regex_t));
611 if(regcomp(reg, rule[i].tpattern, REG_EXTENDED))
612 free(reg);
613 else
614 rreg[i].tregex = reg;
615 }
616 } 592 }
617 } 593 }
618 594
619 void 595 void
620 settags(Client *c, Client *trans) { 596 settags(Client *c, Client *trans) {
623 regmatch_t tmp; 599 regmatch_t tmp;
624 Bool matched = trans != NULL; 600 Bool matched = trans != NULL;
625 XClassHint ch = { 0 }; 601 XClassHint ch = { 0 };
626 602
627 if(matched) { 603 if(matched) {
628 for(i = 0; i < ntags; i++) 604 c->tag = trans->tag;
629 c->tags[i] = trans->tags[i]; 605 } else {
630 }
631 else {
632 XGetClassHint(dpy, c->win, &ch); 606 XGetClassHint(dpy, c->win, &ch);
633 snprintf(prop, sizeof prop, "%s:%s:%s", 607 snprintf(prop, sizeof prop, "%s:%s:%s",
634 ch.res_class ? ch.res_class : "", 608 ch.res_class ? ch.res_class : "",
635 ch.res_name ? ch.res_name : "", c->name); 609 ch.res_name ? ch.res_name : "", c->name);
636 for(i = 0; i < len; i++) 610 for(i = 0; i < len; i++)
637 if(rreg[i].clregex && !regexec(rreg[i].clregex, prop, 1, &tmp, 0)) { 611 if(rreg[i].clregex && !regexec(rreg[i].clregex, prop, 1, &tmp, 0)) {
638 c->isfloat = rule[i].isfloat; 612 c->isfloat = rule[i].isfloat;
639 for(j = 0; rreg[i].tregex && j < ntags; j++) { 613 if (rule[i].tag < 0) {
640 if(!regexec(rreg[i].tregex, tags[j], 1, &tmp, 0)) { 614 c->tag = seltag;
641 matched = True; 615 } else if (rule[i].tag == 0) {
642 c->tags[j] = True; 616 c->tag = True;
643 } 617 } else {
618 c->tag = False;
644 } 619 }
620 matched = True;
645 break; /* perform only the first rule matching */ 621 break; /* perform only the first rule matching */
646 } 622 }
647 if(ch.res_class) 623 if(ch.res_class)
648 XFree(ch.res_class); 624 XFree(ch.res_class);
649 if(ch.res_name) 625 if(ch.res_name)
650 XFree(ch.res_name); 626 XFree(ch.res_name);
651 } 627 }
652 if(!matched) 628 if(!matched) {
653 for(i = 0; i < ntags; i++) 629 c->tag = seltag;
654 c->tags[i] = seltag[i]; 630 }
655 } 631 }
656 632
657 void 633 void
658 tag(Arg *arg) { 634 toggletag(Arg *arg) {
659 unsigned int i;
660
661 if(!sel) 635 if(!sel)
662 return; 636 return;
663 for(i = 0; i < ntags; i++) 637 sel->tag = !sel->tag;
664 sel->tags[i] = (arg->i == -1) ? True : False; 638 toggleview();
665 if(arg->i >= 0 && arg->i < ntags) 639 }
666 sel->tags[arg->i] = True; 640
667 arrange();
668 }
669
670 void
671 toggletag(Arg *arg) {
672 unsigned int i;
673
674 if(!sel)
675 return;
676 sel->tags[arg->i] = !sel->tags[arg->i];
677 for(i = 0; i < ntags && !sel->tags[i]; i++);
678 if(i == ntags)
679 sel->tags[arg->i] = True;
680 arrange();
681 }
682
683 /* begin code by jukka */
684 void
685 viewnext(Arg *arg) {
686 unsigned int i;
687 Bool last = seltag[ntags-1];
688
689 for (i=ntags-1; i>0; --i)
690 seltag[i] = seltag[i-1];
691 seltag[0] = last;
692 arrange();
693 }
694 /* end code by jukka */
695 641
696 642
697 643
698 644
699 645
807 x = 0; 753 x = 0;
808 for(a.i = 0; a.i < ntags; a.i++) { 754 for(a.i = 0; a.i < ntags; a.i++) {
809 x += textw(tags[a.i]); 755 x += textw(tags[a.i]);
810 if(ev->x < x) { 756 if(ev->x < x) {
811 if(ev->button == Button1) { 757 if(ev->button == Button1) {
812 view(&a); 758 toggleview();
813 } 759 }
814 return; 760 return;
815 } 761 }
816 } 762 }
817 if(ev->x < x + bmw) 763 if(ev->x < x + bmw)
1139 int i, x; 1085 int i, x;
1140 1086
1141 dc.x = dc.y = 0; 1087 dc.x = dc.y = 0;
1142 for(i = 0; i < ntags; i++) { 1088 for(i = 0; i < ntags; i++) {
1143 dc.w = textw(tags[i]); 1089 dc.w = textw(tags[i]);
1144 drawtext(tags[i], (seltag[i] ? dc.sel : dc.norm)); 1090 drawtext(tags[i], ( (i == 0 && seltag || i == 1 && !seltag) ? dc.sel : dc.norm));
1145 dc.x += dc.w + 1; 1091 dc.x += dc.w + 1;
1146 } 1092 }
1147 dc.w = bmw; 1093 dc.w = bmw;
1148 drawtext("", dc.norm); 1094 drawtext("", dc.norm);
1149 x = dc.x + dc.w; 1095 x = dc.x + dc.w;
1372 manage(Window w, XWindowAttributes *wa) { 1318 manage(Window w, XWindowAttributes *wa) {
1373 Client *c; 1319 Client *c;
1374 Window trans; 1320 Window trans;
1375 1321
1376 c = emallocz(sizeof(Client)); 1322 c = emallocz(sizeof(Client));
1377 c->tags = emallocz(ntags * sizeof(Bool)); 1323 c->tag = True;
1378 c->win = w; 1324 c->win = w;
1379 c->x = wa->x; 1325 c->x = wa->x;
1380 c->y = wa->y; 1326 c->y = wa->y;
1381 c->w = wa->width; 1327 c->w = wa->width;
1382 c->h = wa->height; 1328 c->h = wa->height;
1565 for(nc = stack; nc && !isvisible(nc); nc = nc->snext); 1511 for(nc = stack; nc && !isvisible(nc); nc = nc->snext);
1566 focus(nc); 1512 focus(nc);
1567 } 1513 }
1568 XUngrabButton(dpy, AnyButton, AnyModifier, c->win); 1514 XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
1569 setclientstate(c, WithdrawnState); 1515 setclientstate(c, WithdrawnState);
1570 free(c->tags);
1571 free(c); 1516 free(c);
1572 XSync(dpy, False); 1517 XSync(dpy, False);
1573 XSetErrorHandler(xerror); 1518 XSetErrorHandler(xerror);
1574 XUngrabServer(dpy); 1519 XUngrabServer(dpy);
1575 arrange(); 1520 arrange();
1614 XFreeCursor(dpy, cursor[CurNormal]); 1559 XFreeCursor(dpy, cursor[CurNormal]);
1615 XFreeCursor(dpy, cursor[CurResize]); 1560 XFreeCursor(dpy, cursor[CurResize]);
1616 XFreeCursor(dpy, cursor[CurMove]); 1561 XFreeCursor(dpy, cursor[CurMove]);
1617 XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); 1562 XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
1618 XSync(dpy, False); 1563 XSync(dpy, False);
1619 free(seltag);
1620 } 1564 }
1621 1565
1622 static void 1566 static void
1623 scan(void) { 1567 scan(void) {
1624 unsigned int i, num; 1568 unsigned int i, num;
1675 | EnterWindowMask | LeaveWindowMask; 1619 | EnterWindowMask | LeaveWindowMask;
1676 wa.cursor = cursor[CurNormal]; 1620 wa.cursor = cursor[CurNormal];
1677 XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); 1621 XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
1678 grabkeys(); 1622 grabkeys();
1679 initrregs(); 1623 initrregs();
1680 for(ntags = 0; tags[ntags]; ntags++); 1624 ntags = 2;
1681 seltag = emallocz(sizeof(Bool) * ntags); 1625 seltag = True;
1682 seltag[0] = True;
1683 /* style */ 1626 /* style */
1684 dc.norm[ColBorder] = getcolor(NORMBORDERCOLOR); 1627 dc.norm[ColBorder] = getcolor(NORMBORDERCOLOR);
1685 dc.norm[ColBG] = getcolor(NORMBGCOLOR); 1628 dc.norm[ColBG] = getcolor(NORMBGCOLOR);
1686 dc.norm[ColFG] = getcolor(NORMFGCOLOR); 1629 dc.norm[ColFG] = getcolor(NORMFGCOLOR);
1687 dc.sel[ColBorder] = getcolor(SELBORDERCOLOR); 1630 dc.sel[ColBorder] = getcolor(SELBORDERCOLOR);
1776 fd_set rd; 1719 fd_set rd;
1777 1720
1778 if(argc == 2 && !strncmp("-v", argv[1], 3)) { 1721 if(argc == 2 && !strncmp("-v", argv[1], 3)) {
1779 fputs("dwm-"VERSION", (C)opyright MMVI-MMVII Anselm R. Garbe\n", stdout); 1722 fputs("dwm-"VERSION", (C)opyright MMVI-MMVII Anselm R. Garbe\n", stdout);
1780 exit(EXIT_SUCCESS); 1723 exit(EXIT_SUCCESS);
1781 } 1724 } else if(argc != 1) {
1782 else if(argc != 1)
1783 eprint("usage: dwm [-v]\n"); 1725 eprint("usage: dwm [-v]\n");
1726 }
1784 setlocale(LC_CTYPE, ""); 1727 setlocale(LC_CTYPE, "");
1785 dpy = XOpenDisplay(0); 1728 dpy = XOpenDisplay(0);
1786 if(!dpy) 1729 if(!dpy) {
1787 eprint("dwm: cannot open display\n"); 1730 eprint("dwm: cannot open display\n");
1731 }
1788 xfd = ConnectionNumber(dpy); 1732 xfd = ConnectionNumber(dpy);
1789 screen = DefaultScreen(dpy); 1733 screen = DefaultScreen(dpy);
1790 root = RootWindow(dpy, screen); 1734 root = RootWindow(dpy, screen);
1791 otherwm = False; 1735 otherwm = False;
1792 XSetErrorHandler(xerrorstart); 1736 XSetErrorHandler(xerrorstart);
1793 /* this causes an error if some other window manager is running */ 1737 /* this causes an error if some other window manager is running */
1794 XSelectInput(dpy, root, SubstructureRedirectMask); 1738 XSelectInput(dpy, root, SubstructureRedirectMask);
1795 XSync(dpy, False); 1739 XSync(dpy, False);
1796 if(otherwm) 1740 if(otherwm) {
1797 eprint("dwm: another window manager is already running\n"); 1741 eprint("dwm: another window manager is already running\n");
1742 }
1798 1743
1799 XSync(dpy, False); 1744 XSync(dpy, False);
1800 XSetErrorHandler(NULL); 1745 XSetErrorHandler(NULL);
1801 xerrorxlib = XSetErrorHandler(xerror); 1746 xerrorxlib = XSetErrorHandler(xerror);
1802 XSync(dpy, False); 1747 XSync(dpy, False);