143 long getstate(Window w); |
143 long getstate(Window w); |
144 Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); |
144 Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); |
145 void grabbuttons(Client *c, Bool focused); |
145 void grabbuttons(Client *c, Bool focused); |
146 unsigned int idxoftag(const char *tag); |
146 unsigned int idxoftag(const char *tag); |
147 void initfont(const char *fontstr); |
147 void initfont(const char *fontstr); |
148 Bool isarrange(void (*func)()); |
|
149 Bool isoccupied(unsigned int t); |
148 Bool isoccupied(unsigned int t); |
150 Bool isprotodel(Client *c); |
149 Bool isprotodel(Client *c); |
151 Bool isvisible(Client *c); |
150 Bool isvisible(Client *c); |
152 void keypress(XEvent *e); |
151 void keypress(XEvent *e); |
153 void killclient(const char *arg); |
152 void killclient(const char *arg); |
196 double mwfact; |
195 double mwfact; |
197 int screen, sx, sy, sw, sh, wax, way, waw, wah; |
196 int screen, sx, sy, sw, sh, wax, way, waw, wah; |
198 int (*xerrorxlib)(Display *, XErrorEvent *); |
197 int (*xerrorxlib)(Display *, XErrorEvent *); |
199 unsigned int bh, bpos; |
198 unsigned int bh, bpos; |
200 unsigned int blw = 0; |
199 unsigned int blw = 0; |
201 unsigned int ltidx = 0; /* default */ |
|
202 unsigned int nlayouts = 0; |
|
203 unsigned int nrules = 0; |
|
204 unsigned int numlockmask = 0; |
200 unsigned int numlockmask = 0; |
205 void (*handler[LASTEvent]) (XEvent *) = { |
201 void (*handler[LASTEvent]) (XEvent *) = { |
206 [ButtonPress] = buttonpress, |
202 [ButtonPress] = buttonpress, |
207 [ConfigureRequest] = configurerequest, |
203 [ConfigureRequest] = configurerequest, |
208 [ConfigureNotify] = configurenotify, |
204 [ConfigureNotify] = configurenotify, |
215 [MapRequest] = maprequest, |
211 [MapRequest] = maprequest, |
216 [PropertyNotify] = propertynotify, |
212 [PropertyNotify] = propertynotify, |
217 [UnmapNotify] = unmapnotify |
213 [UnmapNotify] = unmapnotify |
218 }; |
214 }; |
219 Atom wmatom[WMLast], netatom[NetLast]; |
215 Atom wmatom[WMLast], netatom[NetLast]; |
|
216 Bool domwfact = True; |
|
217 Bool dozoom = True; |
220 Bool otherwm, readin; |
218 Bool otherwm, readin; |
221 Bool running = True; |
219 Bool running = True; |
222 Bool selscreen = True; |
220 Bool selscreen = True; |
223 Client *clients = NULL; |
221 Client *clients = NULL; |
224 Client *sel = NULL; |
222 Client *sel = NULL; |
225 Client *stack = NULL; |
223 Client *stack = NULL; |
226 Cursor cursor[CurLast]; |
224 Cursor cursor[CurLast]; |
227 Display *dpy; |
225 Display *dpy; |
228 DC dc = {0}; |
226 DC dc = {0}; |
|
227 Layout *layout = NULL; |
229 Window barwin, root; |
228 Window barwin, root; |
230 Regs *regs = NULL; |
229 Regs *regs = NULL; |
231 |
230 |
232 /* configuration, allows nested code to access above variables */ |
231 /* configuration, allows nested code to access above variables */ |
233 #include "config.h" |
232 #include "config.h" |
244 /* rule matching */ |
243 /* rule matching */ |
245 XGetClassHint(dpy, c->win, &ch); |
244 XGetClassHint(dpy, c->win, &ch); |
246 snprintf(buf, sizeof buf, "%s:%s:%s", |
245 snprintf(buf, sizeof buf, "%s:%s:%s", |
247 ch.res_class ? ch.res_class : "", |
246 ch.res_class ? ch.res_class : "", |
248 ch.res_name ? ch.res_name : "", c->name); |
247 ch.res_name ? ch.res_name : "", c->name); |
249 for(i = 0; i < nrules; i++) |
248 for(i = 0; i < NRULES; i++) |
250 if(regs[i].propregex && !regexec(regs[i].propregex, buf, 1, &tmp, 0)) { |
249 if(regs[i].propregex && !regexec(regs[i].propregex, buf, 1, &tmp, 0)) { |
251 c->isfloating = rules[i].isfloating; |
250 c->isfloating = rules[i].isfloating; |
252 for(j = 0; regs[i].tagregex && j < NTAGS; j++) { |
251 for(j = 0; regs[i].tagregex && j < NTAGS; j++) { |
253 if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) { |
252 if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) { |
254 matched = True; |
253 matched = True; |
332 else if((c = getclient(ev->window))) { |
331 else if((c = getclient(ev->window))) { |
333 focus(c); |
332 focus(c); |
334 if(CLEANMASK(ev->state) != MODKEY) |
333 if(CLEANMASK(ev->state) != MODKEY) |
335 return; |
334 return; |
336 if(ev->button == Button1) { |
335 if(ev->button == Button1) { |
337 if(isarrange(floating) || c->isfloating) |
336 if((floating == layout->arrange) || c->isfloating) |
338 restack(); |
337 restack(); |
339 else |
338 else |
340 togglefloating(NULL); |
339 togglefloating(NULL); |
341 movemouse(c); |
340 movemouse(c); |
342 } |
341 } |
343 else if(ev->button == Button2) { |
342 else if(ev->button == Button2) { |
344 if((ISTILE) && !c->isfixed && c->isfloating) |
343 if((floating != layout->arrange) && !c->isfixed && c->isfloating) |
345 togglefloating(NULL); |
344 togglefloating(NULL); |
346 else |
345 else |
347 zoom(NULL); |
346 zoom(NULL); |
348 } |
347 } |
349 else if(ev->button == Button3 && !c->isfixed) { |
348 else if(ev->button == Button3 && !c->isfixed) { |
350 if(isarrange(floating) || c->isfloating) |
349 if((floating == layout->arrange) || c->isfloating) |
351 restack(); |
350 restack(); |
352 else |
351 else |
353 togglefloating(NULL); |
352 togglefloating(NULL); |
354 resizemouse(c); |
353 resizemouse(c); |
355 } |
354 } |
399 unsigned int i; |
398 unsigned int i; |
400 regex_t *reg; |
399 regex_t *reg; |
401 |
400 |
402 if(regs) |
401 if(regs) |
403 return; |
402 return; |
404 nrules = sizeof rules / sizeof rules[0]; |
403 regs = emallocz(NRULES * sizeof(Regs)); |
405 regs = emallocz(nrules * sizeof(Regs)); |
404 for(i = 0; i < NRULES; i++) { |
406 for(i = 0; i < nrules; i++) { |
|
407 if(rules[i].prop) { |
405 if(rules[i].prop) { |
408 reg = emallocz(sizeof(regex_t)); |
406 reg = emallocz(sizeof(regex_t)); |
409 if(regcomp(reg, rules[i].prop, REG_EXTENDED)) |
407 if(regcomp(reg, rules[i].prop, REG_EXTENDED)) |
410 free(reg); |
408 free(reg); |
411 else |
409 else |
462 |
460 |
463 if((c = getclient(ev->window))) { |
461 if((c = getclient(ev->window))) { |
464 c->ismax = False; |
462 c->ismax = False; |
465 if(ev->value_mask & CWBorderWidth) |
463 if(ev->value_mask & CWBorderWidth) |
466 c->border = ev->border_width; |
464 c->border = ev->border_width; |
467 if(c->isfixed || c->isfloating || isarrange(floating)) { |
465 if(c->isfixed || c->isfloating || (floating == layout->arrange)) { |
468 if(ev->value_mask & CWX) |
466 if(ev->value_mask & CWX) |
469 c->x = ev->x; |
467 c->x = ev->x; |
470 if(ev->value_mask & CWY) |
468 if(ev->value_mask & CWY) |
471 c->y = ev->y; |
469 c->y = ev->y; |
472 if(ev->value_mask & CWWidth) |
470 if(ev->value_mask & CWWidth) |
674 |
672 |
675 void |
673 void |
676 floating(void) { /* default floating layout */ |
674 floating(void) { /* default floating layout */ |
677 Client *c; |
675 Client *c; |
678 |
676 |
|
677 domwfact = dozoom = False; |
679 for(c = clients; c; c = c->next) |
678 for(c = clients; c; c = c->next) |
680 if(isvisible(c)) |
679 if(isvisible(c)) |
681 resize(c, c->x, c->y, c->w, c->h, True); |
680 resize(c, c->x, c->y, c->w, c->h, True); |
682 } |
681 } |
683 |
682 |
930 } |
923 } |
931 |
924 |
932 void |
925 void |
933 keypress(XEvent *e) { |
926 keypress(XEvent *e) { |
934 KEYS |
927 KEYS |
935 unsigned int len = sizeof keys / sizeof keys[0]; |
|
936 unsigned int i; |
928 unsigned int i; |
937 KeyCode code; |
929 KeyCode code; |
938 KeySym keysym; |
930 KeySym keysym; |
939 XKeyEvent *ev; |
931 XKeyEvent *ev; |
940 |
932 |
941 if(!e) { /* grabkeys */ |
933 if(!e) { /* grabkeys */ |
942 XUngrabKey(dpy, AnyKey, AnyModifier, root); |
934 XUngrabKey(dpy, AnyKey, AnyModifier, root); |
943 for(i = 0; i < len; i++) { |
935 for(i = 0; i < NKEYS; i++) { |
944 code = XKeysymToKeycode(dpy, keys[i].keysym); |
936 code = XKeysymToKeycode(dpy, keys[i].keysym); |
945 XGrabKey(dpy, code, keys[i].mod, root, True, |
937 XGrabKey(dpy, code, keys[i].mod, root, True, |
946 GrabModeAsync, GrabModeAsync); |
938 GrabModeAsync, GrabModeAsync); |
947 XGrabKey(dpy, code, keys[i].mod | LockMask, root, True, |
939 XGrabKey(dpy, code, keys[i].mod | LockMask, root, True, |
948 GrabModeAsync, GrabModeAsync); |
940 GrabModeAsync, GrabModeAsync); |
953 } |
945 } |
954 return; |
946 return; |
955 } |
947 } |
956 ev = &e->xkey; |
948 ev = &e->xkey; |
957 keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); |
949 keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); |
958 for(i = 0; i < len; i++) |
950 for(i = 0; i < NKEYS; i++) |
959 if(keysym == keys[i].keysym |
951 if(keysym == keys[i].keysym |
960 && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)) |
952 && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)) |
961 { |
953 { |
962 if(keys[i].func) |
954 if(keys[i].func) |
963 keys[i].func(keys[i].arg); |
955 keys[i].func(keys[i].arg); |
1264 XWindowChanges wc; |
1256 XWindowChanges wc; |
1265 |
1257 |
1266 drawbar(); |
1258 drawbar(); |
1267 if(!sel) |
1259 if(!sel) |
1268 return; |
1260 return; |
1269 if(sel->isfloating || isarrange(floating)) |
1261 if(sel->isfloating || (floating == layout->arrange)) |
1270 XRaiseWindow(dpy, sel->win); |
1262 XRaiseWindow(dpy, sel->win); |
1271 if(!isarrange(floating)) { |
1263 if(floating != layout->arrange) { |
1272 wc.stack_mode = Below; |
1264 wc.stack_mode = Below; |
1273 wc.sibling = barwin; |
1265 wc.sibling = barwin; |
1274 if(!sel->isfloating) { |
1266 if(!sel->isfloating) { |
1275 XConfigureWindow(dpy, sel->win, CWSibling | CWStackMode, &wc); |
1267 XConfigureWindow(dpy, sel->win, CWSibling | CWStackMode, &wc); |
1276 wc.sibling = sel->win; |
1268 wc.sibling = sel->win; |
1560 void |
1552 void |
1561 tile(void) { |
1553 tile(void) { |
1562 unsigned int i, n, nx, ny, nw, nh, mw, th; |
1554 unsigned int i, n, nx, ny, nw, nh, mw, th; |
1563 Client *c, *mc; |
1555 Client *c, *mc; |
1564 |
1556 |
|
1557 domwfact = dozoom = True; |
1565 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) |
1558 for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) |
1566 n++; |
1559 n++; |
1567 |
1560 |
1568 /* window geoms */ |
1561 /* window geoms */ |
1569 mw = (n == 1) ? waw : mwfact * waw; |
1562 mw = (n == 1) ? waw : mwfact * waw; |
1625 XEvent ev; |
1618 XEvent ev; |
1626 |
1619 |
1627 if(!sel || sel->isfixed) |
1620 if(!sel || sel->isfixed) |
1628 return; |
1621 return; |
1629 if((sel->ismax = !sel->ismax)) { |
1622 if((sel->ismax = !sel->ismax)) { |
1630 if(isarrange(floating) || sel->isfloating) |
1623 if((floating == layout->arrange) || sel->isfloating) |
1631 sel->wasfloating = True; |
1624 sel->wasfloating = True; |
1632 else { |
1625 else { |
1633 togglefloating(NULL); |
1626 togglefloating(NULL); |
1634 sel->wasfloating = False; |
1627 sel->wasfloating = False; |
1635 } |
1628 } |