[PATCH libinput 2/8] evdev: Add middle button scrolling for trackpoints

Hans de Goede hdegoede at redhat.com
Thu Sep 18 00:51:44 PDT 2014


Hi,

On 09/18/2014 03:49 AM, Peter Hutterer wrote:
> On Tue, Sep 16, 2014 at 04:22:36PM +0200, Hans de Goede wrote:
>> Most trackpoint users want to be able to scroll using the trackpoint with
>> the middle button pressed, add support for this.
>>
>> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
>> Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
>> ---
>>  include/linux/input.h    |  1 +
>>  src/evdev.c              | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
>>  src/evdev.h              |  5 +++++
>>  test/litest-trackpoint.c |  2 ++
>>  test/pointer.c           |  4 +++-
>>  5 files changed, 67 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/linux/input.h b/include/linux/input.h
>> index aa98ce7..39b550b 100644
>> --- a/include/linux/input.h
>> +++ b/include/linux/input.h
>> @@ -163,6 +163,7 @@ struct input_keymap_entry {
>>  #define INPUT_PROP_BUTTONPAD		0x02	/* has button(s) under pad */
>>  #define INPUT_PROP_SEMI_MT		0x03	/* touch rectangle only */
>>  #define INPUT_PROP_TOPBUTTONPAD		0x04	/* softbuttons at top of pad */
>> +#define INPUT_PROP_POINTING_STICK	0x05	/* is a pointing stick */
>>  
>>  #define INPUT_PROP_MAX			0x1f
>>  #define INPUT_PROP_CNT			(INPUT_PROP_MAX + 1)
>> diff --git a/src/evdev.c b/src/evdev.c
>> index 45020ba..85e4d71 100644
>> --- a/src/evdev.c
>> +++ b/src/evdev.c
>> @@ -41,6 +41,7 @@
>>  #include "libinput-private.h"
>>  
>>  #define DEFAULT_AXIS_STEP_DISTANCE 10
>> +#define DEFAULT_MIDDLE_BUTTON_SCROLL_TIMEOUT 200
>>  
>>  enum evdev_key_type {
>>  	EVDEV_KEY_TYPE_NONE,
>> @@ -203,6 +204,15 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
>>  		device->rel.dx = 0;
>>  		device->rel.dy = 0;
>>  
>> +		/* Use unaccelerated deltas for pointing stick scroll */
>> +		if (device->scroll.has_middle_button_scroll &&
>> +		    hw_is_key_down(device, BTN_MIDDLE)) {
>> +			if (device->scroll.middle_button_scroll_active)
>> +				evdev_post_scroll(device, time,
>> +						  motion.dx, motion.dy);
>> +			break;
>> +		}
>> +
> 
> Just to verify: the behaviour here is that the scrolling does not activate
> until after the timeout, regardless of the number of motion events during
> the timeout period. Is this intentional, or do we need a threshold here?

This behavior is copied from the xf86-input-evdev driver, and so far in
my testing scrolling through web-pages and pdfs I've not noticed the timeout
being an issue. So my vote goes to the KISS approach of keeping this as is.

Regards,

Hans




> 
> Cheers,
>    Peter
> 
> 
>>  		/* Apply pointer acceleration. */
>>  		filter_dispatch(device->pointer.filter, &motion, device, time);
>>  
>> @@ -346,6 +356,37 @@ get_key_type(uint16_t code)
>>  }
>>  
>>  static void
>> +evdev_middle_button_scroll_timeout(uint64_t time, void *data)
>> +{
>> +	struct evdev_device *device = data;
>> +
>> +	device->scroll.middle_button_scroll_active = true;
>> +}
>> +
>> +static void
>> +evdev_middle_button_scroll_button(struct evdev_device *device,
>> +				 uint64_t time, int is_press)
>> +{
>> +	if (is_press) {
>> +		libinput_timer_set(&device->scroll.timer,
>> +				time + DEFAULT_MIDDLE_BUTTON_SCROLL_TIMEOUT);
>> +	} else {
>> +		libinput_timer_cancel(&device->scroll.timer);
>> +		if (device->scroll.middle_button_scroll_active) {
>> +			evdev_stop_scroll(device, time);
>> +			device->scroll.middle_button_scroll_active = false;
>> +		} else {
>> +			/* If the button is released quickly enough emit the
>> +			 * button press/release events. */
>> +			evdev_pointer_notify_button(device, time, BTN_MIDDLE,
>> +					LIBINPUT_BUTTON_STATE_PRESSED);
>> +			evdev_pointer_notify_button(device, time, BTN_MIDDLE,
>> +					LIBINPUT_BUTTON_STATE_RELEASED);
>> +		}
>> +	}
>> +}
>> +
>> +static void
>>  evdev_process_touch_button(struct evdev_device *device,
>>  			   uint64_t time, int value)
>>  {
>> @@ -405,6 +446,12 @@ evdev_process_key(struct evdev_device *device,
>>  				   LIBINPUT_KEY_STATE_RELEASED);
>>  		break;
>>  	case EVDEV_KEY_TYPE_BUTTON:
>> +		if (device->scroll.has_middle_button_scroll &&
>> +		    e->code == BTN_MIDDLE) {
>> +			evdev_middle_button_scroll_button(device, time,
>> +							  e->value);
>> +			break;
>> +		}
>>  		evdev_pointer_notify_button(
>>  			device,
>>  			time,
>> @@ -946,6 +993,15 @@ evdev_configure_device(struct evdev_device *device)
>>  			device->mt.slot = active_slot;
>>  		}
>>  	}
>> +
>> +	if (libevdev_has_property(evdev, INPUT_PROP_POINTING_STICK)) {
>> +		libinput_timer_init(&device->scroll.timer,
>> +				    device->base.seat->libinput,
>> +				    evdev_middle_button_scroll_timeout,
>> +				    device);
>> +		device->scroll.has_middle_button_scroll = true;
>> +	}
>> +
>>  	if (libevdev_has_event_code(evdev, EV_REL, REL_X) ||
>>  	    libevdev_has_event_code(evdev, EV_REL, REL_Y))
>>  		has_rel = 1;
>> diff --git a/src/evdev.h b/src/evdev.h
>> index 311dddc..e1506d2 100644
>> --- a/src/evdev.h
>> +++ b/src/evdev.h
>> @@ -26,10 +26,12 @@
>>  
>>  #include "config.h"
>>  
>> +#include <stdbool.h>
>>  #include "linux/input.h"
>>  #include <libevdev/libevdev.h>
>>  
>>  #include "libinput-private.h"
>> +#include "timer.h"
>>  
>>  enum evdev_event_type {
>>  	EVDEV_NONE,
>> @@ -96,6 +98,9 @@ struct evdev_device {
>>  	} rel;
>>  
>>  	struct {
>> +		struct libinput_timer timer;
>> +		bool has_middle_button_scroll;
>> +		bool middle_button_scroll_active;
>>  		double threshold;
>>  		uint32_t direction;
>>  	} scroll;
>> diff --git a/test/litest-trackpoint.c b/test/litest-trackpoint.c
>> index 25a377c..40b9ed0 100644
>> --- a/test/litest-trackpoint.c
>> +++ b/test/litest-trackpoint.c
>> @@ -49,6 +49,8 @@ static int events[] = {
>>  	EV_KEY, BTN_MIDDLE,
>>  	EV_REL, REL_X,
>>  	EV_REL, REL_Y,
>> +	INPUT_PROP_MAX, INPUT_PROP_POINTER,
>> +	INPUT_PROP_MAX, INPUT_PROP_POINTING_STICK,
>>  	-1, -1,
>>  };
>>  
>> diff --git a/test/pointer.c b/test/pointer.c
>> index 82c5245..f704372 100644
>> --- a/test/pointer.c
>> +++ b/test/pointer.c
>> @@ -132,7 +132,9 @@ START_TEST(pointer_button)
>>  		test_button_event(dev, BTN_RIGHT, 0);
>>  	}
>>  
>> -	if (libevdev_has_event_code(dev->evdev, EV_KEY, BTN_MIDDLE)) {
>> +	/* Skip middle button test on trackpoints (used for scrolling) */
>> +	if (!libevdev_has_property(dev->evdev, INPUT_PROP_POINTING_STICK) &&
>> +	    libevdev_has_event_code(dev->evdev, EV_KEY, BTN_MIDDLE)) {
>>  		test_button_event(dev, BTN_MIDDLE, 1);
>>  		test_button_event(dev, BTN_MIDDLE, 0);
>>  	}
>> -- 
>> 2.1.0
>>
>> _______________________________________________
>> wayland-devel mailing list
>> wayland-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>>


More information about the wayland-devel mailing list