linuxwacom / input-wacom

Linux kernel driver for Wacom devices
GNU General Public License v2.0
612 stars 58 forks source link

Jumpy cursor with Relative mode on CTH-670 and CTH-470 #54

Closed pepper-jelly closed 5 years ago

pepper-jelly commented 5 years ago

Hi. I am used to Relative mode with the tablet but starting from input-wacom-0.41.0 cursor jumps randomly. It looks like if Absolute and Relative modes would work at the same time. For solid behavior I am using input-wacom-0.40.0 for now. Please let me know if I can provide debug information or help somehow.

P.S. On any other wacom tablet without touch the issue does not appear with input-wacom-0.41.0 and later.

jigpu commented 5 years ago

There was one change between 0.40 and 0.41 which could potentially affect these tablets, but tests on my machine with a CTH-670 don't turn up anything. Does the jumpy cursor happen whenever the pen is in proximity, or only at specific times? Does moving the tablet to another location change the behavior (electrical interference can sometimes cause a jumpy cursor, and the change I mention might be more susceptible to noise). To make a recording of the jumpy pen events, you can try installing the "hid-replay" tools as described here and the "xinput" and "evemu-utils" packages from your distribution's repository. Next, run my capture.sh script as root and move the pen around, capturing a pointer jump. Finally, hit CTRL+C to stop the recording and attach the generated tarball to this bug.

Pinglinux commented 5 years ago

The version of the running kernel may tell us something too since Jason may be testing a kernel which is different from yours.

pepper-jelly commented 5 years ago

Thanks for prompt reply. Absolute mode "jumps" in Relative mode are reproducible among kernels 4.14, 4.18 and 4.19.

While recording events I also recorded video(attachment below). After each move on canvas I moved off pen completely for first 3 and all seems good. Then the issue appears while pen above but in range up to couple inches from tablet surface.

Here my settings:

!/bin/sh

xsetwacom --set "Wacom Bamboo 16FG 4x5 Finger touch" touch off

xsetwacom --set "Wacom Bamboo 16FG 4x5 Pen stylus" Mode Relative xinput set-prop "Wacom Bamboo 16FG 4x5 Pen stylus" "Device Accel Constant Deceleration" 3 xsetwacom --set "Wacom Bamboo 16FG 4x5 Pen stylus" Suppress 16

input-wacom-0.42.0 was rebuild and used with sudo modprobe -r wacom;sudo modprobe wacom switching back to input-wacom-0.40.0 makes all smooth again

Here the files: input-wacom#54.tar.gz

asokoloski commented 5 years ago

Hi all, I may be able to add some insight here. I came across this same bug using a CTH-470 after upgrading my kernel to 4.20 from 4.14 -- it worked fine before. Based on the info leschalu has given, I've managed to further narrow it down to this commit.

commit c3c633ee6013cb37182cf1eb5bef01fafeb8754c Author: Jason Gerecke killertofu@gmail.com Date: Fri May 18 07:17:18 2018 -0700

HID: wacom: Support "in range" for Intuos/Bamboo tablets where possible

The 1st-generation Intuos tablets (CTL-X80) include an "in range" flag
like some professional tablets. To ensure the pen remains usable at as
large as distance as possible (and to preemptively disable touch when
it is nearby) we need to ensure that we handle these "in range" events.
Handling of tool type identification has been moved to occur only when
the pen is fully in prox rather than any time the "stylus_in_proximity"
flag changes (which is controlled by the further-out "in range" flag).

Link: https://sourceforge.net/p/linuxwacom/bugs/358/
Link: https://github.com/linuxwacom/xf86-input-wacom/issues/14
Link: https://github.com/linuxwacom/xf86-input-wacom/issues/17
Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
Tested-by: Ping Cheng <ping.cheng@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
[jason.gerecke@wacom.com: Imported into input-wacom repository (8947b0cfdc)]
Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>

Immediately prior to this commit (at version 0.40.0, 0419a8a3f0898e1e5d01e02b06731c9b51fafcaf) relative mode works as expected. After this commit, raising the stylus up until the it's high enough that the cursor stops moving, but it's not fully out of range (I'm guessing) means that when the stylus is brought back down again, the cursor jumps immediately to the new location, rather than staying where it is. Only when the stylus is raised completely out of range does the cursor maintain its position as would be expected for relative mode.

I've also run capture.sh before and after the commit in question to illustrate the difference. For each, I first did some movements barely above the range where the cursor updates to test the bug, and then the same thing but lifting the stylus well out of range, which works in both cases.

Before, at 0.40.0 (0419a8a3f0898e1e5d01e02b06731c9b51fafcaf) This shows normal relative mode behaviour: record_1548560232.tar.gz

After, at c3c633ee6013cb37182cf1eb5bef01fafeb8754c. This shows the bug: record_1548560607.tar.gz

And manually downgrading to input-wacom-0.40.0 works for me too.

Thank you to everyone for your hard work on the wacom drivers!

scholar-mage commented 5 years ago

I have a wacom Intuos draw (CTL-490/w). I'm experiencing an issue which I believe is the same as the one described in this ticket. This happens for me on Ubuntu 18.04 with kernel 4.15.0-43-lowlatency. I've tried using the wacom kernel module that's in apt, as well as compiling 0.36.0, 0.40.0, and 0.42.0 from source. None of them seem to work for me without the weird absolute-jump-in-relative-mode behavior. Here's output from xev showing a huge jump when I place the pen back down near the tablet. See events #⁠3 - #⁠6 below.

MotionNotify event, serial 38, synthetic NO, window 0x4600001,
    root 0x15d, subw 0x0, time 322244, (405,491), root:(405,520),
    state 0x10, is_hint 0, same_screen YES

MotionNotify event, serial 37, synthetic NO, window 0x4600001,
    root 0x15d, subw 0x0, time 322260, (404,490), root:(404,519),
    state 0x10, is_hint 0, same_screen YES

MotionNotify event, serial 37, synthetic NO, window 0x4600001,
    root 0x15d, subw 0x0, time 323030, (576,551), root:(576,580),
    state 0x10, is_hint 0, same_screen YES

MotionNotify event, serial 37, synthetic NO, window 0x4600001,
    root 0x15d, subw 0x0, time 323036, (748,612), root:(748,641),
    state 0x10, is_hint 0, same_screen YES

MotionNotify event, serial 37, synthetic NO, window 0x4600001,
    root 0x15d, subw 0x0, time 323044, (919,673), root:(919,702),
    state 0x10, is_hint 0, same_screen YES

MotionNotify event, serial 37, synthetic NO, window 0x4600001,
    root 0x15d, subw 0x0, time 323052, (1090,734), root:(1090,763),
    state 0x10, is_hint 0, same_screen YES

MotionNotify event, serial 37, synthetic NO, window 0x4600001,
    root 0x15d, subw 0x0, time 323060, (1086,733), root:(1086,762),
    state 0x10, is_hint 0, same_screen YES

MotionNotify event, serial 37, synthetic NO, window 0x4600001,
    root 0x15d, subw 0x0, time 323066, (1083,732), root:(1083,761),
    state 0x10, is_hint 0, same_screen YES
asokoloski commented 5 years ago

@scholar-mage have you double-checked that the compiled versions are actually the ones loaded? You can do this by running "modinfo -F version wacom"

scholar-mage commented 5 years ago

Yeah. General procedure was as follows:

download tarball
$ tar -xf <file>
$ cd <dir>
$ ./configure
$ make
$ sudo make install
$ sudo rmmod wacom
$ sudo modprobe wacom
$ modinfo wacom | grep version

Now, I didn't try restarting the window manager or logging back out / back in. I suppose it's possible/likely that when reloading the module, that it doesn't automatically apply my window manager's (XFCE) settings of being in relative mode... I'll do some more testing and explicitly set it to relative mode after the modprobe.

Update: Yeah, it still happens with these configurations:

$ modinfo wacom | grep version
version:        v2.00-input-wacom-input-wacom-0.36.0

$ modinfo wacom | grep version
version:        v2.00-0.40.0

$ modinfo wacom | grep version
version:        v2.00-0.42.0
scholar-mage commented 5 years ago

Is this bug appropriately listed as an input-wacom bug, or is it more likely a bug in linuxwacom/xf86-input-wacom ?

I installed the most recent git version of xf86-input-wacom, but this still happens for me.

What can I do to bump this issue up on the priority list?

pepper-jelly commented 5 years ago

@scholar-mage There might be a conflict in xfce settings and applying the mode through terminal. Plus after module reload everything defaults so settings has to be re-applied. Could you test it again and re-plug tablet after 0.40.0 module reload?

scholar-mage commented 5 years ago

I just tested it, replugging the device doesn't seem to change anything.

I was configuring it via the command line, with this script:

#!/bin/bash
for x in $(xsetwacom --list devices | grep -o -P "id: \d+" | cut -f2 -d' ')
do
    xsetwacom set $x Mode Relative
done

Also, just for a sanity check:

$ xsetwacom --list devices | grep -o -P "id: \d+" | cut -f2 -d' '
17
18

$ xsetwacom --list devices 
Wacom Intuos S 2 Pen stylus         id: 17  type: STYLUS    
Wacom Intuos S 2 Pad pad            id: 18  type: PAD

I also tried disabling & re-enabling the device in the XFCE Mouse & Touchpad settings dialog. And setting it to relative there. But that also doesn't seem to change anything.

Trying to set relative mode on the pad via the above script yields an error message to the console (XI_BadMode). I presume that means the pad doesn't support relative mode - only the stylus does.

Also for sanity check:

$ modinfo wacom
filename:       /lib/modules/4.15.0-45-lowlatency/extra/wacom.ko
license:        GPL
description:    USB Wacom tablet driver
author:         Vojtech Pavlik <vojtech@ucw.cz>
version:        v2.00-0.40.0
srcversion:     D158DDA3466DFBA7E55F619
alias:          hid:b0005g0101v0000056Ap*
alias:          hid:b0018g0101v0000056Ap*
alias:          hid:b0003g0101v0000056Ap*
alias:          hid:b0003g*v000017EFp00006004
alias:          hid:b0003g0101v0000056Ap00005002
alias:          hid:b0003g0101v0000056Ap00005000
alias:          hid:b0003g0101v0000056Ap00004004
alias:          hid:b0003g0101v0000056Ap00004001
alias:          hid:b0003g0101v0000056Ap0000037B
alias:          hid:b0003g0101v0000056Ap0000037A
alias:          hid:b0005g0101v0000056Ap00000379
alias:          hid:b0005g0101v0000056Ap00000377
alias:          hid:b0005g0101v0000056Ap00000361
alias:          hid:b0005g0101v0000056Ap00000360
alias:          hid:b0003g0101v0000056Ap00000343
alias:          hid:b0003g0101v0000056Ap0000033E
alias:          hid:b0003g0101v0000056Ap0000033D
alias:          hid:b0003g0101v0000056Ap0000033C
alias:          hid:b0003g0101v0000056Ap0000033B
alias:          hid:b0003g0101v0000056Ap00000336
alias:          hid:b0003g0101v0000056Ap00000335
alias:          hid:b0003g0101v0000056Ap00000333
alias:          hid:b0003g0101v0000056Ap00000331
alias:          hid:b0003g0101v0000056Ap0000032F
alias:          hid:b0003g0101v0000056Ap0000032C
alias:          hid:b0003g0101v0000056Ap0000032B
alias:          hid:b0003g0101v0000056Ap0000032A
alias:          hid:b0003g0101v0000056Ap00000326
alias:          hid:b0003g0101v0000056Ap00000325
alias:          hid:b0003g0101v0000056Ap00000323
alias:          hid:b0003g0101v0000056Ap00000319
alias:          hid:b0003g0101v0000056Ap00000318
alias:          hid:b0003g0101v0000056Ap00000317
alias:          hid:b0003g0101v0000056Ap00000315
alias:          hid:b0003g0101v0000056Ap00000314
alias:          hid:b0003g0101v0000056Ap0000030E
alias:          hid:b0003g0101v0000056Ap0000030C
alias:          hid:b0003g0101v0000056Ap0000030A
alias:          hid:b0003g0101v0000056Ap00000309
alias:          hid:b0003g0101v0000056Ap00000307
alias:          hid:b0003g0101v0000056Ap00000304
alias:          hid:b0003g0101v0000056Ap00000303
alias:          hid:b0003g0101v0000056Ap00000302
alias:          hid:b0003g0101v0000056Ap00000301
alias:          hid:b0003g0101v0000056Ap00000300
alias:          hid:b0003g0101v0000056Ap0000012C
alias:          hid:b0003g0101v0000056Ap00000116
alias:          hid:b0003g0101v0000056Ap0000010F
alias:          hid:b0003g0101v0000056Ap0000010E
alias:          hid:b0003g0101v0000056Ap0000010D
alias:          hid:b0003g0101v0000056Ap00000101
alias:          hid:b0003g0101v0000056Ap00000100
alias:          hid:b0003g0101v0000056Ap000000FB
alias:          hid:b0003g0101v0000056Ap000000FA
alias:          hid:b0003g0101v0000056Ap000000F8
alias:          hid:b0003g0101v0000056Ap000000F6
alias:          hid:b0003g0101v0000056Ap000000F4
alias:          hid:b0003g0101v0000056Ap000000F0
alias:          hid:b0003g0101v0000056Ap000000EF
alias:          hid:b0003g0101v0000056Ap000000ED
alias:          hid:b0003g0101v0000056Ap000000EC
alias:          hid:b0003g0101v0000056Ap000000E6
alias:          hid:b0003g0101v0000056Ap000000E5
alias:          hid:b0003g0101v0000056Ap000000E3
alias:          hid:b0003g0101v0000056Ap000000E2
alias:          hid:b0003g0101v0000056Ap000000DF
alias:          hid:b0003g0101v0000056Ap000000DE
alias:          hid:b0003g0101v0000056Ap000000DD
alias:          hid:b0003g0101v0000056Ap000000DB
alias:          hid:b0003g0101v0000056Ap000000DA
alias:          hid:b0003g0101v0000056Ap000000D8
alias:          hid:b0003g0101v0000056Ap000000D7
alias:          hid:b0003g0101v0000056Ap000000D6
alias:          hid:b0003g0101v0000056Ap000000D5
alias:          hid:b0003g0101v0000056Ap000000D4
alias:          hid:b0003g0101v0000056Ap000000D3
alias:          hid:b0003g0101v0000056Ap000000D2
alias:          hid:b0003g0101v0000056Ap000000D1
alias:          hid:b0003g0101v0000056Ap000000D0
alias:          hid:b0003g0101v0000056Ap000000CE
alias:          hid:b0003g0101v0000056Ap000000CC
alias:          hid:b0003g0101v0000056Ap000000C7
alias:          hid:b0003g0101v0000056Ap000000C6
alias:          hid:b0003g0101v0000056Ap000000C5
alias:          hid:b0003g0101v0000056Ap000000C4
alias:          hid:b0003g0101v0000056Ap000000C2
alias:          hid:b0003g0101v0000056Ap000000C0
alias:          hid:b0005g0101v0000056Ap000000BD
alias:          hid:b0003g0101v0000056Ap000000BC
alias:          hid:b0003g0101v0000056Ap000000BB
alias:          hid:b0003g0101v0000056Ap000000BA
alias:          hid:b0003g0101v0000056Ap000000B9
alias:          hid:b0003g0101v0000056Ap000000B8
alias:          hid:b0003g0101v0000056Ap000000B7
alias:          hid:b0003g0101v0000056Ap000000B5
alias:          hid:b0003g0101v0000056Ap000000B4
alias:          hid:b0003g0101v0000056Ap000000B3
alias:          hid:b0003g0101v0000056Ap000000B2
alias:          hid:b0003g0101v0000056Ap000000B1
alias:          hid:b0003g0101v0000056Ap000000B0
alias:          hid:b0003g0101v0000056Ap0000009F
alias:          hid:b0003g0101v0000056Ap0000009A
alias:          hid:b0003g0101v0000056Ap00000097
alias:          hid:b0003g0101v0000056Ap00000093
alias:          hid:b0003g0101v0000056Ap00000090
alias:          hid:b0003g0101v0000056Ap00000084
alias:          hid:b0005g0101v0000056Ap00000081
alias:          hid:b0003g0101v0000056Ap0000006B
alias:          hid:b0003g0101v0000056Ap0000006A
alias:          hid:b0003g0101v0000056Ap00000069
alias:          hid:b0003g0101v0000056Ap00000065
alias:          hid:b0003g0101v0000056Ap00000064
alias:          hid:b0003g0101v0000056Ap00000063
alias:          hid:b0003g0101v0000056Ap00000062
alias:          hid:b0003g0101v0000056Ap00000061
alias:          hid:b0003g0101v0000056Ap00000060
alias:          hid:b0003g0101v0000056Ap0000005E
alias:          hid:b0003g0101v0000056Ap0000005D
alias:          hid:b0003g0101v0000056Ap0000005B
alias:          hid:b0003g0101v0000056Ap00000059
alias:          hid:b0003g0101v0000056Ap00000057
alias:          hid:b0003g0101v0000056Ap00000047
alias:          hid:b0003g0101v0000056Ap00000045
alias:          hid:b0003g0101v0000056Ap00000044
alias:          hid:b0003g0101v0000056Ap00000043
alias:          hid:b0003g0101v0000056Ap00000042
alias:          hid:b0003g0101v0000056Ap00000041
alias:          hid:b0003g0101v0000056Ap0000003F
alias:          hid:b0003g0101v0000056Ap00000039
alias:          hid:b0003g0101v0000056Ap00000038
alias:          hid:b0003g0101v0000056Ap00000037
alias:          hid:b0003g0101v0000056Ap00000035
alias:          hid:b0003g0101v0000056Ap00000034
alias:          hid:b0003g0101v0000056Ap00000033
alias:          hid:b0003g0101v0000056Ap00000032
alias:          hid:b0003g0101v0000056Ap00000031
alias:          hid:b0003g0101v0000056Ap00000030
alias:          hid:b0003g0101v0000056Ap0000002A
alias:          hid:b0003g0101v0000056Ap00000029
alias:          hid:b0003g0101v0000056Ap00000028
alias:          hid:b0003g0101v0000056Ap00000027
alias:          hid:b0003g0101v0000056Ap00000026
alias:          hid:b0003g0101v0000056Ap00000024
alias:          hid:b0003g0101v0000056Ap00000023
alias:          hid:b0003g0101v0000056Ap00000022
alias:          hid:b0003g0101v0000056Ap00000021
alias:          hid:b0003g0101v0000056Ap00000020
alias:          hid:b0003g0101v0000056Ap00000019
alias:          hid:b0003g0101v0000056Ap00000018
alias:          hid:b0003g0101v0000056Ap00000017
alias:          hid:b0003g0101v0000056Ap00000016
alias:          hid:b0003g0101v0000056Ap00000015
alias:          hid:b0003g0101v0000056Ap00000014
alias:          hid:b0003g0101v0000056Ap00000013
alias:          hid:b0003g0101v0000056Ap00000012
alias:          hid:b0003g0101v0000056Ap00000011
alias:          hid:b0003g0101v0000056Ap00000010
alias:          hid:b0003g0101v0000056Ap00000003
alias:          hid:b0003g0101v0000056Ap00000000
depends:        hid,usbhid
retpoline:      Y
name:           wacom
vermagic:       4.15.0-45-lowlatency SMP preempt mod_unload 
parm:           touch_arbitration: on (Y) off (N) (bool)
pepper-jelly commented 5 years ago

@scholar-mage Strangely my cursor was jumping when I rebuilt just a module on a laptop but on desktop everything was fine. Bug still there but I could help to workaround the issue that works for me but you will have to rebuild kernel.

DISCLAIMER: it's still might not work for you

sudo apt install bc bison flex libssl-dev dpkg-dev
mkdir build
cd build

Then:

cd kernel
export CFLAGS="-O2 -pipe"
export CXXFLAGS="${CFLAGS}"
make olddefconfig
./scripts/config --disable DEBUG_INFO

sidenote: for "lowlatency" edit .config and change CONFIG_HZ=1000 and comment others with #, CONFIG_PREEMPT=y and run make olddefconfig again

time make -j8 bindeb-pkg
cd ..

All you need just image and headers.

scholar-mage commented 5 years ago

So I tried recompiling the kernel tonight. Effectively I did this:

export CFLAGS="-O2 -pipe"
export CXXFLAGS="${CFLAGS}"

wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.15.18.tar.gz
tar -xf linux-4.15.18.tar.gz 
cd linux-4.15.18/
cp /lib/modules/$(uname -r)/build/.config .
make oldconfig
./scripts/config --disable DEBUG_INFO

cp ~/downloads/input-wacom-0.40.0/4.5/{wacom.h,wacom_sys.c,wacom_wac.c,wacom_wac.h} drivers/hid/
cp ~/downloads/input-wacom-0.40.0/config.h drivers/

sudo apt-get install libelf-dev

time make -j5 bindeb-pkg
cd ..
sudo dpkg -i linux-headers-4.15.18_4.15.18-1_amd64.deb linux-image-4.15.18_4.15.18-1_amd64.deb
sudo reboot

After the reboot:

$ uname -r
4.15.18

I still notice unexpected/surprising cursor jumps. However, I did notice tonight that they seem to be limited to only about 2 inches of physical space on the pad. That is, if I move the pen about 2 inches or less, the cursor will jump across the screen, but for larger pen jumps than that, the cursor will stay where it is. I'm not sure if under the old kernel if jumps were limited to about 2 inches or not. I'll have to reboot and check.

Update: further testing shows the same behavior on both kernels. The jumping thing does seem to be dependent on how high I lift the pen off the pad. If I bring it up a few inches, and set it down, the cursor wont jump. But if it is only about 1/2" off the pad then it will jump.

Unrelated, I get a weird ACPI error with the new kernel. Will likely revert to the old one.

Maybe I can patch my copy of the driver to not report jumps greater than some specified number of pixels? Basically just clamp down on how far the cursor is allowed to move in one update?

jigpu commented 5 years ago

My apologies to everyone; I haven't been able to keep up with the bug tracker for the past few weeks...

I've taken a fresh look at this with all the information gathered so far and think I finally understand what is going on. It would seem to boil down to the fact that an "in range" pen does not send position updates. Consider the following:

  1. The pen is "in prox" at the left edge of the tablet
  2. The pen is lifted away from the tablet far enough to leave prox but still be "in range"
  3. The pen is moved to the right edge of the tablet while staying "in range"
  4. The pen is brought closer to the tablet and comes back "in prox"

This will result in the driver seeing events from the pen at the left edge of the tablet, then nothing for a while, then the pen a large distance away. If the driver is in absolute mode, this isn't a problem: the cursor just warps to where it should be. If the driver is in relative mode, this is a problem: the cursor will linger at its last position just like you had completely removed the pen, but then suddenly move a large distance when step 4 is reached.

I'm not yet sure what the most appropriate fix would be. We could change the kernel to claim the pen is out of prox but still leave touch disabled (which was the problem commit c3c633ee60 was supposed to solve). Another solution would be to have xf86-input-wacom act as though the pen is out of prox when its distance becomes too large in relative mode -- we already do this for relative "cursor" devices, so it would be simple to extend to pens as well.

scholar-mage commented 5 years ago

No news in while... What can I do to help accelerate resolution of this issue?

asokoloski commented 5 years ago

Hi folks,

@jigpu What you describe sounds accurate to me. I'm way out of my depth, but I've been able to find a little bit of time to look into this. I've made a patch that works for me -- but I don't fully understand what the problem was that was fixed by commit c3c633ee6013cb37182cf1eb5bef01fafeb8754c, so I suspect it would break that commit.

Here's the patch: cursor-skip.patch.txt

I don't have a good mental model of how relative mode works. What causes the system to decide that it should consider the next set of coordinates to be at the same point as the last update? Is it the call to input_report_key for wacom->tool[0] changing from false and then back to true? That might be why this patch works for me. Even without the patch, relative mode works correctly if I raise the stylus up until it's "out of range".

Based on what I've seen using the capture script, I never get any x/y data when my stylus is out of prox, even if it's in range. I don't know if other tablets that use the wacom_bpt_pen code path are different.

@jigpu I'd appreciate any info you, or anyone else, can provide.

Anyway, what's the typical approach in a situation like this? I'd like to maybe turn this into a patch to the kernel, but I've never done this before and I'm very hesitant to go ahead and fix my problem but break it for everyone else.

@scholar-mage Also -- as I poked around the code, I think there's a good possibility that the reason you couldn't fix your problem by rolling back the driver is that it uses a different code path. I don't see either "intuos draw" or "CTL-490/w" in 4.5/wacom_wac.c, so I'm not sure which function is handling the IRQ events -- but there are multiple different handlers for various Intuos tablets, so it could be any one of them, and it would seem to be a good explanation for why this didn't fix your problem.

I'm sorry, I don't know enough about this stuff to even have an idea of how to tell which code path is used in the driver for your tablet -- that would be the first step to figuring it out, though.

jigpu commented 5 years ago

@asokoloski your patch looks fine as a workaround. It takes the "change the kernel to claim the pen is out of prox but still leave touch disabled" approach that I mentioned previously. Commit c3c633e was primarily concerned with enabling the tablet's ability to sense the pen at a greater distance ("in range") and using that ability to keep the touchpad more reliably disabled when using the pen. Your commit shouldn't break that core feature and should basically restore the original feel of the pen in relative mode.

I'm still a little hesitant to accept it upstream though. Right now the kernel is primarily responsible for performing palm rejection, but in the future userspace could/should handle it. Userspace needs to know when the pen is nearby to make that happen, so ideally we wouldn't claim the pen is out of prox while it is still close enough to be sensed.

I don't have a good mental model of how relative mode works. What causes the system to decide that it should consider the next set of coordinates to be at the same point as the last update? Is it the call to input_report_key for wacom->tool[0] changing from false and then back to true?

Yes. The reason commit c3c633e causes trouble for relative use is that the pen "feels" out of prox to the user (position updates aren't sent at the greater pen range) but the driver still treats the pen as being in prox. If the user moves the pen while it is not-really-out-of-prox and then brings it closer to the tablet, the driver sees a sudden large change in position which it interprets as a large relative motion.

jigpu commented 5 years ago

Coincidentally, I've been working on another possible solution. The code can be checked out by running git clone https://github.com/jigpu/xf86-input-wacom -b fix-54 and then built/installed following the standard instructions.

After a logout/login to load the installed driver, tap the pen to the tablet (to work around a limitation of the current patches) and then the code should take effect. The distance at which the pen is treated as being out-of-prox can be adjusted through xsetwacom with the "CursorProximity" parameter. E.g. xsetwacom get <stylus_id> CursorProximity to check the current value and xsetwacom set <stylus_id> CursorProximity <distance> to change it. Distance values are going to be somewhere in the range of 0-63.

My code basically just ports a feature that "cursor" devices have had for a long time (the ability to have a driver-limited in-prox distance) to the stylus and eraser. I'm not sure if the default distance is comfortable to use with a pen though, so do let me know if it seems okay or if you need to adjust it.

asokoloski commented 5 years ago

I'm still a little hesitant to accept it upstream though. Right now the kernel is primarily responsible for performing palm rejection, but in the future userspace could/should handle it. Userspace needs to know when the pen is nearby to make that happen, so ideally we wouldn't claim the pen is out of prox while it is still close enough to be sensed.

Hmm, ok, so palm rejection applies to tablets that accept touch input as well as pen, right? Now I think I understand what commit c3c633ee6013cb37182cf1eb5bef01fafeb8754c means about disabling touch. It didn't occur to me before because my "Bamboo Pen" version of the CTL-470 doesn't have touch input, just the pen.

Man, I'm way out of my depth, here. I'm confused about all the terminology -- CursorProximity, prox/out-of-prox, "hardware prox", and range/out-of-range. And how does changing the CursorProximity fix this issue? Wouldn't it still exist if you wanted the CursorProximity to be the same as whatever the default was before the patch? Or is there another part of the change that fixes it, and being able to change the CursorProximity is just a side benefit?

And correct me if I'm wrong, but my understanding is that xf86-input-wacom lives in user space, reading the events sent by the input-wacom kernel module, right?

Sorry, I know I'm asking a lot of questions, please don't feel obligated to take the time to answer if you're busy -- I'm just curious. Since I've got a workaround patch already, I can manage. I don't know if I'll be able to help much beyond this; it's the first time I've ever tried digging into the kernel, and I'm not a terribly experienced C programmer. Thanks for all the help you've given already.

jigpu commented 5 years ago

The terminology can definitely be confusing, so don't feel too bad. A quick cheat-sheet:

And correct me if I'm wrong, but my understanding is that xf86-input-wacom lives in user space, reading the events sent by the input-wacom kernel module, right?

That's absolutely correct. It will modify those events as necessary to enable certain features, however (e.g. turning the absolute X/Y data into relative motion, or sending an "out of prox" notification if CursorProx says the tool is too far away).

d-packs commented 5 years ago

I have the same problem as OP, my tablet model is Wacom CTL-490 (Intuos S 2). I've tried both the patch made by @asokoloski and also @jigpu 's fork and the problem is still there, the cursor jumps around. I have played a bit with the values of CursorProximity and 20 seems to solve the jumping cursor but is still to small a distance for comfortable pen manipulation. The default 10 is not usable at all while 30 might be the minimum acceptable distance, but at 30 the cursor still jumps.

@asokoloski did you eventually solve your problem? what i have tried:

I'm at a loss. Here's the current state of my machine:

$ uname -sr
Linux 5.2.4-arch1-1-ARCH

$ xsetwacom --list devices
Wacom Intuos S 2 Pen stylus         id: 11  type: STYLUS    
Wacom Intuos S 2 Pad pad            id: 12  type: PAD  

$ xsetwacom -V
xf86-input-wacom-fix-54

$ modinfo wacom | grep version
version:        v2.00-input-wacom-input-wacom-0.40.0
srcversion:     D158DDA3466DFBA7E55F619

$ xinput --list-props "Wacom Intuos S 2 Pen stylus" 
Device 'Wacom Intuos S 2 Pen stylus':
    Device Enabled (164):   1
    Coordinate Transformation Matrix (166): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
    Device Accel Profile (298): 0
    Device Accel Constant Deceleration (299):   1.000000
    Device Accel Adaptive Deceleration (300):   1.000000
    Device Accel Velocity Scaling (301):    10.000000
    Device Node (290):  "/dev/input/event11"
    Wacom Tablet Area (387):    0, 0, 15200, 9500
    Wacom Rotation (388):   0
    Wacom Pressurecurve (389):  0, 0, 100, 100
    Wacom Serial IDs (390): 827, 1988257419, 2274, 0, 0
    Wacom Serial ID binding (391):  0
    Wacom Proximity Threshold (392):    30
    Wacom Pressure Threshold (393): 26
    Wacom Sample and Suppress (394):    2, 4
    Wacom Enable Touch (395):   0
    Wacom Hover Click (396):    1
    Wacom Enable Touch Gesture (397):   0
    Wacom Touch Gesture Parameters (398):   0, 0, 250
    Wacom Tool Type (399):  "STYLUS" (380)
    Wacom Button Actions (400): "Wacom button action 0" (401), "Wacom button action 1" (402), "Wacom button action 2" (403), "None" (0), "None" (0), "None" (0), "None" (0), "Wacom button action 3" (404)
    Wacom button action 0 (401):    1572865
    Wacom button action 1 (402):    1572866
    Wacom button action 2 (403):    1572867
    Wacom button action 3 (404):    1572872
    Wacom Pressure Recalibration (405): 1
    Wacom Panscroll Threshold (406):    1300
    Device Product ID (291):    1386, 827
    Wacom Debug Levels (407):   0, 0

Jipu's script output is here: record_1564570542.tar.gz (the jump is at line 1225 in the *.evemu file)

Is there a way to hack the drivers to simply ignore any input once outside of Proximity Threshold even if it somehow interferes with touch (my tablet doesn't have touch, so it wouldn't affect me)?

jigpu commented 5 years ago

@d-packs I haven't tuned the default CursorProximity threshold with my patches, so its entirely possible that the value would have to be adjusted to work well. I'm surprised you were still seeing jumps with patch from @asokoloski though. His changes should restore the original non-jumpy behavior in all cases.

Is there a way to hack the drivers to simply ignore any input once outside of Proximity Threshold even if it somehow interferes with touch (my tablet doesn't have touch, so it wouldn't affect me)?

That's exactly what my patch does. If the pen moves further away than Proximity Threshold ("CursorProximity" xsetwacom option), the driver treats it as though it was completely removed. The state is cleared and events are ignored until the pen comes closer again.

If the threshold is set too low, the pen will have a very small usable hover distance. There shouldn't be a problem with setting the threshold too high (since the kernel will in theory report the maximum possible distance when the pen goes to "in range") but its possible that isn't working correctly. I'll have to double-check the kernel driver to see what's going on.

I've taken a peek at your recording and am actually a little confused by it. Some of the events don't match up with what I'm expecting... I'll have to see if I can find the same tablet in my collection over here for more testing...

jigpu commented 5 years ago

@d-packs here's what I've found out from my tests:

I'm working on patches to fix all these issues and should have an update for you to test soon.

jigpu commented 5 years ago

Okay, fixes have been pushed up to my repos for testing.

  1. Update your xf86-input-wacom tree by running git pull from inside the directory. Rebuild and reinstall the driver. Reboot to ensure the driver gets loaded. Running xsetwacom -V should print out 0.37.0.8.g892285d

  2. Run git clone https://github.com/jigpu/input-wacom.git -b fix-issue-98 to checkout a copy of my fixed input-wacom driver. Build and install the driver. Reboot again to ensure the driver gets loaded. Running cat /sys/module/wacom/version should print out v2.00-0.42.0.65.g1a2e384

  3. Test to see if operation of the pen is improved. Try tweaking the CursorProximity through xsetwacom to find a good height and let me know what you find is comfortable.

d-packs commented 5 years ago

Wow, @jigpu, thanks for looking into this. The new driver didn't change things. Cursor still jumps. One question though. I've since reverted to the stable x86-input-wacom version provided by arch repos, so that I can't change the CursorProximity value. I've now installed the latest version of your driver, but still no go.

d-packs commented 5 years ago

I've looked some more into this. The input-wacom driver is at v2.00-0.42.0.65.g1a2e384, but the new version of xf86-input-wacom says it's version 0.35.99.1.35.gdaafdda.

Here's what I'm doing: I've uninstalled the xf86-input-wacom drivers that came from the Arch repositories then ran the following commands:

$ git clone https://github.com/jigpu/xf86-input-wacom.git
$ cd xf86-input-wacom
$ git checkout fix-54
$ if test -x ./autogen.sh; then ./autogen.sh; else ./configure; fi && make && sudo make install || echo "Build Failed"

it builds and apparently finishes successfully. then I get this:

$ xsetwacom -V
0.35.99.1.35.gdaafdda

Interesting enough I still cannot access CursorProximity: Property 'Wacom Proximity Threshold' does not exist on device.

jigpu commented 5 years ago

Hmm. The wrong version is checked out for some reason, which is why you aren't able to access CursorProximity. Try running the following commands from inside the xf86-input-wacom directory to force git to checkout the correct commit and then rebuild (if the commands error out, please post their output so I can see what's wrong):

$ git remote -v
$ git checkout fix-54
$ git reset --hard 892285d542beb2c2d7683000b61d16c8b5d7d079
d-packs commented 5 years ago

Hmm, yeah, it looks like some problems with the checked out branch. I've tried some resets myself with various parameters. Here's some commands I've tried and their output:

$ git remote -v
origin  https://github.com/jigpu/xf86-input-wacom.git (fetch)
origin  https://github.com/jigpu/xf86-input-wacom.git (push)

$ git checkout fix-54
Already on 'fix-54'

$ git reset --hard 892285d542beb2c2d7683000b61d16c8b5d7d079
HEAD is now at 892285d WIP: Use a proxout height of 30 for all stylus devices

$ sudo make uninstall
...
$ if test -x ./autogen.sh; then ./autogen.sh; else ./configure; fi && make && sudo make install || echo "Build Failed"

$ xsetwacom -V
0.35.99.1.37.g892285d

$ git reflog
892285d (HEAD -> fix-54, origin/fix-54) HEAD@{0}: reset: moving to 892285d542beb2c2d7683000b61d16c8b5d7d079
daafdda (origin/master, origin/HEAD, master) HEAD@{1}: checkout: moving from fix-54 to fix-54
daafdda (origin/master, origin/HEAD, master) HEAD@{2}: reset: moving to HEAD
daafdda (origin/master, origin/HEAD, master) HEAD@{3}: reset: moving to HEAD
daafdda (origin/master, origin/HEAD, master) HEAD@{4}: reset: moving to HEAD
daafdda (origin/master, origin/HEAD, master) HEAD@{5}: checkout: moving from master to fix-54
daafdda (origin/master, origin/HEAD, master) HEAD@{6}: checkout: moving from fix-54 to master
daafdda (origin/master, origin/HEAD, master) HEAD@{7}: checkout: moving from master to fix-54
daafdda (origin/master, origin/HEAD, master) HEAD@{8}: clone: from https://github.com/jigpu/xf86-input-wacom.git
jigpu commented 5 years ago

Have you rebooted (or at least done a logout/login) after installing the driver? The old driver will still be in use until the X server has a chance to restart and load the freshly-installed copy.

d-packs commented 5 years ago

Of course I do reboots, but the xsetwacom -V command reacts immediately to the new build. the branch fix-54 build appears to build an old version.

Is there a patch I can apply to the official release of linuxwacom/xf86-input-wacom so I can get the same results as expected here?

jigpu commented 5 years ago

One last thing to check... Could you try tapping the pen to the tablet and seeing if that stops the jumps? The code is relying on a "click" event to figure out where the tablet surface is and the CursorProximity won't take effect until after that happens. Though if xsetwacom can't set CursorProximity, there's little chance this would actually do anything...

In case that doesn't work, here's a patch from the official 0.37.0 release that should transform it into "fix-54": 0.37.0_892285d.patch.gz. You'll need to run gunzip on the file and then apply it to the 0.37.0 release by running patch -p1 < 0.37.0_892285d.patch from within the xf86-input-wacom directory.

d-packs commented 5 years ago

First of all thank you for the effort you put into this. Tapping does not make it work.

I've cloned the official repo (linuxwacom/xf86-input-wacom), then I've applied the patch. One of the files failed to apply the patch automatically, so I had to carefully apply the patch manually to that file (src/wcmCommon.c). Here's the resulting source: wcmCommon.c.zip

I've then committed the changes and ran the make install command.

$ xsetwacom -V
0.37.0.10.g4f1b5ea

I then rebooted. The result: no change, cursor jumps around when not perpendicularly lifted out of range. Also:

$ xsetwacom set 11 CursorProximity 40
Property 'Wacom Proximity Threshold' does not exist on device.

$ xinput --set-prop "Wacom Intuos S 2 Pen stylus" "Wacom Proximity Threshold" 35
property 'Wacom Proximity Threshold' doesn't exist, you need to specify its type and format

I'm using the tablet as a mouse replacement. I might get used to the jumping around eventually.

Here's a recorded cursor movement package maybe it sheds some light: record_1564767455.tar.gz

jigpu commented 5 years ago

And thank you for your patience! :) Would you mind running our sysinfo.sh script and attaching the generated tarball here? It should also aid with the detective work...

d-packs commented 5 years ago

sysinfo.HLE2KwIcDw.tar.gz

jigpu commented 5 years ago

The sysinfo does confirm that the driver hasn't been updated, so the question becomes "why not?". The usual suspect is the --libdir option not being set at configure time, but there could be other problems too. Could you paste the full output of the following commands (just the regular build commands with an extra echo of "$@" to see what libdir is):

$ set -- --prefix="/usr" --libdir="$(readlink -e $(ls -d /usr/lib*/xorg/modules/input/../../../ | head -n1))"
$ echo "$@"
$ if test -x ./autogen.sh; then ./autogen.sh "$@"; else ./configure "$@"; fi && make && sudo make install || echo "Build Failed"
d-packs commented 5 years ago

here is the output: https://gist.github.com/d-packs/fd0408a96453be9e91eda984beab12d5 I just rebooted and it works, the cursor stopped jumping :)

jigpu commented 5 years ago

Huh. Well at least it works now :)

d-packs commented 5 years ago

After a few Kernel upgrades the if test -x ./autogen.sh; then ./autogen.sh "$@"; else ./configure "$@"; fi && make && sudo make install || echo "Build Failed" command dosn't make the module install anymore, effectively leaving the system without a driver for the tablet. i would have to install input-wacom or input-wacom-dkms from the repos. Any idea what could have gone wrong?

This is the output of the above command

One more question. This pointer behaviour seems to be a bug allright. Is there any possibility that your fix might make it in the official driver eventually? So that the whole patching and compiling is no longer necessary?

jigpu commented 5 years ago

The output looks good, but if you have multiple kernels installed (like the previous version of your post seemed to indicate) its possible that the driver is building against an unexpected version. You can add the --with-kernel-version=<version> option to the "./configure" command to build/install for specific kernels (you can get the possible version numbers by running ls /lib/modules).

As for building with dkms, I've just uploaded a new "input-wacom-dkms-git" package to the AUR that should be much easier for you to work with compared to the previous "input-wacom-dkms" package (only have to change the git URL instead of a whole bunch of other small mods).

  1. Go to https://aur.archlinux.org/packages/input-wacom-dkms-git/
  2. Click "download snapshot" and extract it to your disk
  3. Edit the PKGBUILD file, replacing git+https://github.com/linuxwacom/input-wacom.git#branch=master with git+https://github.com/jigpu/input-wacom.git#branch=fix-issue-98
  4. Run makepkg to build the package and then install it with pacman.

Given that this seems to be working, I definitely plan on getting this integrated into the driver. I've been a bit distracted with other issues, but I'll try to make a pull request soon.

d-packs commented 5 years ago

Wow, thanks for the *-git AUR package. The instructions worked perfectly and the driver works as expected. I had to do an extra intermediate step because I installed the input-wacom-dkms package previously and now i was getting a conflict so I had to do a sudo rm /etc/modprobe.d/blacklist-input-wacom-dkms.conf to remove the file the other package had installed before installing the input-wacom-dkms-git package.

This is a lifesaver. I tried for a few hours today to tinker and somehow work with the simple *-dkms package from AUR with no luck. Thanks a million. Yeah I've deleted my previous posts because they were not really relevant any longer as at some point I was not even able to install the patched driver irrespective of the kernel I was building against. Thanks for your hint at --with-kernel-version, I learned something new today.

Once again thanks for the time.

jigpu commented 5 years ago

The "CursorProximity" patches have just been merged into xf86-input-wacom and should be available in the next 0.38.0 release.

pepper-jelly commented 4 years ago

For me fix was to use another tablet without touch(and still). Yesterday I checked how old CTH-470 tablet works. Jumps are present(in wayland and xorg sessions same behaviour in relative mode). Section in code to blame starts with "static int wacom_bpt_pen(struct wacom_wac *wacom)"

Here code from latest 0.46.0 release

Spoiler 1 ```c static int wacom_bpt_pen(struct wacom_wac *wacom) { struct wacom_features *features = &wacom->features; struct input_dev *input = wacom->pen_input; unsigned char *data = wacom->data; int x = 0, y = 0, p = 0, d = 0; bool pen = false, btn1 = false, btn2 = false; bool range, prox, rdy; if (data[0] != WACOM_REPORT_PENABLED) return 0; range = (data[1] & 0x80) == 0x80; prox = (data[1] & 0x40) == 0x40; rdy = (data[1] & 0x20) == 0x20; wacom->shared->stylus_in_proximity = range; if (delay_pen_events(wacom)) return 0; if (rdy) { p = le16_to_cpup((__le16 *)&data[6]); pen = data[1] & 0x01; btn1 = data[1] & 0x02; btn2 = data[1] & 0x04; } if (prox) { x = le16_to_cpup((__le16 *)&data[2]); y = le16_to_cpup((__le16 *)&data[4]); if (data[1] & 0x08) { wacom->tool[0] = BTN_TOOL_RUBBER; wacom->id[0] = ERASER_DEVICE_ID; } else { wacom->tool[0] = BTN_TOOL_PEN; wacom->id[0] = STYLUS_DEVICE_ID; } wacom->reporting_data = true; } if (range) { /* * Convert distance from out prox to distance from tablet. * distance will be greater than distance_max once * touching and applying pressure; do not report negative * distance. */ if (data[8] <= features->distance_max) d = features->distance_max - data[8]; } else { wacom->id[0] = 0; } if (wacom->reporting_data) { input_report_key(input, BTN_TOUCH, pen); input_report_key(input, BTN_STYLUS, btn1); input_report_key(input, BTN_STYLUS2, btn2); if (prox || !range) { input_report_abs(input, ABS_X, x); input_report_abs(input, ABS_Y, y); } input_report_abs(input, ABS_PRESSURE, p); input_report_abs(input, ABS_DISTANCE, d); input_report_key(input, wacom->tool[0], range); /* PEN or RUBBER */ input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */ } if (!range) { wacom->reporting_data = false; } return 1; } ```

And here code that just works and touch auto disables too when pen close to surface but without any glitch

Spoiler 2 ```c static int wacom_bpt_pen(struct wacom_wac *wacom) { struct wacom_features *features = &wacom->features; struct input_dev *input = wacom->pen_input; unsigned char *data = wacom->data; int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0; if (data[0] != WACOM_REPORT_PENABLED) return 0; prox = (data[1] & 0x20) == 0x20; /* * All reports shared between PEN and RUBBER tool must be * forced to a known starting value (zero) when transitioning to * out-of-prox. * * If not reset then, to userspace, it will look like lost events * if new tool comes in-prox with same values as previous tool sent. * * Hardware does report zero in most out-of-prox cases but not all. */ if (!wacom->shared->stylus_in_proximity) { if (data[1] & 0x08) { wacom->tool[0] = BTN_TOOL_RUBBER; wacom->id[0] = ERASER_DEVICE_ID; } else { wacom->tool[0] = BTN_TOOL_PEN; wacom->id[0] = STYLUS_DEVICE_ID; } } wacom->shared->stylus_in_proximity = prox; if (delay_pen_events(wacom)) return 0; if (prox) { x = le16_to_cpup((__le16 *)&data[2]); y = le16_to_cpup((__le16 *)&data[4]); p = le16_to_cpup((__le16 *)&data[6]); /* * Convert distance from out prox to distance from tablet. * distance will be greater than distance_max once * touching and applying pressure; do not report negative * distance. */ if (data[8] <= features->distance_max) d = features->distance_max - data[8]; pen = data[1] & 0x01; btn1 = data[1] & 0x02; btn2 = data[1] & 0x04; } else { wacom->id[0] = 0; } input_report_key(input, BTN_TOUCH, pen); input_report_key(input, BTN_STYLUS, btn1); input_report_key(input, BTN_STYLUS2, btn2); input_report_abs(input, ABS_X, x); input_report_abs(input, ABS_Y, y); input_report_abs(input, ABS_PRESSURE, p); input_report_abs(input, ABS_DISTANCE, d); input_report_key(input, wacom->tool[0], prox); /* PEN or RUBBER */ input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */ return 1; } ```

Would you accept PR if I send?

rafaelnco commented 2 years ago

hi @pepper-jelly ! can i ask for you help onn this issue? https://github.com/linuxwacom/input-wacom/issues/293