Bug 105830

Summary: libinput ignores xinput settings regarding mouse wheel (quick fix included)
Product: Wayland Reporter: Stefan B <sblachmann>
Component: libinputAssignee: Wayland bug list <wayland-bugs>
Status: RESOLVED NOTOURBUG QA Contact:
Severity: normal    
Priority: medium CC: peter.hutterer, sblachmann
Version: unspecified   
Hardware: All   
OS: All   
Whiteboard:
i915 platform: i915 features:

Description Stefan B 2018-03-31 00:38:33 UTC
PROBLEM:
libinput ignores settings done by "xinput set-button-map" that set wheels to zero to deactivate them.

For details, please see: http://forums.debian.net/viewtopic.php?f=6&t=137104
Bug https://bugs.freedesktop.org/show_bug.cgi?id=104960 is possibly also influenced by this issue.

CAUSE:
My investigation showed what causes the bug.
The problem is in libinput.c.
Please look at the comments added by me to understand the problem.

SOLUTION:
My quick fix factually just consisted of disabling the wheel by always returning zero movement.
A *proper* fix would check whether the wheel is enabled at all in the button map set by xinput or xorg.conf, and discard the events if wheel is disabled.

<<<CODE SNIPPET START>>>
LIBINPUT_EXPORT double
libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer *event,
					       enum libinput_pointer_axis axis)
{
	struct libinput *libinput = event->base.device->seat->libinput;
	double value = 0;

	require_event_type(libinput_event_get_context(&event->base),
			   event->base.type,
			   0.0,
			   LIBINPUT_EVENT_POINTER_AXIS);

	if (!libinput_event_pointer_has_axis(event, axis)) {
		log_bug_client(libinput, "value requested for unset axis\n");
	} else {
		switch (axis) {
		case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
			value = event->discrete.x;
			break;
		case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
			value = event->discrete.y;
			break;
		}
	}
// 	return value;
// 	
// 	YUCKY BUG HERE: xinput-disabled wheels will generate events
// 	FIX by checking xinput button map
// 	for now just FSCK THE SCROLL SH!T
		
	return 0;
}

LIBINPUT_EXPORT enum libinput_pointer_axis_source
libinput_event_pointer_get_axis_source(struct libinput_event_pointer *event)
{
	require_event_type(libinput_event_get_context(&event->base),
			   event->base.type,
			   0,
			   LIBINPUT_EVENT_POINTER_AXIS);

// 	return event->source;
// 	
// 	YUCKY BUG HERE: xinput-disabled wheels will generate events
// 	FIX by checking xinput button map
// 	for now just FSCK THE SCROLL SH!T
	
	return 0;
}
<<<CODE SNIPPET END>>>
Comment 1 Peter Hutterer 2018-04-02 23:02:27 UTC
libinput doesn't do button mapping, that's handled in the X server. Likewise with the scroll axis to button emulation.  This "fix" here is like hacking glibc because you don't want to resolve a specific hostname - less than ideal and, despite your eye-roll in the debian user forum comment, this is not a bug in libinput.

The fix would have to be in the server, specifically in emulate_scroll_button_events() which doesn't appear to take the button mapping into account.

The main question here though is: why do you need to disable the mouse wheel? Apparently:

> The problem is that the cat hairs in the mice make them "scroll" even without 
> touching the wheel - highly annoying!

So yeah, nah. Not going to hack libinput for this. Feel free to open a bug against the X server when you've verified that button mapping isn't taking into account for scroll button emulation, but don't expect anyone to have the time to fix this right now. I suggest to get a new mouse, because the amount of effort required on our side to keep your cat hairs off your wheel is disproportional to the money a new mouse costs.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.