Package: xwit Version: 3.4-16+b1 Severity: wishlist Dear Maintainer,
xwit should support the Multi Pointer X system that comes with the current Xorg server. It should have options to run - XISetClientPointer because window managers don't bother to run it. - XISetFocus for the same reason. - XIWarpPointer in addition to XWarpPointer Having these options in xwit will enable users to do many multi pointer things that otherwise would require patching many applications. It enables running multiple programs or program instances simultaneously that each want to grab the pointer or have some unwanted effect when losing focus. Examples: Running multiple instances of minetest on same Xorg server is normally not possible, because each instance will want to grab the pointer. After running XISetClientPointer on them, each instance will grab only the designated pointer and all instances can be used simultanously. Running koules with a gamepad while doing something else with a mouse and keyboard is normally not possible, because koules will pause when losing focus. Running XISetClientPointer and XISetFocus can prevent it form losing focus. I wrote a patch to add these options to xwit.
diff -u -r a/Makefile b/Makefile --- a/Makefile 2022-09-05 20:51:10.000000000 +0300 +++ b/Makefile 2022-06-07 23:55:47.933537017 +0300 @@ -1,6 +1,6 @@ CFLAGS ?= -Wall -O2 -g -Wstrict-prototypes -Wmissing-prototypes LDFLAGS ?= -Wl,-z,defs -LIBRARIES = -lX11 +LIBRARIES = -lX11 -lXi all: xwit diff -u -r a/xwit.c b/xwit.c --- a/xwit.c 2022-09-05 20:51:10.000000000 +0300 +++ b/xwit.c 2022-09-05 21:22:06.414875202 +0300 @@ -31,6 +31,7 @@ #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/Xproto.h> +#include <X11/extensions/XInput2.h> #include <stdio.h> #include <stdlib.h> #include <limits.h> @@ -66,11 +67,12 @@ -pop -focus -iconify -unmap -print \n\ -raise -lower -opposite -[un]circulate\n\ -resize w h -rows r -columns c -[r]move x y\n\ - -[r]warp x y -colormap <colormapid> -[no]save\n\ + -[xi][r]warp x y -colormap <colormapid> -[no]save\n\ -name <name> -iconname <name> -property <lookfor>\n\ -bitmap <file> -mask <file> -[r]iconmove x y\n\ -[no]backingstore -[no]saveunder\n\ -[no]keyrepeat keycode ... keycode - keycode\n\ + -keyboard n -pointer n -xifocus -xisetpointer\n\ -id <windowid> -root -current -select -all\n\ -names <initialsubstrings>... [must be last]\n", program_name); @@ -78,26 +80,28 @@ } enum functions { - pop, focus, icon, unmap, colormap, + pop, focus, xifocus, icon, unmap, colormap, print, raise, lower, opposite, circulate, uncirculate, - move, rmove, warp, rwarp, + move, rmove, warp, rwarp, xiwarp, xirwarp, resize, save, nosave, keyrepeat, nokeyrepeat, name, iconname, rows, columns, iconbitmap, iconmove, riconmove, + xisetpointer, F_winattr, lastfunc }; static long function; -#define FBIT(func) (1 << (func)) +#define FBIT(func) (1ll << (func)) /* options that don't need a window */ #define NOWINDOW \ (FBIT(save) | FBIT(nosave) | \ FBIT(keyrepeat) | FBIT(nokeyrepeat) | \ - FBIT(rwarp)) + FBIT(rwarp) | \ + FBIT(xirwarp)) static enum winidmode { WID_none, @@ -126,6 +130,8 @@ static char *bitmapname; static char *maskname; static int Gbs, Gsu; +static int clientpointer; +static int clientkeyboard; /* set if we found a window to act on*/ static int Gwinfound; @@ -562,10 +568,18 @@ XWarpPointer(dpy, None, window, 0, 0, 0, 0, warpx, warpy); break; + case xiwarp: + XIWarpPointer(dpy, clientpointer, None, window, 0, 0, 0, 0, + warpx, warpy); + break; case rwarp: XWarpPointer(dpy, None, None, 0, 0, 0, 0, warpx, warpy); break; + case xirwarp: + XIWarpPointer(dpy, clientpointer, None, None, 0, 0, 0, 0, + warpx, warpy); + break; case move: domove(window, tox, toy, Gright, Gbottom); break; @@ -616,6 +630,14 @@ } break; } + case xifocus: { + XISetFocus(dpy, clientkeyboard, window, CurrentTime); + break; + } + case xisetpointer: { + XISetClientPointer(dpy, window, clientpointer); + break; + } case raise: values.stack_mode = Above; value_mask = CWStackMode; @@ -1028,6 +1050,9 @@ else if (matchopt("f*ocus", 0, pargc, argv)) { function |= FBIT(focus); } + else if (matchopt("xifocus", 0, pargc, argv)) { + function |= FBIT(xifocus); + } else if (matchopt("ra*ise", 0, pargc, argv)) { function |= FBIT(raise); } @@ -1068,6 +1093,29 @@ warpy = atoi(argv[2]); argv += 2; } + else if (matchopt("xiwarp", 2, pargc, argv)) { + function |= FBIT(xiwarp); + warpx = atoi(argv[1]); + warpy = atoi(argv[2]); + argv += 2; + } + else if (matchopt("xirwarp", 2, pargc, argv)) { + function |= FBIT(xirwarp); + warpx = atoi(argv[1]); + warpy = atoi(argv[2]); + argv += 2; + } + else if (matchopt("xisetpointer", 0, pargc, argv)) { + function |= FBIT(xisetpointer); + } + else if (matchopt("pointer", 1, pargc, argv)) { + clientpointer = atoi(argv[1]); + argv += 1; + } + else if (matchopt("keyboard", 1, pargc, argv)) { + clientkeyboard = atoi(argv[1]); + argv += 1; + } else if (matchopt("r*esize", 2, pargc, argv)) { function |= FBIT(resize); towidth = atoi(argv[1]); diff -u -r a/xwit.man b/xwit.man --- a/xwit.man 2022-09-05 20:51:10.000000000 +0300 +++ b/xwit.man 2022-09-05 20:49:32.107400495 +0300 @@ -51,6 +51,16 @@ .RB [ \- [ no ] keyrepeat .IR "keycode ... keycode \- keycode ..." ] .br +.RB [ \-keyboard +.IR deviceid ] +.RB [ \-pointer +.IR deviceid ] +.RB [ \-xi [ r ] warp +.IR x\ y ] +.br +.RB [ \-xifocus ] +.RB [ \-xisetpointer ] +.br .RB [ \-id .IR windowid ] .RB [ \-root ] @@ -182,6 +192,25 @@ selected windows. If \-property is given, that one will be printed instead of the name. .TP +\-keyboard n +use keyboard n with xifocus +.TP +\-pointer n +use pointer n with xiwarp, xirwarp and xifocus +.TP +\-xiwarp x y +warp the specified pointer to the given position relative to the specified +window. Add -root to rasp to and absolut position +.TP +\-xirwarp x y +move the specified pointer by the given relative amount. +.TP +\-xifocus +will give the input focus of the specified keyboard to the specified window +.TP +\-xisetpointer +calls XISetClientPointer on the specified window with the specified pointer +.TP Window Selection .br If no window is specified, $WINDOWID will be used if set;