From c005568a7fe03010dcd1b2df311e3cd7f7459448 Mon Sep 17 00:00:00 2001 From: rsc Date: Tue, 30 Mar 2004 05:01:53 +0000 Subject: Border resizing and 9term greying. --- src/cmd/rio/README | 10 ++- src/cmd/rio/client.c | 13 ++-- src/cmd/rio/cursor.c | 16 +++-- src/cmd/rio/dat.h | 21 ++++-- src/cmd/rio/event.c | 27 +++---- src/cmd/rio/fns.h | 2 +- src/cmd/rio/grab.c | 194 +++++++++++++++++++++++++++++++++++++++++---------- src/cmd/rio/main.c | 99 ++++++++++++++++++++------ src/cmd/rio/manage.c | 37 +++++++++- 9 files changed, 319 insertions(+), 100 deletions(-) (limited to 'src') diff --git a/src/cmd/rio/README b/src/cmd/rio/README index bece6c32..15c9a77d 100644 --- a/src/cmd/rio/README +++ b/src/cmd/rio/README @@ -4,15 +4,10 @@ and I'd prefer not to resort to patches, I have renamed it "rio". Current incompatibilities that would be nice to fix: -- Rio uses X11 fonts for the menu, and there aren't any good ones! -I'm tempted to hard-code the Plan 9 default font bitmap. - - The command-line options should be made more like Plan 9. - Should work out a protocol between 9term and rio so that: * 9term can tell rio to blue its border during hold mode - * rio can tell 9term to fade its text when it loses focus - * rio can tell 9term to unfade its text when it regains focus - Should change window focus on b2/b3 clicks and then pass along the click event to the now-focused window. @@ -20,11 +15,14 @@ I'm tempted to hard-code the Plan 9 default font bitmap. - Should change 9term to redirect b3 clicks to rio so that rio can put up the usual b3 menu. +Axel Belinfante contributed the code to handle border grabbing +for resize. + The original README is below. - russ cox rsc@swtch.com -20 march 2004 +30 march 2004 9wm Version 1.2 diff --git a/src/cmd/rio/client.c b/src/cmd/rio/client.c index c9f24c54..702ba9cb 100644 --- a/src/cmd/rio/client.c +++ b/src/cmd/rio/client.c @@ -25,10 +25,12 @@ setactive(Client *c, int on) if (c->proto & Ptakefocus) sendcmessage(c->window, wm_protocols, wm_take_focus, 0); cmapfocus(c); - } - else + } else { + if (c->proto & Plosefocus) + sendcmessage(c->window, wm_protocols, wm_lose_focus, 0); XGrabButton(dpy, AnyButton, AnyModifier, c->parent, False, ButtonMask, GrabModeAsync, GrabModeSync, None, None); + } draw_border(c, on); } @@ -49,7 +51,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); + if (debug) fprintf(stderr, "draw_border %p pixel %ld active %d hold %d\n", c, pixel, active, c->hold); XSetWindowBackground(dpy, c->parent, pixel); XClearWindow(dpy, c->parent); } @@ -104,10 +106,11 @@ nofocus(void) } current = 0; if (w == 0) { - mask = CWOverrideRedirect; + mask = CWOverrideRedirect/*|CWColormap*/; attr.override_redirect = 1; + /* attr.colormap = screens[0].def_cmap;*/ w = XCreateWindow(dpy, screens[0].root, 0, 0, 1, 1, 0, - CopyFromParent, InputOnly, CopyFromParent, mask, &attr); + 0 /*screens[0].depth*/, InputOnly, screens[0].vis, mask, &attr); XMapWindow(dpy, w); } XSetInputFocus(dpy, w, RevertToPointerRoot, timestamp()); diff --git a/src/cmd/rio/cursor.c b/src/cmd/rio/cursor.c index a2832ede..f1991ba7 100644 --- a/src/cmd/rio/cursor.c +++ b/src/cmd/rio/cursor.c @@ -197,16 +197,20 @@ ScreenInfo *s; s->root_pixmap = XCreatePixmapFromBitmapData(dpy, s->root, grey_bits, grey_width, grey_height, - s->black, s->white, DefaultDepth(dpy, s->num)); + s->black, s->white, s->depth); s->bordcurs[BorderN] = XCreateFontCursor(dpy, 138); + s->bordcurs[BorderNNE] = XCreateFontCursor(dpy, 136); + s->bordcurs[BorderENE] = s->bordcurs[BorderNNE] ; + s->bordcurs[BorderE] = XCreateFontCursor(dpy, 96); + s->bordcurs[BorderESE] = XCreateFontCursor(dpy, 14); + s->bordcurs[BorderSSE] = s->bordcurs[BorderESE]; s->bordcurs[BorderS] = XCreateFontCursor(dpy, 16); + s->bordcurs[BorderSSW] = XCreateFontCursor(dpy, 12); + s->bordcurs[BorderWSW] = s->bordcurs[BorderSSW]; 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); + s->bordcurs[BorderWNW] = XCreateFontCursor(dpy, 134); + s->bordcurs[BorderNNW] = s->bordcurs[BorderWNW]; } diff --git a/src/cmd/rio/dat.h b/src/cmd/rio/dat.h index dc4c6fa5..afa9bb91 100644 --- a/src/cmd/rio/dat.h +++ b/src/cmd/rio/dat.h @@ -21,7 +21,7 @@ typedef struct Client Client; typedef struct Menu Menu; typedef struct ScreenInfo ScreenInfo; -typedef enum BorderLocation BorderLocation; +typedef enum BorderOrient BorderOrient; struct Client { Window window; @@ -67,6 +67,7 @@ struct Client { /* c->proto */ #define Pdelete 1 #define Ptakefocus 2 +#define Plosefocus 4 struct Menu { char **item; @@ -74,22 +75,27 @@ struct Menu { int lasthit; }; -enum BorderLocation { +enum BorderOrient { + BorderUnknown = 0, /* we depend on this!*/ BorderN, - BorderNE, + BorderNNE, + BorderENE, BorderE, - BorderSE, + BorderESE, + BorderSSE, BorderS, - BorderSW, + BorderSSW, + BorderWSW, BorderW, - BorderNW, - BorderUnknown, + BorderWNW, + BorderNNW, NBorder, }; struct ScreenInfo { int num; int depth; + Visual *vis; int width; int height; Window root; @@ -149,6 +155,7 @@ extern Atom _9wm_hold_mode; extern Atom wm_protocols; extern Atom wm_delete; extern Atom wm_take_focus; +extern Atom wm_lose_focus; extern Atom wm_colormaps; /* client.c */ diff --git a/src/cmd/rio/event.c b/src/cmd/rio/event.c index 88551bac..3e732879 100644 --- a/src/cmd/rio/event.c +++ b/src/cmd/rio/event.c @@ -460,7 +460,8 @@ leave(XCrossingEvent *e) Client *c; c = getclient(e->window, 0); - XUndefineCursor(dpy, c->parent); + if (c) + XUndefineCursor(dpy, c->parent); /* XDefineCursor(dpy, c->parent, c->screen->arrow); */ } @@ -481,17 +482,17 @@ focusin(XFocusChangeEvent *e) } } -BorderLocation -borderlocation(Client *c, int x, int y) +BorderOrient +borderorient(Client *c, int x, int y) { if (x <= BORDER) { if (y <= CORNER) { if (debug) fprintf(stderr, "topleft\n"); - return BorderNW; + return BorderWNW; } if (y >= (c->dy + 2*BORDER) - CORNER) { if (debug) fprintf(stderr, "botleft\n"); - return BorderSW; + return BorderWSW; } if (y > CORNER && y < (c->dy + 2*BORDER) - CORNER) { @@ -501,20 +502,20 @@ borderlocation(Client *c, int x, int y) } else if (x <= CORNER) { if (y <= BORDER) { if (debug) fprintf(stderr, "topleft\n"); - return BorderNW; + return BorderNNW; } if (y >= (c->dy + BORDER)) { if (debug) fprintf(stderr, "botleft\n"); - return BorderSW; + return BorderSSW; } } else if (x >= (c->dx + BORDER)) { if (y <= CORNER) { if (debug) fprintf(stderr, "topright\n"); - return BorderNE; + return BorderENE; } if (y >= (c->dy + 2*BORDER) - CORNER) { if (debug) fprintf(stderr, "botright\n"); - return BorderSE; + return BorderESE; } if (y > CORNER && y < (c->dy + 2*BORDER) - CORNER) { @@ -524,11 +525,11 @@ borderlocation(Client *c, int x, int y) } else if (x >= (c->dx + 2*BORDER) - CORNER) { if (y <= BORDER) { if (debug) fprintf(stderr, "topright\n"); - return BorderNE; + return BorderNNE; } if (y >= (c->dy + BORDER)) { if (debug) fprintf(stderr, "botright\n"); - return BorderSE; + return BorderSSE; } } else if (x > CORNER && x < (c->dx + 2*BORDER) - CORNER) { @@ -548,11 +549,11 @@ void motionnotify(XMotionEvent *e) { Client *c; - BorderLocation bl; + BorderOrient bl; c = getclient(e->window, 0); if (c) { - bl = borderlocation(c, e->x, e->y); + bl = borderorient(c, e->x, e->y); if (bl == BorderUnknown) XUndefineCursor(dpy, c->parent); else diff --git a/src/cmd/rio/fns.h b/src/cmd/rio/fns.h index bdc3f23a..e3c214d2 100644 --- a/src/cmd/rio/fns.h +++ b/src/cmd/rio/fns.h @@ -40,7 +40,7 @@ void leave(); void focusin(); void reparent(); void motionnotify(); -BorderLocation borderlocation(); +BorderOrient borderorient(); /* manage.c */ int manage(); diff --git a/src/cmd/rio/grab.c b/src/cmd/rio/grab.c index fafc3180..9b987ea2 100644 --- a/src/cmd/rio/grab.c +++ b/src/cmd/rio/grab.c @@ -222,8 +222,8 @@ selectwin(int release, int *shift, ScreenInfo *s) } } -void -sweepcalc(Client *c, int x, int y, BorderLocation bl) +int +sweepcalc(Client *c, int x, int y, BorderOrient bl, int ignored) { int dx, dy, sx, sy; @@ -264,56 +264,166 @@ sweepcalc(Client *c, int x, int y, BorderLocation bl) } c->dx = sx*(dx + 2*BORDER); c->dy = sy*(dy + 2*BORDER); + + return ignored; } -void -dragcalc(Client *c, int x, int y, BorderLocation bl) +int +dragcalc(Client *c, int x, int y, BorderOrient bl, int ignored) { c->x += x; c->y += y; + + return ignored; } -void -pullcalc(Client *c, int x, int y, BorderLocation bl) +int +pullcalc(Client *c, int x, int y, BorderOrient bl, int init) { + int dx, dy, sx, sy, px, py, spx, spy, rdx, rdy, xoff, yoff, xcorn, ycorn; + + px = c->x; + py = c->y; + dx = c->dx; + dy = c->dy; + sx = sy = 1; + spx = spy = 0; + xoff = yoff = 0; + xcorn = ycorn = 0; + switch(bl) { case BorderN: - c->y += y; - c->dy -= y; + py = y; + dy = (c->y + c->dy) - y; + spy = 1; + yoff = y - c->y; break; case BorderS: - c->dy += y; + dy = y - c->y; + yoff = (c->y + c->dy) - y; break; case BorderE: - c->dx += x; + dx = x - c->x; + xoff = (c->x + c->dx) - x; break; case BorderW: - c->x += x; - c->dx -= x; + px = x; + dx = (c->x + c->dx) - x; + spx = 1; + xoff = x - c->x; break; - case BorderNW: - c->x += x; - c->dx -= x; - c->y += y; - c->dy -= y; + case BorderNNW: + case BorderWNW: + px = x; + dx = (c->x + c->dx) - x; + spx = 1; + py = y; + dy = (c->y + c->dy) - y; + spy = 1; + xoff = x - c->x; + yoff = y - c->y; break; - case BorderNE: - c->dx += x; - c->y += y; - c->dy -= y; + case BorderNNE: + case BorderENE: + dx = x - c->x; + py = y; + dy = (c->y + c->dy) - y; + spy = 1; + xoff = (c->x + c->dx) - x; + yoff = y - c->y; break; - case BorderSE: - c->dx += x; - c->dy += y; + case BorderSSE: + case BorderESE: + dx = x - c->x; + dy = y - c->y; + xoff = (c->x + c->dx) - x; + yoff = (c->y + c->dy) - y; break; - case BorderSW: - c->x += x; - c->dx -= x; - c->dy += y; + case BorderSSW: + case BorderWSW: + px = x; + dx = (c->x + c->dx) - x; + spx = 1; + dy = y - c->y; + xoff = x - c->x; + yoff = (c->y + c->dy) - y; break; default: break; } + switch(bl) { + case BorderNNW: + case BorderNNE: + case BorderSSW: + case BorderSSE: + xcorn = 1; + break; + case BorderWNW: + case BorderENE: + case BorderWSW: + case BorderESE: + ycorn = 1; + break; + } + if (!init + || xoff < 0 || (xcorn && xoff > CORNER) || (!xcorn && xoff > BORDER) + || yoff < 0 || (ycorn && yoff > CORNER) || (!ycorn && yoff > BORDER)) { + xoff = 0; + yoff = 0; + init = 0; + } + + if (debug) fprintf(stderr, "c %dx%d+%d+%d m +%d+%d r %dx%d+%d+%d sp (%d,%d) bl %d\n", + c->dx, c->dy, c->x, c->y, x, y, dx, dy, px, py, spx, spy, bl); + if (dx < 0) { + dx = -dx; + sx = -1; + } + if (dy < 0) { + dy = -dy; + sy = -1; + } + + /* remember requested size; + * after applying size hints we may have to correct position + */ + rdx = sx*dx; + rdy = sy*dy; + + /* apply size hints */ + dx -= (2*BORDER - xoff); + dy -= (2*BORDER - yoff); + + if (!c->is9term) { + if (dx < c->min_dx) + dx = c->min_dx; + if (dy < c->min_dy) + dy = c->min_dy; + } + + if (c->size.flags & PResizeInc) { + dx = c->min_dx + (dx-c->min_dx)/c->size.width_inc*c->size.width_inc; + dy = c->min_dy + (dy-c->min_dy)/c->size.height_inc*c->size.height_inc; + } + + if (c->size.flags & PMaxSize) { + if (dx > c->size.max_width) + dx = c->size.max_width; + if (dy > c->size.max_height) + dy = c->size.max_height; + } + + /* set size and position */ + c->dx = sx*(dx + 2*BORDER ); + c->dy = sy*(dy + 2*BORDER ); + c->x = px; + c->y = py; + + /* compensate position for size changed due to size hints */ + c->x -= spx*(c->dx - rdx); + c->y -= spy*(c->dy - rdy); + + return init; } static void @@ -330,6 +440,8 @@ drawbound(Client *c, int drawing) { int x, y, dx, dy; ScreenInfo *s; + + if (debug) fprintf(stderr, "drawbound %dx%d +%d+%d\n", c->dx, c->dy, c->x, c->y); s = c->screen; x = c->x; @@ -393,14 +505,16 @@ misleep(int msec) } int -sweepdrag(Client *c, int but, XButtonEvent *e0, BorderLocation bl, void (*recalc)(Client*, int, int, BorderLocation)) +sweepdrag(Client *c, int but, XButtonEvent *e0, BorderOrient bl, int (*recalc)(Client*, int, int, BorderOrient, int)) { XEvent ev; int idle; int cx, cy, rx, ry; int ox, oy, odx, ody; XButtonEvent *e; + int notmoved; + notmoved = 1; ox = c->x; oy = c->y; odx = c->dx; @@ -409,13 +523,14 @@ sweepdrag(Client *c, int but, XButtonEvent *e0, BorderLocation bl, void (*recalc c->y -= BORDER; c->dx += 2*BORDER; c->dy += 2*BORDER; - if (bl) + if (bl || e0 == 0) getmouse(&cx, &cy, c->screen); - else if (e0) - getmouse(&c->x, &c->y, c->screen); else - getmouse(&cx, &cy, c->screen); + getmouse(&c->x, &c->y, c->screen); XGrabServer(dpy); + if (bl) { + notmoved = recalc(c, cx, cy, bl, notmoved); + } drawbound(c, 1); idle = 0; for (;;) { @@ -430,10 +545,10 @@ sweepdrag(Client *c, int but, XButtonEvent *e0, BorderLocation bl, void (*recalc XGrabServer(dpy); idle = 0; } - if(e0) - recalc(c, rx, ry, bl); + if(e0 || bl) + notmoved = recalc(c, rx, ry, bl, notmoved); else - recalc(c, rx-cx, ry-cy, bl); + notmoved = recalc(c, rx-cx, ry-cy, bl, notmoved); cx = rx; cy = ry; drawbound(c, 1); @@ -508,9 +623,11 @@ pull(Client *c, int but, XButtonEvent *e) { int status; ScreenInfo *s; - BorderLocation bl; + BorderOrient bl; + + bl = borderorient(c, e->x, e->y); + /* assert(bl > BorderUnknown && bl < NBorder); */ - bl = borderlocation(c, e->x, e->y); s = c->screen; status = grab(s->root, s->root, ButtonMask, s->bordcurs[bl], 0); if (status != GrabSuccess) { @@ -544,6 +661,7 @@ getmouse(int *x, int *y, ScreenInfo *s) unsigned int t3; XQueryPointer(dpy, s->root, &dw1, &dw2, x, y, &t1, &t2, &t3); + if (debug) fprintf(stderr, "getmouse: %d %d\n", *x, *y); } void diff --git a/src/cmd/rio/main.c b/src/cmd/rio/main.c index 2eb63867..c25f8a4c 100644 --- a/src/cmd/rio/main.c +++ b/src/cmd/rio/main.c @@ -46,6 +46,7 @@ Atom wm_change_state; Atom wm_protocols; Atom wm_delete; Atom wm_take_focus; +Atom wm_lose_focus; Atom wm_colormaps; Atom _9wm_running; Atom _9wm_hold_mode; @@ -152,11 +153,14 @@ main(int argc, char *argv[]) exit(0); } + if (0) XSynchronize(dpy, True); + wm_state = XInternAtom(dpy, "WM_STATE", False); wm_change_state = XInternAtom(dpy, "WM_CHANGE_STATE", False); wm_protocols = XInternAtom(dpy, "WM_PROTOCOLS", False); wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False); wm_take_focus = XInternAtom(dpy, "WM_TAKE_FOCUS", False); + wm_lose_focus = XInternAtom(dpy, "_9WM_LOSE_FOCUS", False); wm_colormaps = XInternAtom(dpy, "WM_COLORMAP_WINDOWS", False); _9wm_running = XInternAtom(dpy, "_9WM_RUNNING", False); _9wm_hold_mode = XInternAtom(dpy, "_9WM_HOLD_MODE", False); @@ -214,8 +218,11 @@ initscreen(ScreenInfo *s, int i, int background) { char *ds, *colon, *dot1; unsigned long mask; + unsigned long gmask; XGCValues gv; XSetWindowAttributes attr; + XVisualInfo xvi; + XSetWindowAttributes attrs; s->num = i; s->root = RootWindow(dpy, i); @@ -223,6 +230,44 @@ initscreen(ScreenInfo *s, int i, int background) s->min_cmaps = MinCmapsOfScreen(ScreenOfDisplay(dpy, i)); s->depth = DefaultDepth(dpy, i); + /* + * Figure out underlying screen format. + */ + if(XMatchVisualInfo(dpy, i, 16, TrueColor, &xvi) + || XMatchVisualInfo(dpy, i, 16, DirectColor, &xvi)){ + s->vis = xvi.visual; + s->depth = 16; + } + else + if(XMatchVisualInfo(dpy, i, 15, TrueColor, &xvi) + || XMatchVisualInfo(dpy, i, 15, DirectColor, &xvi)){ + s->vis = xvi.visual; + s->depth = 15; + } + else + if(XMatchVisualInfo(dpy, i, 24, TrueColor, &xvi) + || XMatchVisualInfo(dpy, i, 24, DirectColor, &xvi)){ + s->vis = xvi.visual; + s->depth = 24; + } + else + if(XMatchVisualInfo(dpy, i, 8, PseudoColor, &xvi) + || XMatchVisualInfo(dpy, i, 8, StaticColor, &xvi)){ + s->vis = xvi.visual; + s->depth = 8; + } + else{ + s->depth = DefaultDepth(dpy, i); + if(s->depth != 8){ + fprintf(stderr, "can't understand depth %d screen", s->depth); + exit(1); + } + s->vis = DefaultVisual(dpy, i); + } + if(DefaultDepth(dpy, i) != s->depth) { + s->def_cmap = XCreateColormap(dpy, s->root, s->vis, AllocNone); + } + ds = DisplayString(dpy); colon = rindex(ds, ':'); if (colon && num_screens > 1) { @@ -254,36 +299,36 @@ initscreen(ScreenInfo *s, int i, int background) gv.function = GXxor; gv.line_width = 0; gv.subwindow_mode = IncludeInferiors; - mask = GCForeground | GCBackground | GCFunction | GCLineWidth + gmask = GCForeground | GCBackground | GCFunction | GCLineWidth | GCSubwindowMode; if (font != 0) { gv.font = font->fid; - mask |= GCFont; + gmask |= GCFont; } - s->gc = XCreateGC(dpy, s->root, mask, &gv); + s->gc = XCreateGC(dpy, s->root, gmask, &gv); gv.function = GXcopy; - s->gccopy = XCreateGC(dpy, s->root, mask, &gv); + s->gccopy = XCreateGC(dpy, s->root, gmask, &gv); gv.foreground = s->red; - s->gcred = XCreateGC(dpy, s->root, mask, &gv); + s->gcred = XCreateGC(dpy, s->root, gmask, &gv); gv.foreground = colorpixel(dpy, s->depth, 0xEEEEEE, s->black); - s->gcsweep = XCreateGC(dpy, s->root, mask, &gv); + s->gcsweep = XCreateGC(dpy, s->root, gmask, &gv); gv.foreground = colorpixel(dpy, s->depth, 0xE9FFE9, s->white); - s->gcmenubg = XCreateGC(dpy, s->root, mask, &gv); + s->gcmenubg = XCreateGC(dpy, s->root, gmask, &gv); gv.foreground = colorpixel(dpy, s->depth, 0x448844, s->black); - s->gcmenubgs = XCreateGC(dpy, s->root, mask, &gv); + s->gcmenubgs = XCreateGC(dpy, s->root, gmask, &gv); gv.foreground = s->black; gv.background = colorpixel(dpy, s->depth, 0xE9FFE9, s->white); - s->gcmenufg = XCreateGC(dpy, s->root, mask, &gv); + s->gcmenufg = XCreateGC(dpy, s->root, gmask, &gv); 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); + s->gcmenufgs = XCreateGC(dpy, s->root, gmask, &gv); initcurs(s); @@ -300,21 +345,31 @@ 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, 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, + + attrs.border_pixel = colorpixel(dpy, s->depth, 0x88CC88, s->black); + attrs.background_pixel = colorpixel(dpy, s->depth, 0xE9FFE9, s->white); + attrs.save_under = True; /* Does this help us in anyway? */ + attrs.colormap = s->def_cmap; + + s->menuwin = XCreateWindow(dpy, s->root, 0, 0, 1, 1, 2, + s->depth, CopyFromParent, + s->vis, + CWBackPixel | CWBorderPixel | CWSaveUnder|CWColormap, + &attrs + ); + + attrs.border_pixel = s->red; + attrs.background_pixel = colorpixel(dpy, s->depth, 0xEEEEEE, s->black); + attrs.save_under = True; /* Does this help us in anyway? */ + attrs.colormap = s->def_cmap; + s->sweepwin = XCreateWindow(dpy, s->root, 0, 0, 1, 1, 4, + s->depth, CopyFromParent, - CWBackPixel | CWBorderPixel | CWSaveUnder, + s->vis, + CWBackPixel | CWBorderPixel | CWSaveUnder|CWColormap, &attrs ); - } } ScreenInfo* @@ -360,6 +415,8 @@ sendcmessage(Window w, Atom a, long x, int isroot) mask = 0L; if (isroot) mask = SubstructureRedirectMask; /* magic! */ + else + mask = ExposureMask; /* not really correct but so be it */ status = XSendEvent(dpy, w, False, mask, &ev); if (status == 0) fprintf(stderr, "9wm: sendcmessage failed\n"); diff --git a/src/cmd/rio/manage.c b/src/cmd/rio/manage.c index 790286f6..8fc08364 100644 --- a/src/cmd/rio/manage.c +++ b/src/cmd/rio/manage.c @@ -19,6 +19,7 @@ manage(Client *c, int mapped) long msize; XClassHint class; XWMHints *hints; + XSetWindowAttributes attrs; trace("manage", c, 0); XSelectInput(dpy, c->window, ColormapChangeMask | EnterWindowMask | PropertyChangeMask | FocusChangeMask); @@ -118,20 +119,38 @@ manage(Client *c, int mapped) else gravitate(c, 0); - c->parent = XCreateSimpleWindow(dpy, c->screen->root, + attrs.border_pixel = c->screen->black; + attrs.background_pixel = c->screen->white; + attrs.colormap = c->screen->def_cmap; + c->parent = XCreateWindow(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); + c->screen->depth, + CopyFromParent, + c->screen->vis, + CWBackPixel | CWBorderPixel | CWColormap, + &attrs); + 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) { + + /* + * To have something more than only a big white or black border + * XXX should replace this by a pattern in the white or black + * such that we can see the border also if all our + * windows are black and/or white + * (black (or white) border around black (or white) window + * is not very helpful. + */ + if (c->screen->depth <= 8) { XSetWindowBorderWidth(dpy, c->parent, 1); } + XReparentWindow(dpy, c->window, c->parent, BORDER, BORDER); #ifdef SHAPE if (shape) { @@ -159,6 +178,16 @@ manage(Client *c, int mapped) if (current && (current != c)) cmapfocus(current); c->init = 1; + + /* + * If we swept the window, let's send a resize event to the + * guy who just got resized. It's not clear whether the apps + * should notice their new size via other means. Try as I might, + * I can't find a way to have them notice during initdraw, so + * I solve the problem this way instead. -rsc + */ + if(c->is9term) + sendconfig(c); return 1; } @@ -488,6 +517,8 @@ getproto(Client *c) c->proto |= Pdelete; else if (p[i] == wm_take_focus) c->proto |= Ptakefocus; + else if (p[i] == wm_lose_focus) + c->proto |= Plosefocus; XFree((char *) p); } -- cgit v1.2.3