219 static void toggletag(const Arg *arg); |
219 static void toggletag(const Arg *arg); |
220 static void toggleview(const Arg *arg); |
220 static void toggleview(const Arg *arg); |
221 static void unfocus(Client *c); |
221 static void unfocus(Client *c); |
222 static void unmanage(Client *c, Bool destroyed); |
222 static void unmanage(Client *c, Bool destroyed); |
223 static void unmapnotify(XEvent *e); |
223 static void unmapnotify(XEvent *e); |
224 static void updategeom(void); |
224 static Bool updategeom(void); |
225 static void updatebarpos(Monitor *m); |
225 static void updatebarpos(Monitor *m); |
226 static void updatebars(void); |
226 static void updatebars(void); |
227 static void updatenumlockmask(void); |
227 static void updatenumlockmask(void); |
228 static void updatesizehints(Client *c); |
228 static void updatesizehints(Client *c); |
229 static void updatestatus(void); |
229 static void updatestatus(void); |
533 XConfigureEvent *ev = &e->xconfigure; |
533 XConfigureEvent *ev = &e->xconfigure; |
534 |
534 |
535 if(ev->window == root) { |
535 if(ev->window == root) { |
536 sw = ev->width; |
536 sw = ev->width; |
537 sh = ev->height; |
537 sh = ev->height; |
538 updategeom(); |
538 if(updategeom()) { |
539 if(dc.drawable != 0) |
539 if(dc.drawable != 0) |
540 XFreePixmap(dpy, dc.drawable); |
540 XFreePixmap(dpy, dc.drawable); |
541 dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); |
541 dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); |
542 updatebars(); |
542 updatebars(); |
543 for(m = mons; m; m = m->next) |
543 for(m = mons; m; m = m->next) |
544 XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); |
544 XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); |
545 arrange(); |
545 arrange(); |
|
546 } |
546 } |
547 } |
547 } |
548 } |
548 |
549 |
549 void |
550 void |
550 configurerequest(XEvent *e) { |
551 configurerequest(XEvent *e) { |
1690 } |
1691 } |
1691 else |
1692 else |
1692 m->by = -bh; |
1693 m->by = -bh; |
1693 } |
1694 } |
1694 |
1695 |
1695 void |
1696 Bool |
1696 updategeom(void) { |
1697 updategeom(void) { |
1697 int i, n = 1; |
1698 int i, j, nn = 1, n = 1; |
1698 Client *c; |
1699 Client *c; |
1699 Monitor *newmons = NULL, *m = NULL, *tm; |
1700 Monitor *newmons = NULL, *m = NULL, *tm; |
1700 |
1701 |
1701 #ifdef XINERAMA |
1702 #ifdef XINERAMA |
1702 int nn; |
|
1703 XineramaScreenInfo *info = NULL; |
1703 XineramaScreenInfo *info = NULL; |
|
1704 Bool *flags = NULL; |
1704 |
1705 |
1705 if(XineramaIsActive(dpy)) |
1706 if(XineramaIsActive(dpy)) |
1706 info = XineramaQueryScreens(dpy, &n); |
1707 info = XineramaQueryScreens(dpy, &n); |
1707 for(i = 1, nn = n; i < n; i++) |
1708 flags = (Bool *)malloc(sizeof(Bool) * n); |
1708 if(info[i - 1].x_org == info[i].x_org && info[i - 1].y_org == info[i].y_org |
1709 for(i = 0; i < n; i++) |
1709 && info[i - 1].width == info[i].width && info[i - 1].height == info[i].height) |
1710 flags[i] = False; |
1710 --nn; |
1711 /* next double-loop seeks any combination of retrieved Xinerama info |
1711 n = nn; /* we only consider unique geometries as separate screens */ |
1712 * with existing monitors, this is used to avoid unnecessary |
|
1713 * re-allocations of monitor structs */ |
|
1714 for(i = 0, nn = n; i < n; i++) |
|
1715 for(j = 0, m = mons; m; m = m->next, j++) |
|
1716 if(!flags[j]) { |
|
1717 if((flags[j] = ( |
|
1718 info[i].x_org == m->mx |
|
1719 && info[i].y_org == m->my |
|
1720 && info[i].width == m->mw |
|
1721 && info[i].height == m->mh) |
|
1722 )) |
|
1723 --nn; |
|
1724 } |
|
1725 if(nn == 0) { /* no need to re-allocate monitors */ |
|
1726 j = 0; |
|
1727 for(i = 0, m = mons; m; m = m->next, i++) { |
|
1728 m->num = info[i].screen_number; |
|
1729 if(info[i].x_org != m->mx |
|
1730 || info[i].y_org != m->my |
|
1731 || info[i].width != m->mw |
|
1732 || info[i].height != m->mh) |
|
1733 { |
|
1734 m->mx = m->wx = info[i].x_org; |
|
1735 m->my = m->wy = info[i].y_org; |
|
1736 m->mw = m->ww = info[i].width; |
|
1737 m->mh = m->wh = info[i].height; |
|
1738 updatebarpos(m); |
|
1739 j++; |
|
1740 } |
|
1741 } |
|
1742 XFree(info); |
|
1743 free(flags); |
|
1744 return j > 0; |
|
1745 } |
|
1746 /* next algorithm only considers unique geometries as separate screens */ |
|
1747 for(i = 0; i < n; i++) |
|
1748 flags[i] = False; /* used for ignoring certain monitors */ |
|
1749 for(i = 0, nn = n; i < n; i++) |
|
1750 for(j = 0; j < n; j++) |
|
1751 if(i != j && !flags[i]) { |
|
1752 if((flags[i] = ( |
|
1753 info[i].x_org == info[j].x_org |
|
1754 && info[i].y_org == info[j].y_org |
|
1755 && info[i].width == info[j].width |
|
1756 && info[i].height == info[j].height) |
|
1757 )) |
|
1758 --nn; |
|
1759 } |
1712 #endif /* XINERAMA */ |
1760 #endif /* XINERAMA */ |
1713 /* allocate monitor(s) for the new geometry setup */ |
1761 /* allocate monitor(s) for the new geometry setup */ |
1714 for(i = 0; i < n; i++) { |
1762 for(i = 0; i < nn; i++) { |
1715 if(!(m = (Monitor *)malloc(sizeof(Monitor)))) |
1763 if(!(m = (Monitor *)malloc(sizeof(Monitor)))) |
1716 die("fatal: could not malloc() %u bytes\n", sizeof(Monitor)); |
1764 die("fatal: could not malloc() %u bytes\n", sizeof(Monitor)); |
1717 m->next = newmons; |
1765 m->next = newmons; |
1718 newmons = m; |
1766 newmons = m; |
1719 } |
1767 } |
1720 /* initialise monitor(s) */ |
1768 /* initialise monitor(s) */ |
1721 #ifdef XINERAMA |
1769 #ifdef XINERAMA |
1722 if(XineramaIsActive(dpy)) { |
1770 if(XineramaIsActive(dpy)) { |
1723 for(i = 0, m = newmons; m; m = m->next, i++) { |
1771 for(i = 0, m = newmons; m && i < n; i++) { |
1724 m->num = info[i].screen_number; |
1772 if(!flags[i]) { /* only use screens that aren't dublettes */ |
1725 m->mx = m->wx = info[i].x_org; |
1773 m->num = info[i].screen_number; |
1726 m->my = m->wy = info[i].y_org; |
1774 m->mx = m->wx = info[i].x_org; |
1727 m->mw = m->ww = info[i].width; |
1775 m->my = m->wy = info[i].y_org; |
1728 m->mh = m->wh = info[i].height; |
1776 m->mw = m->ww = info[i].width; |
|
1777 m->mh = m->wh = info[i].height; |
|
1778 m = m->next; |
|
1779 } |
1729 } |
1780 } |
1730 XFree(info); |
1781 XFree(info); |
|
1782 free(flags); |
1731 } |
1783 } |
1732 else |
1784 else |
1733 #endif /* XINERAMA */ |
1785 #endif /* XINERAMA */ |
1734 /* default monitor setup */ |
1786 /* default monitor setup */ |
1735 { |
1787 { |