Bug: kanata breaks trackpoint scrolling
Requirements
- [X] I've searched issues to see if this has not been reported before.
Describe the bug
Whenever I run kanata, I am no longer able to scroll by holding down the "mouse wheel button" and moving the trackpoint up and down.
Relevant kanata config
It happens with https://github.com/jtroo/kanata/blob/main/cfg_samples/simple.kbd as well as my own config so I think it's fair to say that the config is completely irrelevant.
To Reproduce
- Own a thinkpad.
- Start kanata with
sudo kanata - Try to scroll as described.
Expected behavior
It should not break the trackpoint scrolling feature.
Kanata version
kanata v1.4.0
Debug logs
2023-10-17T20:33:25.316979444+02:00 [INFO] registering /dev/input/event9: "TPPS/2 IBM TrackPoint"
2023-10-17T20:33:25.380271956+02:00 [INFO] registering /dev/input/event3: "AT Translated Set 2 keyboard"
This happens on every startup, does that mean that the trackpoint is registered as a keyboard?
2023-10-17T20:42:17.776983268+02:00 [DEBUG] (1) kanata::oskbd::linux: send to uinput: InputEvent { time: SystemTime { tv_sec: 0, tv_nsec: 0 }, kind: Key(BTN_MIDDLE), value: 0 }
This happens whenever I press the mouse button.
Operating system
Linux with KDE
Additional context
I assume that this problem could be eliminated by allowing the user to choose which input devices are intercepted. I was unable to find a flag or config entry that does that, which is weird for a feature that probably has many other applications, so there's a good chance I'm just bad at googling or reading tfm ...
Here are the relevant docs: https://github.com/jtroo/kanata/blob/main/docs/config.adoc#linux-only-linux-dev
Let me know if that helps 🙂
Thanks, that's what I was looking for, fixed my problem. Sometimes I'm just bad at scanning documentation :/ Teeny tiny nitpick: isn't that the kind of option that should really be a command line flag? If I was syncing my kanata config across multiple devices (which I may just actually do), I wouldn't want to adjust it to remap the correct input devices. Having a separate file for the device-specific configuration is not the perfect solution because that would require me to put my whole defcfg in there, since includes are not allowed within parenthesis, if I understand that correctly.
(oh god I've done it again, instead of thanking you for your very polite and helpful response and your work on this amazing project, I wrote a paragraph about what I dislike about it)
Feel free to open an enhancement ticket with all that 🙂 seems like it's a valid use case.
Another alternative is to use common excludes and includes across devices - presumably this wouldn't conflict too badly.
Another alternative is to use common excludes and includes across devices - presumably this wouldn't conflict too badly.
Fair, and I just realised that variables exist, so I guess an extra file for every device should work quite well, actually.
@jtroo I think this ticket should be reopened, as it should be possible to keep [thinkpad middle hold + trackpoint scrolling] without losing the possibility of remapping the left and right thinkpad mouse buttons. The "fix" today is to exclude all thinkpad mouse buttons, but it will be great and very useful to remap left/right mouse buttons to use them as thumbs layer switching keys without breaking trackpoint scrolling.
Also, we should be able to remap thinkpad mouse buttons independently of any external mouse buttons.
Sure 🙂
Would you be able to help investigate?
I don't have any ThinkPad natively running Linux on hand.
it looks like the reason this happens is that libinput turns Button Scrolling on by default for trackpoints. I was able to restore it, without excluding the trackpoint in my kanata config, by running xinput set-prop <id> "libinput Scroll Method Enabled" 0, 0, 1 where <id> corresponds to the Virtual core pointer ↳ kanata id in the output of xinput.
this is the full difference in the output of xinput --listprops:
1c1
< Device 'kanata':
---
> Device 'TPPS/2 IBM TrackPoint':
7,8c7,8
< libinput Scroll Method Enabled (348): 0, 0, 0
< libinput Scroll Method Enabled Default (349): 0, 0, 0
---
> libinput Scroll Method Enabled (348): 0, 0, 1
> libinput Scroll Method Enabled Default (349): 0, 0, 1
15,16d14
< libinput Rotation Angle (289): 0.000000
< libinput Rotation Angle Default (290): 0.000000
33,34c31,32
< Device Node (294): "/dev/input/event15"
< Device Product ID (295): 1, 1
---
> Device Node (294): "/dev/input/event14"
> Device Product ID (295): 2, 10
However, this is still only a partial fix, as the trackpoint is much more sluggish when passed through kanata. it looks like some trackpoints have a Magic Trackpoint Multipluer added via quirks, but for my trackpoint, libinput quirks list /dev/input/event<num> doesn't list any, so I'm not sure what difference when kanata is passing through the mouse events?
docs: https://wayland.freedesktop.org/libinput/doc/latest/trackpoints.html https://wayland.freedesktop.org/libinput/doc/latest/trackpoint-configuration.html#trackpoint-multiplier
changing the name of the kanata libinput device to end in trackpoint increases the pointer speed (but not necessarily to match the unmodified case) and automatically confers Mouse Button Scrolling.
src/oskbd/linux.rs
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
───────────────────────────────────────────────────────┐
241: pub fn is_input_device(device: &Device) -> bool { │
───────────────────────────────────────────────────────┘
.supported_relative_axes()
.map_or(false, |axes| axes.contains(RelativeAxisType::REL_X));
if is_keyboard || is_mouse {
- if device.name() == Some("kanata") {
+ if device.name() == Some("kanata TrackPoint") {
return false;
}
log::debug!(
───────────────────┐
346: impl KbdOut { │
───────────────────┘
]);
let mut device = uinput::VirtualDeviceBuilder::new()?
- .name("kanata")
+ .name("kanata TrackPoint")
// libinput's "disable while typing" feature don't work when bus_type
// is set to BUS_USB, but appears to work when it's set to BUS_I8042.
.input_id(evdev::InputId::new(evdev::BusType::BUS_I8042, 1, 1, 1))
it seems like hidden trackpoint behavior in libinput, but a quick search of the codebase didn't turn up anything obvious.
ok I think I've found an explanation for the behavior change when renaming the kanata virtual device.
- udev tags things that end in trackpoint as pointing sticks
- when configuring a device, libinput passes all mice through
evdev_tag_trackpoint() - devices having the
ID_INPUT_POINTINGSTICKproperty from udev (orINPUT_PROP_POINTING_STICKfrom evdev) are awarded theEVDEV_TAG_TRACKPOINTtag - devices with
EVDEV_TAG_TRACKPOINThave the default scroll method set toLIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN
I was able to test setting INPUT_PROP_POINTING_STICK on the kanata virtual device (keeping the name unmodified) and it worked! However property setting was only added in evdev-0.12.1, which is masked in Cargo.toml due to a bug?
Assuming at some point the evdev bug is resolved, my proposal would be to check the evdev properties of mouse devices that kanata registers for that property and then use it on the virtual device, if found.
EDIT: alternatively, Mouse Button Scroll could simply be a static configuration option.
in addition to enabling mouse button scrolling, applying the POINTING_STICK property in kanata, as I've done in #1007, has several effects:
- a different acceleration curve is used
- DPI doesn't apply
- a trackpoint multiplier is set, but it will be 1.0 unless there a a quirks file that matches kanata
- the trackpoint is paired to a touchpad, if applicable, for palm detection (this doesn't seem to work even without kanata involved?)
so it might be recommended not to capture other pointing devices at the same time as using kanata with a trackpoint.
Thanks for the investigation!