commit b1533df3279d51283d7d42c2cd47239e2dee94fa
parent f46cf2a305792ce6d6f60fc820cfbbb10621fe45
Author: wh1tepearl <wh1tepearl@gmail.com>
Date: Wed, 25 Mar 2026 21:19:29 +0000
make focusdir actually work in infinite canvas (tags)
Diffstat:
1 file changed, 75 insertions(+), 33 deletions(-)
diff --git a/modules/directionalfocus/directionalfocus.c b/modules/directionalfocus/directionalfocus.c
@@ -8,8 +8,6 @@ focusdir(const Arg *arg)
unsigned int score = -1;
unsigned int client_score;
- int dist;
- int dirweight = 20;
int isfloating = s->isfloating;
next = s->next;
@@ -21,38 +19,82 @@ focusdir(const Arg *arg)
if (!next)
next = s->mon->clients;
- if (!ISVISIBLE(c) || c->isfloating != isfloating) // || HIDDEN(c)
+ 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 INFINITE_TAGS
+ if (selmon->lt[selmon->sellt]->arrange == NULL) {
+
+ int s_cx = s->x + s->w / 2;
+ int s_cy = s->y + s->h / 2;
+ int c_cx = c->x + c->w / 2;
+ int c_cy = c->y + c->h / 2;
+
+ int dx = c_cx - s_cx; /* positive = c is to the right */
+ int dy = c_cy - s_cy; /* positive = c is below */
+
+ int axial, lateral;
+
+ switch (arg->i) {
+ case 0: /* left */
+ if (dx >= 0) continue;
+ axial = -dx;
+ lateral = abs(dy);
+ break;
+ case 1: /* right */
+ if (dx <= 0) continue;
+ axial = dx;
+ lateral = abs(dy);
+ break;
+ case 2: /* up */
+ if (dy >= 0) continue;
+ axial = -dy;
+ lateral = abs(dx);
+ break;
+ default:
+ case 3: /* down */
+ if (dy <= 0) continue;
+ axial = dy;
+ lateral = abs(dx);
+ break;
+ }
+
+ client_score = axial + (lateral * lateral) / (axial + 1);
+ } else
+#endif
+ {
+ int dist;
+ int dirweight = 20;
+ switch (arg->i) {
+ case 0:
+ 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:
+ 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:
+ 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:
+ 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) {
+ if (client_score < score) {
score = client_score;
f = c;
}
@@ -61,11 +103,11 @@ focusdir(const Arg *arg)
if (f && f != s) {
focus(f);
#if INFINITE_TAGS
- centerwindow(NULL);
+ centerwindow(NULL);
#endif
#if WARP_TO_CLIENT && WARP_TO_CENTER_OF_WINDOW_AFFECTED_BY_FOCUSSTACK
- warptoclient(f);
+ warptoclient(f);
#endif
- restack(f->mon);
+ restack(f->mon);
}
}