|
|
- void
- moveorplace(const Arg *arg) {
- if ((!selmon->lt[selmon->sellt]->arrange || selmon->sel->isfloating))
- movemouse(arg);
- else
- placemouse(arg);
- }
-
- void
- placemouse(const Arg *arg)
- {
- int x, y, px, py, ocx, ocy, nx = -9999, ny = -9999, freemove = 0;
- Client *c, *r = NULL, *at, *prevr;
- Monitor *m;
- XEvent ev;
- XWindowAttributes wa;
- Time lasttime = 0;
- int attachmode, prevattachmode;
- attachmode = prevattachmode = -1;
-
- if (!(c = selmon->sel) || !c->mon->lt[c->mon->sellt]->arrange) /* no support for placemouse when floating layout is used */
- return;
- if (c->isfullscreen) /* no support placing fullscreen windows by mouse */
- return;
- restack(selmon);
- prevr = c;
- if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
- None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess)
- return;
-
- c->isfloating = 0;
- c->beingmoved = 1;
-
- XGetWindowAttributes(dpy, c->win, &wa);
- ocx = wa.x;
- ocy = wa.y;
-
- if (arg->i == 2) // warp cursor to client center
- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, WIDTH(c) / 2, HEIGHT(c) / 2);
-
- if (!getrootptr(&x, &y))
- return;
-
- do {
- XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
- switch (ev.type) {
- case ConfigureRequest:
- case Expose:
- case MapRequest:
- handler[ev.type](&ev);
- break;
- case MotionNotify:
- if ((ev.xmotion.time - lasttime) <= (1000 / 60))
- continue;
- lasttime = ev.xmotion.time;
-
- nx = ocx + (ev.xmotion.x - x);
- ny = ocy + (ev.xmotion.y - y);
-
- if (!freemove && (abs(nx - ocx) > snap || abs(ny - ocy) > snap))
- freemove = 1;
-
- if (freemove)
- XMoveWindow(dpy, c->win, nx, ny);
-
- if ((m = recttomon(ev.xmotion.x, ev.xmotion.y, 1, 1)) && m != selmon)
- selmon = m;
-
- if (arg->i == 1) { // tiled position is relative to the client window center point
- px = nx + wa.width / 2;
- py = ny + wa.height / 2;
- } else { // tiled position is relative to the mouse cursor
- px = ev.xmotion.x;
- py = ev.xmotion.y;
- }
-
- r = recttoclient(px, py, 1, 1);
-
- if (!r || r == c)
- break;
-
- if ((((float)(r->y + r->h - py) / r->h) > ((float)(r->x + r->w - px) / r->w)
- && (abs(r->y - py) < r->h / 2)) || (abs(r->x - px) < r->w / 2))
- attachmode = 1; // above
- else
- attachmode = 0; // below
-
- if ((r && r != prevr) || (attachmode != prevattachmode)) {
- detachstack(c);
- detach(c);
- if (c->mon != r->mon)
- arrangemon(c->mon);
-
- c->mon = r->mon;
- r->mon->sel = r;
-
- if (attachmode) {
- if (r == r->mon->clients)
- attach(c);
- else {
- for (at = r->mon->clients; at->next != r; at = at->next);
- c->next = at->next;
- at->next = c;
- }
- } else {
- c->next = r->next;
- r->next = c;
- }
-
- attachstack(c);
- arrangemon(r->mon);
- prevr = r;
- prevattachmode = attachmode;
- }
- break;
- }
- } while (ev.type != ButtonRelease);
- XUngrabPointer(dpy, CurrentTime);
-
- if ((m = recttomon(ev.xmotion.x, ev.xmotion.y, 1, 1)) && m != c->mon) {
- detach(c);
- detachstack(c);
- arrangemon(c->mon);
- c->mon = m;
- attach(c);
- attachstack(c);
- selmon = m;
- }
-
- focus(c);
- c->beingmoved = 0;
-
- if (nx != -9999)
- resize(c, nx, ny, c->w, c->h, 0);
- arrangemon(c->mon);
- }
-
- Client *
- recttoclient(int x, int y, int w, int h)
- {
- Client *c, *r = NULL;
- int a, area = 0;
-
- for (c = nexttiled(selmon->clients); c; c = nexttiled(c->next)) {
- if ((a = INTERSECTC(x, y, w, h, c)) > area) {
- area = a;
- r = c;
- }
- }
- return r;
- }
|