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