screen.c
changeset 782 92862ab407d5
parent 780 6dc7578a5107
child 784 74722317b171
equal deleted inserted replaced
781:dde5852bf151 782:92862ab407d5
     7 #include <stdlib.h>
     7 #include <stdlib.h>
     8 #include <string.h>
     8 #include <string.h>
     9 #include <sys/types.h>
     9 #include <sys/types.h>
    10 #include <X11/Xutil.h>
    10 #include <X11/Xutil.h>
    11 
    11 
    12 void (*arrange)(void) = DEFMODE;
       
    13 unsigned int master = MASTER;
    12 unsigned int master = MASTER;
    14 unsigned int nmaster = NMASTER;
    13 unsigned int nmaster = NMASTER;
       
    14 unsigned int blw = 0;
       
    15 Layout *lt = NULL;
    15 
    16 
    16 /* static */
    17 /* static */
    17 
    18 
    18 typedef struct {
    19 typedef struct {
    19 	const char *prop;
    20 	const char *prop;
    22 } Rule;
    23 } Rule;
    23 
    24 
    24 typedef struct {
    25 typedef struct {
    25 	regex_t *propregex;
    26 	regex_t *propregex;
    26 	regex_t *tagregex;
    27 	regex_t *tagregex;
    27 } Regexps;
    28 } Regs;
    28 
    29 
       
    30 LAYOUTS
    29 TAGS
    31 TAGS
    30 RULES
    32 RULES
    31 
    33 
    32 static Regexps *regexps = NULL;
    34 static Regs *regs = NULL;
    33 static unsigned int len = 0;
    35 static unsigned int nrules = 0;
       
    36 static unsigned int nlayouts = 0;
    34 
    37 
    35 /* extern */
    38 /* extern */
    36 
    39 
    37 void
    40 void
    38 compileregexps(void) {
    41 compileregs(void) {
    39 	unsigned int i;
    42 	unsigned int i;
    40 	regex_t *reg;
    43 	regex_t *reg;
    41 
    44 
    42 	if(regexps)
    45 	if(regs)
    43 		return;
    46 		return;
    44 	len = sizeof rule / sizeof rule[0];
    47 	nrules = sizeof rule / sizeof rule[0];
    45 	regexps = emallocz(len * sizeof(Regexps));
    48 	regs = emallocz(nrules * sizeof(Regs));
    46 	for(i = 0; i < len; i++) {
    49 	for(i = 0; i < nrules; i++) {
    47 		if(rule[i].prop) {
    50 		if(rule[i].prop) {
    48 			reg = emallocz(sizeof(regex_t));
    51 			reg = emallocz(sizeof(regex_t));
    49 			if(regcomp(reg, rule[i].prop, REG_EXTENDED))
    52 			if(regcomp(reg, rule[i].prop, REG_EXTENDED))
    50 				free(reg);
    53 				free(reg);
    51 			else
    54 			else
    52 				regexps[i].propregex = reg;
    55 				regs[i].propregex = reg;
    53 		}
    56 		}
    54 		if(rule[i].tags) {
    57 		if(rule[i].tags) {
    55 			reg = emallocz(sizeof(regex_t));
    58 			reg = emallocz(sizeof(regex_t));
    56 			if(regcomp(reg, rule[i].tags, REG_EXTENDED))
    59 			if(regcomp(reg, rule[i].tags, REG_EXTENDED))
    57 				free(reg);
    60 				free(reg);
    58 			else
    61 			else
    59 				regexps[i].tagregex = reg;
    62 				regs[i].tagregex = reg;
    60 		}
    63 		}
    61 	}
    64 	}
    62 }
    65 }
    63 
    66 
    64 void
    67 void
   136 	restack();
   139 	restack();
   137 }
   140 }
   138 
   141 
   139 void
   142 void
   140 incnmaster(Arg *arg) {
   143 incnmaster(Arg *arg) {
   141 	if((arrange == dofloat) || (nmaster + arg->i < 1)
   144 	if((lt->arrange == dofloat) || (nmaster + arg->i < 1)
   142 	|| (wah / (nmaster + arg->i) <= 2 * BORDERPX))
   145 	|| (wah / (nmaster + arg->i) <= 2 * BORDERPX))
   143 		return;
   146 		return;
   144 	nmaster += arg->i;
   147 	nmaster += arg->i;
   145 	if(sel)
   148 	if(sel)
   146 		arrange();
   149 		lt->arrange();
   147 	else
   150 	else
   148 		drawstatus();
   151 		drawstatus();
       
   152 }
       
   153 
       
   154 void
       
   155 initlayouts(void) {
       
   156 	unsigned int i, w;
       
   157 
       
   158 	lt = &layout[0];
       
   159 	nlayouts = sizeof layout / sizeof layout[0];
       
   160 	for(blw = i = 0; i < nlayouts; i++) {
       
   161 		w = textw(layout[i].symbol);
       
   162 		if(w > blw)
       
   163 			blw = w;
       
   164 	}
   149 }
   165 }
   150 
   166 
   151 Bool
   167 Bool
   152 isvisible(Client *c) {
   168 isvisible(Client *c) {
   153 	unsigned int i;
   169 	unsigned int i;
   158 	return False;
   174 	return False;
   159 }
   175 }
   160 
   176 
   161 void
   177 void
   162 resizemaster(Arg *arg) {
   178 resizemaster(Arg *arg) {
   163 	if(arrange != dotile)
   179 	if(lt->arrange != dotile)
   164 		return;
   180 		return;
   165 	if(arg->i == 0)
   181 	if(arg->i == 0)
   166 		master = MASTER;
   182 		master = MASTER;
   167 	else {
   183 	else {
   168 		if(waw * (master + arg->i) / 1000 >= waw - 2 * BORDERPX
   184 		if(waw * (master + arg->i) / 1000 >= waw - 2 * BORDERPX
   169 		|| waw * (master + arg->i) / 1000 <= 2 * BORDERPX)
   185 		|| waw * (master + arg->i) / 1000 <= 2 * BORDERPX)
   170 			return;
   186 			return;
   171 		master += arg->i;
   187 		master += arg->i;
   172 	}
   188 	}
   173 	arrange();
   189 	lt->arrange();
   174 }
   190 }
   175 
   191 
   176 void
   192 void
   177 restack(void) {
   193 restack(void) {
   178 	Client *c;
   194 	Client *c;
   179 	XEvent ev;
   195 	XEvent ev;
   180 
   196 
   181 	drawstatus();
   197 	drawstatus();
   182 	if(!sel)
   198 	if(!sel)
   183 		return;
   199 		return;
   184 	if(sel->isfloat || arrange == dofloat)
   200 	if(sel->isfloat || lt->arrange == dofloat)
   185 		XRaiseWindow(dpy, sel->win);
   201 		XRaiseWindow(dpy, sel->win);
   186 	if(arrange != dofloat) {
   202 	if(lt->arrange != dofloat) {
   187 		if(!sel->isfloat)
   203 		if(!sel->isfloat)
   188 			XLowerWindow(dpy, sel->win);
   204 			XLowerWindow(dpy, sel->win);
   189 		for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
   205 		for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
   190 			if(c == sel)
   206 			if(c == sel)
   191 				continue;
   207 				continue;
   210 	else {
   226 	else {
   211 		XGetClassHint(dpy, c->win, &ch);
   227 		XGetClassHint(dpy, c->win, &ch);
   212 		snprintf(prop, sizeof prop, "%s:%s:%s",
   228 		snprintf(prop, sizeof prop, "%s:%s:%s",
   213 				ch.res_class ? ch.res_class : "",
   229 				ch.res_class ? ch.res_class : "",
   214 				ch.res_name ? ch.res_name : "", c->name);
   230 				ch.res_name ? ch.res_name : "", c->name);
   215 		for(i = 0; i < len; i++)
   231 		for(i = 0; i < nrules; i++)
   216 			if(regexps[i].propregex && !regexec(regexps[i].propregex, prop, 1, &tmp, 0)) {
   232 			if(regs[i].propregex && !regexec(regs[i].propregex, prop, 1, &tmp, 0)) {
   217 				c->isfloat = rule[i].isfloat;
   233 				c->isfloat = rule[i].isfloat;
   218 				for(j = 0; regexps[i].tagregex && j < ntags; j++) {
   234 				for(j = 0; regs[i].tagregex && j < ntags; j++) {
   219 					if(!regexec(regexps[i].tagregex, tags[j], 1, &tmp, 0)) {
   235 					if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) {
   220 						matched = True;
   236 						matched = True;
   221 						c->tags[j] = True;
   237 						c->tags[j] = True;
   222 					}
   238 					}
   223 				}
   239 				}
   224 			}
   240 			}
   240 		return;
   256 		return;
   241 	for(i = 0; i < ntags; i++)
   257 	for(i = 0; i < ntags; i++)
   242 		sel->tags[i] = (arg->i == -1) ? True : False;
   258 		sel->tags[i] = (arg->i == -1) ? True : False;
   243 	if(arg->i >= 0 && arg->i < ntags)
   259 	if(arg->i >= 0 && arg->i < ntags)
   244 		sel->tags[arg->i] = True;
   260 		sel->tags[arg->i] = True;
   245 	arrange();
   261 	lt->arrange();
   246 }
   262 }
   247 
   263 
   248 void
   264 void
   249 togglefloat(Arg *arg) {
   265 togglefloat(Arg *arg) {
   250 	if(!sel || arrange == dofloat)
   266 	if(!sel || lt->arrange == dofloat)
   251 		return;
   267 		return;
   252 	sel->isfloat = !sel->isfloat;
   268 	sel->isfloat = !sel->isfloat;
   253 	arrange();
   269 	lt->arrange();
   254 }
   270 }
   255 
   271 
   256 void
   272 void
   257 toggletag(Arg *arg) {
   273 toggletag(Arg *arg) {
   258 	unsigned int i;
   274 	unsigned int i;
   261 		return;
   277 		return;
   262 	sel->tags[arg->i] = !sel->tags[arg->i];
   278 	sel->tags[arg->i] = !sel->tags[arg->i];
   263 	for(i = 0; i < ntags && !sel->tags[i]; i++);
   279 	for(i = 0; i < ntags && !sel->tags[i]; i++);
   264 	if(i == ntags)
   280 	if(i == ntags)
   265 		sel->tags[arg->i] = True;
   281 		sel->tags[arg->i] = True;
   266 	arrange();
   282 	lt->arrange();
   267 }
   283 }
   268 
   284 
   269 void
   285 void
   270 togglemode(Arg *arg) {
   286 togglelayout(Arg *arg) {
   271 	arrange = (arrange == dofloat) ? dotile : dofloat;
   287 	unsigned int i;
       
   288 
       
   289 	for(i = 0; i < nlayouts && lt != &layout[i]; i++);
       
   290 	if(i == nlayouts - 1)
       
   291 		lt = &layout[0];
       
   292 	else
       
   293 		lt = &layout[++i];
   272 	if(sel)
   294 	if(sel)
   273 		arrange();
   295 		lt->arrange();
   274 	else
   296 	else
   275 		drawstatus();
   297 		drawstatus();
   276 }
   298 }
   277 
   299 
   278 void
   300 void
   281 
   303 
   282 	seltag[arg->i] = !seltag[arg->i];
   304 	seltag[arg->i] = !seltag[arg->i];
   283 	for(i = 0; i < ntags && !seltag[i]; i++);
   305 	for(i = 0; i < ntags && !seltag[i]; i++);
   284 	if(i == ntags)
   306 	if(i == ntags)
   285 		seltag[arg->i] = True; /* cannot toggle last view */
   307 		seltag[arg->i] = True; /* cannot toggle last view */
   286 	arrange();
   308 	lt->arrange();
   287 }
   309 }
   288 
   310 
   289 void
   311 void
   290 view(Arg *arg) {
   312 view(Arg *arg) {
   291 	unsigned int i;
   313 	unsigned int i;
   292 
   314 
   293 	for(i = 0; i < ntags; i++)
   315 	for(i = 0; i < ntags; i++)
   294 		seltag[i] = (arg->i == -1) ? True : False;
   316 		seltag[i] = (arg->i == -1) ? True : False;
   295 	if(arg->i >= 0 && arg->i < ntags)
   317 	if(arg->i >= 0 && arg->i < ntags)
   296 		seltag[arg->i] = True;
   318 		seltag[arg->i] = True;
   297 	arrange();
   319 	lt->arrange();
   298 }
   320 }