sortscreens: Adding for reference

pull/19/head
bakkeby 4 years ago
parent d8551daaee
commit 8a8ece81a1

@ -0,0 +1,76 @@
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
Loading…
Cancel
Save