From de0043b926ba6affdc6348bbed51b7b13bbe0583 Mon Sep 17 00:00:00 2001 From: hazen2215 Date: Fri, 28 Jan 2022 18:06:24 +0900 Subject: [PATCH] New package: keynav-0.0.20180821 --- .../patches/fix-cursor-passthrough.patch | 161 ++++++++++++++++++ .../patches/fix-overlapping-screens.patch | 57 +++++++ srcpkgs/keynav/template | 27 +++ 3 files changed, 245 insertions(+) create mode 100644 srcpkgs/keynav/patches/fix-cursor-passthrough.patch create mode 100644 srcpkgs/keynav/patches/fix-overlapping-screens.patch create mode 100644 srcpkgs/keynav/template diff --git a/srcpkgs/keynav/patches/fix-cursor-passthrough.patch b/srcpkgs/keynav/patches/fix-cursor-passthrough.patch new file mode 100644 index 000000000000..85fcce7ebb6c --- /dev/null +++ b/srcpkgs/keynav/patches/fix-cursor-passthrough.patch @@ -0,0 +1,161 @@ +From 024fc8fe47454f460faa14cbb1727e04596886c0 Mon Sep 17 00:00:00 2001 +From: jabashque +Date: Sun, 23 Feb 2020 01:50:36 -0800 +Subject: [PATCH 1/2] Set input shape to 0x0 to passthrough mouse + +Define the input shape to be empty so that one cannot click on the grid. +This resolves all issues where the cursor ends up pointing to the grid +itself instead of the window under the grid due to openpixel() not being +called. +--- + keynav.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/keynav.c b/keynav.c +index 65abe7c..4453fc8 100644 +--- a/keynav.c ++++ b/keynav.c +@@ -983,6 +983,9 @@ void cmd_start(char *args) { + /* Tell the window manager not to manage us */ + winattr.override_redirect = 1; + XChangeWindowAttributes(dpy, zone, CWOverrideRedirect, &winattr); ++ /* Set the input shape to be nothing so that the mouse can still ++ * click/scroll if on the grid */ ++ XShapeCombineRectangles(dpy, zone, ShapeInput, 0, 0, NULL, 0, ShapeSet, 0); + + XSelectInput(dpy, zone, StructureNotifyMask | ExposureMask + | PointerMotionMask | LeaveWindowMask ); + +From 88aba2415bd20e70be91a24e2eb2409cb44b4076 Mon Sep 17 00:00:00 2001 +From: jabashque +Date: Sun, 23 Feb 2020 04:35:37 -0800 +Subject: [PATCH 2/2] Remove {open,close}pixel(), var mouseinfo, type + mouseinfo_t + +Input shape is now set to 0x0, which takes care of the functionality +that {open,close}pixel() previously provided. As such, completely remove +{open,close}pixel() since they're no longer needed. In addition, remove +the mouseinfo var and the mouseinfo_t type since those were used only by +{open,close}pixel(). +--- + keynav.c | 64 +------------------------------------------------------- + 1 file changed, 1 insertion(+), 63 deletions(-) + +diff --git a/keynav.c b/keynav.c +index 4453fc8..fae5a76 100644 +--- a/keynav.c ++++ b/keynav.c +@@ -80,11 +80,6 @@ typedef struct wininfo { + int curviewport; + } wininfo_t; + +-typedef struct mouseinfo { +- int x; +- int y; +-} mouseinfo_t; +- + typedef struct viewport { + int x; + int y; +@@ -96,7 +91,6 @@ typedef struct viewport { + } viewport_t; + + static wininfo_t wininfo; +-static mouseinfo_t mouseinfo; + static viewport_t *viewports; + static int nviewports = 0; + static int xinerama = 0; +@@ -191,8 +185,6 @@ void sighup(int sig); + void restart(); + void recordings_save(const char *filename); + void parse_recordings(const char *filename); +-void openpixel(Display *dpy, Window zone, mouseinfo_t *mouseinfo); +-void closepixel(Display *dpy, Window zone, mouseinfo_t *mouseinfo); + + typedef struct dispatch { + char *command; +@@ -1178,21 +1170,7 @@ void cmd_warp(char *args) { + x = wininfo.x + wininfo.w / 2; + y = wininfo.y + wininfo.h / 2; + +- if (mouseinfo.x != -1 && mouseinfo.y != -1) { +- closepixel(dpy, zone, &mouseinfo); +- } +- +- /* Open pixels hould be relative to the window coordinates, +- * not screen coordinates. */ +- mouseinfo.x = x - wininfo.x; +- mouseinfo.y = y - wininfo.y; +- openpixel(dpy, zone, &mouseinfo); +- + xdo_move_mouse(xdo, x, y, viewports[wininfo.curviewport].screen_num); +- xdo_wait_for_mouse_move_to(xdo, x, y); +- +- /* TODO(sissel): do we need to open again? */ +- openpixel(dpy, zone, &mouseinfo); + } + + void cmd_click(char *args) { +@@ -1981,36 +1959,6 @@ void parse_recordings(const char *filename) { + fclose(fp); + } + +-void openpixel(Display *dpy, Window zone, mouseinfo_t *mouseinfo) { +- XRectangle rect; +- if (mouseinfo->x == -1 && mouseinfo->y == -1) { +- return; +- } +- +- rect.x = mouseinfo->x; +- rect.y = mouseinfo->y; +- rect.width = 1; +- rect.height = 1; +- +- XShapeCombineRectangles(dpy, zone, ShapeBounding, 0, 0, &rect, 1, +- ShapeSubtract, 0); +-} /* void openpixel */ +- +-void closepixel(Display *dpy, Window zone, mouseinfo_t *mouseinfo) { +- XRectangle rect; +- if (mouseinfo->x == -1 && mouseinfo->y == -1) { +- return; +- } +- +- rect.x = mouseinfo->x; +- rect.y = mouseinfo->y; +- rect.width = 1; +- rect.height = 1; +- +- XShapeCombineRectangles(dpy, zone, ShapeBounding, 0, 0, &rect, 1, +- ShapeUnion, 0); +-} /* void closepixel */ +- + int main(int argc, char **argv) { + char *pcDisplay; + int ret; +@@ -2099,17 +2047,6 @@ int main(int argc, char **argv) { + } + break; + +- case MotionNotify: +- if (zone) { +- if (mouseinfo.x != -1 && mouseinfo.y != -1) { +- closepixel(dpy, zone, &mouseinfo); +- } +- mouseinfo.x = e.xmotion.x; +- mouseinfo.y = e.xmotion.y; +- openpixel(dpy, zone, &mouseinfo); +- } +- break; +- + // Ignorable events. + case GraphicsExpose: + case NoExpose: +@@ -2118,6 +2055,7 @@ int main(int argc, char **argv) { + case DestroyNotify: // window was destroyed + case UnmapNotify: // window was unmapped (hidden) + case MappingNotify: // when keyboard mapping changes ++ case MotionNotify: // when mouse movement is detected + break; + default: + if (e.type == xrandr_event_base + RRScreenChangeNotify) { diff --git a/srcpkgs/keynav/patches/fix-overlapping-screens.patch b/srcpkgs/keynav/patches/fix-overlapping-screens.patch new file mode 100644 index 000000000000..ea9385b9f7a5 --- /dev/null +++ b/srcpkgs/keynav/patches/fix-overlapping-screens.patch @@ -0,0 +1,57 @@ +From b3d7a0966c94ea9b6dd0265c512cb7a14293f71e Mon Sep 17 00:00:00 2001 +From: Yutao Yuan +Date: Mon, 4 Oct 2021 22:33:32 +0800 +Subject: [PATCH] Treat overlapping screens (like xrandr --same-as) as one + screen + +--- + keynav.c | 33 ++++++++++++++++++++++----------- + 1 file changed, 22 insertions(+), 11 deletions(-) + +diff --git a/keynav.c b/keynav.c +index 65abe7c..b4e5103 100644 +--- a/keynav.c ++++ b/keynav.c +@@ -1811,20 +1811,31 @@ void query_screens() { + } + + void query_screen_xinerama() { +- int i; ++ int i, j, num_screens; + XineramaScreenInfo *screeninfo; + +- screeninfo = XineramaQueryScreens(dpy, &nviewports); ++ screeninfo = XineramaQueryScreens(dpy, &num_screens); + free(viewports); +- viewports = calloc(nviewports, sizeof(viewport_t)); +- for (i = 0; i < nviewports; i++) { +- viewports[i].x = screeninfo[i].x_org; +- viewports[i].y = screeninfo[i].y_org; +- viewports[i].w = screeninfo[i].width; +- viewports[i].h = screeninfo[i].height; +- viewports[i].screen_num = 0; +- viewports[i].screen = ScreenOfDisplay(dpy, 0); +- viewports[i].root = DefaultRootWindow(dpy); ++ viewports = calloc(num_screens, sizeof(viewport_t)); ++ nviewports = 0; ++ for (i = 0; i < num_screens; i++) { ++ int overlapping = 0; ++ for (j = 0; j < nviewports; j++) { ++ if (viewports[j].x == screeninfo[i].x_org && viewports[j].y == screeninfo[i].y_org) { ++ overlapping = 1; ++ break; ++ } ++ } ++ if (!overlapping) { ++ viewports[nviewports].x = screeninfo[i].x_org; ++ viewports[nviewports].y = screeninfo[i].y_org; ++ viewports[nviewports].w = screeninfo[i].width; ++ viewports[nviewports].h = screeninfo[i].height; ++ viewports[nviewports].screen_num = 0; ++ viewports[nviewports].screen = ScreenOfDisplay(dpy, 0); ++ viewports[nviewports].root = DefaultRootWindow(dpy); ++ nviewports++; ++ } + } + XFree(screeninfo); + } diff --git a/srcpkgs/keynav/template b/srcpkgs/keynav/template new file mode 100644 index 000000000000..f5f2b5f67452 --- /dev/null +++ b/srcpkgs/keynav/template @@ -0,0 +1,27 @@ +# Template file for 'keynav' +pkgname=keynav +version=0.0.20180821 +revision=1 +_githash=78f9e076a5618aba43b030fbb9344c415c30c1e5 +wrksrc="${pkgname}-${_githash}" +build_style=gnu-makefile +make_use_env=yes +hostmakedepends="pkg-config perl" +makedepends="cairo-devel libXinerama-devel xdotool-devel libglib-devel libXrandr-devel" +checkdepends="xorg-server-xvfb" +short_desc="Quick way to use cursor via the keyboard" +maintainer="hazen2215 " +license="BSD-3-Clause" +homepage="https://www.semicomplete.com/projects/keynav/" +distfiles="https://github.com/jordansissel/keynav/archive/${_githash}.tar.gz" +checksum=def79c32ea8aec57ec65310ede962f4d5d54ef26c5adccb351a19fb5683b678f + +do_check() { + ./test.sh +} + +do_install() { + make PREFIX=${DESTDIR}/usr install + vsconf keynavrc + vlicense COPYRIGHT +}