implemented different version of updategeom 07ad2981
Anselm R Garbe · 2009-09-21 19:51 2 file(s) · +86 −150
config.mk +4 −4
20 20
21 21
# flags
22 22
CPPFLAGS = -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
23 -
#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
24 -
CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
25 -
#LDFLAGS = -g ${LIBS}
26 -
LDFLAGS = -s ${LIBS}
23 +
CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
24 +
#CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
25 +
LDFLAGS = -g ${LIBS}
26 +
#LDFLAGS = -s ${LIBS}
27 27
28 28
# Solaris
29 29
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
dwm.c +82 −146
163 163
static void configure(Client *c);
164 164
static void configurenotify(XEvent *e);
165 165
static void configurerequest(XEvent *e);
166 +
static Monitor *createmon(void);
166 167
static void destroynotify(XEvent *e);
167 168
static void detach(Client *c);
168 169
static void detachstack(Client *c);
592 593
	XSync(dpy, False);
593 594
}
594 595
596 +
Monitor *
597 +
createmon(void) {
598 +
	Monitor *m;
599 +
600 +
	if(!(m = (Monitor *)calloc(1, sizeof(Monitor))))
601 +
		die("fatal: could not malloc() %u bytes\n", sizeof(Monitor));
602 +
	m->tagset[0] = m->tagset[1] = 1;
603 +
	m->mfact = mfact;
604 +
	m->showbar = showbar;
605 +
	m->topbar = topbar;
606 +
	m->lt[0] = &layouts[0];
607 +
	m->lt[1] = &layouts[1 % LENGTH(layouts)];
608 +
	m->ltsymbol = layouts[0].symbol;
609 +
	return m;
610 +
}
611 +
595 612
void
596 613
destroynotify(XEvent *e) {
597 614
	Client *c;
1005 1022
	return ret;
1006 1023
}
1007 1024
1025 +
#ifdef XINERAMA
1026 +
static Bool
1027 +
isuniquegeom(XineramaScreenInfo *unique, size_t len, XineramaScreenInfo *info) {
1028 +
	unsigned int i;
1029 +
1030 +
	for(i = 0; i < len; i++)
1031 +
		if(unique[i].x_org == info->x_org && unique[i].y_org == info->y_org
1032 +
		&& unique[i].width == info->width && unique[i].height == info->height)
1033 +
			return False;
1034 +
	return True;
1035 +
}
1036 +
#endif /* XINERAMA */
1037 +
1008 1038
void
1009 1039
keypress(XEvent *e) {
1010 1040
	unsigned int i;
1695 1725
1696 1726
Bool
1697 1727
updategeom(void) {
1698 -
	int i, j, nn = 1, n = 1;
1699 -
	Client *c;
1700 -
	Monitor *newmons = NULL, *m = NULL, *tm;
1728 +
	Bool dirty = False;
1701 1729
1702 -
	/* TODO:
1703 -
	 * This function needs to be seriously re-designed:
1704 -
	 *
1705 -
	 * #ifdef XINERAMA
1706 -
	 * 1. Determine number of already existing monitors n
1707 -
	 * 2. Determine number of monitors Xinerama reports nn
1708 -
	 * 3. if(n <= nn) {
1709 -
	 *       if(n < nn) {
1710 -
	 *          append nn-n monitors to current struct
1711 -
	 *          flag dirty
1712 -
	 *       }
1713 -
	 *       for(i = 0; i < nn; i++) {
1714 -
	 *           if(oldgeom != newgeom) {
1715 -
	 *               apply newgeom;
1716 -
	 *               flag dirty;
1717 -
	 *           }
1718 -
	 *       }
1719 -
	 *    }
1720 -
	 *    else {
1721 -
	 *       detach all clients
1722 -
	 *       destroy current monitor struct
1723 -
	 *       create new monitor struct 
1724 -
	 *       attach all clients to first monitor
1725 -
	 *       flag dirty;
1726 -
	 *    }
1727 -
	 *    return dirty flag to caller
1728 -
	 *        if dirty is seen by caller:
1729 -
	 *           re-arrange bars/pixmaps
1730 -
	 *           arrange()
1731 -
	 * #else
1732 -
	 *    don't share between XINERAMA and non-XINERAMA handling if it gets
1733 -
	 *    too ugly
1734 -
	 * #endif
1735 -
	 */
1736 1730
#ifdef XINERAMA
1737 -
	XineramaScreenInfo *info = NULL;
1738 -
	Bool *flags = NULL;
1731 +
	if(XineramaIsActive(dpy)) {
1732 +
		int i, j, n, nn;
1733 +
		Monitor *m;
1734 +
		XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn);
1735 +
		XineramaScreenInfo *unique = NULL;
1739 1736
1740 -
	if(XineramaIsActive(dpy))
1741 -
		info = XineramaQueryScreens(dpy, &n);
1742 -
	flags = (Bool *)malloc(sizeof(Bool) * n);
1743 -
	for(i = 0; i < n; i++)
1744 -
		flags[i] = False;
1745 -
	/* next double-loop seeks any combination of retrieved Xinerama info
1746 -
	 * with existing monitors, this is used to avoid unnecessary
1747 -
	 * re-allocations of monitor structs */
1748 -
	for(i = 0, nn = n; i < n; i++)
1749 -
		for(j = 0, m = mons; m; m = m->next, j++)
1750 -
			if(!flags[j]) {
1751 -
				if((flags[j] = (
1752 -
					info[i].x_org == m->mx
1753 -
					&& info[i].y_org == m->my
1754 -
					&& info[i].width == m->mw
1755 -
					&& info[i].height == m->mh)
1756 -
				))
1757 -
					--nn;
1758 -
			}
1759 -
	if(nn == 0) { /* no need to re-allocate monitors */
1760 -
		j = 0;
1761 -
		for(i = 0, m = mons; m; m = m->next, i++) {
1762 -
			m->num = info[i].screen_number;
1763 -
			if(info[i].x_org != m->mx
1764 -
			|| info[i].y_org != m->my
1765 -
			|| info[i].width != m->mw
1766 -
			|| info[i].height != m->mh)
1767 -
			{
1768 -
				m->mx = m->wx = info[i].x_org;
1769 -
				m->my = m->wy = info[i].y_org;
1770 -
				m->mw = m->ww = info[i].width;
1771 -
				m->mh = m->wh = info[i].height;
1772 -
				updatebarpos(m);
1773 -
				j++;
1774 -
			}
1775 -
		}
1737 +
		info = XineramaQueryScreens(dpy, &nn);
1738 +
		for(n = 0, m = mons; m; m = m->next, n++);
1739 +
		/* only consider unique geometries as separate screens */
1740 +
		if(!(unique = (XineramaScreenInfo *)malloc(sizeof(XineramaScreenInfo) * nn)))
1741 +
			die("fatal: could not malloc() %u bytes\n", sizeof(XineramaScreenInfo) * nn);
1742 +
		for(i = 0, j = 0; i < nn; i++)
1743 +
			if(isuniquegeom(unique, j, &info[i]))
1744 +
				memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo));
1776 1745
		XFree(info);
1777 -
		free(flags);
1778 -
		return j > 0;
1779 -
	}
1780 -
	/* next algorithm only considers unique geometries as separate screens */
1781 -
	for(i = 0; i < n; i++)
1782 -
		flags[i] = False; /* used for ignoring certain monitors */
1783 -
	for(i = 0, nn = n; i < n; i++)
1784 -
		for(j = 0; j < n; j++)
1785 -
			if(i != j && !flags[i]) {
1786 -
				if((flags[i] = (
1787 -
					info[i].x_org == info[j].x_org
1788 -
					&& info[i].y_org == info[j].y_org
1789 -
					&& info[i].width == info[j].width
1790 -
					&& info[i].height == info[j].height)
1791 -
				))
1792 -
					--nn;
1746 +
		nn = j;
1747 +
		if(n <= nn) {
1748 +
			for(i = 0; i < (nn - n); i++) { /* new monitors available */
1749 +
				for(m = mons; m && m->next; m = m->next);
1750 +
				if(m)
1751 +
					m->next = createmon();
1752 +
				else
1753 +
					mons = createmon();
1793 1754
			}
1794 -
#endif /* XINERAMA */
1795 -
	/* allocate monitor(s) for the new geometry setup */
1796 -
	for(i = 0; i < nn; i++) {
1797 -
		if(!(m = (Monitor *)malloc(sizeof(Monitor))))
1798 -
			die("fatal: could not malloc() %u bytes\n", sizeof(Monitor));
1799 -
		m->next = newmons;
1800 -
		newmons = m;
1801 -
	}
1802 -
	/* initialise monitor(s) */
1803 -
#ifdef XINERAMA
1804 -
	if(XineramaIsActive(dpy)) {
1805 -
		for(i = 0, m = newmons; m && i < n; i++) {
1806 -
			if(!flags[i]) { /* only use screens that aren't dublettes */
1807 -
				m->num = info[i].screen_number;
1808 -
				m->mx = m->wx = info[i].x_org;
1809 -
				m->my = m->wy = info[i].y_org;
1810 -
				m->mw = m->ww = info[i].width;
1811 -
				m->mh = m->wh = info[i].height;
1812 -
				m = m->next;
1813 -
			}
1755 +
			for(i = 0, m = mons; i < nn && m; m = m->next, i++)
1756 +
				if(i >= n
1757 +
				|| (unique[i].x_org != m->mx || unique[i].y_org != m->my
1758 +
				    || unique[i].width != m->mw || unique[i].height != m->mh))
1759 +
				{
1760 +
					dirty = True;
1761 +
					m->num = unique[i].screen_number;
1762 +
					m->mx = m->wx = unique[i].x_org;
1763 +
					m->my = m->wy = unique[i].y_org;
1764 +
					m->mw = m->ww = unique[i].width;
1765 +
					m->mh = m->wh = unique[i].height;
1766 +
					updatebarpos(m);
1767 +
				}
1814 1768
		}
1815 -
		XFree(info);
1816 -
		free(flags);
1769 +
		else { /* less monitors available */
1770 +
			cleanup();
1771 +
			setup();
1772 +
		}
1773 +
		free(unique);
1817 1774
	}
1818 1775
	else
1819 1776
#endif /* XINERAMA */
1820 1777
	/* default monitor setup */
1821 1778
	{
1822 -
		m->num = 0;
1823 -
		m->mx = m->wx = 0;
1824 -
		m->my = m->wy = 0;
1825 -
		m->mw = m->ww = sw;
1826 -
		m->mh = m->wh = sh;
1779 +
		if(!mons)
1780 +
			mons = createmon();
1781 +
		if(mons->mw != sw || mons->mh != sh) {
1782 +
			dirty = True;
1783 +
			mons->mw = mons->ww = sw;
1784 +
			mons->mh = mons->wh = sh;
1785 +
			updatebarpos(mons);
1786 +
		}
1827 1787
	}
1828 -
	/* bar geometry setup */
1829 -
	for(m = newmons; m; m = m->next) {
1830 -
		m->sel = m->stack = m->clients = NULL;
1831 -
		m->seltags = 0;
1832 -
		m->sellt = 0;
1833 -
		m->tagset[0] = m->tagset[1] = 1;
1834 -
		m->mfact = mfact;
1835 -
		m->showbar = showbar;
1836 -
		m->topbar = topbar;
1837 -
		m->lt[0] = &layouts[0];
1838 -
		m->lt[1] = &layouts[1 % LENGTH(layouts)];
1839 -
		m->ltsymbol = layouts[0].symbol;
1840 -
		updatebarpos(m);
1788 +
	if(dirty) {
1789 +
		selmon = mons;
1790 +
		selmon = wintomon(root);
1841 1791
	}
1842 -
	/* reassign left over clients of disappeared monitors */
1843 -
	for(tm = mons; tm; tm = tm->next)
1844 -
		while(tm->clients) {
1845 -
			c = tm->clients;
1846 -
			tm->clients = c->next;
1847 -
			detachstack(c);
1848 -
			c->mon = newmons;
1849 -
			attach(c);
1850 -
			attachstack(c);
1851 -
		}
1852 -
	/* select focused monitor */
1853 -
	cleanupmons();
1854 -
	selmon = mons = newmons;
1855 -
	selmon = wintomon(root);
1856 -
	return True;
1792 +
	return dirty;
1857 1793
}
1858 1794
1859 1795
void