sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

commit efa06680da77bcca77995840d20adab824ecec04
parent bd337776bdf316967c18877f324857039a8ad43d
Author: Niky Kovalski <nikykovalski@gmail.com>
Date:   Tue, 29 Sep 2026 05:12:54 -0400

[dwm][patch] movestackmouse

A patch that adds a function which drags the focused window and places
it on a tiled layout without toggling the float state.

Diffstat:
Adwm.suckless.org/patches/movestackmouse/dwm-movestackmouse-20260929-44dbc68.diff | 156+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/movestackmouse/index.md | 15+++++++++++++++
2 files changed, 171 insertions(+), 0 deletions(-)

diff --git a/dwm.suckless.org/patches/movestackmouse/dwm-movestackmouse-20260929-44dbc68.diff b/dwm.suckless.org/patches/movestackmouse/dwm-movestackmouse-20260929-44dbc68.diff @@ -0,0 +1,156 @@ +From cf83ca2326c9ea6dffa0757fb4805d1f33cfa207 Mon Sep 17 00:00:00 2001 +From: Niky Kovalski <nikykovalski@gmail.com> +Date: Tue, 29 Sep 2026 01:10:41 -0400 +Subject: [PATCH] movestackmouse + +Move focused window while dragging. Tiled windows will not be toggled to +the floating state. +--- + config.def.h | 1 + + dwm.1 | 3 ++ + dwm.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 86 insertions(+) + +diff --git a/config.def.h b/config.def.h +index 81c3fc0..206261b 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -107,6 +107,7 @@ static const Button buttons[] = { + { ClkWinTitle, 0, Button2, zoom, {0} }, + { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, + { ClkClientWin, MODKEY, Button1, movemouse, {0} }, ++ { ClkClientWin, MODKEY|ShiftMask, Button1, movestackmouse, {0} }, + { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, + { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, + { ClkTagBar, 0, Button1, view, {0} }, +diff --git a/dwm.1 b/dwm.1 +index ddc8321..de4bf91 100644 +--- a/dwm.1 ++++ b/dwm.1 +@@ -144,6 +144,9 @@ Add/remove all windows with nth tag to/from the view. + Quit dwm. + .SS Mouse commands + .TP ++.B Mod1\-Shift\-Button1 ++Move focused window while dragging. Tiled windows will not be toggled to the floating state. ++.TP + .B Mod1\-Button1 + Move focused window while dragging. Tiled windows will be toggled to the floating state. + .TP +diff --git a/dwm.c b/dwm.c +index ab3a84c..3e9229e 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -146,6 +146,8 @@ static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interac + static void arrange(Monitor *m); + static void arrangemon(Monitor *m); + static void attach(Client *c); ++static void attachafter(Client *c, Client *t); ++static void attachbefore(Client *c, Client *t); + static void attachstack(Client *c); + static void buttonpress(XEvent *e); + static void checkotherwm(void); +@@ -183,6 +185,7 @@ static void maprequest(XEvent *e); + static void monocle(Monitor *m); + static void motionnotify(XEvent *e); + static void movemouse(const Arg *arg); ++static void movestackmouse(const Arg *arg); + static Client *nexttiled(Client *c); + static void pop(Client *c); + static void propertynotify(XEvent *e); +@@ -407,6 +410,25 @@ attach(Client *c) + c->mon->clients = c; + } + ++void ++attachafter(Client *c, Client *t) ++{ ++ c->next = t->next; ++ t->next = c; ++} ++ ++void ++attachbefore(Client *c, Client *t) ++{ ++ Client **tc; ++ ++ for (tc = &t->mon->clients; *tc && *tc != t; tc = &(*tc)->next); ++ if (*tc) ++ c->next = (*tc)->next; ++ c->next = *tc; ++ *tc = c; ++} ++ + void + attachstack(Client *c) + { +@@ -1202,6 +1224,66 @@ movemouse(const Arg *arg) + } + } + ++void ++movestackmouse(const Arg *arg) ++{ ++ Client *c, *t; ++ Monitor *m; ++ XEvent ev; ++ Time lasttime = 0; ++ int isfound = 0; ++ ++ if (!(c = selmon->sel)) ++ return; ++ if (c->isfullscreen) /* no support moving fullscreen windows by mouse */ ++ return; ++ if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) { /* fallback to movemouse */ ++ movemouse(NULL); ++ return; ++ } ++ if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, ++ None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) ++ 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 / refreshrate)) ++ continue; ++ lasttime = ev.xmotion.time; ++ isfound = 0; ++ ++ for (t = nexttiled(c->mon->clients); t; t = nexttiled(t->next)) { ++ if (t == c) { ++ isfound = 1; ++ continue; ++ } ++ if (ev.xmotion.x_root >= t->x && ++ ev.xmotion.x_root < t->x + t->w + 2 * t->bw && ++ ev.xmotion.y_root >= t->y && ++ ev.xmotion.y_root < t->y + t->h + 2 * t->bw) { ++ detach(c); ++ isfound ? attachafter(c, t) : attachbefore(c, t); ++ focus(c); ++ arrange(c->mon); ++ break; ++ } ++ } ++ break; ++ } ++ } while (ev.type != ButtonRelease); ++ XUngrabPointer(dpy, CurrentTime); ++ if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { ++ selmon = m; ++ focus(NULL); ++ } ++} ++ + Client * + nexttiled(Client *c) + { +-- +2.55.0 + diff --git a/dwm.suckless.org/patches/movestackmouse/index.md b/dwm.suckless.org/patches/movestackmouse/index.md @@ -0,0 +1,15 @@ +movestackmouse +============== + +Description +----------- +A patch that adds a function which drags the focused window and places +it on a tiled layout without toggling the float state. + +Download +-------- +* [dwm-movestackmouse-20260929-44dbc68.diff](dwm-movestackmouse-20260929-44dbc68.diff) + +Author +------ +* Niky Kovalski - <nikykovalski@gmail.com>