Page 1 of 1

Thinkpad trackpad middle mouse button can fail in Linux

PostPosted: 29 Sep 2017, 17:12
by Forgon
Moving the cursor while the middle mouse button is pressed (i.e. dragging it) rotates the screen. In some Thinkpad models, trackpad middle buttons can fail at this task because of a feature called "wheel emulation":

Pressing the trackpad middle button puts the trackpoint in scroll mode instead of generating a "press" event. Because of this missing event, SDL can only recognise that middle button when it is released, not when it is pressed or down:

Code: Select all
// simplified code from ./lib/sdl/main_sdl.cpp

SDL_Event event;
while (true)
{
   /* Deal with any windows messages */
   while (SDL_PollEvent(&event))
   {
      switch (event.type)
      {
          case SDL_MOUSEBUTTONUP:
                                // recognised with both middle mouse and middle trackpad buttons
            debug(LOG_ERROR, "released middle button");
                                break;
          case SDL_MOUSEBUTTONDOWN:
                                // only recognised with middle mouse button
            debug(LOG_ERROR, "pressed middle button");
             break;
          default:
             debug(LOG_ERROR, "unknown event");
             break;
      }
   }
}

// pressing and releasing middle button results in key states:
// KEY_PRESSED, KEY_DOWN and KEY_RELEASED for middle mouse button
// KEY_PRESSRELEASE for middle trackpad button

To disable wheel emulation, you can use xinput:

0. Determine the trackpoint device name (usually 'TPPS/2 IBM TrackPoint'):
Code: Select all
xinput list --name-only

1. List its properties:
Code: Select all
xinput list-props 'TPPS/2 IBM TrackPoint'

2. The name of the property to be changed depends on your input driver.

For libinput, run:
Code: Select all
xinput set-prop 'TPPS/2 IBM TrackPoint' 'libinput Button Scrolling Button' 0

For evdev, run:
Code: Select all
xinput set-prop 'TPPS/2 IBM TrackPoint' 'Evdev Wheel Emulation' 0

3. To test your change, press the middle button inside a window opened by:
Code: Select all
xinput test-xi2 'TPPS/2 IBM TrackPoint'

The result should look similar to:
Code: Select all
TPPS/2 IBM TrackPoint                      id=13   [slave  pointer  (2)]
   Reporting 7 classes:
      Class originated from: 13. Type: XIButtonClass
      Buttons supported: 7
      Button labels: "Button Left" "Button Middle" "Button Right" "Button Wheel Up" "Button Wheel Down" "Button Horiz Wheel Left" "Button Horiz Wheel Right"
      Button state:
      Class originated from: 13. Type: XIValuatorClass
      Detail for Valuator 0:
        Label: Rel X
        Range: -1.000000 - -1.000000
        Resolution: 0 units/m
        Mode: relative
      Class originated from: 13. Type: XIValuatorClass
      Detail for Valuator 1:
        Label: Rel Y
        Range: -1.000000 - -1.000000
        Resolution: 0 units/m
        Mode: relative
      Class originated from: 13. Type: XIValuatorClass
      Detail for Valuator 2:
        Label: Rel Horiz Scroll
        Range: -1.000000 - -1.000000
        Resolution: 0 units/m
        Mode: relative
      Class originated from: 13. Type: XIValuatorClass
      Detail for Valuator 3:
        Label: Rel Vert Scroll
        Range: -1.000000 - -1.000000
        Resolution: 0 units/m
        Mode: relative
      Class originated from: 13. Type: XIScrollClass
      Scroll info for Valuator 2
        type: 2 (horizontal)
        increment: 15.000000
        flags: 0x0
      Class originated from: 13. Type: XIScrollClass
      Scroll info for Valuator 3
        type: 1 (vertical)
        increment: 15.000000
        flags: 0x0

EVENT type 15 (RawButtonPress)
    device: 13 (13)
    detail: 2
    flags:
    valuators:

EVENT type 4 (ButtonPress)
    device: 13 (13)
    detail: 2
    flags:
    root: 87.65/97.23
    event: 87.65/77.23
    buttons:
    modifiers: locked 0 latched 0 base 0 effective: 0
    group: locked 0 latched 0 base 0 effective: 0
    valuators:
    windows: root 0xc2 event 0x1800001 child 0x1800002