several simplifications 1ddfc571
Anselm R Garbe · 2009-06-30 19:39 2 file(s) · +83 −109
config.def.h +2 −3
1 1
/* See LICENSE file for copyright and license details. */
2 2
3 3
/* appearance */
4 +
#define SHOWBAR                       True      /* False means no bar */
5 +
#define TOPBAR                        True      /* False means bottom bar */
4 6
static const char font[]            = "-*-*-medium-*-*-*-14-*-*-*-*-*-*-*";
5 7
static const char normbordercolor[] = "#cccccc";
6 8
static const char normbgcolor[]     = "#cccccc";
10 12
static const char selfgcolor[]      = "#ffffff";
11 13
static unsigned int borderpx        = 1;        /* border pixel of windows */
12 14
static unsigned int snap            = 32;       /* snap pixel */
13 -
static Bool showbar                 = True;     /* False means no bar */
14 -
static Bool topbar                  = True;     /* False means bottom bar */
15 -
16 15
17 16
/* tagging */
18 17
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
dwm.c +81 −106
1 -
//#define XINULATOR /* debug, simulates dual head */
2 1
/* See LICENSE file for copyright and license details.
3 2
 *
4 3
 * dynamic window manager is designed like any other X client as well. It is
174 173
static void focus(Client *c);
175 174
static void focusin(XEvent *e);
176 175
static void focusstack(const Arg *arg);
177 -
static Client *getclient(Window w);
178 176
static unsigned long getcolor(const char *colstr);
179 -
static Monitor *getmon(Window w);
180 -
static Monitor *getmonn(unsigned int n);
181 -
static Monitor *getmonxy(int x, int y);
182 177
static Bool getrootpointer(int *x, int *y);
183 178
static long getstate(Window w);
184 179
static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
185 180
static void grabbuttons(Client *c, Bool focused);
186 181
static void grabkeys(void);
182 +
static Monitor *idxtomon(unsigned int n);
187 183
static void initfont(const char *fontstr);
188 184
static Bool isprotodel(Client *c);
189 185
static void keypress(XEvent *e);
194 190
static void monocle(Monitor *m);
195 191
static void movemouse(const Arg *arg);
196 192
static Client *nexttiled(Client *c);
193 +
static Monitor *pointertomon(int x, int y);
197 194
static void propertynotify(XEvent *e);
198 195
static void quit(const Arg *arg);
199 196
static void resize(Client *c, int x, int y, int w, int h);
228 225
static void updatetitle(Client *c);
229 226
static void updatewmhints(Client *c);
230 227
static void view(const Arg *arg);
228 +
static Client *wintoclient(Window w);
229 +
static Monitor *wintomon(Window w);
231 230
static int xerror(Display *dpy, XErrorEvent *ee);
232 231
static int xerrordummy(Display *dpy, XErrorEvent *ee);
233 232
static int xerrorstart(Display *dpy, XErrorEvent *ee);
402 401
403 402
	click = ClkRootWin;
404 403
	/* focus monitor if necessary */
405 -
	if((m = getmon(ev->window)) && m != selmon) {
404 +
	if((m = wintomon(ev->window)) && m != selmon) {
406 405
		unfocus(selmon->sel);
407 406
		selmon = m;
408 407
		focus(NULL);
424 423
		else
425 424
			click = ClkWinTitle;
426 425
	}
427 -
	else if((c = getclient(ev->window))) {
426 +
	else if((c = wintoclient(ev->window))) {
428 427
		focus(c);
429 428
		click = ClkClientWin;
430 429
	}
457 456
458 457
	view(&a);
459 458
	lt[selmon->sellt] = &foo;
460 -
461 -
	/* TODO: consider simplifying cleanup code of the stack, perhaps do that in cleanmons() ? */
462 459
	for(m = mons; m; m = m->next)
463 460
		while(m->stack)
464 461
			unmanage(m->stack);
546 543
	XConfigureRequestEvent *ev = &e->xconfigurerequest;
547 544
	XWindowChanges wc;
548 545
549 -
	if((c = getclient(ev->window))) {
546 +
	if((c = wintoclient(ev->window))) {
550 547
		if(ev->value_mask & CWBorderWidth)
551 548
			c->bw = ev->border_width;
552 549
		else if(c->isfloating || !lt[selmon->sellt]->arrange) {
589 586
	Client *c;
590 587
	XDestroyWindowEvent *ev = &e->xdestroywindow;
591 588
592 -
	if((c = getclient(ev->window)))
589 +
	if((c = wintoclient(ev->window)))
593 590
		unmanage(c);
594 591
}
595 592
607 604
608 605
	for(tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext);
609 606
	*tc = c->snext;
607 +
608 +
	if(c == c->mon->sel) {
609 +
		for(*tc = c->mon->stack; *tc && !ISVISIBLE((*tc)); *tc = (*tc)->snext);
610 +
		c->mon->sel = *tc;
611 +
	}
610 612
}
611 613
612 614
void
750 752
751 753
	if((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root)
752 754
		return;
753 -
	if((m = getmon(ev->window)) && m != selmon) {
755 +
	if((m = wintomon(ev->window)) && m != selmon) {
754 756
		unfocus(selmon->sel);
755 757
		selmon = m;
756 758
	}
757 -
	if((c = getclient(ev->window)))
759 +
	if((c = wintoclient(ev->window)))
758 760
		focus(c);
759 761
	else
760 762
		focus(NULL);
765 767
	Monitor *m;
766 768
	XExposeEvent *ev = &e->xexpose;
767 769
768 -
	if(ev->count == 0 && (m = getmon(ev->window)))
770 +
	if(ev->count == 0 && (m = wintomon(ev->window)))
769 771
		drawbar(m);
770 772
}
771 773
805 807
focusmon(const Arg *arg) {
806 808
	Monitor *m;
807 809
808 -
	if(!(m = getmonn(arg->ui)) || m == selmon)
810 +
	if(!(m = idxtomon(arg->ui)) || m == selmon)
809 811
		return;
810 812
	unfocus(selmon->sel);
811 813
	selmon = m;
839 841
	}
840 842
}
841 843
842 -
Client *
843 -
getclient(Window w) {
844 -
	Client *c;
845 -
	Monitor *m;
846 -
847 -
	for(m = mons; m; m = m->next)
848 -
		for(c = m->clients; c; c = c->next)
849 -
			if(c->win == w)
850 -
				return c;
851 -
	return NULL;
852 -
}
853 -
854 844
unsigned long
855 845
getcolor(const char *colstr) {
856 846
	Colormap cmap = DefaultColormap(dpy, screen);
861 851
	return color.pixel;
862 852
}
863 853
864 -
Monitor *
865 -
getmon(Window w) {
866 -
	int x, y;
867 -
	Client *c;
868 -
	Monitor *m;
869 -
870 -
	if(w == root && getrootpointer(&x, &y))
871 -
		return getmonxy(x, y);
872 -
	for(m = mons; m; m = m->next)
873 -
		if(w == m->barwin)
874 -
			return m;
875 -
	if((c = getclient(w)))
876 -
		return c->mon;
877 -
	return mons;
878 -
}
879 -
880 -
Monitor *
881 -
getmonn(unsigned int n) {
882 -
	unsigned int i;
883 -
	Monitor *m;
884 -
885 -
	for(m = mons, i = 0; m && i != n; m = m->next, i++);
886 -
	return m;
887 -
}
888 -
889 -
Monitor *
890 -
getmonxy(int x, int y) {
891 -
	Monitor *m;
892 -
893 -
	for(m = mons; m; m = m->next)
894 -
		if(INRECT(x, y, m->wx, m->wy, m->ww, m->wh))
895 -
			return m;
896 -
	return mons;
897 -
}
898 -
899 854
Bool
900 855
getrootpointer(int *x, int *y) {
901 856
	int di;
987 942
	}
988 943
}
989 944
945 +
Monitor *
946 +
idxtomon(unsigned int n) {
947 +
	unsigned int i;
948 +
	Monitor *m;
949 +
950 +
	for(m = mons, i = 0; m && i != n; m = m->next, i++);
951 +
	return m;
952 +
}
953 +
990 954
void
991 955
initfont(const char *fontstr) {
992 956
	char *def, **missing;
1116 1080
	grabbuttons(c, False);
1117 1081
	updatetitle(c);
1118 1082
	if(XGetTransientForHint(dpy, w, &trans))
1119 -
		t = getclient(trans);
1083 +
		t = wintoclient(trans);
1120 1084
	if(t)
1121 1085
		c->tags = t->tags;
1122 1086
	else
1151 1115
		return;
1152 1116
	if(wa.override_redirect)
1153 1117
		return;
1154 -
	if(!getclient(ev->window))
1118 +
	if(!wintoclient(ev->window))
1155 1119
		manage(ev->window, &wa);
1156 1120
}
1157 1121
1212 1176
	}
1213 1177
	while(ev.type != ButtonRelease);
1214 1178
	XUngrabPointer(dpy, CurrentTime);
1215 -
	if((m = getmonxy(c->x + c->w / 2, c->y + c->h / 2)) != selmon) {
1179 +
	if((m = pointertomon(c->x + c->w / 2, c->y + c->h / 2)) != selmon) {
1216 1180
		sendmon(c, m);
1217 1181
		selmon = m;
1218 1182
		focus(NULL);
1225 1189
	return c;
1226 1190
}
1227 1191
1192 +
Monitor *
1193 +
pointertomon(int x, int y) {
1194 +
	Monitor *m;
1195 +
1196 +
	for(m = mons; m; m = m->next)
1197 +
		if(INRECT(x, y, m->wx, m->wy, m->ww, m->wh))
1198 +
			return m;
1199 +
	return mons;
1200 +
}
1201 +
1228 1202
void
1229 1203
propertynotify(XEvent *e) {
1230 1204
	Client *c;
1235 1209
		updatestatus();
1236 1210
	else if(ev->state == PropertyDelete)
1237 1211
		return; /* ignore */
1238 -
	else if((c = getclient(ev->window))) {
1212 +
	else if((c = wintoclient(ev->window))) {
1239 1213
		switch (ev->atom) {
1240 1214
		default: break;
1241 1215
		case XA_WM_TRANSIENT_FOR:
1242 1216
			XGetTransientForHint(dpy, c->win, &trans);
1243 -
			if(!c->isfloating && (c->isfloating = (getclient(trans) != NULL)))
1217 +
			if(!c->isfloating && (c->isfloating = (wintoclient(trans) != NULL)))
1244 1218
				arrange();
1245 1219
			break;
1246 1220
		case XA_WM_NORMAL_HINTS:
1324 1298
	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
1325 1299
	XUngrabPointer(dpy, CurrentTime);
1326 1300
	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
1327 -
	if((m = getmonxy(c->x + c->w / 2, c->y + c->h / 2)) != selmon) {
1301 +
	if((m = pointertomon(c->x + c->w / 2, c->y + c->h / 2)) != selmon) {
1328 1302
		sendmon(c, m);
1329 1303
		selmon = m;
1330 1304
		focus(NULL);
1557 1531
tagmon(const Arg *arg) {
1558 1532
	Monitor *m;
1559 1533
1560 -
	if(!selmon->sel || !(m = getmonn(arg->ui)))
1534 +
	if(!selmon->sel || !(m = idxtomon(arg->ui)))
1561 1535
		return;
1562 1536
	sendmon(selmon->sel, m);
1563 1537
}
1670 1644
	XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
1671 1645
	detach(c);
1672 1646
	detachstack(c);
1673 -
	if(c->mon->sel == c) {
1674 -
		/* TODO: consider separate the next code into a function or into detachstack? */
1675 -
		Client *tc;
1676 -
		for(tc = c->mon->stack; tc && !ISVISIBLE(tc); tc = tc->snext);
1677 -
		c->mon->sel = tc;
1678 -
		focus(NULL);
1679 -
	}
1680 1647
	XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
1681 1648
	setclientstate(c, WithdrawnState);
1682 1649
	free(c);
1683 1650
	XSync(dpy, False);
1684 1651
	XSetErrorHandler(xerror);
1685 1652
	XUngrabServer(dpy);
1653 +
	focus(NULL);
1686 1654
	arrange();
1687 1655
}
1688 1656
1691 1659
	Client *c;
1692 1660
	XUnmapEvent *ev = &e->xunmap;
1693 1661
1694 -
	if((c = getclient(ev->window)))
1662 +
	if((c = wintoclient(ev->window)))
1695 1663
		unmanage(c);
1696 1664
}
1697 1665
1733 1701
	Client *c;
1734 1702
	Monitor *newmons = NULL, *m, *tm;
1735 1703
1736 -
#ifdef XINULATOR
1737 -
	n = 2;
1738 -
#elif defined(XINERAMA)
1704 +
#ifdef XINERAMA
1739 1705
	XineramaScreenInfo *info = NULL;
1740 1706
1741 1707
	if(XineramaIsActive(dpy))
1742 1708
		info = XineramaQueryScreens(dpy, &n);
1743 -
#endif
1709 +
#endif /* XINERAMA */
1744 1710
	/* allocate monitor(s) for the new geometry setup */
1745 1711
	for(i = 0; i < n; i++) {
1746 1712
		m = (Monitor *)malloc(sizeof(Monitor));
1749 1715
	}
1750 1716
1751 1717
	/* initialise monitor(s) */
1752 -
#ifdef XINULATOR
1753 -
	if(1) {
1754 -
		m = newmons;
1755 -
		m->screen_number = 0;
1756 -
		m->wx = sx;
1757 -
		m->my = m->wy = sy;
1758 -
		m->ww = sw;
1759 -
		m->mh = m->wh = sh / 2;
1760 -
		m = newmons->next;
1761 -
		m->screen_number = 1;
1762 -
		m->wx = sx;
1763 -
		m->my = m->wy = sy + sh / 2;
1764 -
		m->ww = sw;
1765 -
		m->mh = m->wh = sh / 2;
1766 -
	}
1767 -
	else
1768 -
#elif defined(XINERAMA)
1718 +
#ifdef XINERAMA
1769 1719
	if(XineramaIsActive(dpy)) {
1770 1720
		for(i = 0, m = newmons; m; m = m->next, i++) {
1771 1721
			m->screen_number = info[i].screen_number;
1777 1727
		XFree(info);
1778 1728
	}
1779 1729
	else
1780 -
#endif
1730 +
#endif /* XINERAMA */
1781 1731
	/* default monitor setup */
1782 1732
	{
1783 1733
		m->screen_number = 0;
1789 1739
1790 1740
	/* bar geometry setup */
1791 1741
	for(m = newmons; m; m = m->next) {
1792 -
		/* TODO: consider removing the following values from config.h */
1793 -
		m->clients = NULL;
1794 -
		m->sel = NULL;
1795 -
		m->stack = NULL;
1742 +
		m->sel = m->stack = m->clients = NULL;
1796 1743
		m->seltags = 0;
1797 1744
		m->sellt = 0;
1798 1745
		m->tagset[0] = m->tagset[1] = 1;
1799 1746
		m->mfact = mfact;
1800 -
		m->showbar = showbar;
1801 -
		m->topbar = topbar;
1747 +
		m->showbar = SHOWBAR;
1748 +
		m->topbar = TOPBAR;
1802 1749
		updatebarpos(m);
1803 1750
	}
1804 1751
1816 1763
	/* select focused monitor */
1817 1764
	cleanupmons();
1818 1765
	mons = newmons;
1819 -
	selmon = getmon(root);
1766 +
	selmon = wintomon(root);
1820 1767
}
1821 1768
1822 1769
void
1921 1868
	if(arg->ui & TAGMASK)
1922 1869
		selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
1923 1870
	arrange();
1871 +
}
1872 +
1873 +
Client *
1874 +
wintoclient(Window w) {
1875 +
	Client *c;
1876 +
	Monitor *m;
1877 +
1878 +
	for(m = mons; m; m = m->next)
1879 +
		for(c = m->clients; c; c = c->next)
1880 +
			if(c->win == w)
1881 +
				return c;
1882 +
	return NULL;
1883 +
}
1884 +
1885 +
Monitor *
1886 +
wintomon(Window w) {
1887 +
	int x, y;
1888 +
	Client *c;
1889 +
	Monitor *m;
1890 +
1891 +
	if(w == root && getrootpointer(&x, &y))
1892 +
		return pointertomon(x, y);
1893 +
	for(m = mons; m; m = m->next)
1894 +
		if(w == m->barwin)
1895 +
			return m;
1896 +
	if((c = wintoclient(w)))
1897 +
		return c->mon;
1898 +
	return mons;
1924 1899
}
1925 1900
1926 1901
/* There's no way to check accesses to destroyed windows, thus those cases are