diff -r 5cfd3c602ede dwm.c --- a/dwm.c Sat Dec 22 14:40:44 2007 +0000 +++ b/dwm.c Fri Dec 28 15:52:44 2007 +0100 @@ -64,6 +64,7 @@ struct Client { struct Client { char name[256]; int x, y, w, h; + int offx, offy; int basew, baseh, incw, inch, maxw, maxh, minw, minh; int minax, maxax, minay, maxay; long flags; @@ -239,6 +240,7 @@ Bool otherwm, readin; Bool otherwm, readin; Bool running = True; Client *clients = NULL; +Client *osc = NULL; Client *sel = NULL; Client *stack = NULL; Cursor cursor[CurLast]; @@ -332,8 +334,10 @@ ban(Client *c) { void buttonpress(XEvent *e) { - unsigned int i, x; + unsigned int i, dui, x; + int x1, y1, di, px, py; Client *c; + Window dummy; XButtonPressedEvent *ev = &e->xbutton; Monitor *m = &monitors[monitorat(-1, -1)]; @@ -360,29 +364,47 @@ buttonpress(XEvent *e) { } if((ev->x < x + blw) && ev->button == Button1) setlayout(NULL); + x += blw; + if(sel && (ev->x > x) && (ev->x < (m->sw - textw(m, stext)))) { + if(ev->button == Button1) { + XQueryPointer(dpy, monitors[selmonitor].root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); + px = x1 - x > (m->sw - textw(m, stext) - x) / 2 ? sel->w : -1; + py = y1 > bh / 2 ? sel->h : -1; + XWarpPointer(dpy, None, sel->win, 0, 0, 0, 0, px, py); + movemouse(sel); + } + else if(ev->button == Button2) { + if(sel->isfloating) + togglefloating(NULL); + zoom(NULL); + } + else if(ev->button == Button3) + resizemouse(sel); + else if(ev->button == Button4) + focusprev(NULL); + else if(ev->button == Button5) + focusnext(NULL); + } } else if((c = getclient(ev->window))) { focus(c); if(CLEANMASK(ev->state) != MODKEY) return; if(ev->button == Button1) { - if((m->layout->arrange == floating) || c->isfloating) - restack(); - else - togglefloating(NULL); + restack(); + XQueryPointer(dpy, monitors[selmonitor].root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); + px = x1 - c->x > c->w / 2 ? c->w : -1; + py = y1 - c->y > c->h / 2 ? c->h : -1; + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, px, py); movemouse(c); } else if(ev->button == Button2) { if((floating != m->layout->arrange) && c->isfloating) togglefloating(NULL); - else - zoom(NULL); + zoom(NULL); } else if(ev->button == Button3 && !c->isfixed) { - if((floating == m->layout->arrange) || c->isfloating) - restack(); - else - togglefloating(NULL); + restack(); resizemouse(c); } } @@ -736,6 +758,18 @@ focus(Client *c) { XSetWindowBorder(dpy, sel->win, monitors[sel->monitor].dc.norm[ColBorder]); } if(c) { + if(osc && c != osc) { + osc->x = osc->offx; + osc->y = osc->offy; + XMoveWindow(dpy, osc->win, osc->x, osc->y); + osc = NULL; + } + if(c->x < 0 || c->y < 0 || c->x + c->w > monitors[selmonitor].sw || c->y + c->h > monitors[selmonitor].sh) { + c->x = c->x < 0 ? 0 : (c->x + c->w > monitors[selmonitor].sw ? monitors[selmonitor].sw - c->w - 2 * c->border : c->x); + c->y = c->y < 0 ? 0 : (c->y + c->h > monitors[selmonitor].sh ? monitors[selmonitor].sh - c->h - 2 * c->border : c->y); + XMoveWindow(dpy, c->win, c->x, c->y); + osc = c; + } detachstack(c); attachstack(c); grabbuttons(c, True); @@ -1169,7 +1203,10 @@ movemouse(Client *c) { ny = m->way; else if(abs((m->way + m->wah) - (ny + c->h + 2 * c->border)) < SNAP) ny = m->way + m->wah - c->h - 2 * c->border; - resize(c, nx, ny, c->w, c->h, False); + if((monitors[selmonitor].layout->arrange != floating) && (abs(nx - c->x) > SNAP || abs(ny -c->y) > SNAP) && !sel->isfloating) + togglefloating(NULL); + if((monitors[selmonitor].layout->arrange == floating) || c->isfloating) + resize(c, nx, ny, c->w, c->h, False); memcpy(c->tags, monitors[monitorat(nx, ny)].seltags, sizeof initags); break; } @@ -1291,6 +1328,8 @@ resize(Client *c, int x, int y, int w, i c->h = wc.height = h; wc.border_width = c->border; XConfigureWindow(dpy, c->win, CWX | CWY | CWWidth | CWHeight | CWBorderWidth, &wc); + c->offx = c->x; + c->offy = c->y; configure(c); XSync(dpy, False); } @@ -1328,7 +1367,10 @@ resizemouse(Client *c) { nw = 1; if((nh = ev.xmotion.y - ocy - 2 * c->border + 1) <= 0) nh = 1; - resize(c, c->x, c->y, nw, nh, True); + if((monitors[selmonitor].layout->arrange != floating) && (abs(nw - c->w) > SNAP || abs(nh -c->h) > SNAP)) + togglefloating(NULL); + if((monitors[selmonitor].layout->arrange == floating) || c->isfloating) + resize(c, c->x, c->y, nw, nh, True); break; } }