[PATCH libinput v2 9/9] touchpad: Disable touchpads on trackpoint activity

Peter Hutterer peter.hutterer at who-t.net
Mon Nov 3 21:35:32 PST 2014


On Sun, Sep 28, 2014 at 01:21:08PM +0200, Hans de Goede wrote:
> Some laptops with both a clickpad and a trackpoint have such a large touchpad,
> that parts of the users hands will touch the pad when using the trackpoint.
> Examples of this are the Lenovo T440s and the Toshiba Tecra Z40-A.
> 
> This commit makes libinput automatically disable the touchpad while using
> the trackpoint on these devices, except for the buttons, as people may want
> to use the touchpad (hardware or soft) buttons while using the trackpoint.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

I've merged this set locally except for 7, please send me v3 of that and
I'll push it out after some more testing. Thanks.

Cheers,
   Peter

> ---
>  src/evdev-mt-touchpad.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++-
>  src/evdev-mt-touchpad.h |  3 +++
>  2 files changed, 63 insertions(+), 1 deletion(-)
> 
> diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
> index 092e26f..b7a559f 100644
> --- a/src/evdev-mt-touchpad.c
> +++ b/src/evdev-mt-touchpad.c
> @@ -31,6 +31,7 @@
>  
>  #define DEFAULT_ACCEL_NUMERATOR 1200.0
>  #define DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR 700.0
> +#define DEFAULT_TRACKPOINT_ACTIVITY_TIMEOUT 500 /* ms */
>  
>  static inline int
>  tp_hysteresis(int in, int center, int margin)
> @@ -538,7 +539,7 @@ tp_post_events(struct tp_dispatch *tp, uint64_t time)
>  	filter_motion |= tp_tap_handle_state(tp, time);
>  	filter_motion |= tp_post_button_events(tp, time);
>  
> -	if (filter_motion) {
> +	if (filter_motion || tp->sendevents.trackpoint_active) {
>  		evdev_stop_scroll(tp->device, time);
>  		return;
>  	}
> @@ -600,6 +601,16 @@ tp_process(struct evdev_dispatch *dispatch,
>  }
>  
>  static void
> +tp_destroy_sendevents(struct tp_dispatch *tp)
> +{
> +	libinput_timer_cancel(&tp->sendevents.trackpoint_timer);
> +
> +	if (tp->buttons.trackpoint)
> +		libinput_device_remove_event_listener(
> +					&tp->sendevents.trackpoint_listener);
> +}
> +
> +static void
>  tp_destroy(struct evdev_dispatch *dispatch)
>  {
>  	struct tp_dispatch *tp =
> @@ -607,6 +618,7 @@ tp_destroy(struct evdev_dispatch *dispatch)
>  
>  	tp_destroy_tap(tp);
>  	tp_destroy_buttons(tp);
> +	tp_destroy_sendevents(tp);
>  
>  	free(tp->touches);
>  	free(tp);
> @@ -672,6 +684,35 @@ tp_resume(struct tp_dispatch *tp, struct evdev_device *device)
>  }
>  
>  static void
> +tp_trackpoint_timeout(uint64_t now, void *data)
> +{
> +	struct tp_dispatch *tp = data;
> +
> +	tp_tap_resume(tp, now);
> +	tp->sendevents.trackpoint_active = false;
> +}
> +
> +static void
> +tp_trackpoint_event(uint64_t time, struct libinput_event *event, void *data)
> +{
> +	struct tp_dispatch *tp = data;
> +
> +	/* Buttons do not count as trackpad activity, as people may use
> +	   the trackpoint buttons in combination with the touchpad. */
> +	if (event->type == LIBINPUT_EVENT_POINTER_BUTTON)
> +		return;
> +
> +	if (!tp->sendevents.trackpoint_active) {
> +		evdev_stop_scroll(tp->device, time);
> +		tp_tap_suspend(tp, time);
> +		tp->sendevents.trackpoint_active = true;
> +	}
> +
> +	libinput_timer_set(&tp->sendevents.trackpoint_timer,
> +			   time + DEFAULT_TRACKPOINT_ACTIVITY_TIMEOUT);
> +}
> +
> +static void
>  tp_device_added(struct evdev_device *device,
>  		struct evdev_device *added_device)
>  {
> @@ -682,6 +723,9 @@ tp_device_added(struct evdev_device *device,
>  		/* Don't send any pending releases to the new trackpoint */
>  		tp->buttons.active_is_topbutton = false;
>  		tp->buttons.trackpoint = added_device;
> +		libinput_device_add_event_listener(&added_device->base,
> +					&tp->sendevents.trackpoint_listener,
> +					tp_trackpoint_event, tp);
>  	}
>  
>  	if (tp->sendevents.current_mode !=
> @@ -705,6 +749,8 @@ tp_device_removed(struct evdev_device *device,
>  			tp->buttons.active = 0;
>  			tp->buttons.active_is_topbutton = false;
>  		}
> +		libinput_device_remove_event_listener(
> +					&tp->sendevents.trackpoint_listener);
>  		tp->buttons.trackpoint = NULL;
>  	}
>  
> @@ -941,6 +987,16 @@ tp_init_palmdetect(struct tp_dispatch *tp,
>  }
>  
>  static int
> +tp_init_sendevents(struct tp_dispatch *tp,
> +		   struct evdev_device *device)
> +{
> +	libinput_timer_init(&tp->sendevents.trackpoint_timer,
> +			    tp->device->base.seat->libinput,
> +			    tp_trackpoint_timeout, tp);
> +	return 0;
> +}
> +
> +static int
>  tp_init(struct tp_dispatch *tp,
>  	struct evdev_device *device)
>  {
> @@ -979,6 +1035,9 @@ tp_init(struct tp_dispatch *tp,
>  	if (tp_init_palmdetect(tp, device) != 0)
>  		return -1;
>  
> +	if (tp_init_sendevents(tp, device) != 0)
> +		return -1;
> +
>  	device->seat_caps |= EVDEV_DEVICE_POINTER;
>  
>  	return 0;
> diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
> index cc04dc9..2fda4ef 100644
> --- a/src/evdev-mt-touchpad.h
> +++ b/src/evdev-mt-touchpad.h
> @@ -225,6 +225,9 @@ struct tp_dispatch {
>  	struct {
>  		struct libinput_device_config_send_events config;
>  		enum libinput_config_send_events_mode current_mode;
> +		bool trackpoint_active;
> +		struct libinput_event_listener trackpoint_listener;
> +		struct libinput_timer trackpoint_timer;
>  	} sendevents;
>  };
>  
> -- 
> 2.1.0
 


More information about the wayland-devel mailing list