summaryrefslogtreecommitdiffstats
path: root/wm-addons
diff options
context:
space:
mode:
authorVlad Glagolev2018-08-11 17:37:28 -0700
committerVlad Glagolev2018-08-11 17:37:28 -0700
commiteeeb0d672a91fa6e02aea13fde33cfee289a7069 (patch)
tree995782d693be13757ba9d0ea09d3fed9c18fa89f /wm-addons
parenta1a5af0a95cd941afa2347b45050495f74a38ed8 (diff)
jgmenu: added xrandr support
Diffstat (limited to 'wm-addons')
-rwxr-xr-xwm-addons/jgmenu/CONFIGURE4
-rwxr-xr-xwm-addons/jgmenu/DEPENDS8
-rw-r--r--wm-addons/jgmenu/HISTORY6
-rwxr-xr-xwm-addons/jgmenu/PRE_BUILD5
-rw-r--r--wm-addons/jgmenu/at-pointer.patch104
-rw-r--r--wm-addons/jgmenu/xrandr.patch150
6 files changed, 275 insertions, 2 deletions
diff --git a/wm-addons/jgmenu/CONFIGURE b/wm-addons/jgmenu/CONFIGURE
index 7ae3323c6d..13a78b1465 100755
--- a/wm-addons/jgmenu/CONFIGURE
+++ b/wm-addons/jgmenu/CONFIGURE
@@ -1 +1,3 @@
-config_query JGMENU_SINGLE_WINDOW "Re-enable single window mode option?" n
+config_query JGMENU_SINGLE_WINDOW "Re-enable single window mode option?" n &&
+
+config_query JGMENU_XRANDR "Use modern Xrandr extension instead of Xinerama?" n
diff --git a/wm-addons/jgmenu/DEPENDS b/wm-addons/jgmenu/DEPENDS
index 855583f8af..0f50a37421 100755
--- a/wm-addons/jgmenu/DEPENDS
+++ b/wm-addons/jgmenu/DEPENDS
@@ -1,6 +1,12 @@
depends libpng &&
depends libx11 &&
-depends libxinerama &&
+
+if [ ${JGMENU_XRANDR} == y ]; then
+ depends libxrandr
+else
+ depends libxinerama
+fi &&
+
depends pango &&
depends cairo &&
depends librsvg2 &&
diff --git a/wm-addons/jgmenu/HISTORY b/wm-addons/jgmenu/HISTORY
index 29a8658601..ede90b5ec4 100644
--- a/wm-addons/jgmenu/HISTORY
+++ b/wm-addons/jgmenu/HISTORY
@@ -1,3 +1,9 @@
+2018-08-11 Vlad Glagolev <stealth@sourcemage.org>
+ * CONFIGURE, DEPENDS: added xrandr option
+ * PRE_BUILD: apply patches
+ * at-pointer.patch, xrandr.patch: added, official patches for optional
+ xrandr support
+
2018-04-06 Vlad Glagolev <stealth@sourcemage.org>
* CONFIGURE: added, for single window mode option
* PRE_BUILD: added, to apply patch
diff --git a/wm-addons/jgmenu/PRE_BUILD b/wm-addons/jgmenu/PRE_BUILD
index 064396da95..2af9ca2483 100755
--- a/wm-addons/jgmenu/PRE_BUILD
+++ b/wm-addons/jgmenu/PRE_BUILD
@@ -1,6 +1,11 @@
default_pre_build &&
cd "${SOURCE_DIRECTORY}" &&
+if [ ${JGMENU_XRANDR} == y ]; then
+ patch -p1 < "${SPELL_DIRECTORY}/at-pointer.patch" &&
+ patch -p1 < "${SPELL_DIRECTORY}/xrandr.patch"
+fi &&
+
if [ ${JGMENU_SINGLE_WINDOW} == y ]; then
patch -p1 < "${SPELL_DIRECTORY}/single_window.patch"
fi
diff --git a/wm-addons/jgmenu/at-pointer.patch b/wm-addons/jgmenu/at-pointer.patch
new file mode 100644
index 0000000000..aed6c7f5a1
--- /dev/null
+++ b/wm-addons/jgmenu/at-pointer.patch
@@ -0,0 +1,104 @@
+From 1e0bae4e0bacbb0570ac2181055ce628748d35ee Mon Sep 17 00:00:00 2001
+From: Johan Malm <jgm323@gmail.com>
+Date: Thu, 17 May 2018 18:28:36 +0100
+Subject: [PATCH] multi-monitor: launch correctly 'at-pointer' (issue #56)
+
+Update screen dimensions before launching when in at_pointer mode in
+order to use the correct x0, y0, width and height.
+---
+ geometry.c | 12 ++++++++----
+ geometry.h | 1 +
+ jgmenu.c | 1 +
+ x11-ui.c | 15 +++++++++++++++
+ 4 files changed, 25 insertions(+), 4 deletions(-)
+
+diff --git a/geometry.c b/geometry.c
+index 55aa737..541ac2e 100644
+--- a/geometry.c
++++ b/geometry.c
+@@ -133,6 +133,13 @@ static void geo_update(void)
+ update_sub_window();
+ }
+
++void geo_update_monitor_coords(void)
++{
++ ui_get_screen_res(&screen_x0, &screen_y0, &screen_width,
++ &screen_height, config.monitor);
++ geo_update();
++}
++
+ void geo_init(void)
+ {
+ /*
+@@ -155,10 +162,7 @@ void geo_init(void)
+ item_margin_x = 4;
+ item_margin_y = 4;
+
+- ui_get_screen_res(&screen_x0, &screen_y0, &screen_width,
+- &screen_height, config.monitor);
+-
+- geo_update();
++ geo_update_monitor_coords();
+ }
+
+ int geo_get_item_coordinates(struct area *a)
+diff --git a/geometry.h b/geometry.h
+index f0647f9..ce57adf 100644
+--- a/geometry.h
++++ b/geometry.h
+@@ -47,6 +47,7 @@
+ #include "x11-ui.h"
+ #include "align.h"
+
++void geo_update_monitor_coords(void);
+ void geo_init(void);
+ int geo_get_item_coordinates(struct area *a);
+ struct point geo_get_max_itemarea_that_fits(void);
+diff --git a/jgmenu.c b/jgmenu.c
+index 7b75cec..9b41ea4 100644
+--- a/jgmenu.c
++++ b/jgmenu.c
+@@ -809,6 +809,7 @@ void launch_menu_at_pointer(void)
+ struct point pos;
+ struct area wa;
+
++ geo_update_monitor_coords();
+ XQueryPointer(ui->dpy, DefaultRootWindow(ui->dpy), &dw, &dw, &di, &di,
+ &pos.x, &pos.y, &du);
+
+diff --git a/x11-ui.c b/x11-ui.c
+index edc6bde..3404f84 100644
+--- a/x11-ui.c
++++ b/x11-ui.c
+@@ -131,6 +131,17 @@ void ui_init(void)
+ ui->root = RootWindow(ui->dpy, ui->screen);
+ }
+
++static void print_screen_info(int n, XineramaScreenInfo *screen_info)
++{
++ 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);
++}
++
+ #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) - \
+@@ -146,9 +157,13 @@ void ui_get_screen_res(int *x0, int *y0, int *width, int *height, int monitor)
+ 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;
++
++ /* handle user specified monitor (from config file) */
+ if (monitor) {
+ if (monitor > n)
+ die("cannot connect to monitor '%d' (max %d)", monitor, n);
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)