From b2fe1e07087fa6ecff9f1d4395acf59047028935 Mon Sep 17 00:00:00 2001 From: Jaimos Skriletz Date: Wed, 16 Oct 2024 19:55:46 -0600 Subject: [PATCH] FindScreenOfXY: Return closest monitor in dead area. If a monitor is not found, due to the point (x,y) being in a dead area, instead of returning RB_MIN, return the closest monitor using the taxi cab metric to the closest border. This is makes it so if a window is placed in a dead area when honoring the working area, the window is placed on the closest monitor instead of the first monitor. --- libs/FScreen.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/libs/FScreen.c b/libs/FScreen.c index a7742f660..6cc1693d6 100644 --- a/libs/FScreen.c +++ b/libs/FScreen.c @@ -824,11 +824,32 @@ FindScreenOfXY(int x, int y) return (m); } - /* FIXME: this is a convenience, but could confuse callers. */ - if (m == NULL) - return RB_MIN(monitors, &monitor_q); + struct monitor *m_min; + if (m == NULL) { + /* No monitor found, point is in a dead area. + * Find closest monitor using the taxi cab metric. + */ + int dmin = INT_MAX; + struct monitor *m_min; + + RB_FOREACH(m, monitors, &monitor_q) { + int d = 0; + if (x < m->si->x) + d += m->si->x - x; + if (x > m->si->x + m->si->w) + d += x - m->si->x - m->si->w; + if (y < m->si->y) + d += m->si->y - y; + if (y > m->si->y + m->si->h) + d += y - m->si->y - m->si->h; + if (d < dmin) { + dmin = d; + m_min = m; + } + } + } - return (NULL); + return (m_min); } /* Returns the primary screen if arg.name is NULL. */