From 4aa7d94347b2dc940901d6e073a65df75ae04829 Mon Sep 17 00:00:00 2001 From: ProsperousPotato Date: Wed, 31 Dec 2025 22:42:26 +0000 Subject: dragmfact with mouse --- config.h | 1 + dwm.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 111 insertions(+), 1 deletion(-) diff --git a/config.h b/config.h index bee334d..bc83231 100644 --- a/config.h +++ b/config.h @@ -164,6 +164,7 @@ static const Button buttons[] = { /* click event mask button function argument */ { ClkClientWin, MODKEY, Button1, movemouse, {0} }, // regular window move { ClkClientWin, MODKEY|ShiftMask, Button1, movemouse, {.i = 1} }, // tiled window move + { ClkClientWin, MODKEY|ShiftMask, Button3, dragmfact, {0} }, { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, diff --git a/dwm.c b/dwm.c index 80e6c12..ec11435 100644 --- a/dwm.c +++ b/dwm.c @@ -62,7 +62,7 @@ #define TAGMASK ((1 << LENGTH(tags)) - 1) /* enums */ -enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ +enum { CurNormal, CurResize, CurMove, CurResizeHorzArrow, CurResizeVertArrow, CurLast }; /* cursor */ enum { SchemeNorm, SchemeSel }; /* color schemes */ enum { NetSupported, NetWMName, NetWMState, NetWMCheck, NetWMFullscreen, NetActiveWindow, NetWMWindowType, @@ -164,6 +164,7 @@ static void destroynotify(XEvent *e); static void detach(Client *c); static void detachstack(Client *c); static Monitor *dirtomon(int dir); +static void dragmfact(const Arg *arg); static void enternotify(XEvent *e); static void focus(Client *c); static void focusin(XEvent *e); @@ -696,6 +697,112 @@ destroynotify(XEvent *e) unmanage(c->swallowing, 1); } +void +dragmfact(const Arg *arg) +{ + unsigned int n; + int py, px; // pointer coordinates + int ax, ay, aw, ah; // area position, width and height + int center = 0, horizontal = 0, mirror = 0, fixed = 0; // layout configuration + double fact; + Monitor *m; + XEvent ev; + Time lasttime = 0; + + m = selmon; + + Client *c; + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + + ax = m->wx; + ay = m->wy; + ah = m->wh; + aw = m->ww; + + if (!n) + return; + + /* do not allow mfact to be modified under certain conditions */ + if (!m->lt[m->sellt]->arrange // floating layout + || (!fixed && m->nmaster && n <= m->nmaster) // no master + || m->lt[m->sellt]->arrange == &monocle) + return; + + if (center) { + if (horizontal) { + px = ax + aw / 2; + py = ay + ah / 2 + ah * m->mfact / 2.0; + } else { // vertical split + px = ax + aw / 2 + aw * m->mfact / 2.0; + py = ay + ah / 2; + } + } else if (horizontal) { + px = ax + aw / 2; + if (mirror) + py = ay + (ah * (1.0 - m->mfact)); + else + py = ay + (ah * m->mfact); + } else { // vertical split + if (mirror) + px = ax + (aw * m->mfact); + else + px = ax + (aw * m->mfact); + py = ay + ah / 2; + } + + if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, + None, cursor[horizontal ? CurResizeVertArrow : CurResizeHorzArrow]->cursor, CurrentTime) != GrabSuccess) + return; + XWarpPointer(dpy, None, root, 0, 0, 0, 0, px, py); + + 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 / 40)) + continue; + if (lasttime != 0) { + px = ev.xmotion.x; + py = ev.xmotion.y; + } + lasttime = ev.xmotion.time; + + if (center) + if (horizontal) + if (py - ay > ah / 2) + fact = (double) 1.0 - (ay + ah - py) * 2 / (double) ah; + else + fact = (double) 1.0 - (py - ay) * 2 / (double) ah; + else + if (px - ax > aw / 2) + fact = (double) 1.0 - (ax + aw - px) * 2 / (double) aw; + else + fact = (double) 1.0 - (px - ax) * 2 / (double) aw; + else + if (horizontal) + fact = (double) (py - ay) / (double) ah; + else + fact = (double) (px - ax) / (double) aw; + + if (!center && mirror) + fact = 1.0 - fact; + + setmfact(&((Arg) { .f = 1.0 + fact })); + px = ev.xmotion.x; + py = ev.xmotion.y; + break; + } + } while (ev.type != ButtonRelease); + + XUngrabPointer(dpy, CurrentTime); + while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); +} + void detach(Client *c) { @@ -1713,6 +1820,8 @@ setup(void) cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); cursor[CurResize] = drw_cur_create(drw, XC_sizing); cursor[CurMove] = drw_cur_create(drw, XC_fleur); + cursor[CurResizeHorzArrow] = drw_cur_create(drw, XC_sb_h_double_arrow); + cursor[CurResizeVertArrow] = drw_cur_create(drw, XC_sb_v_double_arrow); /* init appearance */ scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); for (i = 0; i < LENGTH(colors); i++) -- cgit v1.2.3