tag.c
changeset 967 66f17bf2c278
parent 966 3ad7903c9e83
child 968 ce9a5452ac8c
equal deleted inserted replaced
966:3ad7903c9e83 967:66f17bf2c278
     1 /* See LICENSE file for copyright and license details. */
       
     2 #include "dwm.h"
       
     3 #include <regex.h>
       
     4 #include <stdio.h>
       
     5 #include <stdlib.h>
       
     6 #include <X11/Xutil.h>
       
     7 
       
     8 /* static */
       
     9 
       
    10 typedef struct {
       
    11 	const char *prop;
       
    12 	const char *tags;
       
    13 	Bool isfloating;
       
    14 } Rule;
       
    15 
       
    16 typedef struct {
       
    17 	regex_t *propregex;
       
    18 	regex_t *tagregex;
       
    19 } Regs;
       
    20 
       
    21 TAGS
       
    22 RULES
       
    23 
       
    24 static Regs *regs = NULL;
       
    25 static unsigned int nrules = 0;
       
    26 static char prop[512];
       
    27 
       
    28 static unsigned int
       
    29 idxoftag(const char *tag) {
       
    30 	unsigned int i;
       
    31 
       
    32 	for(i = 0; i < ntags; i++)
       
    33 		if(tags[i] == tag)
       
    34 			return i;
       
    35 	return 0;
       
    36 }
       
    37 
       
    38 /* extern */
       
    39 
       
    40 void
       
    41 applyrules(Client *c) {
       
    42 	unsigned int i, j;
       
    43 	regmatch_t tmp;
       
    44 	Bool matched = False;
       
    45 	XClassHint ch = { 0 };
       
    46 
       
    47 	/* rule matching */
       
    48 	XGetClassHint(dpy, c->win, &ch);
       
    49 	snprintf(prop, sizeof prop, "%s:%s:%s",
       
    50 			ch.res_class ? ch.res_class : "",
       
    51 			ch.res_name ? ch.res_name : "", c->name);
       
    52 	for(i = 0; i < nrules; i++)
       
    53 		if(regs[i].propregex && !regexec(regs[i].propregex, prop, 1, &tmp, 0)) {
       
    54 			c->isfloating = rules[i].isfloating;
       
    55 			for(j = 0; regs[i].tagregex && j < ntags; j++) {
       
    56 				if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) {
       
    57 					matched = True;
       
    58 					c->tags[j] = True;
       
    59 				}
       
    60 			}
       
    61 		}
       
    62 	if(ch.res_class)
       
    63 		XFree(ch.res_class);
       
    64 	if(ch.res_name)
       
    65 		XFree(ch.res_name);
       
    66 	if(!matched)
       
    67 		for(i = 0; i < ntags; i++)
       
    68 			c->tags[i] = seltags[i];
       
    69 }
       
    70 
       
    71 void
       
    72 compileregs(void) {
       
    73 	unsigned int i;
       
    74 	regex_t *reg;
       
    75 
       
    76 	if(regs)
       
    77 		return;
       
    78 	nrules = sizeof rules / sizeof rules[0];
       
    79 	regs = emallocz(nrules * sizeof(Regs));
       
    80 	for(i = 0; i < nrules; i++) {
       
    81 		if(rules[i].prop) {
       
    82 			reg = emallocz(sizeof(regex_t));
       
    83 			if(regcomp(reg, rules[i].prop, REG_EXTENDED))
       
    84 				free(reg);
       
    85 			else
       
    86 				regs[i].propregex = reg;
       
    87 		}
       
    88 		if(rules[i].tags) {
       
    89 			reg = emallocz(sizeof(regex_t));
       
    90 			if(regcomp(reg, rules[i].tags, REG_EXTENDED))
       
    91 				free(reg);
       
    92 			else
       
    93 				regs[i].tagregex = reg;
       
    94 		}
       
    95 	}
       
    96 }
       
    97 
       
    98 Bool
       
    99 isvisible(Client *c) {
       
   100 	unsigned int i;
       
   101 
       
   102 	for(i = 0; i < ntags; i++)
       
   103 		if(c->tags[i] && seltags[i])
       
   104 			return True;
       
   105 	return False;
       
   106 }
       
   107 
       
   108 void
       
   109 tag(const char *arg) {
       
   110 	unsigned int i;
       
   111 
       
   112 	if(!sel)
       
   113 		return;
       
   114 	for(i = 0; i < ntags; i++)
       
   115 		sel->tags[i] = arg == NULL;
       
   116 	i = idxoftag(arg);
       
   117 	if(i >= 0 && i < ntags)
       
   118 		sel->tags[i] = True;
       
   119 	saveprops(sel);
       
   120 	arrange();
       
   121 }
       
   122 
       
   123 void
       
   124 togglefloating(const char *arg) {
       
   125 	if(!sel || isfloating())
       
   126 		return;
       
   127 	sel->isfloating = !sel->isfloating;
       
   128 	if(sel->isfloating) {
       
   129 		resize(sel, sel->x, sel->y, sel->w, sel->h, True);
       
   130 		saveprops(sel);
       
   131 	}
       
   132 	arrange();
       
   133 }
       
   134 
       
   135 void
       
   136 toggletag(const char *arg) {
       
   137 	unsigned int i, j;
       
   138 
       
   139 	if(!sel)
       
   140 		return;
       
   141 	i = idxoftag(arg);
       
   142 	sel->tags[i] = !sel->tags[i];
       
   143 	for(j = 0; j < ntags && !sel->tags[j]; j++);
       
   144 	if(j == ntags)
       
   145 		sel->tags[i] = True;
       
   146 	saveprops(sel);
       
   147 	arrange();
       
   148 }
       
   149 
       
   150 void
       
   151 toggleview(const char *arg) {
       
   152 	unsigned int i, j;
       
   153 
       
   154 	i = idxoftag(arg);
       
   155 	seltags[i] = !seltags[i];
       
   156 	for(j = 0; j < ntags && !seltags[j]; j++);
       
   157 	if(j == ntags)
       
   158 		seltags[i] = True; /* cannot toggle last view */
       
   159 	savedwmprops();
       
   160 	arrange();
       
   161 }
       
   162 
       
   163 void
       
   164 view(const char *arg) {
       
   165 	unsigned int i;
       
   166 
       
   167 	for(i = 0; i < ntags; i++)
       
   168 		seltags[i] = arg == NULL;
       
   169 	i = idxoftag(arg);
       
   170 	if(i >= 0 && i < ntags)
       
   171 		seltags[i] = True;
       
   172 	savedwmprops();
       
   173 	arrange();
       
   174 }