tBorder resizing by dragging. Thanks to Axel Belinfante. - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 1cb3fa80938299775382766b4b754e6220bf9831
 (DIR) parent d99b2f34e69bc363c2973a2473e75654196ab40e
 (HTM) Author: rsc <devnull@localhost>
       Date:   Mon, 29 Mar 2004 12:00:15 +0000
       
       Border resizing by dragging.
       Thanks to Axel Belinfante.
       
       Diffstat:
         M src/cmd/rio/client.c                |       1 +
         M src/cmd/rio/color.c                 |       6 ++----
         M src/cmd/rio/cursor.c                |       9 +++++++++
         M src/cmd/rio/dat.h                   |      17 +++++++++++++++++
         M src/cmd/rio/event.c                 |      94 +++++++++++++++++++++++++++++++
         M src/cmd/rio/fns.h                   |       6 +++++-
         M src/cmd/rio/grab.c                  |      88 ++++++++++++++++++++++++++-----
         M src/cmd/rio/main.c                  |      41 ++++++++++++++++++++-----------
         M src/cmd/rio/manage.c                |      18 +++++++++++-------
         M src/cmd/rio/menu.c                  |      33 ++++++++++++++++++++++++-------
       
       10 files changed, 268 insertions(+), 45 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/rio/client.c b/src/cmd/rio/client.c
       t@@ -49,6 +49,7 @@ draw_border(Client *c, int active)
                                pixel = c->screen->inactiveborder;
                }
        
       +        if (debug) fprintf(stderr, "draw_border 0x%p pixel %ld active %d hold %d\n", c, pixel, active, c->hold);
                XSetWindowBackground(dpy, c->parent, pixel);
                XClearWindow(dpy, c->parent);
        }
 (DIR) diff --git a/src/cmd/rio/color.c b/src/cmd/rio/color.c
       t@@ -8,7 +8,7 @@
        #include "fns.h"
        
        unsigned long
       -colorpixel(Display *dpy, int depth, unsigned long rgb)
       +colorpixel(Display *dpy, int depth, unsigned long rgb, unsigned long def)
        {
                int r, g, b;
        
       t@@ -23,9 +23,7 @@ colorpixel(Display *dpy, int depth, unsigned long rgb)
                case 8:
                default:
                        /* not going to waste color map entries */
       -                if(rgb == 0xFFFFFF)
       -                        return WhitePixel(dpy, DefaultScreen(dpy));
       -                return BlackPixel(dpy, DefaultScreen(dpy));
       +                return def;
                case 15:
                        r >>= 3;
                        g >>= 3;
 (DIR) diff --git a/src/cmd/rio/cursor.c b/src/cmd/rio/cursor.c
       t@@ -198,6 +198,15 @@ ScreenInfo *s;
                s->root_pixmap = XCreatePixmapFromBitmapData(dpy,
                        s->root, grey_bits, grey_width, grey_height,
                        s->black, s->white, DefaultDepth(dpy, s->num));
       +        
       +        s->bordcurs[BorderN] = XCreateFontCursor(dpy, 138);
       +        s->bordcurs[BorderS] = XCreateFontCursor(dpy, 16);
       +        s->bordcurs[BorderW] = XCreateFontCursor(dpy, 70);
       +        s->bordcurs[BorderE] = XCreateFontCursor(dpy, 96);
       +        s->bordcurs[BorderNW] = XCreateFontCursor(dpy, 134);
       +        s->bordcurs[BorderSW] = XCreateFontCursor(dpy, 12);
       +        s->bordcurs[BorderNE] = XCreateFontCursor(dpy, 136);
       +        s->bordcurs[BorderSE] = XCreateFontCursor(dpy, 14);
        }
        
        
 (DIR) diff --git a/src/cmd/rio/dat.h b/src/cmd/rio/dat.h
       t@@ -1,6 +1,7 @@
        /* Copyright (c) 1994-1996 David Hogan, see README for licence details */
        
        #define BORDER                _border
       +#define CORNER                _corner
        #define        INSET                _inset
        #define MAXHIDDEN        32
        #define B3FIXED         5
       t@@ -20,6 +21,7 @@
        typedef struct Client Client;
        typedef struct Menu Menu;
        typedef struct ScreenInfo ScreenInfo;
       +typedef enum BorderLocation BorderLocation;
        
        struct Client {
                Window                window;
       t@@ -72,6 +74,19 @@ struct Menu {
                int        lasthit;
        };
        
       +enum BorderLocation {
       +        BorderN,
       +        BorderNE,
       +        BorderE,
       +        BorderSE,
       +        BorderS,
       +        BorderSW,
       +        BorderW,
       +        BorderNW,
       +        BorderUnknown,
       +        NBorder,
       +};
       +
        struct ScreenInfo {
                int                        num;
                int                        depth;
       t@@ -102,6 +117,7 @@ struct ScreenInfo {
                Cursor                sweep0;
                Cursor                boxcurs;
                Cursor                arrow;
       +        Cursor                bordcurs[NBorder];
                Pixmap                root_pixmap;
                char                        display[256];        /* arbitrary limit */
        };
       t@@ -119,6 +135,7 @@ extern char                 *termprog;
        extern char                 *shell;
        extern char                 *version[];
        extern int                        _border;
       +extern int                        _corner;
        extern int                        _inset;
        extern int                        curtime;
        extern int                        debug;
 (DIR) diff --git a/src/cmd/rio/event.c b/src/cmd/rio/event.c
       t@@ -78,6 +78,9 @@ mainloop(int shape_event)
                        case EnterNotify:
                                enter(&ev.xcrossing);
                                break;
       +                case LeaveNotify:
       +                        leave(&ev.xcrossing);
       +                        break;
                        case ReparentNotify:
                                reparent(&ev.xreparent);
                                break;
       t@@ -85,6 +88,8 @@ mainloop(int shape_event)
                                focusin(&ev.xfocus);
                                break;
                        case MotionNotify:
       +                        motionnotify(&ev.xmotion);
       +                        break;
                        case Expose:
                        case NoExpose:
                        case FocusOut:
       t@@ -450,6 +455,16 @@ enter(XCrossingEvent *e)
        }
        
        void
       +leave(XCrossingEvent *e)
       +{
       +        Client *c;
       +
       +        c = getclient(e->window, 0);
       +        XUndefineCursor(dpy, c->parent);
       +/*         XDefineCursor(dpy, c->parent, c->screen->arrow); */
       +}
       +
       +void
        focusin(XFocusChangeEvent *e)
        {
                Client *c;
       t@@ -465,3 +480,82 @@ focusin(XFocusChangeEvent *e)
                        active(c);
                }
        }
       +
       +BorderLocation
       +borderlocation(Client *c, int x, int y)
       +{
       +        if (x <= BORDER) {
       +                if (y <= CORNER) {
       +                        if (debug) fprintf(stderr, "topleft\n");
       +                        return BorderNW;
       +                }
       +                if (y >= (c->dy + 2*BORDER) - CORNER) {
       +                        if (debug) fprintf(stderr, "botleft\n");
       +                        return BorderSW;
       +                }
       +                if (y > CORNER &&
       +                y < (c->dy + 2*BORDER) - CORNER) {
       +                        if (debug) fprintf(stderr, "left\n");
       +                        return BorderW;
       +                }
       +        } else if (x <= CORNER) {
       +                if (y <= BORDER) {
       +                        if (debug) fprintf(stderr, "topleft\n");
       +                        return BorderNW;
       +                }
       +                if  (y >= (c->dy + BORDER)) {
       +                        if (debug) fprintf(stderr, "botleft\n");
       +                        return BorderSW;
       +                }
       +        } else if (x >= (c->dx + BORDER)) {
       +                if (y <= CORNER) {
       +                        if (debug) fprintf(stderr, "topright\n");
       +                        return BorderNE;
       +                }
       +                if (y >= (c->dy + 2*BORDER) - CORNER) {
       +                        if (debug) fprintf(stderr, "botright\n");
       +                        return BorderSE;
       +                }
       +                if (y > CORNER &&
       +                        y < (c->dy + 2*BORDER) - CORNER) {
       +                        if (debug) fprintf(stderr, "right\n");
       +                        return BorderE;
       +                }
       +        } else if (x >= (c->dx + 2*BORDER) - CORNER) {
       +                if (y <= BORDER) {
       +                        if (debug) fprintf(stderr, "topright\n");
       +                        return BorderNE;
       +                }
       +                if  (y >= (c->dy + BORDER)) {
       +                        if (debug) fprintf(stderr, "botright\n");
       +                        return BorderSE;
       +                }
       +        } else if (x > CORNER &&
       +                       x < (c->dx + 2*BORDER) - CORNER) {
       +                if (y <= BORDER) {
       +                        if (debug) fprintf(stderr, "top\n");
       +                        return BorderN;
       +                }
       +                if (y >= (c->dy + BORDER)) {
       +                        if (debug) fprintf(stderr, "bot\n");
       +                        return BorderS;
       +                }
       +        }
       +        return BorderUnknown;
       +}
       +
       +void
       +motionnotify(XMotionEvent *e)
       +{
       +        Client *c;
       +        BorderLocation bl;
       +
       +        c = getclient(e->window, 0);
       +        if (c) {
       +                bl = borderlocation(c, e->x, e->y);
       +                if (bl == BorderUnknown)
       +                        XUndefineCursor(dpy, c->parent);
       +                else
       +                        XDefineCursor(dpy, c->parent, c->screen->bordcurs[bl]);
       +        }
       +}
 (DIR) diff --git a/src/cmd/rio/fns.h b/src/cmd/rio/fns.h
       t@@ -10,7 +10,7 @@
        
        
        /* color.c */
       -unsigned long colorpixel(Display*, int, unsigned long);
       +unsigned long colorpixel(Display*, int, unsigned long, unsigned long);
        
        /* main.c */
        void        usage();
       t@@ -36,8 +36,11 @@ void        cmap();
        void        property();
        void        shapenotify();
        void        enter();
       +void        leave();
        void        focusin();
        void        reparent();
       +void         motionnotify();
       +BorderLocation borderlocation();
        
        /* manage.c */
        int         manage();
       t@@ -85,6 +88,7 @@ int         menuhit();
        Client        *selectwin();
        int         sweep();
        int         drag();
       +int         pull();
        void        getmouse();
        void        setmouse();
        
 (DIR) diff --git a/src/cmd/rio/grab.c b/src/cmd/rio/grab.c
       t@@ -223,7 +223,7 @@ selectwin(int release, int *shift, ScreenInfo *s)
        }
        
        void
       -sweepcalc(Client *c, int x, int y)
       +sweepcalc(Client *c, int x, int y, BorderLocation bl)
        {
                int dx, dy, sx, sy;
        
       t@@ -267,12 +267,55 @@ sweepcalc(Client *c, int x, int y)
        }
        
        void
       -dragcalc(Client *c, int x, int y)
       +dragcalc(Client *c, int x, int y, BorderLocation bl)
        {
                c->x += x;
                c->y += y;
        }
        
       +void
       +pullcalc(Client *c, int x, int y, BorderLocation bl)
       +{
       +        switch(bl) {
       +        case BorderN:
       +                c->y += y;
       +                c->dy -= y;
       +                break;
       +        case BorderS:
       +                c->dy += y;
       +                break;
       +        case BorderE:
       +                c->dx += x;
       +                break;
       +        case BorderW:
       +                c->x += x;
       +                c->dx -= x;
       +                break;
       +        case BorderNW:
       +                c->x += x;
       +                c->dx -= x;
       +                c->y += y;
       +                c->dy -= y;
       +                break;
       +        case BorderNE:
       +                c->dx += x;
       +                c->y += y;
       +                c->dy -= y;
       +                break;
       +        case BorderSE:
       +                c->dx += x;
       +                c->dy += y;
       +                break;
       +        case BorderSW:
       +                c->x += x;
       +                c->dx -= x;
       +                c->dy += y;
       +                break;
       +        default:
       +                break;
       +        }
       +}
       +
        static void
        xcopy(int fwd, Display *dpy, Drawable src, Drawable dst, GC gc, int x, int y, int dx, int dy, int x1, int y1)
        {
       t@@ -350,7 +393,7 @@ misleep(int msec)
        }
        
        int
       -sweepdrag(Client *c, XButtonEvent *e0, void (*recalc)(Client*, int, int))
       +sweepdrag(Client *c, int but, XButtonEvent *e0, BorderLocation bl, void (*recalc)(Client*, int, int, BorderLocation))
        {
                XEvent ev;
                int idle;
       t@@ -366,7 +409,9 @@ sweepdrag(Client *c, XButtonEvent *e0, void (*recalc)(Client*, int, int))
                c->y -= BORDER;
                c->dx += 2*BORDER;
                c->dy += 2*BORDER;
       -        if (e0)
       +        if (bl)
       +                getmouse(&cx, &cy, c->screen);
       +        else if (e0)
                        getmouse(&c->x, &c->y, c->screen);
                else
                        getmouse(&cx, &cy, c->screen);
       t@@ -386,9 +431,9 @@ sweepdrag(Client *c, XButtonEvent *e0, void (*recalc)(Client*, int, int))
                                                idle = 0;
                                        }
                                        if(e0)
       -                                        recalc(c, rx, ry);
       +                                        recalc(c, rx, ry, bl);
                                        else
       -                                        recalc(c, rx-cx, ry-cy);
       +                                        recalc(c, rx-cx, ry-cy, bl);
                                        cx = rx;
                                        cy = ry;
                                        drawbound(c, 1);
       t@@ -404,7 +449,7 @@ sweepdrag(Client *c, XButtonEvent *e0, void (*recalc)(Client*, int, int))
                                drawbound(c, 0);
                                ungrab(e);
                                XUngrabServer(dpy);
       -                        if (e->button != Button3 && c->init)
       +                        if (e->button != but && c->init)
                                        goto bad;
                                if (c->dx < 0) {
                                        c->x += c->dx;
       t@@ -424,6 +469,7 @@ sweepdrag(Client *c, XButtonEvent *e0, void (*recalc)(Client*, int, int))
                        }
                }
        bad:
       +        if (debug) fprintf(stderr, "sweepdrag bad\n");
                c->x = ox;
                c->y = oy;
                c->dx = odx;
       t@@ -433,7 +479,7 @@ bad:
        }
        
        int
       -sweep(Client *c)
       +sweep(Client *c, int but, XButtonEvent *ignored)
        {
                XEvent ev;
                int status;
       t@@ -449,16 +495,34 @@ sweep(Client *c)
        
                XMaskEvent(dpy, ButtonMask, &ev);
                e = &ev.xbutton;
       -        if (e->button != Button3) {
       +        if (e->button != but) {
                        ungrab(e);
                        return 0;
                }
                XChangeActivePointerGrab(dpy, ButtonMask, s->boxcurs, e->time);
       -        return sweepdrag(c, e, sweepcalc);
       +        return sweepdrag(c, but, e, 0, sweepcalc);
       +}
       +
       +int
       +pull(Client *c, int but, XButtonEvent *e)
       +{
       +        int status;
       +        ScreenInfo *s;
       +        BorderLocation bl;
       +
       +        bl = borderlocation(c, e->x, e->y);
       +        s = c->screen;
       +        status = grab(s->root, s->root, ButtonMask, s->bordcurs[bl], 0);
       +        if (status != GrabSuccess) {
       +                graberror("pull", status); /* */
       +                return 0;
       +        }
       +
       +        return sweepdrag(c, but, 0, bl, pullcalc);
        }
        
        int
       -drag(Client *c)
       +drag(Client *c, int but)
        {
                int status;
                ScreenInfo *s;
       t@@ -469,7 +533,7 @@ drag(Client *c)
                        graberror("drag", status); /* */
                        return 0;
                }
       -        return sweepdrag(c, 0, dragcalc);
       +        return sweepdrag(c, but, 0, 0, dragcalc);
        }
        
        void
 (DIR) diff --git a/src/cmd/rio/main.c b/src/cmd/rio/main.c
       t@@ -31,6 +31,7 @@ char                        *termprog;
        char                        *shell;
        Bool                        shape;
        int                         _border = 4;
       +int                         _corner = 25;
        int                         _inset = 1;
        int                         curtime;
        int                         debug;
       t@@ -236,13 +237,13 @@ initscreen(ScreenInfo *s, int i, int background)
                else
                        s->display[0] = '\0';
        
       -        s->activeholdborder = colorpixel(dpy, s->depth, 0x000099);
       -        s->inactiveholdborder = colorpixel(dpy, s->depth, 0x005DBB);
       -        s->activeborder = colorpixel(dpy, s->depth ,0x55AAAA);
       -        s->inactiveborder = colorpixel(dpy, s->depth, 0x9EEEEE);
       -        s->red = colorpixel(dpy, s->depth, 0xDD0000);
                s->black = BlackPixel(dpy, i);
                s->white = WhitePixel(dpy, i);
       +        s->activeholdborder = colorpixel(dpy, s->depth, 0x000099, s->white);
       +        s->inactiveholdborder = colorpixel(dpy, s->depth, 0x005DBB, s->black);
       +        s->activeborder = colorpixel(dpy, s->depth ,0x55AAAA, s->black);
       +        s->inactiveborder = colorpixel(dpy, s->depth, 0x9EEEEE, s->white);
       +        s->red = colorpixel(dpy, s->depth, 0xDD0000, s->white);
                s->width = WidthOfScreen(ScreenOfDisplay(dpy, i));
                s->height = HeightOfScreen(ScreenOfDisplay(dpy, i));
                s->bkup[0] = XCreatePixmap(dpy, s->root, 2*s->width, BORDER, DefaultDepth(dpy, i));
       t@@ -267,21 +268,21 @@ initscreen(ScreenInfo *s, int i, int background)
                gv.foreground = s->red;
                s->gcred = XCreateGC(dpy, s->root, mask, &gv);
        
       -        gv.foreground = colorpixel(dpy, s->depth, 0xEEEEEE);
       +        gv.foreground = colorpixel(dpy, s->depth, 0xEEEEEE, s->black);
                s->gcsweep = XCreateGC(dpy, s->root, mask, &gv);
        
       -        gv.foreground = colorpixel(dpy, s->depth, 0xE9FFE9);
       +        gv.foreground = colorpixel(dpy, s->depth, 0xE9FFE9, s->white);
                s->gcmenubg = XCreateGC(dpy, s->root, mask, &gv);
        
       -        gv.foreground = colorpixel(dpy, s->depth, 0x448844);
       +        gv.foreground = colorpixel(dpy, s->depth, 0x448844, s->black);
                s->gcmenubgs = XCreateGC(dpy, s->root, mask, &gv);
        
                gv.foreground = s->black;
       -        gv.background = colorpixel(dpy, s->depth, 0xE9FFE9);
       +        gv.background = colorpixel(dpy, s->depth, 0xE9FFE9, s->white);
                s->gcmenufg = XCreateGC(dpy, s->root, mask, &gv);
        
       -        gv.foreground = colorpixel(dpy, s->depth, 0xE9FFE9);
       -        gv.background = colorpixel(dpy, s->depth, 0x448844);
       +        gv.foreground = colorpixel(dpy, s->depth, 0xE9FFE9, s->white);
       +        gv.background = colorpixel(dpy, s->depth, 0x448844, s->black);
                s->gcmenufgs = XCreateGC(dpy, s->root, mask, &gv);
        
                initcurs(s);
       t@@ -299,9 +300,21 @@ initscreen(ScreenInfo *s, int i, int background)
                        XClearWindow(dpy, s->root);
                } else
                        system("xsetroot -solid grey30");
       -
       -        s->menuwin = XCreateSimpleWindow(dpy, s->root, 0, 0, 1, 1, 2, colorpixel(dpy, s->depth, 0x88CC88), colorpixel(dpy, s->depth, 0xE9FFE9));
       -        s->sweepwin = XCreateSimpleWindow(dpy, s->root, 0, 0, 1, 1, 4, s->red, colorpixel(dpy, s->depth, 0xEEEEEE));
       +        s->menuwin = XCreateSimpleWindow(dpy, s->root, 0, 0, 1, 1, 2, colorpixel(dpy, s->depth, 0x88CC88, s->black), colorpixel(dpy, s->depth, 0xE9FFE9, s->white));
       +        // s->sweepwin = XCreateWindow(dpy, s->root, 0, 0, 1, 1, 4, s->red, colorpixel(dpy, s->depth, 0xEEEEEE, s->black));
       +        {
       +                XSetWindowAttributes attrs;
       +                attrs.background_pixel =  colorpixel(dpy, s->depth, 0xEEEEEE, s->black);
       +                attrs.border_pixel =  s->red;
       +                attrs.save_under = True;
       +        s->sweepwin = XCreateWindow(dpy, s->root, 0, 0, 1, 1, 4,
       +                                                CopyFromParent,
       +                                                CopyFromParent,
       +                                                CopyFromParent,
       +                                                CWBackPixel | CWBorderPixel | CWSaveUnder,
       +                                                &attrs
       +                                                );
       +        }
        }
        
        ScreenInfo*
 (DIR) diff --git a/src/cmd/rio/manage.c b/src/cmd/rio/manage.c
       t@@ -107,7 +107,7 @@ manage(Client *c, int mapped)
                                nwin %= 10;
                        }
        
       -                if (c->is9term && !(fixsize ? drag(c) : sweep(c))) {
       +                if (c->is9term && !(fixsize ? drag(c, Button3) : sweep(c, Button3))) {
                                XKillClient(dpy, c->window);
                                rmclient(c);
                                if (current && current->screen == c->screen)
       t@@ -121,13 +121,17 @@ manage(Client *c, int mapped)
                c->parent = XCreateSimpleWindow(dpy, c->screen->root,
                                c->x - BORDER, c->y - BORDER,
                                c->dx + 2*BORDER, c->dy + 2*BORDER,
       -                        0, c->screen->black, c->screen->white);
       -        XSelectInput(dpy, c->parent, SubstructureRedirectMask | SubstructureNotifyMask);
       +                        0,
       +                        c->screen->black, c->screen->white);
       +        XSelectInput(dpy, c->parent, SubstructureRedirectMask | SubstructureNotifyMask|ButtonPressMask| PointerMotionMask|LeaveWindowMask);
                if (mapped)
                        c->reparenting = 1;
                if (doreshape && !fixsize)
                        XResizeWindow(dpy, c->window, c->dx, c->dy);
                XSetWindowBorderWidth(dpy, c->window, 0);
       +        if (1 || c->screen->depth <= 8) {
       +                XSetWindowBorderWidth(dpy, c->parent, 1);
       +        }
                XReparentWindow(dpy, c->window, c->parent, BORDER, BORDER);
        #ifdef        SHAPE
                if (shape) {
       t@@ -328,7 +332,7 @@ getcmaps(Client *c)
                        c->cmap = attr.colormap;
                }
        
       -        n = _getprop(c->window, wm_colormaps, XA_WINDOW, 100L, (unsigned char **)&cw);
       +        n = _getprop(c->window, wm_colormaps, XA_WINDOW, 100L, (void*)&cw);
                if (c->ncmapwins != 0) {
                        XFree((char *)c->cmapwins);
                        free((char *)c->wmcmaps);
       t@@ -421,7 +425,7 @@ get1prop(Window w, Atom a, Atom type)
        {
                char **p, *x;
        
       -        if (_getprop(w, a, type, 1L, (unsigned char**)&p) <= 0)
       +        if (_getprop(w, a, type, 1L, (void*)&p) <= 0)
                        return 0;
                x = *p;
                XFree((void*) p);
       t@@ -458,7 +462,7 @@ getstate(Window w, int *state)
        {
                long *p = 0;
        
       -        if (_getprop(w, wm_state, wm_state, 2L, (unsigned char**)&p) <= 0)
       +        if (_getprop(w, wm_state, wm_state, 2L, (void*)&p) <= 0)
                        return 0;
        
                *state = (int) *p;
       t@@ -476,7 +480,7 @@ getproto(Client *c)
        
                w = c->window;
                c->proto = 0;
       -        if ((n = _getprop(w, wm_protocols, XA_ATOM, 20L, (unsigned char**)&p)) <= 0)
       +        if ((n = _getprop(w, wm_protocols, XA_ATOM, 20L, (void*)&p)) <= 0)
                        return;
        
                for (i = 0; i < n; i++)
 (DIR) diff --git a/src/cmd/rio/menu.c b/src/cmd/rio/menu.c
       t@@ -48,12 +48,31 @@ button(XButtonEvent *e)
                        return;
                c = getclient(e->window, 0);
                if (c) {
       +                if (debug) fprintf(stderr, "but: e x=%d y=%d c x=%d y=%d dx=%d dy=%d BORDR %d\n",
       +                                e->x, e->y, c->x, c->y, c->dx, c->dy, BORDER);
       +            if (e->x <= BORDER || e->x > (c->dx + BORDER) ||
       +                e->y <= BORDER || e->y > (c->dy + BORDER)) {
       +                        switch (e->button) {
       +                        case Button1:
       +                        case Button2:
       +                                reshape(c, e->button, pull, e);
       +                                return;
       +                        case Button3:
       +                                move(c, Button3);
       +                                return;
       +                        default:
       +                                return;
       +                        }
       +            }
                        e->x += c->x - BORDER;
                        e->y += c->y - BORDER;
                }
       -        else if (e->window != e->root)
       +        else if (e->window != e->root) {
       +                if (debug) fprintf(stderr, "but no client: e x=%d y=%d\n",
       +                                e->x, e->y);
                        XTranslateCoordinates(dpy, e->window, s->root, e->x, e->y,
                                        &e->x, &e->y, &dw);
       +        }                
                switch (e->button) {
                case Button1:
                        if (c) {
       t@@ -79,10 +98,10 @@ button(XButtonEvent *e)
                        spawn(s);
                        break;
                case 1:         /* Reshape */
       -                reshape(selectwin(1, 0, s));
       +                reshape(selectwin(1, 0, s), Button3, sweep, 0);
                        break;
                case 2:         /* Move */
       -                move(selectwin(0, 0, s));
       +                move(selectwin(0, 0, s), Button3);
                        break;
                case 3:         /* Delete */
                        shift = 0;
       t@@ -137,7 +156,7 @@ spawn(ScreenInfo *s)
        }
        
        void
       -reshape(Client *c)
       +reshape(Client *c, int but, int (*fn)(Client*, int, XButtonEvent *), XButtonEvent *e)
        {
                int odx, ody;
        
       t@@ -145,7 +164,7 @@ reshape(Client *c)
                        return;
                odx = c->dx;
                ody = c->dy;
       -        if (sweep(c) == 0)
       +        if (fn(c, but, e) == 0)
                        return;
                active(c);
                top(c);
       t@@ -159,11 +178,11 @@ reshape(Client *c)
        }
        
        void
       -move(Client *c)
       +move(Client *c, int but)
        {
                if (c == 0)
                        return;
       -        if (drag(c) == 0)
       +        if (drag(c, but) == 0)
                        return;
                active(c);
                top(c);