Page 1 of 1

Thinkpad trackpad middle mouse button can fail in Linux

Posted: 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