diff -up dwm-4.4/client.c dwm-4.4-offscreen/client.c --- dwm-4.4/client.c 2007-08-23 18:11:41.000000000 +0200 +++ dwm-4.4-offscreen/client.c 2007-08-24 14:22:53.000000000 +0200 @@ -290,6 +290,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); } diff -up dwm-4.4/dwm.h dwm-4.4-offscreen/dwm.h --- dwm-4.4/dwm.h 2007-08-23 18:11:41.000000000 +0200 +++ dwm-4.4-offscreen/dwm.h 2007-08-24 13:30:37.000000000 +0200 @@ -46,6 +46,7 @@ struct Client { char name[256]; int x, y, w, h; int rx, ry, rw, rh; /* revert geometry */ + int offx, offy; int basew, baseh, incw, inch, maxw, maxh, minw, minh; int minax, maxax, minay, maxay; long flags; diff -up dwm-4.4/event.c dwm-4.4-offscreen/event.c --- dwm-4.4/event.c 2007-08-23 18:11:41.000000000 +0200 +++ dwm-4.4-offscreen/event.c 2007-08-24 15:30:31.000000000 +0200 @@ -7,6 +7,8 @@ /* static */ +static Client *osc; /* offscreen client */ + typedef struct { unsigned long mod; KeySym keysym; @@ -27,7 +29,7 @@ getclient(Window w) { static void movemouse(Client *c) { - int x1, y1, ocx, ocy, di, nx, ny; + int x1, y1, ocx, ocy, di, nx, ny, px, py; unsigned int dui; Window dummy; XEvent ev; @@ -39,6 +41,10 @@ movemouse(Client *c) { return; c->ismax = False; XQueryPointer(dpy, 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); + XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); for(;;) { XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); switch (ev.type) { @@ -62,7 +68,12 @@ movemouse(Client *c) { ny = way; else if(abs((way + wah) - (ny + c->h + 2 * c->border)) < SNAP) ny = way + wah - c->h - 2 * c->border; - resize(c, nx, ny, c->w, c->h, False); + if(!isfloating() && (abs(nx - c->x) > SNAP || abs(ny -c->y) > SNAP)) { + c->isfloating = True; + arrange(); + } + if(isfloating() || c->isfloating) + resize(c, nx, ny, c->w, c->h, False); break; } } @@ -70,8 +81,7 @@ movemouse(Client *c) { static void resizemouse(Client *c) { - int ocx, ocy; - int nw, nh; + int ocx, ocy, nw, nh; XEvent ev; ocx = c->x; @@ -140,12 +150,15 @@ buttonpress(XEvent *e) { focus(c); if(CLEANMASK(ev->state) != MODKEY) return; - if(ev->button == Button1 && (isfloating() || c->isfloating)) { + if(ev->button == Button1) { restack(); movemouse(c); } - else if(ev->button == Button2) + else if(ev->button == Button2) { + if(sel->isfloating) + sel->isfloating = False; zoom(NULL); + } else if(ev->button == Button3 && (isfloating() || c->isfloating) && !c->isfixed) { @@ -231,8 +244,21 @@ enternotify(XEvent *e) { if(ev->mode != NotifyNormal || ev->detail == NotifyInferior) return; - if((c = getclient(ev->window))) + if(c = getclient(ev->window)) { focus(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 > sw || c->y + c->h > sh) { + c->x = c->x < 0 ? 0 : (c->x + c->w > sw ? sw - c->w - 2 * c->border : c->x); + c->y = c->y < 0 ? 0 : (c->y + c->h > sh ? sh - c->h - 2 * c->border : c->y); + XMoveWindow(dpy, c->win, c->x, c->y); + osc = c; + } + } else if(ev->window == root) { selscreen = True; focus(NULL); @@ -270,6 +296,7 @@ keypress(XEvent *e) { static void leavenotify(XEvent *e) { XCrossingEvent *ev = &e->xcrossing; + Client *c; if((ev->window == root) && !ev->same_screen) { selscreen = False;