summaryrefslogtreecommitdiffstats
path: root/wm-addons/jgmenu/xrandr.patch
diff options
context:
space:
mode:
Diffstat (limited to 'wm-addons/jgmenu/xrandr.patch')
-rw-r--r--wm-addons/jgmenu/xrandr.patch150
1 files changed, 150 insertions, 0 deletions
diff --git a/wm-addons/jgmenu/xrandr.patch b/wm-addons/jgmenu/xrandr.patch
new file mode 100644
index 0000000000..71047a30a8
--- /dev/null
+++ b/wm-addons/jgmenu/xrandr.patch
@@ -0,0 +1,150 @@
+From f8ccef404fe8436e4473e48cfa66d8389286e234 Mon Sep 17 00:00:00 2001
+From: Johan Malm <jgm323@gmail.com>
+Date: Sat, 11 Aug 2018 13:45:35 +0100
+Subject: [PATCH] x11-ui.c: replace xinerama with xrandr (issue #60)
+
+xinerama has been reported to segfault with some new graphics cards.
+
+Suggested-by: @vaygr
+---
+ Makefile.inc | 2 +-
+ x11-ui.c | 91 +++++++++++++++++++++++++++++++++++-----------------
+ 2 files changed, 63 insertions(+), 30 deletions(-)
+
+diff --git a/Makefile.inc b/Makefile.inc
+index b33b399..9f362c8 100644
+--- a/Makefile.inc
++++ b/Makefile.inc
+@@ -23,7 +23,7 @@ jgmenu-ob: CFLAGS += `xml2-config --cflags`
+ jgmenu-xdg: CFLAGS += `xml2-config --cflags`
+ jgmenu-lx: CFLAGS += `pkg-config --cflags glib-2.0 libmenu-cache`
+
+-jgmenu: LIBS += `pkg-config x11 xinerama cairo pango pangocairo librsvg-2.0 --libs`
++jgmenu: LIBS += `pkg-config x11 xrandr cairo pango pangocairo librsvg-2.0 --libs`
+ jgmenu: LIBS += -pthread -lrt -lpng
+ jgmenu-ob: LIBS += `xml2-config --libs`
+ jgmenu-xdg: LIBS += `xml2-config --libs`
+diff --git a/x11-ui.c b/x11-ui.c
+index 7ed7678..e6df14d 100644
+--- a/x11-ui.c
++++ b/x11-ui.c
+@@ -16,7 +16,7 @@
+ #include <X11/Xlib.h>
+ #include <X11/Xatom.h>
+ #include <X11/Xutil.h>
+-#include <X11/extensions/Xinerama.h>
++#include <X11/extensions/Xrandr.h>
+ #include <unistd.h> /* for usleep */
+
+ #include "x11-ui.h"
+@@ -131,49 +131,82 @@ void ui_init(void)
+ ui->root = RootWindow(ui->dpy, ui->screen);
+ }
+
+-static void print_screen_info(int n, XineramaScreenInfo *screen_info)
++static void print_screen_info(void)
+ {
+- int i;
+-
+- info("%d monitor(s) detected", n);
+- for (i = 0; i < n; i++)
+- printf(" - monitor-%d: x0=%d; y0=%d; w=%d; h=%d\n",
+- i + 1, screen_info[i].x_org, screen_info[i].y_org,
+- screen_info[i].width, screen_info[i].height);
++ int i, n;
++ XRRScreenResources *sr;
++ XRRCrtcInfo *ci = NULL;
++
++ sr = XRRGetScreenResources(ui->dpy, DefaultRootWindow(ui->dpy));
++ n = sr->noutput;
++ info("%d xrandr outputs(s) detected", n);
++ for (i = 0; i < n; i++) {
++ ci = XRRGetCrtcInfo(ui->dpy, sr, sr->crtcs[i]);
++ if (!ci->width || !ci->height)
++ printf(" - monitor-%d: not connected\n", i + 1);
++ else
++ printf(" - monitor-%d: x0=%d; y0=%d; w=%d; h=%d\n",
++ i + 1, ci->x, ci->y, ci->width, ci->height);
++ }
++ XRRFreeCrtcInfo(ci);
++ XRRFreeScreenResources(sr);
+ }
+
+-#define INTERSECT(x, y, w, h, r) (MAX(0, MIN((x) + (w), (r).x_org + (r).width) - \
+- MAX((x), (r).x_org)) &&\
+- MAX(0, MIN((y) + (h), (r).y_org + (r).height) - \
+- MAX((y), (r).y_org)))
++static int intersect(int x, int y, int w, int h, XRRCrtcInfo *ci)
++{
++ return MAX(0, MIN(x + w, (int)ci->x + (int)ci->width) - MAX(x, (int)ci->x)) &&
++ MAX(0, MIN(y + h, (int)ci->y + (int)ci->height) - MAX(y, (int)ci->y));
++}
+
+ void ui_get_screen_res(int *x0, int *y0, int *width, int *height, int monitor)
+ {
+ int i, n, x, y, di;
+ unsigned int du;
+ Window dw;
+- XineramaScreenInfo *screen_info;
++ XRRScreenResources *sr;
++ XRRCrtcInfo *ci = NULL;
+
+- screen_info = XineramaQueryScreens(ui->dpy, &n);
+- BUG_ON(!screen_info);
+- XQueryPointer(ui->dpy, ui->root, &dw, &dw, &x, &y, &di, &di, &du);
+ if (getenv("JGMENU_SCREEN_INFO"))
+- print_screen_info(n, screen_info);
+- for (i = 0; i < n; i++)
+- if (INTERSECT(x, y, 1, 1, screen_info[i]))
+- break;
++ print_screen_info();
++ sr = XRRGetScreenResources(ui->dpy, DefaultRootWindow(ui->dpy));
++ BUG_ON(!sr);
++ n = sr->noutput;
+
+- /* handle user specified monitor (from config file) */
++ /*
++ * Global variable config.monitor let's the user specify a monitor.
++ * If not set, we use the current pointer position
++ */
+ if (monitor) {
+ if (monitor > n)
+- die("cannot connect to monitor '%d' (max %d)", monitor, n);
+- i = monitor - 1;
++ die("cannot connect to monitor '%d'", monitor);
++ ci = XRRGetCrtcInfo(ui->dpy, sr, sr->crtcs[monitor - 1]);
++ if (!ci->width || !ci->height)
++ die("cannot connect to monitor '%d'", monitor);
++ info("using user specified monitor '%d'", monitor);
++ goto monitor_selected;
++ }
++
++ XQueryPointer(ui->dpy, ui->root, &dw, &dw, &x, &y, &di, &di, &du);
++ for (i = 0; i < n; i++) {
++ ci = XRRGetCrtcInfo(ui->dpy, sr, sr->crtcs[i]);
++ BUG_ON(!ci);
++ if (!ci->width || !ci->height)
++ continue;
++ if (intersect(x, y, 1, 1, ci)) {
++ info("using monitor '%d'", i + 1);
++ break;
++ }
+ }
+- *x0 = screen_info[i].x_org;
+- *y0 = screen_info[i].y_org;
+- *width = screen_info[i].width;
+- *height = screen_info[i].height;
+- XFree(screen_info);
++
++monitor_selected:
++ if (!ci)
++ die("connection could be established to monitor");
++ *x0 = ci->x;
++ *y0 = ci->y;
++ *width = ci->width;
++ *height = ci->height;
++ XRRFreeCrtcInfo(ci);
++ XRRFreeScreenResources(sr);
+ }
+
+ void set_wm_class(void)