diff options
Diffstat (limited to 'wm-addons/jgmenu/xrandr.patch')
-rw-r--r-- | wm-addons/jgmenu/xrandr.patch | 150 |
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) |