dwm.c
changeset 1152 960659820908
parent 1151 8b2bff54fd0f
child 1154 88e144ce6527
equal deleted inserted replaced
1151:8b2bff54fd0f 1152:960659820908
    67 	char name[256];
    67 	char name[256];
    68 	int x, y, w, h;
    68 	int x, y, w, h;
    69 	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
    69 	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
    70 	int minax, maxax, minay, maxay;
    70 	int minax, maxax, minay, maxay;
    71 	long flags;
    71 	long flags;
    72 	unsigned int border, oldborder;
    72 	unsigned int bw, oldbw;
    73 	Bool isbanned, isfixed, isfloating, isurgent;
    73 	Bool isbanned, isfixed, isfloating, isurgent;
    74 	Bool *tags;
    74 	Bool *tags;
    75 	Client *next;
    75 	Client *next;
    76 	Client *prev;
    76 	Client *prev;
    77 	Client *snext;
    77 	Client *snext;
   411 	ce.window = c->win;
   411 	ce.window = c->win;
   412 	ce.x = c->x;
   412 	ce.x = c->x;
   413 	ce.y = c->y;
   413 	ce.y = c->y;
   414 	ce.width = c->w;
   414 	ce.width = c->w;
   415 	ce.height = c->h;
   415 	ce.height = c->h;
   416 	ce.border_width = c->border;
   416 	ce.border_width = c->bw;
   417 	ce.above = None;
   417 	ce.above = None;
   418 	ce.override_redirect = False;
   418 	ce.override_redirect = False;
   419 	XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce);
   419 	XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce);
   420 }
   420 }
   421 
   421 
   433 	XConfigureRequestEvent *ev = &e->xconfigurerequest;
   433 	XConfigureRequestEvent *ev = &e->xconfigurerequest;
   434 	XWindowChanges wc;
   434 	XWindowChanges wc;
   435 
   435 
   436 	if((c = getclient(ev->window))) {
   436 	if((c = getclient(ev->window))) {
   437 		if(ev->value_mask & CWBorderWidth)
   437 		if(ev->value_mask & CWBorderWidth)
   438 			c->border = ev->border_width;
   438 			c->bw = ev->border_width;
   439 		if(c->isfixed || c->isfloating || lt->isfloating) {
   439 		if(c->isfixed || c->isfloating || lt->isfloating) {
   440 			if(ev->value_mask & CWX)
   440 			if(ev->value_mask & CWX)
   441 				c->x = sx + ev->x;
   441 				c->x = sx + ev->x;
   442 			if(ev->value_mask & CWY)
   442 			if(ev->value_mask & CWY)
   443 				c->y = sy + ev->y;
   443 				c->y = sy + ev->y;
   998 	/* geometry */
   998 	/* geometry */
   999 	c->x = wa->x;
   999 	c->x = wa->x;
  1000 	c->y = wa->y;
  1000 	c->y = wa->y;
  1001 	c->w = wa->width;
  1001 	c->w = wa->width;
  1002 	c->h = wa->height;
  1002 	c->h = wa->height;
  1003 	c->oldborder = wa->border_width;
  1003 	c->oldbw = wa->border_width;
  1004 	if(c->w == sw && c->h == sh) {
  1004 	if(c->w == sw && c->h == sh) {
  1005 		c->x = sx;
  1005 		c->x = sx;
  1006 		c->y = sy;
  1006 		c->y = sy;
  1007 		c->border = wa->border_width;
  1007 		c->bw = wa->border_width;
  1008 	}
  1008 	}
  1009 	else {
  1009 	else {
  1010 		if(c->x + c->w + 2 * c->border > wx + ww)
  1010 		if(c->x + c->w + 2 * c->bw > wx + ww)
  1011 			c->x = wx + ww - c->w - 2 * c->border;
  1011 			c->x = wx + ww - c->w - 2 * c->bw;
  1012 		if(c->y + c->h + 2 * c->border > wy + wh)
  1012 		if(c->y + c->h + 2 * c->bw > wy + wh)
  1013 			c->y = wy + wh - c->h - 2 * c->border;
  1013 			c->y = wy + wh - c->h - 2 * c->bw;
  1014 		if(c->x < wx)
  1014 		if(c->x < wx)
  1015 			c->x = wx;
  1015 			c->x = wx;
  1016 		if(c->y < wy)
  1016 		if(c->y < wy)
  1017 			c->y = wy;
  1017 			c->y = wy;
  1018 		c->border = BORDERPX;
  1018 		c->bw = BORDERPX;
  1019 	}
  1019 	}
  1020 
  1020 
  1021 	wc.border_width = c->border;
  1021 	wc.border_width = c->bw;
  1022 	XConfigureWindow(dpy, w, CWBorderWidth, &wc);
  1022 	XConfigureWindow(dpy, w, CWBorderWidth, &wc);
  1023 	XSetWindowBorder(dpy, w, dc.norm[ColBorder]);
  1023 	XSetWindowBorder(dpy, w, dc.norm[ColBorder]);
  1024 	configure(c); /* propagates border_width, if size doesn't change */
  1024 	configure(c); /* propagates border_width, if size doesn't change */
  1025 	updatesizehints(c);
  1025 	updatesizehints(c);
  1026 	XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
  1026 	XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
  1069 monocle(void) {
  1069 monocle(void) {
  1070 	Client *c;
  1070 	Client *c;
  1071 
  1071 
  1072 	for(c = clients; c; c = c->next)
  1072 	for(c = clients; c; c = c->next)
  1073 		if(isvisible(c))
  1073 		if(isvisible(c))
  1074 			resize(c, mox, moy, mow, moh, RESIZEHINTS);
  1074 			resize(c, mox, moy, mow - 2 * c->bw, moh - 2 * c->bw, RESIZEHINTS);
  1075 }
  1075 }
  1076 
  1076 
  1077 void
  1077 void
  1078 movemouse(Client *c) {
  1078 movemouse(Client *c) {
  1079 	int x1, y1, ocx, ocy, di, nx, ny;
  1079 	int x1, y1, ocx, ocy, di, nx, ny;
  1102 			XSync(dpy, False);
  1102 			XSync(dpy, False);
  1103 			nx = ocx + (ev.xmotion.x - x1);
  1103 			nx = ocx + (ev.xmotion.x - x1);
  1104 			ny = ocy + (ev.xmotion.y - y1);
  1104 			ny = ocy + (ev.xmotion.y - y1);
  1105 			if(abs(wx - nx) < SNAP)
  1105 			if(abs(wx - nx) < SNAP)
  1106 				nx = wx;
  1106 				nx = wx;
  1107 			else if(abs((wx + ww) - (nx + c->w + 2 * c->border)) < SNAP)
  1107 			else if(abs((wx + ww) - (nx + c->w + 2 * c->bw)) < SNAP)
  1108 				nx = wx + ww - c->w - 2 * c->border;
  1108 				nx = wx + ww - c->w - 2 * c->bw;
  1109 			if(abs(wy - ny) < SNAP)
  1109 			if(abs(wy - ny) < SNAP)
  1110 				ny = wy;
  1110 				ny = wy;
  1111 			else if(abs((wy + wh) - (ny + c->h + 2 * c->border)) < SNAP)
  1111 			else if(abs((wy + wh) - (ny + c->h + 2 * c->bw)) < SNAP)
  1112 				ny = wy + wh - c->h - 2 * c->border;
  1112 				ny = wy + wh - c->h - 2 * c->bw;
  1113 			if(!c->isfloating && !lt->isfloating && (abs(nx - c->x) > SNAP || abs(ny - c->y) > SNAP))
  1113 			if(!c->isfloating && !lt->isfloating && (abs(nx - c->x) > SNAP || abs(ny - c->y) > SNAP))
  1114 				togglefloating(NULL);
  1114 				togglefloating(NULL);
  1115 			if((lt->isfloating) || c->isfloating)
  1115 			if((lt->isfloating) || c->isfloating)
  1116 				resize(c, nx, ny, c->w, c->h, False);
  1116 				resize(c, nx, ny, c->w, c->h, False);
  1117 			break;
  1117 			break;
  1217 			h = c->maxh;
  1217 			h = c->maxh;
  1218 	}
  1218 	}
  1219 	if(w <= 0 || h <= 0)
  1219 	if(w <= 0 || h <= 0)
  1220 		return;
  1220 		return;
  1221 	if(x > sx + sw)
  1221 	if(x > sx + sw)
  1222 		x = sw - w - 2 * c->border;
  1222 		x = sw - w - 2 * c->bw;
  1223 	if(y > sy + sh)
  1223 	if(y > sy + sh)
  1224 		y = sh - h - 2 * c->border;
  1224 		y = sh - h - 2 * c->bw;
  1225 	if(x + w + 2 * c->border < sx)
  1225 	if(x + w + 2 * c->bw < sx)
  1226 		x = sx;
  1226 		x = sx;
  1227 	if(y + h + 2 * c->border < sy)
  1227 	if(y + h + 2 * c->bw < sy)
  1228 		y = sy;
  1228 		y = sy;
  1229 	if(c->x != x || c->y != y || c->w != w || c->h != h) {
  1229 	if(c->x != x || c->y != y || c->w != w || c->h != h) {
  1230 		c->x = wc.x = x;
  1230 		c->x = wc.x = x;
  1231 		c->y = wc.y = y;
  1231 		c->y = wc.y = y;
  1232 		c->w = wc.width = w;
  1232 		c->w = wc.width = w;
  1233 		c->h = wc.height = h;
  1233 		c->h = wc.height = h;
  1234 		wc.border_width = c->border;
  1234 		wc.border_width = c->bw;
  1235 		XConfigureWindow(dpy, c->win,
  1235 		XConfigureWindow(dpy, c->win,
  1236 				CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
  1236 				CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
  1237 		configure(c);
  1237 		configure(c);
  1238 		XSync(dpy, False);
  1238 		XSync(dpy, False);
  1239 	}
  1239 	}
  1248 	ocx = c->x;
  1248 	ocx = c->x;
  1249 	ocy = c->y;
  1249 	ocy = c->y;
  1250 	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
  1250 	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
  1251 			None, cursor[CurResize], CurrentTime) != GrabSuccess)
  1251 			None, cursor[CurResize], CurrentTime) != GrabSuccess)
  1252 		return;
  1252 		return;
  1253 	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->border - 1, c->h + c->border - 1);
  1253 	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
  1254 	for(;;) {
  1254 	for(;;) {
  1255 		XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask , &ev);
  1255 		XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask , &ev);
  1256 		switch(ev.type) {
  1256 		switch(ev.type) {
  1257 		case ButtonRelease:
  1257 		case ButtonRelease:
  1258 			XWarpPointer(dpy, None, c->win, 0, 0, 0, 0,
  1258 			XWarpPointer(dpy, None, c->win, 0, 0, 0, 0,
  1259 					c->w + c->border - 1, c->h + c->border - 1);
  1259 					c->w + c->bw - 1, c->h + c->bw - 1);
  1260 			XUngrabPointer(dpy, CurrentTime);
  1260 			XUngrabPointer(dpy, CurrentTime);
  1261 			while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
  1261 			while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
  1262 			return;
  1262 			return;
  1263 		case ConfigureRequest:
  1263 		case ConfigureRequest:
  1264 		case Expose:
  1264 		case Expose:
  1265 		case MapRequest:
  1265 		case MapRequest:
  1266 			handler[ev.type](&ev);
  1266 			handler[ev.type](&ev);
  1267 			break;
  1267 			break;
  1268 		case MotionNotify:
  1268 		case MotionNotify:
  1269 			XSync(dpy, False);
  1269 			XSync(dpy, False);
  1270 			if((nw = ev.xmotion.x - ocx - 2 * c->border + 1) <= 0)
  1270 			if((nw = ev.xmotion.x - ocx - 2 * c->bw + 1) <= 0)
  1271 				nw = 1;
  1271 				nw = 1;
  1272 			if((nh = ev.xmotion.y - ocy - 2 * c->border + 1) <= 0)
  1272 			if((nh = ev.xmotion.y - ocy - 2 * c->bw + 1) <= 0)
  1273 				nh = 1;
  1273 				nh = 1;
  1274 			if(!c->isfloating && !lt->isfloating && (abs(nw - c->w) > SNAP || abs(nh - c->h) > SNAP))
  1274 			if(!c->isfloating && !lt->isfloating && (abs(nw - c->w) > SNAP || abs(nh - c->h) > SNAP))
  1275 				togglefloating(NULL);
  1275 				togglefloating(NULL);
  1276 			if((lt->isfloating) || c->isfloating)
  1276 			if((lt->isfloating) || c->isfloating)
  1277 				resize(c, c->x, c->y, nw, nh, True);
  1277 				resize(c, c->x, c->y, nw, nh, True);
  1606 	if(w < bh)
  1606 	if(w < bh)
  1607 		w = tw;
  1607 		w = tw;
  1608 
  1608 
  1609 	for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) {
  1609 	for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) {
  1610 		if(i + 1 == n) /* remainder */
  1610 		if(i + 1 == n) /* remainder */
  1611 			tileresize(c, x, ty, (tx + tw) - x - 2 * c->border, th - 2 * c->border);
  1611 			tileresize(c, x, ty, (tx + tw) - x - 2 * c->bw, th - 2 * c->bw);
  1612 		else
  1612 		else
  1613 			tileresize(c, x, ty, w - 2 * c->border, th - 2 * c->border);
  1613 			tileresize(c, x, ty, w - 2 * c->bw, th - 2 * c->bw);
  1614 		if(w != tw)
  1614 		if(w != tw)
  1615 			x = c->x + c->w + 2 * c->border;
  1615 			x = c->x + c->w + 2 * c->bw;
  1616 	}
  1616 	}
  1617 }
  1617 }
  1618 
  1618 
  1619 Client *
  1619 Client *
  1620 tilemaster(unsigned int n) {
  1620 tilemaster(unsigned int n) {
  1621 	Client *c = nexttiled(clients);
  1621 	Client *c = nexttiled(clients);
  1622 
  1622 
  1623 	if(n == 1)
  1623 	if(n == 1)
  1624 		tileresize(c, mox, moy, mow - 2 * c->border, moh - 2 * c->border);
  1624 		tileresize(c, mox, moy, mow - 2 * c->bw, moh - 2 * c->bw);
  1625 	else
  1625 	else
  1626 		tileresize(c, mx, my, mw - 2 * c->border, mh - 2 * c->border);
  1626 		tileresize(c, mx, my, mw - 2 * c->bw, mh - 2 * c->bw);
  1627 	return c;
  1627 	return c;
  1628 }
  1628 }
  1629 
  1629 
  1630 void
  1630 void
  1631 tileresize(Client *c, int x, int y, int w, int h) {
  1631 tileresize(Client *c, int x, int y, int w, int h) {
  1652 	if(h < bh)
  1652 	if(h < bh)
  1653 		h = th;
  1653 		h = th;
  1654 
  1654 
  1655 	for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) {
  1655 	for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) {
  1656 		if(i + 1 == n) /* remainder */
  1656 		if(i + 1 == n) /* remainder */
  1657 			tileresize(c, tx, y, tw - 2 * c->border, (ty + th) - y - 2 * c->border);
  1657 			tileresize(c, tx, y, tw - 2 * c->bw, (ty + th) - y - 2 * c->bw);
  1658 		else
  1658 		else
  1659 			tileresize(c, tx, y, tw - 2 * c->border, h - 2 * c->border);
  1659 			tileresize(c, tx, y, tw - 2 * c->bw, h - 2 * c->bw);
  1660 		if(h != th)
  1660 		if(h != th)
  1661 			y = c->y + c->h + 2 * c->border;
  1661 			y = c->y + c->h + 2 * c->bw;
  1662 	}
  1662 	}
  1663 }
  1663 }
  1664 
  1664 
  1665 void
  1665 void
  1666 togglefloating(const char *arg) {
  1666 togglefloating(const char *arg) {
  1708 
  1708 
  1709 void
  1709 void
  1710 unmanage(Client *c) {
  1710 unmanage(Client *c) {
  1711 	XWindowChanges wc;
  1711 	XWindowChanges wc;
  1712 
  1712 
  1713 	wc.border_width = c->oldborder;
  1713 	wc.border_width = c->oldbw;
  1714 	/* The server grab construct avoids race conditions. */
  1714 	/* The server grab construct avoids race conditions. */
  1715 	XGrabServer(dpy);
  1715 	XGrabServer(dpy);
  1716 	XSetErrorHandler(xerrordummy);
  1716 	XSetErrorHandler(xerrordummy);
  1717 	XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
  1717 	XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
  1718 	detach(c);
  1718 	detach(c);