commit bd8d5bb8784dc30bd89ade2df52165a348877cfc
parent bbe5769caf7c058db35ab466ed18ffbb08a2ac3f
Author: wh1tepearl <wh1tepearl@gmail.com>
Date: Mon, 23 Feb 2026 22:36:15 +0000
add directional move
Diffstat:
6 files changed, 99 insertions(+), 0 deletions(-)
diff --git a/config.def.h b/config.def.h
@@ -188,6 +188,12 @@ static const Key keys[] = {
{ MODKEY, XK_Up, focusdir, {.i = 2 } }, // up
{ MODKEY, XK_Down, focusdir, {.i = 3 } }, // down
#endif
+#if DIRECTIONAL_MOVE
+ { Mod1Mask, XK_Left, movedir, {.i = 0} },
+ { Mod1Mask, XK_Right, movedir, {.i = 1} },
+ { Mod1Mask, XK_Up, movedir, {.i = 2} },
+ { Mod1Mask, XK_Down, movedir, {.i = 3} },
+#endif
};
/* button definitions */
diff --git a/modules.def.h b/modules.def.h
@@ -79,6 +79,7 @@ Even though this sounds complex, it is actually pretty lightweight ~250 l.o.c, a
#define MOVE_IN_TILED 0 // Support for moving windows in tiled mode.
#define EWMH_TAGS 0 // Support for EWMH tags, recommended if you want to use external bars with less pain
#define DIRECTIONAL_FOCUS 0 // yeah.
+#define DIRECTIONAL_MOVE 0 // yeah.
diff --git a/modules/directionalmove/directionalmove.c b/modules/directionalmove/directionalmove.c
@@ -0,0 +1,83 @@
+void
+movedir(const Arg *arg)
+{
+ Client *s = selmon->sel, *f = NULL, *c, *next;
+ if (!s)
+ return;
+ unsigned int score = -1;
+ unsigned int client_score;
+ int dist;
+ int dirweight = 20;
+ int isfloating = s->isfloating;
+ next = s->next;
+ if (!next)
+ next = s->mon->clients;
+ for (c = next; c != s; c = next) {
+ next = c->next;
+ if (!next)
+ next = s->mon->clients;
+ if (!ISVISIBLE(c) || c->isfloating != isfloating)
+ continue;
+ switch (arg->i) {
+ case 0: // left
+ dist = s->x - c->x - c->w;
+ client_score =
+ dirweight * MIN(abs(dist), abs(dist + s->mon->ww)) +
+ abs(s->y - c->y);
+ break;
+ case 1: // right
+ dist = c->x - s->x - s->w;
+ client_score =
+ dirweight * MIN(abs(dist), abs(dist + s->mon->ww)) +
+ abs(c->y - s->y);
+ break;
+ case 2: // up
+ dist = s->y - c->y - c->h;
+ client_score =
+ dirweight * MIN(abs(dist), abs(dist + s->mon->wh)) +
+ abs(s->x - c->x);
+ break;
+ default:
+ case 3: // down
+ dist = c->y - s->y - s->h;
+ client_score =
+ dirweight * MIN(abs(dist), abs(dist + s->mon->wh)) +
+ abs(c->x - s->x);
+ break;
+ }
+ if (((arg->i == 0 || arg->i == 2) && client_score <= score) || client_score < score) {
+ score = client_score;
+ f = c;
+ }
+ }
+ if (!f || f == s)
+ return;
+
+ Client *ps = NULL, *pf = NULL, *p;
+ for (p = s->mon->clients; p; p = p->next) {
+ if (p->next == s) ps = p;
+ if (p->next == f) pf = p;
+ }
+
+ if (s->next == f) {
+ if (ps) ps->next = f; else s->mon->clients = f;
+ s->next = f->next;
+ f->next = s;
+ } else if (f->next == s) {
+ if (pf) pf->next = s; else s->mon->clients = s;
+ f->next = s->next;
+ s->next = f;
+ } else {
+ if (ps) ps->next = f; else s->mon->clients = f;
+ if (pf) pf->next = s; else s->mon->clients = s;
+ Client *tmp = s->next;
+ s->next = f->next;
+ f->next = tmp;
+ }
+
+ focus(s);
+#if WARP_TO_CLIENT && WARP_TO_CENTER_OF_WINDOW_AFFECTED_BY_FOCUSSTACK
+ warptoclient(f);
+#endif
+ arrange(s->mon);
+}
diff --git a/modules/directionalmove/directionalmove.h b/modules/directionalmove/directionalmove.h
@@ -0,0 +1 @@
+static void movedir(const Arg *arg);
diff --git a/modules/vxwm_includes.c b/modules/vxwm_includes.c
@@ -43,3 +43,7 @@
#if DIRECTIONAL_FOCUS
#include "directionalfocus/directionalfocus.c"
#endif
+
+#if DIRECTIONAL_MOVE
+#include "directionalmove/directionalmove.c"
+#endif
diff --git a/modules/vxwm_includes.h b/modules/vxwm_includes.h
@@ -39,3 +39,7 @@
#if DIRECTIONAL_FOCUS
#include "directionalfocus/directionalfocus.h"
#endif
+
+#if DIRECTIONAL_MOVE
+#include "directionalmove/directionalmove.h"
+#endif