drastically changed updategeom() handling, see comment in updategeom() for details
20f69179
2 file(s) · +54 −71
| 1 | 1 | # dwm version |
|
| 2 | - | VERSION = 6.0-tip |
|
| 2 | + | VERSION = 6.1 |
|
| 3 | 3 | ||
| 4 | 4 | # Customize below to fit your system |
|
| 5 | 5 |
| 235 | 235 | static void unfocus(Client *c, Bool setfocus); |
|
| 236 | 236 | static void unmanage(Client *c, Bool destroyed); |
|
| 237 | 237 | static void unmapnotify(XEvent *e); |
|
| 238 | - | static Bool updategeom(void); |
|
| 238 | + | static void updategeom(void); |
|
| 239 | 239 | static void updatebarpos(Monitor *m); |
|
| 240 | 240 | static void updatebars(void); |
|
| 241 | 241 | static void updateclientlist(void); |
|
| 573 | 573 | configurenotify(XEvent *e) { |
|
| 574 | 574 | Monitor *m; |
|
| 575 | 575 | XConfigureEvent *ev = &e->xconfigure; |
|
| 576 | - | Bool dirty; |
|
| 577 | 576 | ||
| 578 | - | // TODO: updategeom handling sucks, needs to be simplified |
|
| 579 | 577 | if(ev->window == root) { |
|
| 580 | - | dirty = (sw != ev->width || sh != ev->height); |
|
| 581 | 578 | sw = ev->width; |
|
| 582 | 579 | sh = ev->height; |
|
| 583 | - | if(updategeom() || dirty) { |
|
| 584 | - | if(dc.drawable != 0) |
|
| 585 | - | XFreePixmap(dpy, dc.drawable); |
|
| 586 | - | dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); |
|
| 587 | - | updatebars(); |
|
| 588 | - | for(m = mons; m; m = m->next) |
|
| 589 | - | XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); |
|
| 590 | - | focus(NULL); |
|
| 591 | - | arrange(NULL); |
|
| 592 | - | } |
|
| 580 | + | if(dc.drawable != 0) |
|
| 581 | + | XFreePixmap(dpy, dc.drawable); |
|
| 582 | + | dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); |
|
| 583 | + | updatebars(); |
|
| 584 | + | for(m = mons; m; m = m->next) |
|
| 585 | + | XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); |
|
| 586 | + | focus(NULL); |
|
| 587 | + | arrange(NULL); |
|
| 593 | 588 | } |
|
| 594 | 589 | } |
|
| 595 | 590 | ||
| 1076 | 1071 | static Bool |
|
| 1077 | 1072 | isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) { |
|
| 1078 | 1073 | while(n--) |
|
| 1079 | - | if(unique[n].x_org == info->x_org && unique[n].y_org == info->y_org |
|
| 1080 | - | && unique[n].width == info->width && unique[n].height == info->height) |
|
| 1074 | + | /* treat origin (x, y) as fixpoint for uniqueness only, first screen wins */ |
|
| 1075 | + | if(unique[n].x_org == info->x_org && unique[n].y_org == info->y_org) |
|
| 1081 | 1076 | return False; |
|
| 1082 | 1077 | return True; |
|
| 1083 | 1078 | } |
|
| 1887 | 1882 | (unsigned char *) &(c->win), 1); |
|
| 1888 | 1883 | } |
|
| 1889 | 1884 | ||
| 1890 | - | Bool |
|
| 1885 | + | void |
|
| 1891 | 1886 | updategeom(void) { |
|
| 1892 | - | Bool dirty = False; |
|
| 1887 | + | /* Starting with dwm 6.1 this function uses a new (simpler) strategy: |
|
| 1888 | + | * whenever screen changes are reported, we destroy all monitors |
|
| 1889 | + | * and recreate all unique origin monitors and add all clients to |
|
| 1890 | + | * the first monitor, only. In several circumstances this may suck, |
|
| 1891 | + | * but dealing with all corner-cases sucks even more.*/ |
|
| 1893 | 1892 | ||
| 1894 | 1893 | #ifdef XINERAMA |
|
| 1895 | 1894 | if(XineramaIsActive(dpy)) { |
|
| 1896 | - | int i, j, n, nn; |
|
| 1895 | + | int i, j, n; |
|
| 1897 | 1896 | Client *c; |
|
| 1898 | - | Monitor *m; |
|
| 1899 | - | XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn); |
|
| 1897 | + | Monitor *m, *oldmons = mons; |
|
| 1898 | + | XineramaScreenInfo *info = XineramaQueryScreens(dpy, &n); |
|
| 1900 | 1899 | XineramaScreenInfo *unique = NULL; |
|
| 1901 | 1900 | ||
| 1902 | - | for(n = 0, m = mons; m; m = m->next, n++); |
|
| 1903 | 1901 | /* only consider unique geometries as separate screens */ |
|
| 1904 | - | if(!(unique = (XineramaScreenInfo *)malloc(sizeof(XineramaScreenInfo) * nn))) |
|
| 1905 | - | die("fatal: could not malloc() %u bytes\n", sizeof(XineramaScreenInfo) * nn); |
|
| 1906 | - | for(i = 0, j = 0; i < nn; i++) |
|
| 1902 | + | if(!(unique = (XineramaScreenInfo *)malloc(sizeof(XineramaScreenInfo) * n))) |
|
| 1903 | + | die("fatal: could not malloc() %u bytes\n", sizeof(XineramaScreenInfo) * n); |
|
| 1904 | + | for(i = 0, j = 0; i < n; i++) |
|
| 1907 | 1905 | if(isuniquegeom(unique, j, &info[i])) |
|
| 1908 | 1906 | memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo)); |
|
| 1909 | 1907 | XFree(info); |
|
| 1910 | - | nn = j; |
|
| 1911 | - | if(n <= nn) { |
|
| 1912 | - | for(i = 0; i < (nn - n); i++) { /* new monitors available */ |
|
| 1913 | - | for(m = mons; m && m->next; m = m->next); |
|
| 1914 | - | if(m) |
|
| 1915 | - | m->next = createmon(); |
|
| 1916 | - | else |
|
| 1917 | - | mons = createmon(); |
|
| 1918 | - | } |
|
| 1919 | - | for(i = 0, m = mons; i < nn && m; m = m->next, i++) |
|
| 1920 | - | if(i >= n |
|
| 1921 | - | || (unique[i].x_org != m->mx || unique[i].y_org != m->my |
|
| 1922 | - | || unique[i].width != m->mw || unique[i].height != m->mh)) |
|
| 1923 | - | { |
|
| 1924 | - | dirty = True; |
|
| 1925 | - | m->num = i; |
|
| 1926 | - | m->mx = m->wx = unique[i].x_org; |
|
| 1927 | - | m->my = m->wy = unique[i].y_org; |
|
| 1928 | - | m->mw = m->ww = unique[i].width; |
|
| 1929 | - | m->mh = m->wh = unique[i].height; |
|
| 1930 | - | updatebarpos(m); |
|
| 1931 | - | } |
|
| 1908 | + | /* create new monitor structure */ |
|
| 1909 | + | n = j; |
|
| 1910 | + | mons = m = createmon(); /* new first monitor */ |
|
| 1911 | + | for(i = 1; i < n; i++) { |
|
| 1912 | + | m->next = createmon(); |
|
| 1913 | + | m = m->next; |
|
| 1914 | + | } |
|
| 1915 | + | for(i = 0, m = mons; i < n && m; m = m->next, i++) { |
|
| 1916 | + | m->num = i; |
|
| 1917 | + | m->mx = m->wx = unique[i].x_org; |
|
| 1918 | + | m->my = m->wy = unique[i].y_org; |
|
| 1919 | + | m->mw = m->ww = unique[i].width; |
|
| 1920 | + | m->mh = m->wh = unique[i].height; |
|
| 1921 | + | updatebarpos(m); |
|
| 1932 | 1922 | } |
|
| 1933 | - | else { /* less monitors available nn < n */ |
|
| 1934 | - | for(i = nn; i < n; i++) { |
|
| 1935 | - | for(m = mons; m && m->next; m = m->next); |
|
| 1936 | - | while(m->clients) { |
|
| 1937 | - | dirty = True; |
|
| 1938 | - | c = m->clients; |
|
| 1939 | - | m->clients = c->next; |
|
| 1940 | - | detachstack(c); |
|
| 1941 | - | c->mon = mons; |
|
| 1942 | - | attach(c); |
|
| 1943 | - | attachstack(c); |
|
| 1944 | - | } |
|
| 1945 | - | if(m == selmon) |
|
| 1946 | - | selmon = mons; |
|
| 1947 | - | cleanupmon(m); |
|
| 1923 | + | free(unique); |
|
| 1924 | + | /* re-attach old clients and cleanup old monitor structure */ |
|
| 1925 | + | while(oldmons) { |
|
| 1926 | + | m = oldmons; |
|
| 1927 | + | while(m->clients) { |
|
| 1928 | + | c = m->clients; |
|
| 1929 | + | m->clients = c->next; |
|
| 1930 | + | detachstack(c); |
|
| 1931 | + | c->mon = mons; |
|
| 1932 | + | attach(c); |
|
| 1933 | + | attachstack(c); |
|
| 1948 | 1934 | } |
|
| 1935 | + | oldmons = m->next; |
|
| 1936 | + | cleanupmon(m); |
|
| 1949 | 1937 | } |
|
| 1950 | - | free(unique); |
|
| 1951 | 1938 | } |
|
| 1952 | 1939 | else |
|
| 1953 | 1940 | #endif /* XINERAMA */ |
|
| 1954 | 1941 | /* default monitor setup */ |
|
| 1955 | 1942 | { |
|
| 1956 | - | if(!mons) |
|
| 1943 | + | if(!mons) /* only true if !XINERAMA compile flag */ |
|
| 1957 | 1944 | mons = createmon(); |
|
| 1958 | 1945 | if(mons->mw != sw || mons->mh != sh) { |
|
| 1959 | - | dirty = True; |
|
| 1960 | 1946 | mons->mw = mons->ww = sw; |
|
| 1961 | 1947 | mons->mh = mons->wh = sh; |
|
| 1962 | 1948 | updatebarpos(mons); |
|
| 1963 | 1949 | } |
|
| 1964 | 1950 | } |
|
| 1965 | - | if(dirty) { |
|
| 1966 | - | selmon = mons; |
|
| 1967 | - | selmon = wintomon(root); |
|
| 1968 | - | } |
|
| 1969 | - | return dirty; |
|
| 1951 | + | selmon = mons; |
|
| 1952 | + | selmon = wintomon(root); |
|
| 1970 | 1953 | } |
|
| 1971 | 1954 | ||
| 1972 | 1955 | void |
|