some more rearrangements 9449ea3e
Anselm R. Garbe · 2007-09-16 12:34 1 file(s) · +143 −147
dwm.c +143 −147
112 112
	regex_t *tagregex;
113 113
} Regs;
114 114
115 -
/* functions */
116 -
115 +
/* forward declarations */
117 116
static void applyrules(Client *c);
118 117
static void arrange(void);
119 118
static void attach(Client *c);
120 119
static void attachstack(Client *c);
121 120
static void ban(Client *c);
122 121
static void buttonpress(XEvent *e);
122 +
static void checkotherwm(void);
123 123
static void cleanup(void);
124 124
static void compileregs(void);
125 125
static void configure(Client *c);
140 140
static void focusnext(const char *arg);
141 141
static void focusprev(const char *arg);
142 142
static Client *getclient(Window w);
143 +
static unsigned long getcolor(const char *colstr);
143 144
static long getstate(Window w);
144 145
static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
145 146
static void grabbuttons(Client *c, Bool focused);
146 147
static unsigned int idxoftag(const char *tag);
147 -
static void initbar(void);
148 -
static unsigned long initcolor(const char *colstr);
149 148
static void initfont(const char *fontstr);
150 -
static void initlayouts(void);
151 -
static void initstyle(void);
152 149
static Bool isarrange(void (*func)());
153 -
static Bool isfloating(void);
154 150
static Bool isoccupied(unsigned int t);
155 151
static Bool isprotodel(Client *c);
156 152
static Bool isvisible(Client *c);
167 163
static void resize(Client *c, int x, int y, int w, int h, Bool sizehints);
168 164
static void resizemouse(Client *c);
169 165
static void restack(void);
166 +
static void run(void);
170 167
static void scan(void);
171 168
static void setclientstate(Client *c, long state);
172 169
static void setlayout(const char *arg);
236 233
/* configuration, allows nested code to access above variables */
237 234
#include "config.h"
238 235
239 -
/* implementation */
236 +
/* functions*/
240 237
static void
241 238
applyrules(Client *c) {
242 239
	static char buf[512];
338 335
		focus(c);
339 336
		if(CLEANMASK(ev->state) != MODKEY)
340 337
			return;
341 -
		if(ev->button == Button1 && (isfloating() || c->isfloating)) {
338 +
		if(ev->button == Button1 && (isarrange(floating) || c->isfloating)) {
342 339
			restack();
343 340
			movemouse(c);
344 341
		}
345 342
		else if(ev->button == Button2)
346 343
			zoom(NULL);
347 344
		else if(ev->button == Button3
348 -
		&& (isfloating() || c->isfloating) && !c->isfixed)
345 +
		&& (isarrange(floating) || c->isfloating) && !c->isfixed)
349 346
		{
350 347
			restack();
351 348
			resizemouse(c);
354 351
}
355 352
356 353
static void
354 +
checkotherwm(void) {
355 +
	otherwm = False;
356 +
	XSetErrorHandler(xerrorstart);
357 +
358 +
	/* this causes an error if some other window manager is running */
359 +
	XSelectInput(dpy, root, SubstructureRedirectMask);
360 +
	XSync(dpy, False);
361 +
	if(otherwm)
362 +
		eprint("dwm: another window manager is already running\n");
363 +
	XSync(dpy, False);
364 +
	XSetErrorHandler(NULL);
365 +
	xerrorxlib = XSetErrorHandler(xerror);
366 +
	XSync(dpy, False);
367 +
}
368 +
369 +
static void
357 370
cleanup(void) {
358 371
	close(STDIN_FILENO);
359 372
	while(stack) {
446 459
		c->ismax = False;
447 460
		if(ev->value_mask & CWBorderWidth)
448 461
			c->border = ev->border_width;
449 -
		if(c->isfixed || c->isfloating || isfloating()) {
462 +
		if(c->isfixed || c->isfloating || isarrange(floating)) {
450 463
			if(ev->value_mask & CWX)
451 464
				c->x = ev->x;
452 465
			if(ev->value_mask & CWY)
728 741
	return c;
729 742
}
730 743
744 +
static unsigned long
745 +
getcolor(const char *colstr) {
746 +
	Colormap cmap = DefaultColormap(dpy, screen);
747 +
	XColor color;
748 +
749 +
	if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color))
750 +
		eprint("error, cannot allocate color '%s'\n", colstr);
751 +
	return color.pixel;
752 +
}
753 +
731 754
static long
732 755
getstate(Window w) {
733 756
	int format, status;
821 844
}
822 845
823 846
static void
824 -
initbar(void) {
825 -
	XSetWindowAttributes wa;
826 -
827 -
	wa.override_redirect = 1;
828 -
	wa.background_pixmap = ParentRelative;
829 -
	wa.event_mask = ButtonPressMask | ExposureMask;
830 -
	barwin = XCreateWindow(dpy, root, sx, sy, sw, bh, 0,
831 -
			DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen),
832 -
			CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
833 -
	XDefineCursor(dpy, barwin, cursor[CurNormal]);
834 -
	updatebarpos();
835 -
	XMapRaised(dpy, barwin);
836 -
	strcpy(stext, "dwm-"VERSION);
837 -
	dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
838 -
	dc.gc = XCreateGC(dpy, root, 0, 0);
839 -
	XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
840 -
	if(!dc.font.set)
841 -
		XSetFont(dpy, dc.gc, dc.font.xfont->fid);
842 -
}
843 -
844 -
static unsigned long
845 -
initcolor(const char *colstr) {
846 -
	Colormap cmap = DefaultColormap(dpy, screen);
847 -
	XColor color;
848 -
849 -
	if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color))
850 -
		eprint("error, cannot allocate color '%s'\n", colstr);
851 -
	return color.pixel;
852 -
}
853 -
854 -
static void
855 847
initfont(const char *fontstr) {
856 848
	char *def, **missing;
857 849
	int i, n;
893 885
	dc.font.height = dc.font.ascent + dc.font.descent;
894 886
}
895 887
896 -
static void
897 -
initlayouts(void) {
898 -
	unsigned int i, w;
899 -
900 -
	nlayouts = sizeof layouts / sizeof layouts[0];
901 -
	for(blw = i = 0; i < nlayouts; i++) {
902 -
		w = textw(layouts[i].symbol);
903 -
		if(w > blw)
904 -
			blw = w;
905 -
	}
906 -
}
907 -
908 -
static void
909 -
initstyle(void) {
910 -
	dc.norm[ColBorder] = initcolor(NORMBORDERCOLOR);
911 -
	dc.norm[ColBG] = initcolor(NORMBGCOLOR);
912 -
	dc.norm[ColFG] = initcolor(NORMFGCOLOR);
913 -
	dc.sel[ColBorder] = initcolor(SELBORDERCOLOR);
914 -
	dc.sel[ColBG] = initcolor(SELBGCOLOR);
915 -
	dc.sel[ColFG] = initcolor(SELFGCOLOR);
916 -
	initfont(FONT);
917 -
	dc.h = bh = dc.font.height + 2;
918 -
}
919 -
920 888
static Bool
921 889
isarrange(void (*func)())
922 890
{
923 891
	return func == layouts[ltidx].arrange;
924 -
}
925 -
926 -
static Bool
927 -
isfloating(void) {
928 -
	return layouts[ltidx].arrange == floating;
929 892
}
930 893
931 894
static Bool
1300 1263
	drawbar();
1301 1264
	if(!sel)
1302 1265
		return;
1303 -
	if(sel->isfloating || isfloating())
1266 +
	if(sel->isfloating || isarrange(floating))
1304 1267
		XRaiseWindow(dpy, sel->win);
1305 -
	if(!isfloating()) {
1268 +
	if(!isarrange(floating)) {
1306 1269
		wc.stack_mode = Below;
1307 1270
		wc.sibling = barwin;
1308 1271
		if(!sel->isfloating) {
1321 1284
}
1322 1285
1323 1286
static void
1287 +
run(void) {
1288 +
	char *p;
1289 +
	int r, xfd;
1290 +
	fd_set rd;
1291 +
	XEvent ev;
1292 +
1293 +
	/* main event loop, also reads status text from stdin */
1294 +
	XSync(dpy, False);
1295 +
	xfd = ConnectionNumber(dpy);
1296 +
	readin = True;
1297 +
	while(running) {
1298 +
		FD_ZERO(&rd);
1299 +
		if(readin)
1300 +
			FD_SET(STDIN_FILENO, &rd);
1301 +
		FD_SET(xfd, &rd);
1302 +
		if(select(xfd + 1, &rd, NULL, NULL, NULL) == -1) {
1303 +
			if(errno == EINTR)
1304 +
				continue;
1305 +
			eprint("select failed\n");
1306 +
		}
1307 +
		if(FD_ISSET(STDIN_FILENO, &rd)) {
1308 +
			switch(r = read(STDIN_FILENO, stext, sizeof stext - 1)) {
1309 +
			case -1:
1310 +
				strncpy(stext, strerror(errno), sizeof stext - 1);
1311 +
				stext[sizeof stext - 1] = '\0';
1312 +
				readin = False;
1313 +
				break;
1314 +
			case 0:
1315 +
				strncpy(stext, "EOF", 4);
1316 +
				readin = False;
1317 +
				break;
1318 +
			default:
1319 +
				for(stext[r] = '\0', p = stext + strlen(stext) - 1; p >= stext && *p == '\n'; *p-- = '\0');
1320 +
				for(; p >= stext && *p != '\n'; --p);
1321 +
				if(p > stext)
1322 +
					strncpy(stext, p + 1, sizeof stext);
1323 +
			}
1324 +
			drawbar();
1325 +
		}
1326 +
		while(XPending(dpy)) {
1327 +
			XNextEvent(dpy, &ev);
1328 +
			if(handler[ev.type])
1329 +
				(handler[ev.type])(&ev); /* call handler */
1330 +
		}
1331 +
	}
1332 +
}
1333 +
1334 +
static void
1324 1335
scan(void) {
1325 1336
	unsigned int i, num;
1326 1337
	Window *wins, d1, d2;
1401 1412
1402 1413
static void
1403 1414
setup(void) {
1404 -
	int i, j;
1405 -
	unsigned int mask;
1415 +
	unsigned int i, j, mask;
1406 1416
	Window w;
1407 1417
	XModifierKeymap *modmap;
1408 1418
	XSetWindowAttributes wa;
1416 1426
	netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
1417 1427
	XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
1418 1428
			PropModeReplace, (unsigned char *) netatom, NetLast);
1429 +
1419 1430
	/* init cursors */
1420 1431
	cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
1421 1432
	cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
1422 1433
	cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
1434 +
1435 +
	/* init geometry */
1436 +
	sx = sy = 0;
1437 +
	sw = DisplayWidth(dpy, screen);
1438 +
	sh = DisplayHeight(dpy, screen);
1439 +
1423 1440
	/* init modifier map */
1424 1441
	modmap = XGetModifierMapping(dpy);
1425 -
	for (i = 0; i < 8; i++)
1426 -
		for (j = 0; j < modmap->max_keypermod; j++) {
1442 +
	for(i = 0; i < 8; i++)
1443 +
		for(j = 0; j < modmap->max_keypermod; j++) {
1427 1444
			if(modmap->modifiermap[i * modmap->max_keypermod + j]
1428 -
					== XKeysymToKeycode(dpy, XK_Num_Lock))
1445 +
			== XKeysymToKeycode(dpy, XK_Num_Lock))
1429 1446
				numlockmask = (1 << i);
1430 1447
		}
1431 1448
	XFreeModifiermap(modmap);
1449 +
1432 1450
	/* select for events */
1433 1451
	wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask
1434 1452
		| EnterWindowMask | LeaveWindowMask | StructureNotifyMask;
1435 1453
	wa.cursor = cursor[CurNormal];
1436 1454
	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
1437 1455
	XSelectInput(dpy, root, wa.event_mask);
1438 -
	keypress(NULL); /* grabkeys */
1456 +
1457 +
	/* grab keys */
1458 +
	keypress(NULL);
1459 +
1460 +
	/* init tags */
1439 1461
	compileregs();
1440 1462
	for(ntags = 0; tags[ntags]; ntags++);
1441 1463
	seltags = emallocz(sizeof(Bool) * ntags);
1442 1464
	seltags[0] = True;
1443 -
	/* geometry */
1444 -
	sx = sy = 0;
1445 -
	sw = DisplayWidth(dpy, screen);
1446 -
	sh = DisplayHeight(dpy, screen);
1447 -
	initstyle();
1448 -
	initlayouts();
1449 -
	initbar();
1465 +
1466 +
	/* init appearance */
1467 +
	dc.norm[ColBorder] = getcolor(NORMBORDERCOLOR);
1468 +
	dc.norm[ColBG] = getcolor(NORMBGCOLOR);
1469 +
	dc.norm[ColFG] = getcolor(NORMFGCOLOR);
1470 +
	dc.sel[ColBorder] = getcolor(SELBORDERCOLOR);
1471 +
	dc.sel[ColBG] = getcolor(SELBGCOLOR);
1472 +
	dc.sel[ColFG] = getcolor(SELFGCOLOR);
1473 +
	initfont(FONT);
1474 +
	dc.h = bh = dc.font.height + 2;
1475 +
1476 +
	/* init layouts */
1477 +
	mwfact = MWFACT;
1478 +
	nlayouts = sizeof layouts / sizeof layouts[0];
1479 +
	for(blw = i = 0; i < nlayouts; i++) {
1480 +
		j = textw(layouts[i].symbol);
1481 +
		if(j > blw)
1482 +
			blw = j;
1483 +
	}
1484 +
1485 +
	/* init bar */
1486 +
	bpos = BARPOS;
1487 +
	wa.override_redirect = 1;
1488 +
	wa.background_pixmap = ParentRelative;
1489 +
	wa.event_mask = ButtonPressMask | ExposureMask;
1490 +
	barwin = XCreateWindow(dpy, root, sx, sy, sw, bh, 0,
1491 +
			DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen),
1492 +
			CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
1493 +
	XDefineCursor(dpy, barwin, cursor[CurNormal]);
1494 +
	updatebarpos();
1495 +
	XMapRaised(dpy, barwin);
1496 +
	strcpy(stext, "dwm-"VERSION);
1497 +
	dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
1498 +
	dc.gc = XCreateGC(dpy, root, 0, 0);
1499 +
	XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
1500 +
	if(!dc.font.set)
1501 +
		XSetFont(dpy, dc.gc, dc.font.xfont->fid);
1502 +
1450 1503
	/* multihead support */
1451 1504
	selscreen = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask);
1452 1505
}
1568 1621
togglemax(const char *arg) {
1569 1622
	XEvent ev;
1570 1623
1571 -
	if(!sel || (!isfloating() && !sel->isfloating) || sel->isfixed)
1624 +
	if(!sel || (!isarrange(floating) && !sel->isfloating) || sel->isfixed)
1572 1625
		return;
1573 1626
	if((sel->ismax = !sel->ismax)) {
1574 1627
		sel->rx = sel->x;
1794 1847
1795 1848
int
1796 1849
main(int argc, char *argv[]) {
1797 -
	char *p;
1798 -
	int r, xfd;
1799 -
	fd_set rd;
1800 -
	XEvent ev;
1801 -
1802 1850
	if(argc == 2 && !strcmp("-v", argv[1]))
1803 1851
		eprint("dwm-"VERSION", © 2006-2007 A. R. Garbe, S. van Dijk, J. Salmi, P. Hruby, S. Nagy\n");
1804 1852
	else if(argc != 1)
1805 1853
		eprint("usage: dwm [-v]\n");
1806 1854
1807 -
	/* macros from config.h can be used at function level only */
1808 -
	mwfact = MWFACT;
1809 -
	bpos = BARPOS;
1810 -
1811 1855
	setlocale(LC_CTYPE, "");
1812 1856
	if(!(dpy = XOpenDisplay(0)))
1813 1857
		eprint("dwm: cannot open display\n");
1814 -
	xfd = ConnectionNumber(dpy);
1815 1858
	screen = DefaultScreen(dpy);
1816 1859
	root = RootWindow(dpy, screen);
1817 -
	otherwm = False;
1818 -
	XSetErrorHandler(xerrorstart);
1819 -
	/* this causes an error if some other window manager is running */
1820 -
	XSelectInput(dpy, root, SubstructureRedirectMask);
1821 -
	XSync(dpy, False);
1822 -
	if(otherwm)
1823 -
		eprint("dwm: another window manager is already running\n");
1824 1860
1825 -
	XSync(dpy, False);
1826 -
	XSetErrorHandler(NULL);
1827 -
	xerrorxlib = XSetErrorHandler(xerror);
1828 -
	XSync(dpy, False);
1861 +
	checkotherwm();
1829 1862
	setup();
1830 1863
	drawbar();
1831 1864
	scan();
1865 +
	run();
1866 +
	cleanup();
1832 1867
1833 -
	/* main event loop, also reads status text from stdin */
1834 -
	XSync(dpy, False);
1835 -
	readin = True;
1836 -
	while(running) {
1837 -
		FD_ZERO(&rd);
1838 -
		if(readin)
1839 -
			FD_SET(STDIN_FILENO, &rd);
1840 -
		FD_SET(xfd, &rd);
1841 -
		if(select(xfd + 1, &rd, NULL, NULL, NULL) == -1) {
1842 -
			if(errno == EINTR)
1843 -
				continue;
1844 -
			eprint("select failed\n");
1845 -
		}
1846 -
		if(FD_ISSET(STDIN_FILENO, &rd)) {
1847 -
			switch(r = read(STDIN_FILENO, stext, sizeof stext - 1)) {
1848 -
			case -1:
1849 -
				strncpy(stext, strerror(errno), sizeof stext - 1);
1850 -
				stext[sizeof stext - 1] = '\0';
1851 -
				readin = False;
1852 -
				break;
1853 -
			case 0:
1854 -
				strncpy(stext, "EOF", 4);
1855 -
				readin = False;
1856 -
				break;
1857 -
			default:
1858 -
				for(stext[r] = '\0', p = stext + strlen(stext) - 1; p >= stext && *p == '\n'; *p-- = '\0');
1859 -
				for(; p >= stext && *p != '\n'; --p);
1860 -
				if(p > stext)
1861 -
					strncpy(stext, p + 1, sizeof stext);
1862 -
			}
1863 -
			drawbar();
1864 -
		}
1865 -
		while(XPending(dpy)) {
1866 -
			XNextEvent(dpy, &ev);
1867 -
			if(handler[ev.type])
1868 -
				(handler[ev.type])(&ev); /* call handler */
1869 -
		}
1870 -
	}
1871 -
	cleanup();
1872 1868
	XCloseDisplay(dpy);
1873 1869
	return 0;
1874 1870
}