implemented different version of updategeom
07ad2981
2 file(s) · +86 −150
| 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}\" |
| 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 |
|