dwm.c
changeset 1190 c8eaba1445a4
parent 1188 1765468a0546
child 1191 5fabfaafe75e
equal deleted inserted replaced
1189:58366c12324e 1190:c8eaba1445a4
    39 #include <X11/Xlib.h>
    39 #include <X11/Xlib.h>
    40 #include <X11/Xproto.h>
    40 #include <X11/Xproto.h>
    41 #include <X11/Xutil.h>
    41 #include <X11/Xutil.h>
    42 
    42 
    43 /* macros */
    43 /* macros */
    44 #define MAX(a, b) ((a)>(b)?(a):(b))
    44 #define MAX(a, b)	((a) > (b) ? (a) : (b))
    45 #define MIN(a, b) ((a)<(b)?(a):(b))
    45 #define MIN(a, b)	((a) < (b) ? (a) : (b))
    46 #define BUTTONMASK		(ButtonPressMask|ButtonReleaseMask)
    46 #define BUTTONMASK	(ButtonPressMask|ButtonReleaseMask)
    47 #define CLEANMASK(mask)		(mask & ~(numlockmask|LockMask))
    47 #define CLEANMASK(mask)	(mask & ~(numlockmask|LockMask))
    48 #define LENGTH(x)		(sizeof x / sizeof x[0])
    48 #define LENGTH(x)	(sizeof x / sizeof x[0])
    49 #define MAXTAGLEN		16
    49 #define MAXTAGLEN	16
    50 #define MOUSEMASK		(BUTTONMASK|PointerMotionMask)
    50 #define MOUSEMASK	(BUTTONMASK|PointerMotionMask)
    51 #define DEFGEOM(GEONAME,BX,BY,BW,WX,WY,WW,WH,MX,MY,MW,MH,TX,TY,TW,TH,MOX,MOY,MOW,MOH) \
       
    52 void GEONAME(void) { \
       
    53 	bx = (BX); by = (BY); bw = (BW); \
       
    54 	wx = (WX); wy = (WY); ww = (WW); wh = (WH); \
       
    55 	mx = (MX); my = (MY); mw = (MW); mh = (MH); \
       
    56 	tx = (TX); ty = (TY); tw = (TW); th = (TH); \
       
    57 	mox = (MOX); moy = (MOY); mow = (MOW); moh = (MOH); \
       
    58 }
       
    59 
    51 
    60 /* enums */
    52 /* enums */
    61 enum { CurNormal, CurResize, CurMove, CurLast };	/* cursor */
    53 enum { CurNormal, CurResize, CurMove, CurLast };	/* cursor */
    62 enum { ColBorder, ColFG, ColBG, ColLast };		/* color */
    54 enum { ColBorder, ColFG, ColBG, ColLast };		/* color */
    63 enum { NetSupported, NetWMName, NetLast };		/* EWMH atoms */
    55 enum { NetSupported, NetWMName, NetLast };		/* EWMH atoms */
    93 		int height;
    85 		int height;
    94 		XFontSet set;
    86 		XFontSet set;
    95 		XFontStruct *xfont;
    87 		XFontStruct *xfont;
    96 	} font;
    88 	} font;
    97 } DC; /* draw context */
    89 } DC; /* draw context */
    98 
       
    99 typedef struct {
       
   100 	const char *symbol;
       
   101 	void (*apply)(void);
       
   102 } Geom;
       
   103 
    90 
   104 typedef struct {
    91 typedef struct {
   105 	unsigned long mod;
    92 	unsigned long mod;
   106 	KeySym keysym;
    93 	KeySym keysym;
   107 	void (*func)(const char *arg);
    94 	void (*func)(const char *arg);
   176 void resizemouse(Client *c);
   163 void resizemouse(Client *c);
   177 void restack(void);
   164 void restack(void);
   178 void run(void);
   165 void run(void);
   179 void scan(void);
   166 void scan(void);
   180 void setclientstate(Client *c, long state);
   167 void setclientstate(Client *c, long state);
   181 void setgeom(const char *arg);
       
   182 void setlayout(const char *arg);
   168 void setlayout(const char *arg);
   183 void setmfact(const char *arg);
   169 void setmfact(const char *arg);
   184 void setup(void);
   170 void setup(void);
   185 void spawn(const char *arg);
   171 void spawn(const char *arg);
   186 void tag(const char *arg);
   172 void tag(const char *arg);
   196 void toggletag(const char *arg);
   182 void toggletag(const char *arg);
   197 void toggleview(const char *arg);
   183 void toggleview(const char *arg);
   198 void unban(Client *c);
   184 void unban(Client *c);
   199 void unmanage(Client *c);
   185 void unmanage(Client *c);
   200 void unmapnotify(XEvent *e);
   186 void unmapnotify(XEvent *e);
   201 void updatebarpos(void);
   187 void updatebar(void);
       
   188 void updategeom(void);
   202 void updatesizehints(Client *c);
   189 void updatesizehints(Client *c);
   203 void updatetitle(Client *c);
   190 void updatetitle(Client *c);
   204 void updatewmhints(Client *c);
   191 void updatewmhints(Client *c);
   205 void view(const char *arg);
   192 void view(const char *arg);
   206 void viewprevtag(const char *arg);	/* views previous selected tags */
   193 void viewprevtag(const char *arg);	/* views previous selected tags */
   211 
   198 
   212 /* variables */
   199 /* variables */
   213 char stext[256];
   200 char stext[256];
   214 int screen, sx, sy, sw, sh;
   201 int screen, sx, sy, sw, sh;
   215 int (*xerrorxlib)(Display *, XErrorEvent *);
   202 int (*xerrorxlib)(Display *, XErrorEvent *);
   216 int bx, by, bw, bh, blw, bgw, mx, my, mw, mh, mox, moy, mow, moh, tx, ty, tw, th, wx, wy, ww, wh;
   203 int bx, by, bw, bh, blw, mx, my, mw, mh, tx, ty, tw, th, wx, wy, ww, wh;
   217 int seltags = 0;
   204 int seltags = 0;
   218 double mfact;
   205 double mfact;
   219 unsigned int numlockmask = 0;
   206 unsigned int numlockmask = 0;
   220 void (*handler[LASTEvent]) (XEvent *) = {
   207 void (*handler[LASTEvent]) (XEvent *) = {
   221 	[ButtonPress] = buttonpress,
   208 	[ButtonPress] = buttonpress,
   239 Client *sel = NULL;
   226 Client *sel = NULL;
   240 Client *stack = NULL;
   227 Client *stack = NULL;
   241 Cursor cursor[CurLast];
   228 Cursor cursor[CurLast];
   242 Display *dpy;
   229 Display *dpy;
   243 DC dc = {0};
   230 DC dc = {0};
   244 Geom geoms[];
       
   245 Geom *geom = geoms;
       
   246 Layout layouts[];
   231 Layout layouts[];
   247 Layout *lt = layouts;
   232 Layout *lt = layouts;
   248 Window root, barwin;
   233 Window root, barwin;
   249 
   234 
   250 /* configuration, allows nested code to access above variables */
   235 /* configuration, allows nested code to access above variables */
   328 	unsigned int i, x;
   313 	unsigned int i, x;
   329 	Client *c;
   314 	Client *c;
   330 	XButtonPressedEvent *ev = &e->xbutton;
   315 	XButtonPressedEvent *ev = &e->xbutton;
   331 
   316 
   332 	if(ev->window == barwin) {
   317 	if(ev->window == barwin) {
   333 		if((ev->x < bgw) && ev->button == Button1) {
   318 		x = 0;
   334 			setgeom(NULL);
       
   335 			return;
       
   336 		}
       
   337 		x = bgw;
       
   338 		for(i = 0; i < LENGTH(tags); i++) {
   319 		for(i = 0; i < LENGTH(tags); i++) {
   339 			x += textw(tags[i]);
   320 			x += textw(tags[i]);
   340 			if(ev->x >= bgw && ev->x < x) {
   321 			if(ev->x < x) {
   341 				if(ev->button == Button1) {
   322 				if(ev->button == Button1) {
   342 					if(ev->state & MODKEY)
   323 					if(ev->state & MODKEY)
   343 						tag(tags[i]);
   324 						tag(tags[i]);
   344 					else
   325 					else
   345 						view(tags[i]);
   326 						view(tags[i]);
   438 	XConfigureEvent *ev = &e->xconfigure;
   419 	XConfigureEvent *ev = &e->xconfigure;
   439 
   420 
   440 	if(ev->window == root && (ev->width != sw || ev->height != sh)) {
   421 	if(ev->window == root && (ev->width != sw || ev->height != sh)) {
   441 		sw = ev->width;
   422 		sw = ev->width;
   442 		sh = ev->height;
   423 		sh = ev->height;
   443 		setgeom(geom->symbol);
   424 		updategeom();
       
   425 		updatebar();
       
   426 		arrange();
   444 	}
   427 	}
   445 }
   428 }
   446 
   429 
   447 void
   430 void
   448 configurerequest(XEvent *e) {
   431 configurerequest(XEvent *e) {
   529 drawbar(void) {
   512 drawbar(void) {
   530 	int i, x;
   513 	int i, x;
   531 	Client *c;
   514 	Client *c;
   532 
   515 
   533 	dc.x = 0;
   516 	dc.x = 0;
   534 	if(bgw > 0) {
       
   535 		dc.w = bgw;
       
   536 		drawtext(geom->symbol, dc.norm, False);
       
   537 		dc.x += bgw;
       
   538 	}
       
   539 	for(c = stack; c && !isvisible(c, NULL); c = c->snext);
   517 	for(c = stack; c && !isvisible(c, NULL); c = c->snext);
   540 	for(i = 0; i < LENGTH(tags); i++) {
   518 	for(i = 0; i < LENGTH(tags); i++) {
   541 		dc.w = textw(tags[i]);
   519 		dc.w = textw(tags[i]);
   542 		if(tagset[seltags][i]) {
   520 		if(tagset[seltags][i]) {
   543 			drawtext(tags[i], dc.sel, isurgent(i));
   521 			drawtext(tags[i], dc.sel, isurgent(i));
  1062 monocle(void) {
  1040 monocle(void) {
  1063 	Client *c;
  1041 	Client *c;
  1064 
  1042 
  1065 	for(c = clients; c; c = c->next)
  1043 	for(c = clients; c; c = c->next)
  1066 		if((lt->isfloating || !c->isfloating) &&  isvisible(c, NULL))
  1044 		if((lt->isfloating || !c->isfloating) &&  isvisible(c, NULL))
  1067 			resize(c, mox, moy, mow - 2 * c->bw, moh - 2 * c->bw, RESIZEHINTS);
  1045 			resize(c, wx, wy, ww - 2 * c->bw, wh - 2 * c->bw, RESIZEHINTS);
  1068 }
  1046 }
  1069 
  1047 
  1070 void
  1048 void
  1071 movemouse(Client *c) {
  1049 movemouse(Client *c) {
  1072 	int x1, y1, ocx, ocy, di, nx, ny;
  1050 	int x1, y1, ocx, ocy, di, nx, ny;
  1397 	XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32,
  1375 	XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32,
  1398 			PropModeReplace, (unsigned char *)data, 2);
  1376 			PropModeReplace, (unsigned char *)data, 2);
  1399 }
  1377 }
  1400 
  1378 
  1401 void
  1379 void
  1402 setgeom(const char *arg) {
       
  1403 	unsigned int i;
       
  1404 
       
  1405 	if(!arg) {
       
  1406 		if(++geom == &geoms[LENGTH(geoms)])
       
  1407 			geom = &geoms[0];
       
  1408 	}
       
  1409 	else {
       
  1410 		for(i = 0; i < LENGTH(geoms); i++)
       
  1411 			if(!strcmp(geoms[i].symbol, arg))
       
  1412 				break;
       
  1413 		if(i == LENGTH(geoms))
       
  1414 			return;
       
  1415 		geom = &geoms[i];
       
  1416 	}
       
  1417 	geom->apply();
       
  1418 	updatebarpos();
       
  1419 	arrange();
       
  1420 }
       
  1421 
       
  1422 void
       
  1423 setlayout(const char *arg) {
  1380 setlayout(const char *arg) {
  1424 	unsigned int i;
  1381 	unsigned int i;
  1425 
  1382 
  1426 	if(!arg) {
  1383 	if(!arg) {
  1427 		if(++lt == &layouts[LENGTH(layouts)])
  1384 		if(++lt == &layouts[LENGTH(layouts)])
  1455 			d += mfact;
  1412 			d += mfact;
  1456 		if(d < 0.1 || d > 0.9)
  1413 		if(d < 0.1 || d > 0.9)
  1457 			return;
  1414 			return;
  1458 		mfact = d;
  1415 		mfact = d;
  1459 	}
  1416 	}
  1460 	setgeom(geom->symbol);
  1417 	updategeom();
       
  1418 	arrange();
  1461 }
  1419 }
  1462 
  1420 
  1463 void
  1421 void
  1464 setup(void) {
  1422 setup(void) {
  1465 	unsigned int i, w;
  1423 	unsigned int i, w;
  1467 
  1425 
  1468 	/* init screen */
  1426 	/* init screen */
  1469 	screen = DefaultScreen(dpy);
  1427 	screen = DefaultScreen(dpy);
  1470 	root = RootWindow(dpy, screen);
  1428 	root = RootWindow(dpy, screen);
  1471 	initfont(FONT);
  1429 	initfont(FONT);
  1472 
       
  1473 	/* apply default geometry */
       
  1474 	sx = 0;
  1430 	sx = 0;
  1475 	sy = 0;
  1431 	sy = 0;
  1476 	sw = DisplayWidth(dpy, screen);
  1432 	sw = DisplayWidth(dpy, screen);
  1477 	sh = DisplayHeight(dpy, screen);
  1433 	sh = DisplayHeight(dpy, screen);
  1478 	bh = dc.font.height + 2;
  1434 	bh = dc.font.height + 2;
  1479 	mfact = MFACT;
  1435 
  1480 	geom->apply();
  1436 	/* update geometry */
       
  1437 	updategeom();
  1481 
  1438 
  1482 	/* init atoms */
  1439 	/* init atoms */
  1483 	wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
  1440 	wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
  1484 	wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
  1441 	wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
  1485 	wmatom[WMName] = XInternAtom(dpy, "WM_NAME", False);
  1442 	wmatom[WMName] = XInternAtom(dpy, "WM_NAME", False);
  1515 	/* init bar */
  1472 	/* init bar */
  1516 	for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) {
  1473 	for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) {
  1517 		w = textw(layouts[i].symbol);
  1474 		w = textw(layouts[i].symbol);
  1518 		blw = MAX(blw, w);
  1475 		blw = MAX(blw, w);
  1519 	}
  1476 	}
  1520 	for(bgw = i = 0; LENGTH(geoms) > 1 && i < LENGTH(geoms); i++) {
       
  1521 		w = textw(geoms[i].symbol);
       
  1522 		bgw = MAX(bgw, w);
       
  1523 	}
       
  1524 
  1477 
  1525 	wa.override_redirect = 1;
  1478 	wa.override_redirect = 1;
  1526 	wa.background_pixmap = ParentRelative;
  1479 	wa.background_pixmap = ParentRelative;
  1527 	wa.event_mask = ButtonPressMask|ExposureMask;
  1480 	wa.event_mask = ButtonPressMask|ExposureMask;
  1528 
  1481 
  1631 Client *
  1584 Client *
  1632 tilemaster(unsigned int n) {
  1585 tilemaster(unsigned int n) {
  1633 	Client *c = nexttiled(clients);
  1586 	Client *c = nexttiled(clients);
  1634 
  1587 
  1635 	if(n == 1)
  1588 	if(n == 1)
  1636 		tileresize(c, mox, moy, mow - 2 * c->bw, moh - 2 * c->bw);
  1589 		tileresize(c, wx, wy, ww - 2 * c->bw, wh - 2 * c->bw);
  1637 	else
  1590 	else
  1638 		tileresize(c, mx, my, mw - 2 * c->bw, mh - 2 * c->bw);
  1591 		tileresize(c, mx, my, mw - 2 * c->bw, mh - 2 * c->bw);
  1639 	return c;
  1592 	return c;
  1640 }
  1593 }
  1641 
  1594 
  1749 	if((c = getclient(ev->window)))
  1702 	if((c = getclient(ev->window)))
  1750 		unmanage(c);
  1703 		unmanage(c);
  1751 }
  1704 }
  1752 
  1705 
  1753 void
  1706 void
  1754 updatebarpos(void) {
  1707 updatebar(void) {
  1755 
  1708 
  1756 	if(dc.drawable != 0)
  1709 	if(dc.drawable != 0)
  1757 		XFreePixmap(dpy, dc.drawable);
  1710 		XFreePixmap(dpy, dc.drawable);
  1758 	dc.drawable = XCreatePixmap(dpy, root, bw, bh, DefaultDepth(dpy, screen));
  1711 	dc.drawable = XCreatePixmap(dpy, root, bw, bh, DefaultDepth(dpy, screen));
  1759 	XMoveResizeWindow(dpy, barwin, bx, by, bw, bh);
  1712 	XMoveResizeWindow(dpy, barwin, bx, by, bw, bh);
       
  1713 }
       
  1714 
       
  1715 void
       
  1716 updategeom(void) {
       
  1717 
       
  1718 	/* bar geometry */
       
  1719 	bx = 0;
       
  1720 	by = 0;
       
  1721 	bw = sw;
       
  1722 
       
  1723 	/* window area geometry */
       
  1724 	wx = sx;
       
  1725 	wy = sy;
       
  1726 	ww = sw;
       
  1727 	sh = sh - bh;
       
  1728 
       
  1729 	/* master area geometry */
       
  1730 	mfact = MFACT;
       
  1731 	mx = wx;
       
  1732 	my = wy;
       
  1733 	mw = mfact * ww;
       
  1734 	mh = wh;
       
  1735 
       
  1736 	/* tile area geometry */
       
  1737 	tx = mx + mw;
       
  1738 	ty = wy;
       
  1739 	tw = ww - mw;
       
  1740 	th = wh;
  1760 }
  1741 }
  1761 
  1742 
  1762 void
  1743 void
  1763 updatesizehints(Client *c) {
  1744 updatesizehints(Client *c) {
  1764 	long msize;
  1745 	long msize;
  1910 	cleanup();
  1891 	cleanup();
  1911 
  1892 
  1912 	XCloseDisplay(dpy);
  1893 	XCloseDisplay(dpy);
  1913 	return 0;
  1894 	return 0;
  1914 }
  1895 }
  1915