https://bugs.kde.org/show_bug.cgi?id=421295
Bug ID: 421295 Summary: Krita zooms to the max and rotates wildly when using touch gestures with a Wacom Intuos Pro M on Linux Product: krita Version: git master Platform: Compiled Sources OS: Linux Status: REPORTED Severity: normal Priority: NOR Component: tablet support Assignee: krita-bugs-n...@kde.org Reporter: sunda...@ierne.eu.org Target Milestone: --- Created attachment 128340 --> https://bugs.kde.org/attachment.cgi?id=128340&action=edit PyQt5 program to demonstrate the TouchPoint coordinate bug. SUMMARY Context: this issue happens with a Wacom Intuos Pro M tablet on (at least) Ubuntu Linux 19.10 and 20.04, using (at least) Krita 4.2.9 and Krita from git at head. The zoom/rotate touch features randomly misbehaves, and zooms to the max (8000% or so) while rotating to a random angle. This happens mostly at the beginning of gestures, when both fingers come into contact with the tablet, and to a lesser extent at the end of the gesture, when at least one of the fingers leaves the tablet. This happens both in the flatpak package (4.2.9.0 from flathub) and git at head. As to drivers, package xserver-xorg-input-wacom is at version 1:0.39.0-0ubuntu1 and package libwacom2 is at version 1.3-2ubuntu1. Qt is at version 5.12.8+dfsg-0ubuntu1 for the version of Krita compiled from git master. KDE is at version runtime/org.kde.Platform/x86_64/5.14 (I don't know which Qt version is in there but I'm assuming 5.14 too) for the flatpak install of Krita. STEPS TO REPRODUCE 1. Plug in a Wacom Intuos Pro M (or presumably any touch-enabled Wacom tablet of that range?) 2. Configure the tablet to report touches instead of converting them to gestures itself (for instance with "xsetwacom --set "Wacom Intuos Pro M (WL) Finger touch" Gesture off" in a terminal). Tablet is also in absolute mode. 3. Start Krita from git master on Linux. 4. Start a new image. Perhaps draw a few scribbles for a better visualization of the problem. 5. Try to zoom/rotate by a few percents with a two finger gesture. OBSERVED RESULT The picture zooms to the maximum and rotates to a random angle. EXPECTED RESULT The picture zooms/rotates by a few percents. SOFTWARE/OS VERSIONS Linux/KDE Plasma: Ubuntu 19.10 and 20.04 using Cinnamon or i3 as the DE. KDE Plasma Version: N/A. KDE Frameworks Version: 5.12 and 5.14. Qt Version: 5.12 (and probably 5.14). ADDITIONAL INFORMATION The bug here seems to be that Qt feeds spurious TouchEvent positions to Krita at the beginning and end of touches and Krita fails to filter them out. Weirdly this happens with TouchPoint.pos() and .screenPos(), but .normalizedPos() works as expected, except at the very end of the gesture when one of the TouchPoints is in state RELEASED, where that TouchPoint's coordinates are off by some distance no matter what type of coordinates is used. In order to demonstrate this I wrote a pure Qt5 demo (in Python, sorry). You can find it attached to this bug, or here: https://pastebin.com/Zgi2UxEi This demo shows the following noteworthy behaviors: - When a two-finger touch event begins, one TouchPoint is in state PRESSED, and both TouchPoints report the same coordinates even if the fingers are quite apart on the tablet. - Those initial coordinates are always integers, whereas they become floats once the TouchPoints start moving around. This suggests that the coordinates for TouchPoints in state PRESSED are the result of some internal Qt fudging, rather than direct reports from the hardware or its driver. - The fact that both TouchPoints initially have the same coordinates probably explains the instantaneous maximum zoom. - In following events, the TouchPoint that started off PRESSED remains at those incorrect coordinates so long as it's in state STATIONARY. Once it starts being reported as MOVED, it "jumps" to the correct coordinates. - The TouchPoint that did not start off PRESSED does not demonstrate this jump; its reported position seems to remain reliable. - Therefore it looks like the issue is that the state of the non-PRESSED TouchPoint is incorrectly copied to the PRESSED one somewhere during Qt's processing of the event. - TouchPoints in state RELEASED also frequently report coordinates some distance off from their previous position. This feels like it's probably a distinct bug, but can be addressed at the same time. - Replacing the .pos() method with .normalizedPos() fixes those issues except for the one pertaining to TouchPoints in state RELEASED. Therefore: The bug is not Krita's fault, but Krita probably shouldn't fully trust TouchPoint coordinates. CONCLUSIONS - TouchPoint.pos() cannot be trusted for a TouchPoint that has been in state PRESSED until that TouchPoint has reached state MOVED. - No TouchPoint coordinates can be trusted for a TouchPoint that is in state RELEASED. SUGGESTED WORKAROUND - For the RELEASED TouchPoint issue, stop handling the event as soon as one of the TouchPoints reaches this state. - For the PRESSED TouchPoint issue, there are two options. - Option 1: switch to .normalizedPos() instead of .pos(). This will require some fudging with the reported values, as the zoom gesture also handles panning and seems to expect coordinates that make sense for that purpose. This also doesn't preserve the aspect ratio of the gesture on the device, as normalized positions are floats in range [0, 1]. - Option 2: ignore TouchPoints that have been in state PRESSED until they reach state MOVED. This may take multiple events. I will try to write a patch in that light. -- You are receiving this mail because: You are watching all bug changes.