commit 1cb3fa80938299775382766b4b754e6220bf9831 from: rsc date: Mon Mar 29 12:00:15 2004 UTC Border resizing by dragging. Thanks to Axel Belinfante. commit - d99b2f34e69bc363c2973a2473e75654196ab40e commit + 1cb3fa80938299775382766b4b754e6220bf9831 blob - f3f510738f7da42dda3ec5d254a14972e2c87823 blob + c9f24c5447c39539fcaba3e5abb513a220dd75db --- src/cmd/rio/client.c +++ src/cmd/rio/client.c @@ -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); } blob - 0e3c8d89d49b5875b786f67b13ae3f8e79d32ef1 blob + e3410bba2b6e4ca14e9368903571a2151859647b --- src/cmd/rio/color.c +++ src/cmd/rio/color.c @@ -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; @@ -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; blob - f28906f7314e2f95be4edf8d5c123ca9d627f1e4 blob + a2832ede963ef6bb6ba973901f9b6e86bffc6e98 --- src/cmd/rio/cursor.c +++ src/cmd/rio/cursor.c @@ -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); } blob - 3f1a246e627663683bdc63dadb041ad479548cff blob + dc4c6fa59e17592b1e430f116c72437f3ba8b42d --- src/cmd/rio/dat.h +++ src/cmd/rio/dat.h @@ -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 @@ -20,6 +21,7 @@ typedef struct Client Client; typedef struct Menu Menu; typedef struct ScreenInfo ScreenInfo; +typedef enum BorderLocation BorderLocation; struct Client { Window window; @@ -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; @@ -102,6 +117,7 @@ struct ScreenInfo { Cursor sweep0; Cursor boxcurs; Cursor arrow; + Cursor bordcurs[NBorder]; Pixmap root_pixmap; char display[256]; /* arbitrary limit */ }; @@ -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; blob - 9b9b29076bca53c77ba7512fadb17797459d0bc4 blob + 88551baced50cc4032962778c37f7a0aed868679 --- src/cmd/rio/event.c +++ src/cmd/rio/event.c @@ -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; @@ -85,6 +88,8 @@ mainloop(int shape_event) focusin(&ev.xfocus); break; case MotionNotify: + motionnotify(&ev.xmotion); + break; case Expose: case NoExpose: case FocusOut: @@ -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; @@ -463,5 +478,84 @@ focusin(XFocusChangeEvent *e) XMapRaised(dpy, c->parent); top(c); 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]); + } +} blob - b6e1991aa9ad43762d9e096b66d0a54e243c41b0 blob + bdc3f23a80bf26246f17978f6cbda49bcd5562d1 --- src/cmd/rio/fns.h +++ src/cmd/rio/fns.h @@ -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(); @@ -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(); @@ -85,6 +88,7 @@ int menuhit(); Client *selectwin(); int sweep(); int drag(); +int pull(); void getmouse(); void setmouse(); blob - b9a19569cd991356a9353727b1a44a7594a23d78 blob + fafc3180d258429377b61f05db122904436d082b --- src/cmd/rio/grab.c +++ src/cmd/rio/grab.c @@ -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; @@ -267,10 +267,53 @@ 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 @@ -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; @@ -366,7 +409,9 @@ sweepdrag(Client *c, XButtonEvent *e0, void (*recalc)( 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); @@ -386,9 +431,9 @@ sweepdrag(Client *c, XButtonEvent *e0, void (*recalc)( 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); @@ -404,7 +449,7 @@ sweepdrag(Client *c, XButtonEvent *e0, void (*recalc)( 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; @@ -424,6 +469,7 @@ sweepdrag(Client *c, XButtonEvent *e0, void (*recalc)( } } bad: + if (debug) fprintf(stderr, "sweepdrag bad\n"); c->x = ox; c->y = oy; c->dx = odx; @@ -433,7 +479,7 @@ bad: } int -sweep(Client *c) +sweep(Client *c, int but, XButtonEvent *ignored) { XEvent ev; int status; @@ -449,27 +495,45 @@ 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 -drag(Client *c) +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, int but) +{ + int status; + ScreenInfo *s; + + s = c->screen; status = grab(s->root, s->root, ButtonMask, s->boxcurs, 0); if (status != GrabSuccess) { graberror("drag", status); /* */ return 0; } - return sweepdrag(c, 0, dragcalc); + return sweepdrag(c, but, 0, 0, dragcalc); } void blob - 029297735066658d059295bd595e63279b159437 blob + 2eb6386723964426ec4efa9e84f8a8ab3e396bd6 --- src/cmd/rio/main.c +++ src/cmd/rio/main.c @@ -31,6 +31,7 @@ char *termprog; char *shell; Bool shape; int _border = 4; +int _corner = 25; int _inset = 1; int curtime; int debug; @@ -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)); @@ -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); @@ -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* blob - 94e6bf9c5f45fe9992da51145842a81f8fc64296 blob + 790286f67d1385a5d9f17e9e7ad0c77451d7a75a --- src/cmd/rio/manage.c +++ src/cmd/rio/manage.c @@ -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) @@ -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) { @@ -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); @@ -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); @@ -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; @@ -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++) blob - 2e875b4e701ec45fb5b69bc0571e86b3e8bb6cb9 blob + bf621f2b32f4cdac1d0653a1e86b64143998a7e0 --- src/cmd/rio/menu.c +++ src/cmd/rio/menu.c @@ -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) { @@ -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; @@ -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; @@ -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); @@ -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);