KarsMulder / evsieve

A utility for mapping events from Linux event devices.
GNU General Public License v2.0
199 stars 11 forks source link

Translate touchpad events to mouse events? #3

Open oblitzitate opened 2 years ago

oblitzitate commented 2 years ago

So currently, touchpad support is lacking in laptop virtual machines. Translating touchpad events to mouse events would be useful for finally giving the touchpad adequate functionality.

I understand this is more complex than usual, but I think this would be a common enough of a use case for all laptop virtual machines. It'd be nice to be able to solely use the touchpad instead of having to carry around a mouse while moving around with a laptop.

KarsMulder commented 2 years ago

Great suggestion!

This one is a bit difficult to implement for me because none of the devices I regularly use have a touchpad, and from a cursory look on the documentation it appears that there are several classes of touchpads with different protocols as well. Especially correctly handling multi-touch devices looks like an obstacle.

I do have a pentablet, which may or may not be too different from a touchpad. In the last few commits (current commit: 80bd2de) I have added a toy --abs-to-rel argument which converts abs:x to rel:x events and abs:y to rel:y events to test the viability of this feature. I do not particularly like its current interface, so I will most likely rework/remove this argument before releasing a stable version of evsieve.

The following script converts my pentablet to a mouse quite nicely. The problem is the amount of device-specific fiddling required:

evsieve --input /dev/input/by-id/pentablet grab \
        --block abs:x:0 abs:y:0 \
        --abs-to-rel speed=0.1 reset=btn:tool_pen:0 \
        --map abs:pressure:0..1~ btn:left:1 \
        --map abs:pressure:1~..0 btn:left:0 \
        --map btn:stylus btn:middle \
        --map btn:stylus2 btn:right \
        --output rel:x rel:y btn:left btn:middle btn:right

The --block abs:x:0 abs:y:0 exists to prevent my tablet from sporadically moving my cursor to the top-right corner when I lift my pen off the surface; the reset=... instructs evsieve to ignore the next set of abs:x and abs:y after receiving a btn:tool_pen:0 event, which is necessary because reasons. I suppose other devices are going to have other quirks like this.

The difficult part of this feature is going to be (1) finding enough devices to get a good overview of how touchpads generally work and be able to properly test my implementations, and (2) designing an interface to manipulate them that is simple enough that the average user can understand it.

KarsMulder commented 2 years ago

I added some support for relative value maps to the latest development version. For example:

        ---map abs:x rel:x:0.1delta \
        ---map abs:y rel:y:0.1delta \

will map each EV_ABS, ABS_X event to a EV_REL, REL_X event with a value equal to 0.1 times the difference between the current and last value reported for EV_ABS, ABS_X. This doesn't quite solve the touchpad-to-mouse mapping issue yet, but it is an useful tool for this problem space.

As usual, all features added to the the main git branch are subject to change until they become part of a stable release. (Yes, I am aware that a stable 1.3 release is overdue.)

KarsMulder commented 2 years ago

I have removed --abs-to-rel, most of its use is superseded by relative value maps. The remaining functionality it had is technically already implementable with a complex framework of hooks and toggles, but that requires a ton of boilerplate making it practically unusable for the average user. I have some thoughts for an API things that reduce the boilerplate, but that is going to have to wait for version 1.4; I want to prioritise getting version 1.3 released first.

I have also renamed delta to d, turning the above example into:

        ---map abs:x rel:x:0.1d \
        ---map abs:y rel:y:0.1d \

My inner mathematician thinks that either the variables should be a single letter long, or there should be an explicit multiplication symbol like rel:x:0.1*delta. However, the asterisk is a special character that gets interpreted by the shell, which makes it risky to expect that character to show up in a command line argument. Therefore single-letter variables it is.

The good news is that I have found a device with a touchpad, so I can now test things. It seems to work about the same as my pentablet, except that it uses BTN_TOOL_FINGER instead of BTN_TOOL_PEN, and emits EV_ABS_MT events in addition to the regular EV_ABS.

The biggest issue that does not seem easy to handle is gesture interpreting. If all you want to do is translate finger movements to a cursor movement, that seems reachable with relative value maps + some syntactic sugar for toggles. However, gestures like "put two fingers on the touchpad and move them down to scroll" are a different beast. I could either try to integrate with (a patched version of) libinput to accomplish this, or try to reinvent the wheel and try to interpret simple gestures directly in evsieve.

soda-salie commented 3 months ago

Greetings!

I am the owner of the Thinkpad x1 Tablet gen 3 device

OS = ArchLinux WM = Sway

The touchscreen is working out of the box, but in some applications, such as Intellij Idea, it does not want to work

That is, line selection does not work, right-click emulation, two-finger scrolling, the cursor is not displayed

I came up with the idea that all these problems would be solved if the touchscreen worked like a touchpad

I was looking for ways to configure via libinput, libwacom, sway-input, I found different mappers that make up a reaction to gestures from the touchscreen, but these are gestures, not mapping finger movements to cursor movements

Can I use evsieve to make the touchscreen work like a touchpad?

For example, somehow collect events from the touchscreen device and match the events of the virtual mouse device ydotool

libinput splits a physical device into two, one of them is of the tablet type, the other is touch

Events appear in /dev/input/... from a touch device

KarsMulder commented 3 months ago

I don't have any touchscreen and touchpad to test myself, but I would imagine that the events emitted by a touchscreen and touchpad to be pretty similar.

It seems that libinput allows you to override the type of an input device by changing the udev properties of the device.

Maybe changing the type of your touchscreen to ID_INPUT_TOUCHPAD using udev will solve your problem?

(Example udev rules available in posted link. I imagine that you will have to reboot your system after making changes to the udev configuration to make your changes take effect.)