lentinj / tp-compact-keyboard

Fn-Lock switcher for ThinkPad Compact Bluetooth Keyboard with TrackPoint
GNU General Public License v2.0
350 stars 33 forks source link

USB keyboard behaviour undesirable with patched module / 4.0rc3 kernel #23

Closed lorenzhs closed 9 years ago

lorenzhs commented 9 years ago

Thanks for all the work you've done to make these keyboards usable in Linux! However, I'm having trouble with the USB version ("ThinkPad Compact USB Keyboard with TrackPoint"). Using Linux 4.0-rc3 (or its hid-lenovo module on an 3.16 kernel), attempting to scroll with the TrackPoint is very frustrating. A middle-click event is generated as soon as the middle button is pressed. This causes Xorg paste behaviour, and outright breaks scrolling in some applications (Thunderbird opens the message under the cursor instead of scrolling). This is frustrating as evdev settings (xinput set-prop etc) do not work.

Desired behaviour:

Please let me know if I'm not making any sense to you ;)

lorenzhs commented 9 years ago

Specifically, a middle button press event should only be emitted when the middle button is physically released before the timeout expires. This is how hid-generic handles it (when wheel emulation is enabled). The problem with hid-generic is that it doesn't support horizontal scrolling.

lentinj commented 9 years ago

Can you clarify a bit (ideally whilst using evtest in a console). Do you see:- 1) BTN_MIDDLE down 2) Scroll events 3) BTN_MIDDLE up or 1) BTN_MIDDLE down 2) BTN_MIDDLE up 3) Scroll events

lentinj commented 9 years ago

But yes, I feel your pain.

Unlike any other trackpoint keyboard, the middle button scrollwheel emulation is built into the device. By default it works like the latter sequence above (i.e. the middle button releases as soon as emulated scroll events start). In theory in 4.0 it should switch to the former, which I've found far less infuriating (Firefox/Chormium seem to do the right thing at least). Is this how your keyboard is working?

However, like you say it's still not perfect. I think ideally the hardware scroll emulation should be disabled and leave it to Xorg, but I've not thought of a way of neatly doing this yet.

lorenzhs commented 9 years ago

I'm seeing the first kind of behaviour - down, wheel, up, so as you've said, 4.0 is progress :) It does work fine in Chrome for me as well, but it completely breaks in other applications (Thunderbird, Sublime Text) and is a terrible pain on the terminal (as it always triggers a paste). Leaving it to Xorg would probably fix my issue with it (because it'd be configurable), but I'm not sure how to implement any of this.

For the time being, I've switched back to hid-generic and Xorg mouse wheel emulation, which does the right thing for everything but horizontal scrolling (which doesn't work at all).

lentinj commented 9 years ago

The USB version doesn't implement the "compatibility mode" properly, which will be why horizontal scroll doesn't work (see #14). It always sends custom HID reports.

lorenzhs commented 9 years ago

Thanks, what an awful device...

lentinj commented 9 years ago

Aw, it's not that bad :) Although it seems like more effort was put into the Bluetooth version.

v1ne commented 9 years ago

Well, actually it is quite bad. ;) We are talking about a keyboard controller here, not about rocket science. :-D

Thinking of the mode with command 13 09 01, "native mode", or "thinkpad scrolling" as the Lenovo driver calls it: This mode could be used for a work around, since we know that the middle button is pressed, and afterwards, scroll events are received or not and the button is released. So we could translate the scroll events into pointer movements such that the Xorg driver then converts them back into scroll events, if I am not mistaken. This is quite ugly and I still hope that Lenovo fixes the keyboard controller's firmware. They did it before on SK-8855 (famous DOuble CAps bug).

Until then, I am playing with the other HID commands. When the keyboard is plugged in, the Windows driver initialises it with 13 01 08. Do you know what the bits in the 0x08 mean? As far as I see, we only know 0x03 to use the additional Fn keys.

lentinj commented 9 years ago

Thinkpad drivers under windows have either done scrolling or middle-click, as far as I remember, never both. And middle-click isn't really a used action under windows anyway. I'm not sure Lenovo will see anything here to fix.

But yes, I have thought about translating the wheel reports back to mouse movement reports (for X.org to then translate back to wheel events) and may give it a go at some point. This should be reasonably easy to do by modifying the report descriptor, the problem will be bodging around the lack of sensitivity when scrolling.

If there's a command to disable the scroll emulation, that'd be far better. All my knowledge on sent commands is in the tp-compact-keyboard script, and I never saw 01 08. If the bits in 01 08 do anything though, it seems a reasonable guess it's something to do with keys, not the trackpoint.

alexrichert commented 9 years ago

I've been having this same problem with the middle click event happening on press rather than release. lorenzhs, you said that you switched back to the generic driver (sacrificing horiz. scrolling, which I am happy to do)-- how did you do this? Or can you point me in the right direction, since I know very little about the inner workings of how Linux interacts with devices?

lorenzhs commented 9 years ago

@alexrichert you can blacklist the hid-lenovo module in /etc/modprobe.d/blacklist.conf by adding the following line:

blacklist hid-lenovo

This will prevent the module from being loaded automatically. You can still load it manually with modprobe hid-lenovo (as root).

1gn1t10n commented 9 years ago

Workaround

Hi guys, I wanted to share something I have accidentally discovered: if you move the cursor first and then press the middle button, scrolling works as expected.

Long version

Keyboard: ThinkPad Compact USB Keyboard with TrackPoint Kernel: linux-3.19.3-3-ARCH Driver: hid-lenovo Problem: the same "paste vs scroll" dilemma

I tried blacklisting the hid-lenovo module but then the keyboard stopped working completely (regardless whether I manually loaded hid-generic). So I resorted to using it again.

In evtest I observe

  1. BTN_MIDDLE down
  2. BTN_MIDDLE up
  3. scroll events

However, in xev I observe

  1. ButtonPress 2
  2. ButtonPress 5
  3. ButtonRelease 5
  4. ButtonRelease 2 and then alternating ButtonPress/ButtonRelease 5

In both cases I

  1. Press middle button
  2. Scroll (move trackpoint)
  3. either 3.1 stop scrolling 3.2 release middle button or the other way around, it's the same; there is no middle button release event after all the scrolling is done.

I have tried the workaround I mentioned both in this Github editing window, and in Thunderbird, and it works (without adverse pasting -- I made sure the clipboard is not empty) . At the same time, I can paste with the middle button in the terminal emulator or open links in Firefox.

Does this help?

Note: A different problem is that horizontal scrolling doesn't work at all. No event is generated whatsoever. It is inconvenient as it masks the panning behaviour triggered with middle click in applications like Evince.

alexrichert commented 9 years ago

Yes and no-- I had discovered this previously, unfortunately it's still all to easy for me to accidentally middle click... I haven't had this issue with my Lenovo laptop's trackpoint, which waits x amount of time after middle button press to decide whether we are clicking or scrolling...

alexrichert commented 9 years ago

So strangely, after some fiddling the other day, things seem to be working 90% perfectly. It doesn't paste on middle click press (!) but it can still paste and scroll. The only downside is that if I start scrolling too soon after pressing middle click, it turns into a paste. So I just have to wait slightly before I start scrolling. But I can set the relevant timespan, so it's not a huge deal (100ms, as shown below, is working pretty well for me). I'm not 100% sure how I did this, but I think the only thing I changed was my xorg.conf with the following; can somebody else test this out?

Section "InputClass"
    Identifier         "Trackpoint Wheel Emulation"
    MatchDevicePath    "/dev/input/event*"
    Option         "EmulateWheel" "true"
    Option         "EmulateWheelButton" "2"
    Option         "EmulateWheelTimeout" "100"
    Option         "Emulate3Buttons" "true"
    Option         "XAxisMapping" "6 7"
    Option         "YAxisMapping" "4 5"
EndSection
alexrichert commented 9 years ago

By the way @lorenzhs, I tried blacklisting hid-lenovo as suggested but the keyboard just stopped working altogether... So somehow I seem to have gotten things mostly working using the hid-lenovo module, but now I have to figure out what I did!

lorenzhs commented 9 years ago

@alexrichert yeah same for me on 4.0 (it used to work with the backported module in 3.16). I'm just trying out your methods now because the state as it is by default in 4.0 is quite infuriating (things behave differently from the way they used to).

lorenzhs commented 9 years ago

What works for me is disabling middle-click paste in Gnome tweak tools and not doing anything with Xorg. It's not a good solution though because I use middle-click paste a lot :/

lorenzhs commented 9 years ago

My hacky workaround for now is setting the Weech Emulation Button to 3 and scrolling with right-click + trackpoint, and using the middle button for pasting. Will probably take a while to get used to but at least I can do everything I need to

lentinj commented 9 years ago

@v1ne Unfortunately mapping scroll events to X & Y events isn't as simple as you'd think, since somewhere in the HID subsystem insists that only one type of report maps to REL_X, etc. (I thought I had tried it before and forgot something). Not sure this is my mistake, or an insistence of the HID subsystem.

Translating on the fly could work, but will be tricky since the reports are different lengths.

lentinj commented 9 years ago

Okay, you can do it. The following patch maps the wheel events back to X/Y events as close as it can.

https://github.com/lentinj/linux/commit/0646f4f66be391a4e455d7d6eb2f1460c57822d8

Obviously once you do this you'll need to turn wheel emulation on:

xinput set-prop "ThinkPad Compact Bluetooth Keyboard with TrackPoint" "Evdev Wheel Emulation" 1
xinput set-prop "ThinkPad Compact Bluetooth Keyboard with TrackPoint" "Evdev Wheel Emulation Button" 2
xinput set-prop "ThinkPad Compact Bluetooth Keyboard with TrackPoint" "Evdev Wheel Emulation Axes" 6 7 4 5

I really don't like this hack, but it may be there's nothing else to do.

alexrichert commented 9 years ago

Unfortunately even that doesn't work now on Fedora 22, which apparently has switched from evdev to libinput. From what I can tell, middle-click scrolling is automatically supported, except that it pastes on middle-click no matter what, so, for the time being it looks like I just can't have nice things...

Markus00000 commented 9 years ago

This thread in the Arch Linux forums identifies all kernel versions above 3.19.3 to break wheel emulation.

If anyone tries to downgrade as a workaround, make sure to power off the machine instead of just restarting. This might be why @1gn1t10n experienced this issue with 3.19.3.

lentinj commented 9 years ago

@Markus00000 You shouldn't be using Xorg wheel emulation anyway for this keyboard (at least, not currently). Pre 4.0, Xorg wheel emulation wouldn't have done anything---as soon as there is pointer movement, the middle button is raised and there is keyboard scroll events. Post 4.0, the scroll events happen inbetween the middle-button press, but as they're not X/Y motion, Xorg discards the events.

Just turn off Xorg wheel emulation and you should have wheel events on middle button again.

Markus00000 commented 9 years ago

@lentinj Thank you for the explanation! I’m not sure why I activated wheel emulation in the first place. Maybe I ran into the issue that I didn’t power off between booting different kernels and got the false impression wheel emulation fixed my problems. I’ll just use a pre 4.0 kernel (without wheel emulation) until you hopefully find a way to remove the accidental middle clicks in post 4.0 kernels.

lentinj commented 9 years ago

Okay, I think this is a better fix:- https://github.com/lentinj/linux/commits/tp-better-wheel-emulation-v0

Instead of trying to bodge back to X/Y events, this hides the middle-button-click until we're sure there's no scroll events going to happen.

The downside is long middle clicks are no longer possible. This could be fixed by having a timer to see if scroll events happen (the same way Xorg does it), but that'd require more fiddling. If I can't get that to work then I'll push the above at least.

lentinj commented 9 years ago

Roughly this fix has been accepted upstream, and should be in Linux 4.3:-

https://lkml.org/lkml/2015/8/11/742

I've added the patches into the kernel-patches directory in this repository.

vivien commented 9 years ago

Thanks a lot for your work Jamie!

rcj4747 commented 9 years ago

@lentinj I had problems with you kernel patch. After a suspend/resume cycle the scrolling did not work until I disconnected and re-connected the USB keyboard. Have you seen/heard of this happening with the patches?

v1ne commented 9 years ago

@rcj4747 I'm also seeing this. After resume from suspend to RAM, the middle mouse button stops working for me.

lentinj commented 9 years ago

@v1ne thanks, but can you move the discussion to https://github.com/lentinj/tp-compact-keyboard/issues/28 (so we don't spam all the people on this issue).

florianjacob commented 8 years ago

@lentinj just installed 4.3.3 and everything works fine. Thanks alot!

/me middle-scrolls away :grin:

lorenzhs commented 8 years ago

Just a quick update, everything works perfectly now with the 4.5 kernel and Xorg 7.7 / xf86-input-libinput (Debian package xserver-xorg-input-libinput, which was pulled in in an update yesterday) / Gnome 3.20. I'm not sure what fixed it (I suspect libinput) but it behaves exactly like I want it now :)

lorenzhs commented 8 years ago

@alexrichert libinput works great for me (version 1.2.4-1 from Debian unstable). From libinput-list-devices:

Device:           Lenovo ThinkPad Compact USB Keyboard with TrackPoint
Kernel:           /dev/input/event1
Group:            5
Seat:             seat0, default
Capabilities:     keyboard pointer 
Tap-to-click:     n/a
Tap-and-drag:     n/a
Tap drag lock:    n/a
Left-handed:      disabled
Nat.scrolling:    disabled
Middle emulation: disabled
Calibration:      n/a
Scroll methods:   *button
Click methods:    none
Disable-w-typing: n/a
Accel profiles:   flat*adaptive

Pastes on middle click if I don't scroll, scrolls without paste if I do. libinput-debug-events reveals that a BTN_MIDDLE pressed event is only sent once I release it, together with the release event:

event1  POINTER_BUTTON   +41.19s    BTN_MIDDLE (274) pressed, seat count: 1
event1  POINTER_BUTTON   +41.19s    BTN_MIDDLE (274) released, seat count: 0

And no button events are sent if I scroll, just POINTER_AXIS.

lentinj commented 8 years ago

@lorenzhs Good stuff. In theory it's not perfect, see https://github.com/lentinj/tp-compact-keyboard/issues/30 however that hasn't annoyed me enough yet :)

lorenzhs commented 8 years ago

hehe yeah I noticed that too but I'm fine with just scrolling a little bit to prevent that.

bechampion commented 3 years ago

Hi all , this thread is 5 years old but im having the issue , on my lenovo trackpoint II , where you press the middle button and emits the paste even before release , so when i use it for scrolling it pastes all over the place I'm running on

extra libinput 1.17.0-1 [installed: 1.16.3-1]
extra xf86-input-libinput 0.30.0-1 [installed]
> Linux x260 5.4.79-1-lts #1 SMP Sun, 22 Nov 2020 14:22:21 +0000 x86_64 GNU/Linux
extra xorg-server 1.20.10-3 [installed: 1.20.9.r21.g5c400cae1-2]
extra xorg-server-common 1.20.10-3 [installed: 1.20.9.r21.g5c400cae1-2]
extra xorg-server-devel 1.20.10-3 [installed: 1.20.9.r21.g5c400cae1-2]
extra xorg-server-xephyr 1.20.10-3 [installed: 1.20.9.r21.g5c400cae1-2]
extra xorg-server-xnest 1.20.10-3 [installed: 1.20.9.r21.g5c400cae1-2]
extra xorg-server-xvfb 1.20.10-3 [installed: 1.20.9.r21.g5c400cae1-2]

I know its a long shot but i wonder if this ever worked?

lentinj commented 3 years ago

you press the middle button and emits the paste even before release , so when i use it for scrolling it pastes all over the place

Yes, that's what the old compact keyboard does out-of-the-box too. The Lenovo hotkey driver would switch keyboard mode so the middle button output is more sensible. These kernel patches send the mode-switching commands automatically, and then translate the custom events the keyboard now sends back into standard middle-button presses.

But I don't have the new keyboard, and AFAIK the new keyboard doesn't respond to the utilities in this repository (that can also send the relevant commands).

bechampion commented 3 years ago

ahh thanks so much for getting back to me , ill try the patches later and get back , so far i have disabled the middle click with xinput ... and i guess i have to live with this if the patches don't work. The lenovo driver to fix this i've seen around for windows , has anybody tried it and check that it fixes the issue on windows? Thanks!

bechampion commented 3 years ago

Also , do you have some more info about the "lenovo hotkey driver" you referring to?