From b26c8bb3046e80f2be2e5ebc9fa9d067ad443f0d Mon Sep 17 00:00:00 2001 From: Antoine Martin Date: Mon, 7 Aug 2017 10:14:17 +0000 Subject: [PATCH] #1611 * ship udev rule to add MOUSE_WHEEL_CLICK_COUNT to our uinput devices * make wheel multiplier configurable via XPRA_MOUSE_WHEEL_CLICK_MULTIPLIER env var * log uinput button name git-svn-id: https://xpra.org/svn/Xpra/trunk@16652 3bb7dfac-3a0b-4e04-842a-767bc560f471 --- rpmbuild/xpra.spec | 2 ++ src/setup.py | 9 +++++++-- .../rules.d/71-xpra-virtual-pointer.rules | 3 +++ src/xpra/x11/x11_server_base.py | 19 ++++++++++++++++--- 4 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 src/udev/rules.d/71-xpra-virtual-pointer.rules diff --git a/rpmbuild/xpra.spec b/rpmbuild/xpra.spec index a22a00ea3e..8d1b65a264 100644 --- a/rpmbuild/xpra.spec +++ b/rpmbuild/xpra.spec @@ -573,6 +573,7 @@ rm -rf $RPM_BUILD_ROOT %{_prefix}/lib/systemd/system/xpra.service %{_prefix}/lib/systemd/system/xpra.socket %{_prefix}/lib/cups/backend/xpraforwarder +%{_prefix}/lib/udev/rules.d/71-xpra-virtual-pointer.rules %config(noreplace) %{_sysconfdir}/sysconfig/xpra %config %{_prefix}/lib/tmpfiles.d/xpra.conf %config %{_prefix}/lib/sysusers.d/xpra.conf @@ -722,6 +723,7 @@ else /bin/systemctl daemon-reload >/dev/null 2>&1 || : /bin/systemctl restart xpra.socket >/dev/null 2>&1 || : fi +udevadm control --reload-rules && udevadm trigger || : %endif %post common-client diff --git a/src/setup.py b/src/setup.py index 130849bdd0..a7333c9d31 100755 --- a/src/setup.py +++ b/src/setup.py @@ -152,6 +152,7 @@ def is_RH(): x11_ENABLED = DEFAULT and not WIN32 and not OSX xinput_ENABLED = x11_ENABLED +uinput_ENABLED = x11_ENABLED dbus_ENABLED = DEFAULT and x11_ENABLED and not (OSX or WIN32) gtk_x11_ENABLED = DEFAULT and not WIN32 and not OSX gtk2_ENABLED = DEFAULT and client_ENABLED and not PYTHON3 @@ -215,7 +216,7 @@ def is_RH(): "csc_libyuv", "bencode", "cython_bencode", "vsock", "mdns", "clipboard", - "server", "client", "dbus", "x11", "xinput", "sd_listen", + "server", "client", "dbus", "x11", "xinput", "uinput", "sd_listen", "gtk_x11", "service", "gtk2", "gtk3", "example", "html5", "minify", "html5_gzip", "html5_brotli", @@ -1483,7 +1484,9 @@ def copytodir(src, dst_dir, chmod=0o644): if any(x.find("xpra_Xdummy")>=0 for x in (xvfb_command or [])) or Xdummy_wrapper_ENABLED is True: copytodir("scripts/xpra_Xdummy", "bin", chmod=0o755) #install xorg*.conf, cuda.conf and nvenc.keys: - etc_xpra_files = ["xorg.conf", "xorg-uinput.conf"] + etc_xpra_files = ["xorg.conf"] + if uinput_ENABLED: + etc_xpra_files.append("xorg-uinput.conf") if nvenc_ENABLED: etc_xpra_files += ["cuda.conf", "nvenc.keys"] for x in etc_xpra_files: @@ -1535,6 +1538,8 @@ def copytodir(src, dst_dir, chmod=0o644): #not supported by all distros, but doesn't hurt to install them anyway: for x in ("tmpfiles.d", "sysusers.d"): add_data_files("lib/%s" % x, ["%s/xpra.conf" % x]) + if uinput_ENABLED: + add_data_files("lib/udev/rules.d/", ["udev/rules.d/71-xpra-virtual-pointer.rules"]) #gentoo does weird things, calls --no-compile with build *and* install #then expects to find the cython modules!? ie: diff --git a/src/udev/rules.d/71-xpra-virtual-pointer.rules b/src/udev/rules.d/71-xpra-virtual-pointer.rules new file mode 100644 index 0000000000..d06282fea0 --- /dev/null +++ b/src/udev/rules.d/71-xpra-virtual-pointer.rules @@ -0,0 +1,3 @@ +# allow xpra to use fine grained scrolling + +ACTION=="add|change", ATTRS{name}=="Xpra Virtual Pointer", ENV{MOUSE_WHEEL_CLICK_ANGLE}="1", ENV{MOUSE_WHEEL_CLICK_COUNT}="360" diff --git a/src/xpra/x11/x11_server_base.py b/src/xpra/x11/x11_server_base.py index 1b6ca25bd5..407b996c0f 100644 --- a/src/xpra/x11/x11_server_base.py +++ b/src/xpra/x11/x11_server_base.py @@ -53,6 +53,7 @@ MAX_CONCURRENT_CONNECTIONS = envint("XPRA_MAX_CONCURRENT_CONNECTIONS", 20) ALWAYS_NOTIFY_MOTION = envbool("XPRA_ALWAYS_NOTIFY_MOTION", False) +MOUSE_WHEEL_CLICK_MULTIPLIER = envint("XPRA_MOUSE_WHEEL_CLICK_MULTIPLIER", 30) class XTestPointerDevice(object): @@ -100,14 +101,26 @@ def move_pointer(self, screen_no, x, y, *_args): def click(self, button, pressed, *_args): import uinput + BUTTON_STR = { + uinput.BTN_LEFT : "BTN_LEFT", + uinput.BTN_RIGHT : "BTN_RIGHT", + uinput.BTN_MIDDLE : "BTN_MIDDLE", + uinput.BTN_SIDE : "BTN_SIDE", + uinput.BTN_EXTRA : "BTN_EXTRA", + uinput.REL_WHEEL : "REL_WHEEL", + } + #this multiplier is based on the values defined in 71-xpra-virtual-pointer.rules as: + #MOUSE_WHEEL_CLICK_COUNT=360 + #MOUSE_WHEEL_CLICK_ANGLE=1 + mult = MOUSE_WHEEL_CLICK_MULTIPLIER if button==4: ubutton = uinput.REL_WHEEL - val = 1 + val = 1*mult if pressed: #only send one event return elif button==5: ubutton = uinput.REL_WHEEL - val = -1 + val = -1*mult if pressed: #only send one event return else: @@ -120,7 +133,7 @@ def click(self, button, pressed, *_args): }.get(button) val = bool(pressed) if ubutton: - mouselog("UInput.click(%i, %s) uinput button=%#x, %#x, value=%s", button, pressed, ubutton[0], ubutton[1], val) + mouselog("UInput.click(%i, %s) uinput button=%s (%#x), %#x, value=%s", button, pressed, BUTTON_STR.get(ubutton), ubutton[0], ubutton[1], val) self.device.emit(ubutton, val) else: mouselog("UInput.click(%i, %s) uinput button not found - using XTest", button, pressed)