mirror of
https://github.com/bakkeby/dwm-flexipatch
synced 2024-11-09 01:10:26 +00:00
5c321794f1
+ when moving window from monitor with different tags selected the moved window would not get the tags set properly if multiple windows are already on that monitor
156 lines
3.5 KiB
C
156 lines
3.5 KiB
C
void
|
|
moveorplace(const Arg *arg) {
|
|
if ((!selmon->lt[selmon->sellt]->arrange || (selmon->sel && 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->tags = r->mon->tagset[r->mon->seltags];
|
|
}
|
|
|
|
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;
|
|
c->tags = m->tagset[m->seltags];
|
|
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;
|
|
}
|
|
|