NICHOLAS85 / gebaar-libinput

Gebaar, A Super Simple WM Independent Touchpad Gesture Daemon for libinput
GNU General Public License v3.0
7 stars 4 forks source link

[BUG] Touch gestures are not aware of device orientation #14

Open NICHOLAS85 opened 3 years ago

NICHOLAS85 commented 3 years ago

Currently, all touch gestures are recognized based on the device's initial orientation. This becomes problematic for users who plan on using their device in different orientations and expect the gestures to adjust accordingly. Libinput, as far as I'm aware, does not provide accelerometer data or device orientation data which could be used to change gestures accordingly. One way of fixing this behavior is by reading accelerometer data through X11 like https://github.com/GuLinux/ScreenRotator does so.

The knowledge required to implement this functionality is above my skill level for now.

NICHOLAS85 commented 3 years ago

Following https://github.com/JoseExposito/touchegg/issues/459 for a proper solution

NICHOLAS85 commented 3 years ago

Progress made on determining gesture directionality using xinput and X11. This would however add xinput and X11 dependency requirements making this feature incompatible with Wayland.

cdurden commented 3 years ago

On my setup, the vendor ID and product ID do not uniquely identify a device, which gave me some trouble when using this branch. In particular, my touchscreen is associated with three devices ("Wacom HID 482E Finger", "Wacom HID 482E Pen eraser", and "Wacom HID 482E Pen stylus"). When I set my orientation, I only set the "Coordinate Transformation Matrix" on the device named "Wacom HID 482E Finger", but the determine_orientation function retrieves the matrix from the "Pen eraser" device because it is the last device with the given vendor ID and product ID. A possible solution is to set up deviceids to map the device name (which would be a string) to the device id. This works for me, but I am still not sure if the device name is unique.

NICHOLAS85 commented 3 years ago

The reason I fell back to product and vendor ID was because I found that the device name provided by xinput and by libinput differed, making it an unreliable string to map with the device ids. I'll have to do some more research to find a better way of implementing the feature but if you happen to find any more useful information feel free to open a pr or send a message here

How are you setting your Coordinate Transformation Matrix? All implementations I've seen adjust all matrices accordingly which would allow the current code I wrote to work even if it uses the wrong devices matrix. Would there be an issue with also setting your "Pen eraser" matrix in addition to "Finger"?

cdurden commented 3 years ago

In answer to your question, I am setting Coordinate Transformation Matrix like this:

xinput` set-prop "Coordinate Transformation Matrix" ...

Yes, setting these properties for all devices (in my case "Wacom HID 482E Finger" and "Wacom HID 482E Pen eraser") is the solution I went with. This works, but I was not expecting it to be necessary. Below is some further background, as well as a solution that I believe is less problematic.

Background

There is a 1:1 mapping between libinput devices and /dev/input/eventX device nodes. (Source)

Based on the code in the libinput-tools here, it looks like libinput_device_get_sysname returns eventX

Proposed Solution

--- src/io/input.cpp    2021-03-29 01:14:12.107322926 -0500
+++ src/io/input.cpp.new    2021-03-29 01:13:16.535394500 -0500
@@ -102,11 +102,10 @@

 void gebaar::io::Input::determine_orientation(libinput_device* dev) {
   Display * display = XOpenDisplay(NULL);
-  int vendor = libinput_device_get_id_vendor(dev);
-  int product = libinput_device_get_id_product(dev);
-  int id = deviceids[vendor][product];
-  spdlog::get("main")->debug("[{}] at {} - {}: idmap {}.{}.{}",
-                                 FN, __LINE__, __func__, vendor, product, id);
+  const char* sysname = libinput_device_get_sysname(dev);
+  int id = atoi(sysname+5); // is this how you do pointer arithmetic?
+  spdlog::get("main")->debug("[{}] at {} - {}: idmap {}",
+                                 FN, __LINE__, __func__, id);
   Atom floatAtom;
   Atom type_return;
   floatAtom = XInternAtom(display, "FLOAT", false);

Further documentation that seems relevant to this issue is at Initialization and manipulation of input devices (See the section on libinput_device_get_device_group()).