There, now I have your attention, right? :) TLDR: input_defuzz_abs_event() produces pointer jumps at certain slow movement speeds and I don't know what to do about it. While dealing with pointer jitter issues in libinput I stumbled into an issue with how the fuzz value in the kernel is handled during input_defuzz_abs_event(). Specifically, the response is nonlinear and can lead to jumpy pointer movement for deltas d = fuzz and d = fuzz * 2. Note, this bug affects a moving pointer, not a stationary one. For that the defuzzing works as intended. Let's assume that with a perceived-constant finger motion speed, you'll get deltas in the range (fuzz * 2) ± 3. input_defuzz_abs_event() returns: d = fuzz * 2 - 3 → value returned: fuzz - 1 d = fuzz * 2 - 2 → value returned: fuzz - 1 d = fuzz * 2 → value returned: fuzz * 2 d = fuzz * 2 + 1 → value returned: fuzz * 2 + 1 d = fuzz * 2 + 2 → value returned: fuzz * 2 + 2 There's another jump at the fuzz ± 2 range. In concrete numbers for a fuzz of 8, input deltas result in values: d = 6 → value 1 d = 7 → value 1 d = 8 → value 4 d = 9 → value 4 ... d = 14 → value 7 d = 15 → value 7 d = 16 → value 16 d = 17 → value 17 d = 18 → value 18 i.e. at the fuzz and fuzz * 2 points we see a jump of approx size fuzz/2 and fuzz, respectively. These are integer divisons, so some variance is expected. Obviously the numbers change for higher fuzz values but 8 seems to be the most common one. A few more details and a python script to recreate this and play around with it: https://bugs.freedesktop.org/show_bug.cgi?id=105303 In real terms, this means that a pointer moving at a percieved-constant speed will provide deltas of [7, 7, 16, 7, 16, 16, 7, 16, 7]. And if we were to rely on the fuzz in userspace as hint for our hysteresis, we'd end up filtering the 7 values but letting the 16 values pass through. This gives us pointer jumps. Those jumps happen right at the slow speed where we're moving slow enough to notice them. Ironically, slowing down to check what just happened will not reproduce the problem. The defuzzed value is used as 'old' value for the algorithm, so there's a feedback loop as well. So it's very hard to reproduce consistently, you cannot really get a [7, 16, 7, 16] motion with human input. But it's like bad kerning, once you see it you cannot unsee it :) I'm a bit out of ideas on how to deal with this: 1) improve the algorithm in the kernel so the response is more linear 2) figure out a way how to undo the kernel defuzz in userspace and do hysteresis based on the reconstructed raw value 3) provide some way of disabling in-kernel hysteres while leaving fuzz set 4) force the fuzz to 0, while remembering what it should be Neither of them is ideal, but 4 seems the best, with caveats. 1) can remove (some of) the jumps but since we already get processed coordinates, doing the correct thing in libinput is harder 2) possibly possible, but will be lossy or inaccurate 3) would require some new ioctl and per-client behaviour. not ideal 4) this one is both the easiest and messiest. The approach would be: * a udev rule extracts the fuzz value into a AXIS_FUZZ=$fuzz property * use EVIOCSABS to set the fuzz to 0 (thus disabling kernel defuzzing), * have libinput init the hysteresis based on AXIS_FUZZ * pray that no other input-handling clients relies on kernel fuzzing because we just changed the kernel device Any suggestions on how to handle this would be appreciated. Cheers, Peter -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html