mirror of
https://github.com/mintycube/dwm.git
synced 2024-10-22 14:05:45 +02:00
placemouse: adding options for tiled position being relative to client center
This commit is contained in:
parent
0f28402305
commit
b4758c388d
@ -1161,7 +1161,12 @@ static Button buttons[] = {
|
|||||||
#endif // BAR_STATUSCMD_PATCH
|
#endif // BAR_STATUSCMD_PATCH
|
||||||
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
|
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
|
||||||
#if PLACEMOUSE_PATCH
|
#if PLACEMOUSE_PATCH
|
||||||
{ ClkClientWin, MODKEY|ControlMask, Button1, placemouse, {0} },
|
/* placemouse options, choose which feels more natural:
|
||||||
|
* 0 - tiled position is relative to mouse cursor
|
||||||
|
* 1 - tiled postiion is relative to window center
|
||||||
|
* 2 - mouse pointer warps to window center
|
||||||
|
*/
|
||||||
|
{ ClkClientWin, MODKEY|ControlMask, Button1, placemouse, {.i = 1} },
|
||||||
#endif // PLACEMOUSE_PATCH
|
#endif // PLACEMOUSE_PATCH
|
||||||
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
|
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
|
||||||
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
|
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
|
||||||
|
143
patch/placemouse.c
Normal file
143
patch/placemouse.c
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
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;
|
||||||
|
}
|
5
patch/placemouse.h
Normal file
5
patch/placemouse.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#define INTERSECTC(x,y,w,h,z) (MAX(0, MIN((x)+(w),(z)->x+(z)->w) - MAX((x),(z)->x)) \
|
||||||
|
* MAX(0, MIN((y)+(h),(z)->y+(z)->h) - MAX((y),(z)->y)))
|
||||||
|
|
||||||
|
static void placemouse(const Arg *arg);
|
||||||
|
static Client *recttoclient(int x, int y, int w, int h);
|
Loading…
Reference in New Issue
Block a user