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

Peter Hutterer peter.hutterer at who-t.net
Mon Sep 22 23:25:45 PDT 2014


On Mon, Sep 22, 2014 at 09:22:02AM +0200, Hans de Goede wrote:
> Hi,
> 
> On 09/22/2014 07:18 AM, Peter Hutterer wrote:
> > On Thu, Sep 18, 2014 at 01:11:05PM +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>
> >> ---
> >>  src/evdev-mt-touchpad.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++--
> >>  src/evdev-mt-touchpad.h |  3 +++
> >>  2 files changed, 65 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
> >> index 1c32cc6..31e2e83 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)
> >> @@ -523,8 +524,8 @@ tp_post_events(struct tp_dispatch *tp, uint64_t time)
> >>  	double dx, dy;
> >>  	int consumed = 0;
> >>  
> >> -	/* Only post (top) button events while suspended */
> >> -	if (tp->device->suspended) {
> >> +	/* Only post (top) button events? */
> >> +	if (tp->device->suspended || tp->sendevents.trackpoint_active) {
> >>  		tp_post_button_events(tp, time);
> >>  		return;
> >>  	}
> >> @@ -594,6 +595,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_eventlistener(
> >> +					&tp->sendevents.trackpoint_listener);
> >> +}
> >> +
> >> +static void
> >>  tp_destroy(struct evdev_dispatch *dispatch)
> >>  {
> >>  	struct tp_dispatch *tp =
> >> @@ -601,6 +612,7 @@ tp_destroy(struct evdev_dispatch *dispatch)
> >>  
> >>  	tp_destroy_tap(tp);
> >>  	tp_destroy_buttons(tp);
> >> +	tp_destroy_sendevents(tp);
> >>  
> >>  	filter_destroy(tp->filter);
> >>  	free(tp->touches);
> >> @@ -667,6 +679,36 @@ 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_clear_state(tp, tp->device);
> >> +	tp->sendevents.trackpoint_active = false;
> >> +}
> >> +
> >> +static void
> >> +tp_trackpoint_event(struct libinput_event *event, void *data)
> >> +{
> >> +	struct tp_dispatch *tp = data;
> >> +
> >> +	/* Only movement counts as trackpad activity, as people may use
> >> +	   the trackpoint buttons in combination with the touchpad. */
> >> +	if (event->type != LIBINPUT_EVENT_POINTER_MOTION)
> >> +		return;
> > 
> > the wheel emulation code posts axis events, you'll need to include those
> > here as well. 
> 
> Ah good one will fix.
> 
> > 
> >> +
> >> +	if (!tp->sendevents.trackpoint_active) {
> >> +		tp_clear_state(tp, tp->device);
> >> +		tp->sendevents.trackpoint_active = true;
> >> +	}
> >> +
> >> +	/* We don't use the event time as that may wrap */
> >> +	libinput_timer_set(&tp->sendevents.trackpoint_timer,
> >> +			   libinput_now(tp->device->base.seat->libinput) +
> >> +				DEFAULT_TRACKPOINT_ACTIVITY_TIMEOUT);
> > 
> > Can you expand on this?
> > it seems like an odd comment given that we use the event time elsewhere.
> 
> Elsewhere we use evdev_event times. Here we've a libinput_event which uses
> a 32 bit unsigned integer holding ms, which will wrap aprox. every 50 days,
> and since this is clock_monotonic, that is every 50 days since system boot,
> not since last login or some such. Since uptimes of 50 days are not out
> of the ordinary, we need to deal with this.
> 
> I've fixed this for evdev a while back by changing evdev internal timestamps
> to uint64 everywhere. Currently these get truncated to 32 bit timestamps
> the moment one of the (e.g.) pointer_notify_foo functions get called.
> 
> I guess a better fix might be to push the 64 bit timestamps down into
> libinput.c itself, doing the truncating to 32 bit when (e.g.)
> libinput_event_pointer_get_time gets called.

that seems to be the best option here, should slot in nicely enough before
the patchset without much rebasing pain.

> Note that one could argue we should make libinput_event_pointer_get_time
> return a 64 bit value (or add a 64 bit variant), but the wayland wire
> protocol only uses 32 bit time stamps, so there is not much use in that.
 
> > it also provides inconsistent behaviour, if libinput is slow to read the
> > event the timeout is set from when it gets processes as opposed to when the
> > physical interaction happened. That's something we should avoid.
> 
> Under normal circumstances I would expect libinput to get behind say
> 50 ms maximum, which is not all that much on a 500ms timeout.

Normal circumstances are not what we have to worry about :)

Cheers,
   Peter


More information about the wayland-devel mailing list