Border resizing and 9term greying.

This commit is contained in:
rsc 2004-03-30 05:01:53 +00:00
parent 1cb3fa8093
commit c005568a7f
9 changed files with 321 additions and 102 deletions

View file

@ -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: 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. - The command-line options should be made more like Plan 9.
- Should work out a protocol between 9term and rio so that: - Should work out a protocol between 9term and rio so that:
* 9term can tell rio to blue its border during hold mode * 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 - Should change window focus on b2/b3 clicks and then
pass along the click event to the now-focused window. 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 - Should change 9term to redirect b3 clicks to rio so that rio
can put up the usual b3 menu. can put up the usual b3 menu.
Axel Belinfante contributed the code to handle border grabbing
for resize.
The original README is below. The original README is below.
- russ cox - russ cox
rsc@swtch.com rsc@swtch.com
20 march 2004 30 march 2004
9wm Version 1.2 9wm Version 1.2

View file

@ -25,10 +25,12 @@ setactive(Client *c, int on)
if (c->proto & Ptakefocus) if (c->proto & Ptakefocus)
sendcmessage(c->window, wm_protocols, wm_take_focus, 0); sendcmessage(c->window, wm_protocols, wm_take_focus, 0);
cmapfocus(c); cmapfocus(c);
} } else {
else if (c->proto & Plosefocus)
sendcmessage(c->window, wm_protocols, wm_lose_focus, 0);
XGrabButton(dpy, AnyButton, AnyModifier, c->parent, False, XGrabButton(dpy, AnyButton, AnyModifier, c->parent, False,
ButtonMask, GrabModeAsync, GrabModeSync, None, None); ButtonMask, GrabModeAsync, GrabModeSync, None, None);
}
draw_border(c, on); draw_border(c, on);
} }
@ -49,7 +51,7 @@ draw_border(Client *c, int active)
pixel = c->screen->inactiveborder; 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); XSetWindowBackground(dpy, c->parent, pixel);
XClearWindow(dpy, c->parent); XClearWindow(dpy, c->parent);
} }
@ -104,10 +106,11 @@ nofocus(void)
} }
current = 0; current = 0;
if (w == 0) { if (w == 0) {
mask = CWOverrideRedirect; mask = CWOverrideRedirect/*|CWColormap*/;
attr.override_redirect = 1; attr.override_redirect = 1;
/* attr.colormap = screens[0].def_cmap;*/
w = XCreateWindow(dpy, screens[0].root, 0, 0, 1, 1, 0, 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); XMapWindow(dpy, w);
} }
XSetInputFocus(dpy, w, RevertToPointerRoot, timestamp()); XSetInputFocus(dpy, w, RevertToPointerRoot, timestamp());

View file

@ -197,16 +197,20 @@ ScreenInfo *s;
s->root_pixmap = XCreatePixmapFromBitmapData(dpy, s->root_pixmap = XCreatePixmapFromBitmapData(dpy,
s->root, grey_bits, grey_width, grey_height, 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[BorderN] = XCreateFontCursor(dpy, 138);
s->bordcurs[BorderS] = XCreateFontCursor(dpy, 16); s->bordcurs[BorderNNE] = XCreateFontCursor(dpy, 136);
s->bordcurs[BorderW] = XCreateFontCursor(dpy, 70); s->bordcurs[BorderENE] = s->bordcurs[BorderNNE] ;
s->bordcurs[BorderE] = XCreateFontCursor(dpy, 96); s->bordcurs[BorderE] = XCreateFontCursor(dpy, 96);
s->bordcurs[BorderNW] = XCreateFontCursor(dpy, 134); s->bordcurs[BorderESE] = XCreateFontCursor(dpy, 14);
s->bordcurs[BorderSW] = XCreateFontCursor(dpy, 12); s->bordcurs[BorderSSE] = s->bordcurs[BorderESE];
s->bordcurs[BorderNE] = XCreateFontCursor(dpy, 136); s->bordcurs[BorderS] = XCreateFontCursor(dpy, 16);
s->bordcurs[BorderSE] = XCreateFontCursor(dpy, 14); s->bordcurs[BorderSSW] = XCreateFontCursor(dpy, 12);
s->bordcurs[BorderWSW] = s->bordcurs[BorderSSW];
s->bordcurs[BorderW] = XCreateFontCursor(dpy, 70);
s->bordcurs[BorderWNW] = XCreateFontCursor(dpy, 134);
s->bordcurs[BorderNNW] = s->bordcurs[BorderWNW];
} }

View file

@ -21,7 +21,7 @@
typedef struct Client Client; typedef struct Client Client;
typedef struct Menu Menu; typedef struct Menu Menu;
typedef struct ScreenInfo ScreenInfo; typedef struct ScreenInfo ScreenInfo;
typedef enum BorderLocation BorderLocation; typedef enum BorderOrient BorderOrient;
struct Client { struct Client {
Window window; Window window;
@ -67,6 +67,7 @@ struct Client {
/* c->proto */ /* c->proto */
#define Pdelete 1 #define Pdelete 1
#define Ptakefocus 2 #define Ptakefocus 2
#define Plosefocus 4
struct Menu { struct Menu {
char **item; char **item;
@ -74,22 +75,27 @@ struct Menu {
int lasthit; int lasthit;
}; };
enum BorderLocation { enum BorderOrient {
BorderUnknown = 0, /* we depend on this!*/
BorderN, BorderN,
BorderNE, BorderNNE,
BorderENE,
BorderE, BorderE,
BorderSE, BorderESE,
BorderSSE,
BorderS, BorderS,
BorderSW, BorderSSW,
BorderWSW,
BorderW, BorderW,
BorderNW, BorderWNW,
BorderUnknown, BorderNNW,
NBorder, NBorder,
}; };
struct ScreenInfo { struct ScreenInfo {
int num; int num;
int depth; int depth;
Visual *vis;
int width; int width;
int height; int height;
Window root; Window root;
@ -149,6 +155,7 @@ extern Atom _9wm_hold_mode;
extern Atom wm_protocols; extern Atom wm_protocols;
extern Atom wm_delete; extern Atom wm_delete;
extern Atom wm_take_focus; extern Atom wm_take_focus;
extern Atom wm_lose_focus;
extern Atom wm_colormaps; extern Atom wm_colormaps;
/* client.c */ /* client.c */

View file

@ -460,6 +460,7 @@ leave(XCrossingEvent *e)
Client *c; Client *c;
c = getclient(e->window, 0); c = getclient(e->window, 0);
if (c)
XUndefineCursor(dpy, c->parent); XUndefineCursor(dpy, c->parent);
/* XDefineCursor(dpy, c->parent, c->screen->arrow); */ /* XDefineCursor(dpy, c->parent, c->screen->arrow); */
} }
@ -481,17 +482,17 @@ focusin(XFocusChangeEvent *e)
} }
} }
BorderLocation BorderOrient
borderlocation(Client *c, int x, int y) borderorient(Client *c, int x, int y)
{ {
if (x <= BORDER) { if (x <= BORDER) {
if (y <= CORNER) { if (y <= CORNER) {
if (debug) fprintf(stderr, "topleft\n"); if (debug) fprintf(stderr, "topleft\n");
return BorderNW; return BorderWNW;
} }
if (y >= (c->dy + 2*BORDER) - CORNER) { if (y >= (c->dy + 2*BORDER) - CORNER) {
if (debug) fprintf(stderr, "botleft\n"); if (debug) fprintf(stderr, "botleft\n");
return BorderSW; return BorderWSW;
} }
if (y > CORNER && if (y > CORNER &&
y < (c->dy + 2*BORDER) - CORNER) { y < (c->dy + 2*BORDER) - CORNER) {
@ -501,20 +502,20 @@ borderlocation(Client *c, int x, int y)
} else if (x <= CORNER) { } else if (x <= CORNER) {
if (y <= BORDER) { if (y <= BORDER) {
if (debug) fprintf(stderr, "topleft\n"); if (debug) fprintf(stderr, "topleft\n");
return BorderNW; return BorderNNW;
} }
if (y >= (c->dy + BORDER)) { if (y >= (c->dy + BORDER)) {
if (debug) fprintf(stderr, "botleft\n"); if (debug) fprintf(stderr, "botleft\n");
return BorderSW; return BorderSSW;
} }
} else if (x >= (c->dx + BORDER)) { } else if (x >= (c->dx + BORDER)) {
if (y <= CORNER) { if (y <= CORNER) {
if (debug) fprintf(stderr, "topright\n"); if (debug) fprintf(stderr, "topright\n");
return BorderNE; return BorderENE;
} }
if (y >= (c->dy + 2*BORDER) - CORNER) { if (y >= (c->dy + 2*BORDER) - CORNER) {
if (debug) fprintf(stderr, "botright\n"); if (debug) fprintf(stderr, "botright\n");
return BorderSE; return BorderESE;
} }
if (y > CORNER && if (y > CORNER &&
y < (c->dy + 2*BORDER) - 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) { } else if (x >= (c->dx + 2*BORDER) - CORNER) {
if (y <= BORDER) { if (y <= BORDER) {
if (debug) fprintf(stderr, "topright\n"); if (debug) fprintf(stderr, "topright\n");
return BorderNE; return BorderNNE;
} }
if (y >= (c->dy + BORDER)) { if (y >= (c->dy + BORDER)) {
if (debug) fprintf(stderr, "botright\n"); if (debug) fprintf(stderr, "botright\n");
return BorderSE; return BorderSSE;
} }
} else if (x > CORNER && } else if (x > CORNER &&
x < (c->dx + 2*BORDER) - CORNER) { x < (c->dx + 2*BORDER) - CORNER) {
@ -548,11 +549,11 @@ void
motionnotify(XMotionEvent *e) motionnotify(XMotionEvent *e)
{ {
Client *c; Client *c;
BorderLocation bl; BorderOrient bl;
c = getclient(e->window, 0); c = getclient(e->window, 0);
if (c) { if (c) {
bl = borderlocation(c, e->x, e->y); bl = borderorient(c, e->x, e->y);
if (bl == BorderUnknown) if (bl == BorderUnknown)
XUndefineCursor(dpy, c->parent); XUndefineCursor(dpy, c->parent);
else else

View file

@ -40,7 +40,7 @@ void leave();
void focusin(); void focusin();
void reparent(); void reparent();
void motionnotify(); void motionnotify();
BorderLocation borderlocation(); BorderOrient borderorient();
/* manage.c */ /* manage.c */
int manage(); int manage();

View file

@ -222,8 +222,8 @@ selectwin(int release, int *shift, ScreenInfo *s)
} }
} }
void int
sweepcalc(Client *c, int x, int y, BorderLocation bl) sweepcalc(Client *c, int x, int y, BorderOrient bl, int ignored)
{ {
int dx, dy, sx, sy; 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->dx = sx*(dx + 2*BORDER);
c->dy = sy*(dy + 2*BORDER); c->dy = sy*(dy + 2*BORDER);
return ignored;
} }
void int
dragcalc(Client *c, int x, int y, BorderLocation bl) dragcalc(Client *c, int x, int y, BorderOrient bl, int ignored)
{ {
c->x += x; c->x += x;
c->y += y; c->y += y;
return ignored;
} }
void int
pullcalc(Client *c, int x, int y, BorderLocation bl) 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) { switch(bl) {
case BorderN: case BorderN:
c->y += y; py = y;
c->dy -= y; dy = (c->y + c->dy) - y;
spy = 1;
yoff = y - c->y;
break; break;
case BorderS: case BorderS:
c->dy += y; dy = y - c->y;
yoff = (c->y + c->dy) - y;
break; break;
case BorderE: case BorderE:
c->dx += x; dx = x - c->x;
xoff = (c->x + c->dx) - x;
break; break;
case BorderW: case BorderW:
c->x += x; px = x;
c->dx -= x; dx = (c->x + c->dx) - x;
spx = 1;
xoff = x - c->x;
break; break;
case BorderNW: case BorderNNW:
c->x += x; case BorderWNW:
c->dx -= x; px = x;
c->y += y; dx = (c->x + c->dx) - x;
c->dy -= y; spx = 1;
py = y;
dy = (c->y + c->dy) - y;
spy = 1;
xoff = x - c->x;
yoff = y - c->y;
break; break;
case BorderNE: case BorderNNE:
c->dx += x; case BorderENE:
c->y += y; dx = x - c->x;
c->dy -= y; py = y;
dy = (c->y + c->dy) - y;
spy = 1;
xoff = (c->x + c->dx) - x;
yoff = y - c->y;
break; break;
case BorderSE: case BorderSSE:
c->dx += x; case BorderESE:
c->dy += y; dx = x - c->x;
dy = y - c->y;
xoff = (c->x + c->dx) - x;
yoff = (c->y + c->dy) - y;
break; break;
case BorderSW: case BorderSSW:
c->x += x; case BorderWSW:
c->dx -= x; px = x;
c->dy += y; dx = (c->x + c->dx) - x;
spx = 1;
dy = y - c->y;
xoff = x - c->x;
yoff = (c->y + c->dy) - y;
break; break;
default: default:
break; 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 static void
@ -331,6 +441,8 @@ drawbound(Client *c, int drawing)
int x, y, dx, dy; int x, y, dx, dy;
ScreenInfo *s; ScreenInfo *s;
if (debug) fprintf(stderr, "drawbound %dx%d +%d+%d\n", c->dx, c->dy, c->x, c->y);
s = c->screen; s = c->screen;
x = c->x; x = c->x;
y = c->y; y = c->y;
@ -393,14 +505,16 @@ misleep(int msec)
} }
int 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; XEvent ev;
int idle; int idle;
int cx, cy, rx, ry; int cx, cy, rx, ry;
int ox, oy, odx, ody; int ox, oy, odx, ody;
XButtonEvent *e; XButtonEvent *e;
int notmoved;
notmoved = 1;
ox = c->x; ox = c->x;
oy = c->y; oy = c->y;
odx = c->dx; odx = c->dx;
@ -409,13 +523,14 @@ sweepdrag(Client *c, int but, XButtonEvent *e0, BorderLocation bl, void (*recalc
c->y -= BORDER; c->y -= BORDER;
c->dx += 2*BORDER; c->dx += 2*BORDER;
c->dy += 2*BORDER; c->dy += 2*BORDER;
if (bl) if (bl || e0 == 0)
getmouse(&cx, &cy, c->screen); getmouse(&cx, &cy, c->screen);
else if (e0)
getmouse(&c->x, &c->y, c->screen);
else else
getmouse(&cx, &cy, c->screen); getmouse(&c->x, &c->y, c->screen);
XGrabServer(dpy); XGrabServer(dpy);
if (bl) {
notmoved = recalc(c, cx, cy, bl, notmoved);
}
drawbound(c, 1); drawbound(c, 1);
idle = 0; idle = 0;
for (;;) { for (;;) {
@ -430,10 +545,10 @@ sweepdrag(Client *c, int but, XButtonEvent *e0, BorderLocation bl, void (*recalc
XGrabServer(dpy); XGrabServer(dpy);
idle = 0; idle = 0;
} }
if(e0) if(e0 || bl)
recalc(c, rx, ry, bl); notmoved = recalc(c, rx, ry, bl, notmoved);
else else
recalc(c, rx-cx, ry-cy, bl); notmoved = recalc(c, rx-cx, ry-cy, bl, notmoved);
cx = rx; cx = rx;
cy = ry; cy = ry;
drawbound(c, 1); drawbound(c, 1);
@ -508,9 +623,11 @@ pull(Client *c, int but, XButtonEvent *e)
{ {
int status; int status;
ScreenInfo *s; 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; s = c->screen;
status = grab(s->root, s->root, ButtonMask, s->bordcurs[bl], 0); status = grab(s->root, s->root, ButtonMask, s->bordcurs[bl], 0);
if (status != GrabSuccess) { if (status != GrabSuccess) {
@ -544,6 +661,7 @@ getmouse(int *x, int *y, ScreenInfo *s)
unsigned int t3; unsigned int t3;
XQueryPointer(dpy, s->root, &dw1, &dw2, x, y, &t1, &t2, &t3); XQueryPointer(dpy, s->root, &dw1, &dw2, x, y, &t1, &t2, &t3);
if (debug) fprintf(stderr, "getmouse: %d %d\n", *x, *y);
} }
void void

View file

@ -46,6 +46,7 @@ Atom wm_change_state;
Atom wm_protocols; Atom wm_protocols;
Atom wm_delete; Atom wm_delete;
Atom wm_take_focus; Atom wm_take_focus;
Atom wm_lose_focus;
Atom wm_colormaps; Atom wm_colormaps;
Atom _9wm_running; Atom _9wm_running;
Atom _9wm_hold_mode; Atom _9wm_hold_mode;
@ -152,11 +153,14 @@ main(int argc, char *argv[])
exit(0); exit(0);
} }
if (0) XSynchronize(dpy, True);
wm_state = XInternAtom(dpy, "WM_STATE", False); wm_state = XInternAtom(dpy, "WM_STATE", False);
wm_change_state = XInternAtom(dpy, "WM_CHANGE_STATE", False); wm_change_state = XInternAtom(dpy, "WM_CHANGE_STATE", False);
wm_protocols = XInternAtom(dpy, "WM_PROTOCOLS", False); wm_protocols = XInternAtom(dpy, "WM_PROTOCOLS", False);
wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False); wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
wm_take_focus = XInternAtom(dpy, "WM_TAKE_FOCUS", 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); wm_colormaps = XInternAtom(dpy, "WM_COLORMAP_WINDOWS", False);
_9wm_running = XInternAtom(dpy, "_9WM_RUNNING", False); _9wm_running = XInternAtom(dpy, "_9WM_RUNNING", False);
_9wm_hold_mode = XInternAtom(dpy, "_9WM_HOLD_MODE", 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; char *ds, *colon, *dot1;
unsigned long mask; unsigned long mask;
unsigned long gmask;
XGCValues gv; XGCValues gv;
XSetWindowAttributes attr; XSetWindowAttributes attr;
XVisualInfo xvi;
XSetWindowAttributes attrs;
s->num = i; s->num = i;
s->root = RootWindow(dpy, 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->min_cmaps = MinCmapsOfScreen(ScreenOfDisplay(dpy, i));
s->depth = DefaultDepth(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); ds = DisplayString(dpy);
colon = rindex(ds, ':'); colon = rindex(ds, ':');
if (colon && num_screens > 1) { if (colon && num_screens > 1) {
@ -254,36 +299,36 @@ initscreen(ScreenInfo *s, int i, int background)
gv.function = GXxor; gv.function = GXxor;
gv.line_width = 0; gv.line_width = 0;
gv.subwindow_mode = IncludeInferiors; gv.subwindow_mode = IncludeInferiors;
mask = GCForeground | GCBackground | GCFunction | GCLineWidth gmask = GCForeground | GCBackground | GCFunction | GCLineWidth
| GCSubwindowMode; | GCSubwindowMode;
if (font != 0) { if (font != 0) {
gv.font = font->fid; 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; gv.function = GXcopy;
s->gccopy = XCreateGC(dpy, s->root, mask, &gv); s->gccopy = XCreateGC(dpy, s->root, gmask, &gv);
gv.foreground = s->red; 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); 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); 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); 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.foreground = s->black;
gv.background = colorpixel(dpy, s->depth, 0xE9FFE9, s->white); 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.foreground = colorpixel(dpy, s->depth, 0xE9FFE9, s->white);
gv.background = colorpixel(dpy, s->depth, 0x448844, s->black); 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); initcurs(s);
@ -300,21 +345,31 @@ initscreen(ScreenInfo *s, int i, int background)
XClearWindow(dpy, s->root); XClearWindow(dpy, s->root);
} else } else
system("xsetroot -solid grey30"); 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)); attrs.border_pixel = colorpixel(dpy, s->depth, 0x88CC88, s->black);
{ attrs.background_pixel = colorpixel(dpy, s->depth, 0xE9FFE9, s->white);
XSetWindowAttributes attrs; attrs.save_under = True; /* Does this help us in anyway? */
attrs.background_pixel = colorpixel(dpy, s->depth, 0xEEEEEE, s->black); attrs.colormap = s->def_cmap;
attrs.border_pixel = s->red;
attrs.save_under = True; s->menuwin = XCreateWindow(dpy, s->root, 0, 0, 1, 1, 2,
s->sweepwin = XCreateWindow(dpy, s->root, 0, 0, 1, 1, 4, s->depth,
CopyFromParent, CopyFromParent,
CopyFromParent, s->vis,
CopyFromParent, CWBackPixel | CWBorderPixel | CWSaveUnder|CWColormap,
CWBackPixel | CWBorderPixel | CWSaveUnder, &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,
s->vis,
CWBackPixel | CWBorderPixel | CWSaveUnder|CWColormap,
&attrs &attrs
); );
}
} }
ScreenInfo* ScreenInfo*
@ -360,6 +415,8 @@ sendcmessage(Window w, Atom a, long x, int isroot)
mask = 0L; mask = 0L;
if (isroot) if (isroot)
mask = SubstructureRedirectMask; /* magic! */ mask = SubstructureRedirectMask; /* magic! */
else
mask = ExposureMask; /* not really correct but so be it */
status = XSendEvent(dpy, w, False, mask, &ev); status = XSendEvent(dpy, w, False, mask, &ev);
if (status == 0) if (status == 0)
fprintf(stderr, "9wm: sendcmessage failed\n"); fprintf(stderr, "9wm: sendcmessage failed\n");

View file

@ -19,6 +19,7 @@ manage(Client *c, int mapped)
long msize; long msize;
XClassHint class; XClassHint class;
XWMHints *hints; XWMHints *hints;
XSetWindowAttributes attrs;
trace("manage", c, 0); trace("manage", c, 0);
XSelectInput(dpy, c->window, ColormapChangeMask | EnterWindowMask | PropertyChangeMask | FocusChangeMask); XSelectInput(dpy, c->window, ColormapChangeMask | EnterWindowMask | PropertyChangeMask | FocusChangeMask);
@ -118,20 +119,38 @@ manage(Client *c, int mapped)
else else
gravitate(c, 0); 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->x - BORDER, c->y - BORDER,
c->dx + 2*BORDER, c->dy + 2*BORDER, c->dx + 2*BORDER, c->dy + 2*BORDER,
0, 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); XSelectInput(dpy, c->parent, SubstructureRedirectMask | SubstructureNotifyMask|ButtonPressMask| PointerMotionMask|LeaveWindowMask);
if (mapped) if (mapped)
c->reparenting = 1; c->reparenting = 1;
if (doreshape && !fixsize) if (doreshape && !fixsize)
XResizeWindow(dpy, c->window, c->dx, c->dy); XResizeWindow(dpy, c->window, c->dx, c->dy);
XSetWindowBorderWidth(dpy, c->window, 0); 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); XSetWindowBorderWidth(dpy, c->parent, 1);
} }
XReparentWindow(dpy, c->window, c->parent, BORDER, BORDER); XReparentWindow(dpy, c->window, c->parent, BORDER, BORDER);
#ifdef SHAPE #ifdef SHAPE
if (shape) { if (shape) {
@ -159,6 +178,16 @@ manage(Client *c, int mapped)
if (current && (current != c)) if (current && (current != c))
cmapfocus(current); cmapfocus(current);
c->init = 1; 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; return 1;
} }
@ -488,6 +517,8 @@ getproto(Client *c)
c->proto |= Pdelete; c->proto |= Pdelete;
else if (p[i] == wm_take_focus) else if (p[i] == wm_take_focus)
c->proto |= Ptakefocus; c->proto |= Ptakefocus;
else if (p[i] == wm_lose_focus)
c->proto |= Plosefocus;
XFree((char *) p); XFree((char *) p);
} }