fixed several issues with focus handling via mouse, also added sending clients to the right monitor they belong to after mouse moves/resizals
176408af
1 file(s) · +79 −43
| 166 | 166 | static void detachstack(Client *c); |
|
| 167 | 167 | static void die(const char *errstr, ...); |
|
| 168 | 168 | static void drawbar(Monitor *m); |
|
| 169 | - | static void drawbars(); |
|
| 169 | + | static void drawbars(void); |
|
| 170 | 170 | static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); |
|
| 171 | 171 | static void drawtext(const char *text, unsigned long col[ColLast], Bool invert); |
|
| 172 | 172 | static void enternotify(XEvent *e); |
|
| 176 | 176 | static void focusstack(const Arg *arg); |
|
| 177 | 177 | static Client *getclient(Window w); |
|
| 178 | 178 | static unsigned long getcolor(const char *colstr); |
|
| 179 | + | static Monitor *getmonitor(Window w); |
|
| 180 | + | static Monitor *getmonitorxy(int x, int y); |
|
| 181 | + | static Bool getrootpointer(int *x, int *y); |
|
| 179 | 182 | static long getstate(Window w); |
|
| 180 | 183 | static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); |
|
| 181 | 184 | static void grabbuttons(Client *c, Bool focused); |
|
| 197 | 200 | static void restack(Monitor *m); |
|
| 198 | 201 | static void run(void); |
|
| 199 | 202 | static void scan(void); |
|
| 203 | + | static void sendmon(Client *c, Monitor *m); |
|
| 200 | 204 | static void setclientstate(Client *c, long state); |
|
| 201 | 205 | static void setlayout(const Arg *arg); |
|
| 202 | 206 | static void setmfact(const Arg *arg); |
|
| 397 | 401 | ||
| 398 | 402 | click = ClkRootWin; |
|
| 399 | 403 | /* focus monitor if necessary */ |
|
| 400 | - | for(m = mons; m; m = m->next) |
|
| 401 | - | if(ev->window == m->barwin) { |
|
| 402 | - | if(m != selmon) { |
|
| 403 | - | unfocus(selmon->stack); |
|
| 404 | - | selmon = m; |
|
| 405 | - | focus(NULL); |
|
| 406 | - | } |
|
| 407 | - | break; |
|
| 408 | - | } |
|
| 404 | + | if((m = getmonitor(ev->window)) && m != selmon) { |
|
| 405 | + | unfocus(selmon->sel); |
|
| 406 | + | selmon = m; |
|
| 407 | + | focus(NULL); |
|
| 408 | + | } |
|
| 409 | 409 | if(ev->window == selmon->barwin && ev->x >= selmon->btx) { |
|
| 410 | 410 | i = 0; |
|
| 411 | 411 | x = selmon->btx; |
|
| 683 | 683 | } |
|
| 684 | 684 | ||
| 685 | 685 | void |
|
| 686 | - | drawbars() { |
|
| 686 | + | drawbars(void) { |
|
| 687 | 687 | Monitor *m; |
|
| 688 | 688 | ||
| 689 | 689 | for(m = mons; m; m = m->next) |
|
| 742 | 742 | void |
|
| 743 | 743 | enternotify(XEvent *e) { |
|
| 744 | 744 | Client *c; |
|
| 745 | + | Monitor *m; |
|
| 745 | 746 | XCrossingEvent *ev = &e->xcrossing; |
|
| 746 | 747 | ||
| 747 | 748 | if((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) |
|
| 748 | 749 | return; |
|
| 750 | + | if((m = getmonitor(ev->window)) && m != selmon) { |
|
| 751 | + | unfocus(selmon->sel); |
|
| 752 | + | selmon = m; |
|
| 753 | + | } |
|
| 749 | 754 | if((c = getclient(ev->window))) |
|
| 750 | 755 | focus(c); |
|
| 751 | 756 | else |
|
| 757 | 762 | Monitor *m; |
|
| 758 | 763 | XExposeEvent *ev = &e->xexpose; |
|
| 759 | 764 | ||
| 760 | - | if(ev->count == 0) |
|
| 761 | - | for(m = mons; m; m = m->next) |
|
| 762 | - | if(ev->window == m->barwin) { |
|
| 763 | - | drawbar(m); |
|
| 764 | - | break; |
|
| 765 | - | } |
|
| 765 | + | if(ev->count == 0 && (m = getmonitor(ev->window))) |
|
| 766 | + | drawbar(m); |
|
| 766 | 767 | } |
|
| 767 | 768 | ||
| 768 | 769 | void |
|
| 809 | 810 | unfocus(selmon->sel); |
|
| 810 | 811 | selmon = m; |
|
| 811 | 812 | focus(NULL); |
|
| 812 | - | drawbars(); |
|
| 813 | 813 | break; |
|
| 814 | 814 | } |
|
| 815 | 815 | } |
|
| 863 | 863 | return color.pixel; |
|
| 864 | 864 | } |
|
| 865 | 865 | ||
| 866 | + | Monitor * |
|
| 867 | + | getmonitor(Window w) { |
|
| 868 | + | int x, y; |
|
| 869 | + | Client *c; |
|
| 870 | + | Monitor *m; |
|
| 871 | + | ||
| 872 | + | if(w == root && getrootpointer(&x, &y)) |
|
| 873 | + | return getmonitorxy(x, y); |
|
| 874 | + | for(m = mons; m; m = m->next) |
|
| 875 | + | if(w == m->barwin) |
|
| 876 | + | return m; |
|
| 877 | + | if((c = getclient(w))) |
|
| 878 | + | return c->mon; |
|
| 879 | + | return NULL; |
|
| 880 | + | } |
|
| 881 | + | ||
| 882 | + | Monitor * |
|
| 883 | + | getmonitorxy(int x, int y) { |
|
| 884 | + | Monitor *m; |
|
| 885 | + | ||
| 886 | + | for(m = mons; m; m = m->next) |
|
| 887 | + | if(INRECT(x, y, m->wx, m->wy, m->ww, m->wh)) |
|
| 888 | + | return m; |
|
| 889 | + | return NULL; |
|
| 890 | + | } |
|
| 891 | + | ||
| 892 | + | Bool |
|
| 893 | + | getrootpointer(int *x, int *y) { |
|
| 894 | + | int di; |
|
| 895 | + | unsigned int dui; |
|
| 896 | + | Window dummy; |
|
| 897 | + | return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui); |
|
| 898 | + | } |
|
| 899 | + | ||
| 866 | 900 | long |
|
| 867 | 901 | getstate(Window w) { |
|
| 868 | 902 | int format, status; |
|
| 1124 | 1158 | ||
| 1125 | 1159 | void |
|
| 1126 | 1160 | movemouse(const Arg *arg) { |
|
| 1127 | - | int x, y, ocx, ocy, di, nx, ny; |
|
| 1128 | - | unsigned int dui; |
|
| 1161 | + | int x, y, ocx, ocy, nx, ny; |
|
| 1129 | 1162 | Client *c; |
|
| 1130 | - | Window dummy; |
|
| 1163 | + | Monitor *m; |
|
| 1131 | 1164 | XEvent ev; |
|
| 1132 | 1165 | ||
| 1133 | 1166 | if(!(c = selmon->sel)) |
|
| 1138 | 1171 | if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, |
|
| 1139 | 1172 | None, cursor[CurMove], CurrentTime) != GrabSuccess) |
|
| 1140 | 1173 | return; |
|
| 1141 | - | XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui); |
|
| 1174 | + | if(!getrootpointer(&x, &y)) |
|
| 1175 | + | return; |
|
| 1142 | 1176 | do { |
|
| 1143 | 1177 | XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); |
|
| 1144 | 1178 | switch (ev.type) { |
|
| 1171 | 1205 | } |
|
| 1172 | 1206 | while(ev.type != ButtonRelease); |
|
| 1173 | 1207 | XUngrabPointer(dpy, CurrentTime); |
|
| 1208 | + | if((m = getmonitorxy(c->x + c->w / 2, c->y + c->h / 2)) != selmon) |
|
| 1209 | + | sendmon(c, m); |
|
| 1174 | 1210 | } |
|
| 1175 | 1211 | ||
| 1176 | 1212 | Client * |
|
| 1239 | 1275 | int ocx, ocy; |
|
| 1240 | 1276 | int nw, nh; |
|
| 1241 | 1277 | Client *c; |
|
| 1278 | + | Monitor *m; |
|
| 1242 | 1279 | XEvent ev; |
|
| 1243 | 1280 | ||
| 1244 | 1281 | if(!(c = selmon->sel)) |
|
| 1277 | 1314 | XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); |
|
| 1278 | 1315 | XUngrabPointer(dpy, CurrentTime); |
|
| 1279 | 1316 | while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); |
|
| 1317 | + | if((m = getmonitorxy(c->x + c->w / 2, c->y + c->h / 2)) != selmon) |
|
| 1318 | + | sendmon(c, m); |
|
| 1280 | 1319 | } |
|
| 1281 | 1320 | ||
| 1282 | 1321 | void |
|
| 1342 | 1381 | } |
|
| 1343 | 1382 | ||
| 1344 | 1383 | void |
|
| 1384 | + | sendmon(Client *c, Monitor *m) { |
|
| 1385 | + | if(c->mon == m) |
|
| 1386 | + | return; |
|
| 1387 | + | detach(c); |
|
| 1388 | + | detachstack(c); |
|
| 1389 | + | c->mon = m; |
|
| 1390 | + | c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ |
|
| 1391 | + | attach(c); |
|
| 1392 | + | attachstack(c); |
|
| 1393 | + | focus(NULL); |
|
| 1394 | + | arrange(); |
|
| 1395 | + | } |
|
| 1396 | + | ||
| 1397 | + | void |
|
| 1345 | 1398 | setclientstate(Client *c, long state) { |
|
| 1346 | 1399 | long data[] = {state, None}; |
|
| 1347 | 1400 | ||
| 1497 | 1550 | return; |
|
| 1498 | 1551 | for(i = 0, m = mons; m; m = m->next, i++) |
|
| 1499 | 1552 | if(i == arg->ui) { |
|
| 1500 | - | detach(c); |
|
| 1501 | - | detachstack(c); |
|
| 1502 | - | c->mon = m; |
|
| 1503 | - | c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ |
|
| 1504 | - | attach(c); |
|
| 1505 | - | attachstack(c); |
|
| 1506 | - | focus(NULL); |
|
| 1507 | - | arrange(); |
|
| 1553 | + | sendmon(c, m); |
|
| 1508 | 1554 | break; |
|
| 1509 | 1555 | } |
|
| 1510 | 1556 | } |
|
| 1676 | 1722 | ||
| 1677 | 1723 | void |
|
| 1678 | 1724 | updategeom(void) { |
|
| 1679 | - | int i, di, n = 1, x, y; |
|
| 1680 | - | unsigned int dui; |
|
| 1725 | + | int i, n = 1; |
|
| 1681 | 1726 | Client *c; |
|
| 1682 | 1727 | Monitor *newmons = NULL, *m, *tm; |
|
| 1683 | - | Window dummy; |
|
| 1684 | 1728 | ||
| 1685 | 1729 | #ifdef XINULATOR |
|
| 1686 | 1730 | n = 2; |
|
| 1763 | 1807 | } |
|
| 1764 | 1808 | ||
| 1765 | 1809 | /* select focused monitor */ |
|
| 1766 | - | selmon = newmons; |
|
| 1767 | - | if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui)) |
|
| 1768 | - | for(m = newmons; m; m = m->next) |
|
| 1769 | - | if(INRECT(x, y, m->wx, m->wy, m->ww, m->wh)) { |
|
| 1770 | - | selmon = m; |
|
| 1771 | - | break; |
|
| 1772 | - | } |
|
| 1773 | - | ||
| 1774 | - | /* final assignment of new monitors */ |
|
| 1775 | 1810 | cleanupmons(); |
|
| 1776 | 1811 | mons = newmons; |
|
| 1812 | + | selmon = getmonitor(root); |
|
| 1777 | 1813 | } |
|
| 1778 | 1814 | ||
| 1779 | 1815 | void |
|
| 1848 | 1884 | } |
|
| 1849 | 1885 | ||
| 1850 | 1886 | void |
|
| 1851 | - | updatestatus() { |
|
| 1887 | + | updatestatus(void) { |
|
| 1852 | 1888 | if(!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) |
|
| 1853 | 1889 | strcpy(stext, "dwm-"VERSION); |
|
| 1854 | 1890 | drawbar(selmon); |
|