summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorProsperousPotato <ProsperousPotato@users.noreply.github.com>2025-12-31 22:42:26 +0000
committerProsperousPotato <ProsperousPotato@users.noreply.github.com>2025-12-31 22:42:26 +0000
commit4aa7d94347b2dc940901d6e073a65df75ae04829 (patch)
treee6eab851ac68a00205196285583dfc9f0a6ab108
parent48f53402aa54f0c0ca28990db090ead7634f3f39 (diff)
dragmfact with mouse
-rw-r--r--config.h1
-rw-r--r--dwm.c111
2 files changed, 111 insertions, 1 deletions
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);
@@ -697,6 +698,112 @@ destroynotify(XEvent *e)
}
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)
{
Client **tc;
@@ -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++)