JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
grabbuttons() and grabkeys() are now independent from prior numlockmask initialization
[dwm.git] / dwm.c
diff --git a/dwm.c b/dwm.c
index dc14bfd..89bca14 100644 (file)
--- a/dwm.c
+++ b/dwm.c
@@ -24,6 +24,7 @@
  * To understand everything else, start reading main().
  */
 #include <errno.h>
+#include <locale.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -190,6 +191,7 @@ static void unmanage(Client *c);
 static void unmapnotify(XEvent *e);
 static void updatebar(void);
 static void updategeom(void);
+static void updatenumlockmask(void);
 static void updatesizehints(Client *c);
 static void updatetitle(Client *c);
 static void updatewmhints(Client *c);
@@ -581,7 +583,7 @@ drawtext(const char *text, unsigned long col[ColLast], Bool invert) {
        y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
        x = dc.x + (h / 2);
        /* shorten text if necessary */
-       for(len = MIN(olen, sizeof buf); len && textnw(buf, len) > dc.w - h; len--);
+       for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--);
        if(!len)
                return;
        memcpy(buf, text, len);
@@ -734,42 +736,37 @@ gettextprop(Window w, Atom atom, char *text, unsigned int size) {
 
 void
 grabbuttons(Client *c, Bool focused) {
-       unsigned int i, j;
-       unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
-
-       XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
-       if(focused) {
-               for(i = 0; i < LENGTH(buttons); i++)
-                       if(buttons[i].click == ClkClientWin)
-                               for(j = 0; j < LENGTH(modifiers); j++)
-                                       XGrabButton(dpy, buttons[i].button, buttons[i].mask | modifiers[j], c->win, False, BUTTONMASK, GrabModeAsync, GrabModeSync, None, None);
-       } else
-               XGrabButton(dpy, AnyButton, AnyModifier, c->win, False,
-                           BUTTONMASK, GrabModeAsync, GrabModeSync, None, None);
+       updatenumlockmask();
+       {
+               unsigned int i, j;
+               unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
+               XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
+               if(focused) {
+                       for(i = 0; i < LENGTH(buttons); i++)
+                               if(buttons[i].click == ClkClientWin)
+                                       for(j = 0; j < LENGTH(modifiers); j++)
+                                               XGrabButton(dpy, buttons[i].button, buttons[i].mask | modifiers[j], c->win, False, BUTTONMASK, GrabModeAsync, GrabModeSync, None, None);
+               } else
+                       XGrabButton(dpy, AnyButton, AnyModifier, c->win, False,
+                                   BUTTONMASK, GrabModeAsync, GrabModeSync, None, None);
+       }
 }
 
 void
 grabkeys(void) {
-       unsigned int i, j;
-       unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
-       KeyCode code;
-       XModifierKeymap *modmap;
-
-       /* init modifier map */
-       modmap = XGetModifierMapping(dpy);
-       for(i = 0; i < 8; i++)
-               for(j = 0; j < modmap->max_keypermod; j++) {
-                       if(modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock))
-                               numlockmask = (1 << i);
+       updatenumlockmask();
+       { /* grab keys */
+               unsigned int i, j;
+               unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
+               KeyCode code;
+
+               XUngrabKey(dpy, AnyKey, AnyModifier, root);
+               for(i = 0; i < LENGTH(keys); i++) {
+                       code = XKeysymToKeycode(dpy, keys[i].keysym);
+                       for(j = 0; j < LENGTH(modifiers); j++)
+                               XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, True,
+                                        GrabModeAsync, GrabModeAsync);
                }
-       XFreeModifiermap(modmap);
-
-       XUngrabKey(dpy, AnyKey, AnyModifier, root);
-       for(i = 0; i < LENGTH(keys); i++) {
-               code = XKeysymToKeycode(dpy, keys[i].keysym);
-               for(j = 0; j < LENGTH(modifiers); j++)
-                       XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, True,
-                                GrabModeAsync, GrabModeAsync);
        }
 }
 
@@ -779,8 +776,6 @@ initfont(const char *fontstr) {
        int i, n;
 
        missing = NULL;
-       if(dc.font.set)
-               XFreeFontSet(dpy, dc.font.set);
        dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
        if(missing) {
                while(n--)
@@ -961,18 +956,15 @@ movemouse(const Arg *arg) {
        if(!(c = sel))
                return;
        restack();
-       ocx = nx = c->x;
-       ocy = ny = c->y;
+       ocx = c->x;
+       ocy = c->y;
        if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
        None, cursor[CurMove], CurrentTime) != GrabSuccess)
                return;
        XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui);
-       for(;;) {
+       do {
                XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
                switch (ev.type) {
-               case ButtonRelease:
-                       XUngrabPointer(dpy, CurrentTime);
-                       return;
                case ConfigureRequest:
                case Expose:
                case MapRequest:
@@ -1000,6 +992,8 @@ movemouse(const Arg *arg) {
                        break;
                }
        }
+       while(ev.type != ButtonRelease);
+       XUngrabPointer(dpy, CurrentTime);
 }
 
 Client *
@@ -1050,22 +1044,31 @@ resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
        XWindowChanges wc;
 
        if(sizehints) {
+               /* see last two sentences in ICCCM 4.1.2.3 */
+               Bool baseismin = c->basew == c->minw && c->baseh == c->minh;
+
                /* set minimum possible */
                w = MAX(1, w);
                h = MAX(1, h);
 
-               /* temporarily remove base dimensions */
-               w -= c->basew;
-               h -= c->baseh;
+               if(!baseismin) { /* temporarily remove base dimensions */
+                       w -= c->basew;
+                       h -= c->baseh;
+               }
 
                /* adjust for aspect limits */
                if(c->mina > 0 && c->maxa > 0) {
-                       if(c->maxa < (float) w/h)
+                       if(c->maxa < (float)(w / h))
                                w = h * c->maxa;
-                       else if(c->mina > (float) h/w)
+                       else if(c->mina < (float)(h / w))
                                h = w * c->mina;
                }
 
+               if(baseismin) { /* increment calculation requires this */
+                       w -= c->basew;
+                       h -= c->baseh;
+               }
+
                /* adjust for increment value */
                if(c->incw)
                        w -= w % c->incw;
@@ -1128,15 +1131,9 @@ resizemouse(const Arg *arg) {
        None, cursor[CurResize], CurrentTime) != GrabSuccess)
                return;
        XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
-       for(;;) {
-               XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask , &ev);
+       do {
+               XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
                switch(ev.type) {
-               case ButtonRelease:
-                       XWarpPointer(dpy, None, c->win, 0, 0, 0, 0,
-                                       c->w + c->bw - 1, c->h + c->bw - 1);
-                       XUngrabPointer(dpy, CurrentTime);
-                       while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
-                       return;
                case ConfigureRequest:
                case Expose:
                case MapRequest:
@@ -1158,6 +1155,10 @@ resizemouse(const Arg *arg) {
                        break;
                }
        }
+       while(ev.type != ButtonRelease);
+       XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
+       XUngrabPointer(dpy, CurrentTime);
+       while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
 }
 
 void
@@ -1376,8 +1377,6 @@ setup(void) {
        XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
        XSelectInput(dpy, root, wa.event_mask);
 
-
-       /* grab keys */
        grabkeys();
 }
 
@@ -1472,8 +1471,12 @@ togglefloating(const Arg *arg) {
 
 void
 toggletag(const Arg *arg) {
-       unsigned int mask = sel->tags ^ (arg->ui & TAGMASK);
+       unsigned int mask;
 
+       if (!sel)
+               return;
+       
+       mask = sel->tags ^ (arg->ui & TAGMASK);
        if(sel && mask) {
                sel->tags = mask;
                arrange();
@@ -1567,6 +1570,20 @@ updategeom(void) {
 }
 
 void
+updatenumlockmask(void) {
+       unsigned int i, j;
+       XModifierKeymap *modmap;
+
+       numlockmask = 0;
+       modmap = XGetModifierMapping(dpy);
+       for(i = 0; i < 8; i++)
+               for(j = 0; j < modmap->max_keypermod; j++)
+                       if(modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock))
+                               numlockmask = (1 << i);
+       XFreeModifiermap(modmap);
+}
+
+void
 updatesizehints(Client *c) {
        long msize;
        XSizeHints size;
@@ -1702,7 +1719,7 @@ main(int argc, char *argv[]) {
        else if(argc != 1)
                die("usage: dwm [-v]\n");
 
-       if(!XSupportsLocale())
+       if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())
                fprintf(stderr, "warning: no locale support\n");
 
        if(!(dpy = XOpenDisplay(0)))