You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
patches/dwm/dwm-sortscreens-20191007-cb...

77 lines
2.5 KiB
Diff

From fe6553c3d6e7e93aa74242cda0c33e05571147aa Mon Sep 17 00:00:00 2001
From: Sebastian Sareyko <sl@setq.dk>
Date: Fri, 27 Sep 2019 12:32:41 +0200
Subject: [PATCH] Sort screens by origin
Doing a multi-head setup using other means than Xinerama may lead to
XineramaQueryScreens() returning the screens in an order that does not
actually represent the actual screen layout. This in turn may result
in dwm using the "wrong" monitor in monitor related
functions (focusmon(), tagmon(), applying rules, ...).
This change sorts the list of unique screens by their origin to
alleviate this problem.
---
dwm.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/dwm.c b/dwm.c
index 4465af1..3a60b0c 100644
--- a/dwm.c
+++ b/dwm.c
@@ -56,6 +56,8 @@
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
#define TAGMASK ((1 << LENGTH(tags)) - 1)
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
+#define RIGHTOF(a,b) (a.y_org > b.y_org) || \
+ ((a.y_org == b.y_org) && (a.x_org > b.x_org))
/* enums */
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
@@ -205,6 +207,9 @@ static void setup(void);
static void seturgent(Client *c, int urg);
static void showhide(Client *c);
static void sigchld(int unused);
+#ifdef XINERAMA
+static void sortscreens(XineramaScreenInfo *screens, int n);
+#endif /* XINERAMA */
static void spawn(const Arg *arg);
static void tag(const Arg *arg);
static void tagmon(const Arg *arg);
@@ -1636,6 +1641,24 @@ sigchld(int unused)
while (0 < waitpid(-1, NULL, WNOHANG));
}
+#ifdef XINERAMA
+void
+sortscreens(XineramaScreenInfo *screens, int n)
+{
+ int i, j;
+ XineramaScreenInfo *screen = ecalloc(1, sizeof(XineramaScreenInfo));
+
+ for (i = 0; i < n; i++)
+ for (j = i + 1; j < n; j++)
+ if (RIGHTOF(screens[i], screens[j])) {
+ memcpy(&screen[0], &screens[i], sizeof(XineramaScreenInfo));
+ memcpy(&screens[i], &screens[j], sizeof(XineramaScreenInfo));
+ memcpy(&screens[j], &screen[0], sizeof(XineramaScreenInfo));
+ }
+ XFree(screen);
+}
+#endif /* XINERAMA */
+
void
spawn(const Arg *arg)
{
@@ -1868,6 +1891,7 @@ updategeom(void)
memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo));
XFree(info);
nn = j;
+ sortscreens(unique, nn);
if (n <= nn) { /* new monitors available */
for (i = 0; i < (nn - n); i++) {
for (m = mons; m && m->next; m = m->next);
--
2.21.0