X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=dwm.c;h=3699f9955334b9147af73d6eda52419227cbe9ab;hb=5f19423c7bd2aa1ebb3010af15bebffbc3a9cbc3;hp=f5f7c99ee6ab2903bc6088caa505f5a7b504607f;hpb=35efafe8ac901b7764b7950d3a7c8565e53c5381;p=dwm.git diff --git a/dwm.c b/dwm.c index f5f7c99..3699f99 100644 --- a/dwm.c +++ b/dwm.c @@ -44,8 +44,11 @@ /* macros */ #define BUTTONMASK (ButtonPressMask | ButtonReleaseMask) #define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) +#define LENGTH(x) (sizeof x / sizeof x[0]) +#define MAXTAGLEN 16 #define MOUSEMASK (BUTTONMASK | PointerMotionMask) + /* enums */ enum { BarTop, BarBot, BarOff }; /* bar position */ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ @@ -58,12 +61,11 @@ typedef struct Client Client; struct Client { char name[256]; int x, y, w, h; - int rx, ry, rw, rh; /* revert geometry */ int basew, baseh, incw, inch, maxw, maxh, minw, minh; int minax, maxax, minay, maxay; long flags; unsigned int border, oldborder; - Bool isbanned, isfixed, ismax, isfloating, wasfloating; + Bool isbanned, isfixed, isfloating; Bool *tags; Client *next; Client *prev; @@ -134,6 +136,7 @@ void eprint(const char *errstr, ...); void expose(XEvent *e); void floating(void); /* default floating layout */ void focus(Client *c); +void focusin(XEvent *e); void focusnext(const char *arg); void focusprev(const char *arg); Client *getclient(Window w); @@ -141,6 +144,7 @@ unsigned long getcolor(const char *colstr); long getstate(Window w); Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); void grabbuttons(Client *c, Bool focused); +void grabkeys(void); unsigned int idxoftag(const char *tag); void initfont(const char *fontstr); Bool isoccupied(unsigned int t); @@ -152,10 +156,12 @@ void leavenotify(XEvent *e); void manage(Window w, XWindowAttributes *wa); void mappingnotify(XEvent *e); void maprequest(XEvent *e); +void maximize(const char *arg); void movemouse(Client *c); Client *nexttiled(Client *c); void propertynotify(XEvent *e); void quit(const char *arg); +void reapply(const char *arg); void resize(Client *c, int x, int y, int w, int h, Bool sizehints); void resizemouse(Client *c); void restack(void); @@ -172,7 +178,6 @@ unsigned int textw(const char *text); void tile(void); void togglebar(const char *arg); void togglefloating(const char *arg); -void togglemax(const char *arg); void toggletag(const char *arg); void toggleview(const char *arg); void unban(Client *c); @@ -202,9 +207,10 @@ void (*handler[LASTEvent]) (XEvent *) = { [ConfigureNotify] = configurenotify, [DestroyNotify] = destroynotify, [EnterNotify] = enternotify, - [LeaveNotify] = leavenotify, [Expose] = expose, + [FocusIn] = focusin, [KeyPress] = keypress, + [LeaveNotify] = leavenotify, [MappingNotify] = mappingnotify, [MapRequest] = maprequest, [PropertyNotify] = propertynotify, @@ -229,6 +235,8 @@ Regs *regs = NULL; /* configuration, allows nested code to access above variables */ #include "config.h" +Bool prevtags[LENGTH(tags)]; + /* function implementations */ void applyrules(Client *c) { @@ -457,7 +465,6 @@ configurerequest(XEvent *e) { XWindowChanges wc; if((c = getclient(ev->window))) { - c->ismax = False; if(ev->value_mask & CWBorderWidth) c->border = ev->border_width; if(c->isfixed || c->isfloating || (floating == layout->arrange)) { @@ -554,7 +561,7 @@ drawbar(void) { dc.x = x; if(sel) { drawtext(sel->name, dc.sel); - drawsquare(sel->ismax, sel->isfloating, dc.sel); + drawsquare(False, sel->isfloating, dc.sel); } else drawtext(NULL, dc.norm); @@ -704,6 +711,14 @@ focus(Client *c) { } void +focusin(XEvent *e) { /* there are some broken focus acquiring clients */ + XFocusChangeEvent *ev = &e->xfocus; + + if(sel && ev->window != sel->win) + XSetInputFocus(dpy, sel->win, RevertToPointerRoot, CurrentTime); +} + +void focusnext(const char *arg) { Client *c; @@ -834,6 +849,25 @@ grabbuttons(Client *c, Bool focused) { GrabModeAsync, GrabModeSync, None, None); } +void +grabkeys(void) { + unsigned int i; + KeyCode code; + + XUngrabKey(dpy, AnyKey, AnyModifier, root); + for(i = 0; i < LENGTH(keys); i++) { + code = XKeysymToKeycode(dpy, keys[i].keysym); + XGrabKey(dpy, code, keys[i].mod, root, True, + GrabModeAsync, GrabModeAsync); + XGrabKey(dpy, code, keys[i].mod | LockMask, root, True, + GrabModeAsync, GrabModeAsync); + XGrabKey(dpy, code, keys[i].mod | numlockmask, root, True, + GrabModeAsync, GrabModeAsync); + XGrabKey(dpy, code, keys[i].mod | numlockmask | LockMask, root, True, + GrabModeAsync, GrabModeAsync); + } +} + unsigned int idxoftag(const char *tag) { unsigned int i; @@ -921,27 +955,10 @@ isvisible(Client *c) { void keypress(XEvent *e) { - KEYS unsigned int i; - KeyCode code; KeySym keysym; XKeyEvent *ev; - if(!e) { /* grabkeys */ - XUngrabKey(dpy, AnyKey, AnyModifier, root); - for(i = 0; i < LENGTH(keys); i++) { - code = XKeysymToKeycode(dpy, keys[i].keysym); - XGrabKey(dpy, code, keys[i].mod, root, True, - GrabModeAsync, GrabModeAsync); - XGrabKey(dpy, code, keys[i].mod | LockMask, root, True, - GrabModeAsync, GrabModeAsync); - XGrabKey(dpy, code, keys[i].mod | numlockmask, root, True, - GrabModeAsync, GrabModeAsync); - XGrabKey(dpy, code, keys[i].mod | numlockmask | LockMask, root, True, - GrabModeAsync, GrabModeAsync); - } - return; - } ev = &e->xkey; keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); for(i = 0; i < LENGTH(keys); i++) @@ -1018,8 +1035,7 @@ manage(Window w, XWindowAttributes *wa) { XSetWindowBorder(dpy, w, dc.norm[ColBorder]); configure(c); /* propagates border_width, if size doesn't change */ updatesizehints(c); - XSelectInput(dpy, w, - StructureNotifyMask | PropertyChangeMask | EnterWindowMask); + XSelectInput(dpy, w, EnterWindowMask | FocusChangeMask | PropertyChangeMask | StructureNotifyMask); grabbuttons(c, False); updatetitle(c); if((rettrans = XGetTransientForHint(dpy, w, &trans) == Success)) @@ -1044,7 +1060,7 @@ mappingnotify(XEvent *e) { XRefreshKeyboardMapping(ev); if(ev->request == MappingKeyboard) - keypress(NULL); + grabkeys(); } void @@ -1061,6 +1077,13 @@ maprequest(XEvent *e) { } void +maximize(const char *arg) { + if(!sel || (!sel->isfloating && layout->arrange != floating)) + return; + resize(sel, wax, way, waw - 2 * sel->border, wah - 2 * sel->border, True); +} + +void movemouse(Client *c) { int x1, y1, ocx, ocy, di, nx, ny; unsigned int dui; @@ -1072,7 +1095,6 @@ movemouse(Client *c) { if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, None, cursor[CurMove], CurrentTime) != GrabSuccess) return; - c->ismax = False; XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); for(;;) { XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); @@ -1142,6 +1164,17 @@ quit(const char *arg) { readin = running = False; } +void +reapply(const char *arg) { + static Bool zerotags[LENGTH(tags)] = { 0 }; + Client *c; + + for(c = clients; c; c = c->next) { + memcpy(c->tags, zerotags, sizeof zerotags); + applyrules(c); + } + arrange(); +} void resize(Client *c, int x, int y, int w, int h, Bool sizehints) { @@ -1219,7 +1252,6 @@ resizemouse(Client *c) { if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, None, cursor[CurResize], CurrentTime) != GrabSuccess) return; - c->ismax = False; XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->border - 1, c->h + c->border - 1); for(;;) { XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask , &ev); @@ -1279,6 +1311,7 @@ restack(void) { void run(void) { char *p; + char buf[sizeof stext]; fd_set rd; int r, xfd; unsigned int len, offset; @@ -1290,7 +1323,7 @@ run(void) { readin = True; offset = 0; len = sizeof stext - 1; - stext[len] = '\0'; /* 0-terminator is never touched */ + buf[len] = stext[len] = '\0'; /* 0-terminator is never touched */ while(running) { FD_ZERO(&rd); if(readin) @@ -1302,7 +1335,7 @@ run(void) { eprint("select failed\n"); } if(FD_ISSET(STDIN_FILENO, &rd)) { - switch((r = read(STDIN_FILENO, stext + offset, len - offset))) { + switch((r = read(STDIN_FILENO, buf + offset, len - offset))) { case -1: strncpy(stext, strerror(errno), len); readin = False; @@ -1312,14 +1345,18 @@ run(void) { readin = False; break; default: - stext[offset + r] = '\0'; - for(p = stext; *p && *p != '\n'; p++); - if(*p == '\n') { - *p = '\0'; - offset = 0; - } - else - offset = (offset + r < len - 1) ? offset + r : 0; + for(p = buf + offset; r > 0; p++, r--, offset++) + if(*p == '\n' || *p == '\0') { + *p = '\0'; + strncpy(stext, buf, len); + p += r - 1; /* p is buf + offset + r - 1 */ + for(r = 0; *(p - r) && *(p - r) != '\n'; r++); + offset = r; + if(r) + memmove(buf, p - r + 1, r); + break; + } + break; } drawbar(); } @@ -1456,9 +1493,10 @@ setup(void) { XSelectInput(dpy, root, wa.event_mask); /* grab keys */ - keypress(NULL); + grabkeys(); /* init tags */ + memcpy(prevtags, seltags, sizeof seltags); compileregs(); /* init appearance */ @@ -1500,6 +1538,7 @@ setup(void) { /* multihead support */ selscreen = XQueryPointer(dpy, root, &w, &w, &d, &d, &d, &d, &mask); + } void @@ -1573,7 +1612,6 @@ tile(void) { ny = way; nw = 0; /* gcc stupidity requires this */ for(i = 0, c = mc = nexttiled(clients); c; c = nexttiled(c->next), i++) { - c->ismax = False; if(i == 0) { /* master */ nw = mw - 2 * c->border; nh = wah - 2 * c->border; @@ -1619,34 +1657,6 @@ togglefloating(const char *arg) { } void -togglemax(const char *arg) { - XEvent ev; - - if(!sel || sel->isfixed) - return; - if((sel->ismax = !sel->ismax)) { - if((layout->arrange == floating) || sel->isfloating) - sel->wasfloating = True; - else { - togglefloating(NULL); - sel->wasfloating = False; - } - sel->rx = sel->x; - sel->ry = sel->y; - sel->rw = sel->w; - sel->rh = sel->h; - resize(sel, wax, way, waw - 2 * sel->border, wah - 2 * sel->border, True); - } - else { - resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True); - if(!sel->wasfloating) - togglefloating(NULL); - } - drawbar(); - while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); -} - -void toggletag(const char *arg) { unsigned int i, j; @@ -1841,11 +1851,11 @@ view(const char *arg) { void viewprevtag(const char *arg) { - static Bool tmptags[sizeof tags / sizeof tags[0]]; + static Bool tmp[LENGTH(tags)]; - memcpy(tmptags, seltags, sizeof seltags); + memcpy(tmp, seltags, sizeof seltags); memcpy(seltags, prevtags, sizeof seltags); - memcpy(prevtags, tmptags, sizeof seltags); + memcpy(prevtags, tmp, sizeof seltags); arrange(); }