[PATCH libinput] touchpad: remove software middle button when emulation is enabled

Hans de Goede hdegoede at redhat.com
Sat Jul 2 10:30:13 UTC 2016


Hi,

On 01-07-16 07:54, Peter Hutterer wrote:
> Expose the middle button emulation on software buttons as proper config
> option. When enabled, remove the middle button software button area.
>
> https://bugs.freedesktop.org/show_bug.cgi?id=96663
>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

This patch looks good to me:

Reviewed-by: Hans de Goede <hdegoede at redhat.com>

Regards,

Hans

> ---
>  doc/clickpad-softbuttons.dox    |   4 +
>  src/evdev-middle-button.c       |   6 +-
>  src/evdev-mt-touchpad-buttons.c |  92 +++++++++++++++-
>  src/evdev-mt-touchpad.c         |   2 +
>  src/evdev-mt-touchpad.h         |   3 +
>  src/evdev.h                     |   9 ++
>  src/libinput.h                  |   4 +
>  test/litest.h                   |  26 +++++
>  test/pointer.c                  |  16 +--
>  test/touchpad-buttons.c         | 233 ++++++++++++++++++++++++++++++++++++++++
>  10 files changed, 382 insertions(+), 13 deletions(-)
>
> diff --git a/doc/clickpad-softbuttons.dox b/doc/clickpad-softbuttons.dox
> index cf4c8c9..ec0381e 100644
> --- a/doc/clickpad-softbuttons.dox
> +++ b/doc/clickpad-softbuttons.dox
> @@ -37,6 +37,10 @@ location of the button is not visibly obvious.
>
>  @image html software-buttons.svg "Left, right and middle-button click with software button areas"
>
> + at note If middle button emulation is enabled on a clickpad, only left and right
> +button areas are available. For more details, see
> +libinput_device_config_middle_emulation_set_enabled().
> +
>  If fingers are down in the main area in addition to fingers in the
>  left or right button area, those fingers are are ignored.
>  A release event always releases the buttons logically down, regardless of
> diff --git a/src/evdev-middle-button.c b/src/evdev-middle-button.c
> index 48650a4..09f77de 100644
> --- a/src/evdev-middle-button.c
> +++ b/src/evdev-middle-button.c
> @@ -643,7 +643,7 @@ evdev_middlebutton_handle_timeout(uint64_t now, void *data)
>  	evdev_middlebutton_handle_event(device, now, MIDDLEBUTTON_EVENT_TIMEOUT);
>  }
>
> -static int
> +int
>  evdev_middlebutton_is_available(struct libinput_device *device)
>  {
>  	return 1;
> @@ -671,7 +671,7 @@ evdev_middlebutton_set(struct libinput_device *device,
>  	return LIBINPUT_CONFIG_STATUS_SUCCESS;
>  }
>
> -static enum libinput_config_middle_emulation_state
> +enum libinput_config_middle_emulation_state
>  evdev_middlebutton_get(struct libinput_device *device)
>  {
>  	struct evdev_device *evdev = (struct evdev_device*)device;
> @@ -681,7 +681,7 @@ evdev_middlebutton_get(struct libinput_device *device)
>  			LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED;
>  }
>
> -static enum libinput_config_middle_emulation_state
> +enum libinput_config_middle_emulation_state
>  evdev_middlebutton_get_default(struct libinput_device *device)
>  {
>  	struct evdev_device *evdev = (struct evdev_device*)device;
> diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c
> index a9b7521..a2f3121 100644
> --- a/src/evdev-mt-touchpad-buttons.c
> +++ b/src/evdev-mt-touchpad-buttons.c
> @@ -564,6 +564,13 @@ tp_init_softbuttons(struct tp_dispatch *tp,
>  		tp->buttons.bottom_area.top_edge = height * .85 + yoffset;
>  	}
>
> +	tp->buttons.bottom_area.middlebutton_left_edge = INT_MAX;
> +	tp->buttons.bottom_area.rightbutton_left_edge = width/2 + xoffset;
> +
> +	/* if middlebutton emulation is enabled, don't init a software area */
> +	if (device->middlebutton.want_enabled)
> +		return;
> +
>  	/* The middle button is 25% of the touchpad and centered. Many
>  	 * touchpads don't have markings for the middle button at all so we
>  	 * need to make it big enough to reliably hit it but not too big so
> @@ -699,6 +706,80 @@ tp_button_config_click_get_default_method(struct libinput_device *device)
>  	return tp_click_get_default_method(tp);
>  }
>
> +void
> +tp_clickpad_middlebutton_apply_config(struct evdev_device *device)
> +{
> +	struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
> +
> +	if (!tp->buttons.is_clickpad ||
> +	    tp->buttons.state != 0)
> +		return;
> +
> +	if (device->middlebutton.want_enabled ==
> +	    device->middlebutton.enabled)
> +		return;
> +
> +	device->middlebutton.enabled = device->middlebutton.want_enabled;
> +	if (tp->buttons.click_method ==
> +	    LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS)
> +		tp_init_softbuttons(tp, device);
> +}
> +
> +static int
> +tp_clickpad_middlebutton_is_available(struct libinput_device *device)
> +{
> +	return evdev_middlebutton_is_available(device);
> +}
> +
> +static enum libinput_config_status
> +tp_clickpad_middlebutton_set(struct libinput_device *device,
> +		     enum libinput_config_middle_emulation_state enable)
> +{
> +	struct evdev_device *evdev = (struct evdev_device*)device;
> +
> +	switch (enable) {
> +	case LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED:
> +		evdev->middlebutton.want_enabled = true;
> +		break;
> +	case LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED:
> +		evdev->middlebutton.want_enabled = false;
> +		break;
> +	default:
> +		return LIBINPUT_CONFIG_STATUS_INVALID;
> +	}
> +
> +	tp_clickpad_middlebutton_apply_config(evdev);
> +
> +	return LIBINPUT_CONFIG_STATUS_SUCCESS;
> +}
> +
> +static enum libinput_config_middle_emulation_state
> +tp_clickpad_middlebutton_get(struct libinput_device *device)
> +{
> +	return evdev_middlebutton_get(device);
> +}
> +
> +static enum libinput_config_middle_emulation_state
> +tp_clickpad_middlebutton_get_default(struct libinput_device *device)
> +{
> +	return evdev_middlebutton_get_default(device);
> +}
> +
> +static inline void
> +tp_init_clickpad_middlebutton_emulation(struct tp_dispatch *tp,
> +					struct evdev_device *device)
> +{
> +	device->middlebutton.enabled_default = false;
> +	device->middlebutton.want_enabled = false;
> +	device->middlebutton.enabled = false;
> +
> +	device->middlebutton.config.available = tp_clickpad_middlebutton_is_available;
> +	device->middlebutton.config.set = tp_clickpad_middlebutton_set;
> +	device->middlebutton.config.get = tp_clickpad_middlebutton_get;
> +	device->middlebutton.config.get_default = tp_clickpad_middlebutton_get_default;
> +	device->base.config.middle_emulation = &device->middlebutton.config;
> +}
> +
>  static inline void
>  tp_init_middlebutton_emulation(struct tp_dispatch *tp,
>  			       struct evdev_device *device)
> @@ -706,8 +787,12 @@ tp_init_middlebutton_emulation(struct tp_dispatch *tp,
>  	bool enable_by_default,
>  	     want_config_option;
>
> -	if (tp->buttons.is_clickpad)
> +	/* On clickpads we provide the config option but disable by default.
> +	   When enabled, the middle software button disappears */
> +	if (tp->buttons.is_clickpad) {
> +		tp_init_clickpad_middlebutton_emulation(tp, device);
>  		return;
> +	}
>
>  	/* init middle button emulation on non-clickpads, but only if we
>  	 * don't have a middle button. Exception: ALPS touchpads don't know
> @@ -1038,7 +1123,10 @@ tp_post_clickpadbutton_buttons(struct tp_dispatch *tp, uint64_t time)
>  			return 0;
>  		}
>
> -		if ((area & MIDDLE) || ((area & LEFT) && (area & RIGHT))) {
> +		if ((tp->device->middlebutton.enabled || is_top) &&
> +		    (area & LEFT) && (area & RIGHT)) {
> +			button = BTN_MIDDLE;
> +		} else if (area & MIDDLE) {
>  			button = BTN_MIDDLE;
>  		} else if (area & RIGHT) {
>  			button = BTN_RIGHT;
> diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
> index 96e78b9..1d67a53 100644
> --- a/src/evdev-mt-touchpad.c
> +++ b/src/evdev-mt-touchpad.c
> @@ -1145,6 +1145,8 @@ tp_handle_state(struct tp_dispatch *tp,
>  	tp_process_state(tp, time);
>  	tp_post_events(tp, time);
>  	tp_post_process_state(tp, time);
> +
> +	tp_clickpad_middlebutton_apply_config(tp->device);
>  }
>
>  static void
> diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
> index 3f3b728..fe1f1b3 100644
> --- a/src/evdev-mt-touchpad.h
> +++ b/src/evdev-mt-touchpad.h
> @@ -527,4 +527,7 @@ tp_gesture_stop_twofinger_scroll(struct tp_dispatch *tp, uint64_t time);
>  bool
>  tp_palm_tap_is_palm(const struct tp_dispatch *tp, const struct tp_touch *t);
>
> +void
> +tp_clickpad_middlebutton_apply_config(struct evdev_device *device);
> +
>  #endif
> diff --git a/src/evdev.h b/src/evdev.h
> index ca13318..f7ff837 100644
> --- a/src/evdev.h
> +++ b/src/evdev.h
> @@ -468,6 +468,15 @@ evdev_init_middlebutton(struct evdev_device *device,
>  			bool enabled,
>  			bool want_config);
>
> +enum libinput_config_middle_emulation_state
> +evdev_middlebutton_get(struct libinput_device *device);
> +
> +int
> +evdev_middlebutton_is_available(struct libinput_device *device);
> +
> +enum libinput_config_middle_emulation_state
> +evdev_middlebutton_get_default(struct libinput_device *device);
> +
>  static inline double
>  evdev_convert_to_mm(const struct input_absinfo *absinfo, double v)
>  {
> diff --git a/src/libinput.h b/src/libinput.h
> index ed3eb7d..abc737e 100644
> --- a/src/libinput.h
> +++ b/src/libinput.h
> @@ -4307,6 +4307,10 @@ libinput_device_config_middle_emulation_is_available(
>   *
>   * The middle button emulation behavior when combined with other device
>   * buttons, including a physical middle button is device-dependent.
> + * For example, @ref clickpad_softbuttons provides a middle button area when
> + * middle button emulation is disabled. That middle button area disappears
> + * when middle button emulation is enabled - a middle click can then only be
> + * triggered by a simultaneous left + right click.
>   *
>   * @note Some devices provide middle mouse button emulation but do not allow
>   * enabling/disabling that emulation.
> diff --git a/test/litest.h b/test/litest.h
> index c830928..dd299bb 100644
> --- a/test/litest.h
> +++ b/test/litest.h
> @@ -799,6 +799,32 @@ litest_disable_drag_lock(struct libinput_device *device)
>  	litest_assert_int_eq(status, expected);
>  }
>
> +static inline void
> +litest_enable_middleemu(struct litest_device *dev)
> +{
> +	struct libinput_device *device = dev->libinput_device;
> +	enum libinput_config_status status, expected;
> +
> +	expected = LIBINPUT_CONFIG_STATUS_SUCCESS;
> +	status = libinput_device_config_middle_emulation_set_enabled(device,
> +								     LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
> +
> +	litest_assert_int_eq(status, expected);
> +}
> +
> +static inline void
> +litest_disable_middleemu(struct litest_device *dev)
> +{
> +	struct libinput_device *device = dev->libinput_device;
> +	enum libinput_config_status status, expected;
> +
> +	expected = LIBINPUT_CONFIG_STATUS_SUCCESS;
> +	status = libinput_device_config_middle_emulation_set_enabled(device,
> +								     LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
> +
> +	litest_assert_int_eq(status, expected);
> +}
> +
>  #define CK_DOUBLE_EQ_EPSILON 1E-3
>  #define ck_assert_double_eq(X,Y)  \
>  	do { \
> diff --git a/test/pointer.c b/test/pointer.c
> index ea1157e..f8651a7 100644
> --- a/test/pointer.c
> +++ b/test/pointer.c
> @@ -1603,7 +1603,7 @@ START_TEST(middlebutton_default_clickpad)
>  	int available;
>
>  	available = libinput_device_config_middle_emulation_is_available(device);
> -	ck_assert(!available);
> +	ck_assert(available);
>
>  	state = libinput_device_config_middle_emulation_get_enabled(device);
>  	ck_assert_int_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
> @@ -1613,7 +1613,7 @@ START_TEST(middlebutton_default_clickpad)
>
>  	status = libinput_device_config_middle_emulation_set_enabled(device,
>  					    LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
> -	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
> +	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
>
>  	status = libinput_device_config_middle_emulation_set_enabled(device,
>  					    LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
> @@ -1763,12 +1763,12 @@ litest_setup_tests(void)
>  	litest_add("pointer:accel", pointer_accel_profile_invalid, LITEST_RELATIVE, LITEST_ANY);
>  	litest_add("pointer:accel", pointer_accel_profile_flat_motion_relative, LITEST_RELATIVE, LITEST_TOUCHPAD);
>
> -	litest_add("pointer:middlebutton", middlebutton, LITEST_BUTTON, LITEST_ANY);
> -	litest_add("pointer:middlebutton", middlebutton_nostart_while_down, LITEST_BUTTON, LITEST_ANY);
> -	litest_add("pointer:middlebutton", middlebutton_timeout, LITEST_BUTTON, LITEST_ANY);
> -	litest_add("pointer:middlebutton", middlebutton_doubleclick, LITEST_BUTTON, LITEST_ANY);
> -	litest_add("pointer:middlebutton", middlebutton_middleclick, LITEST_BUTTON, LITEST_ANY);
> -	litest_add("pointer:middlebutton", middlebutton_middleclick_during, LITEST_BUTTON, LITEST_ANY);
> +	litest_add("pointer:middlebutton", middlebutton, LITEST_BUTTON, LITEST_CLICKPAD);
> +	litest_add("pointer:middlebutton", middlebutton_nostart_while_down, LITEST_BUTTON, LITEST_CLICKPAD);
> +	litest_add("pointer:middlebutton", middlebutton_timeout, LITEST_BUTTON, LITEST_CLICKPAD);
> +	litest_add("pointer:middlebutton", middlebutton_doubleclick, LITEST_BUTTON, LITEST_CLICKPAD);
> +	litest_add("pointer:middlebutton", middlebutton_middleclick, LITEST_BUTTON, LITEST_CLICKPAD);
> +	litest_add("pointer:middlebutton", middlebutton_middleclick_during, LITEST_BUTTON, LITEST_CLICKPAD);
>  	litest_add("pointer:middlebutton", middlebutton_default_enabled, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_POINTINGSTICK);
>  	litest_add("pointer:middlebutton", middlebutton_default_clickpad, LITEST_CLICKPAD, LITEST_ANY);
>  	litest_add("pointer:middlebutton", middlebutton_default_touchpad, LITEST_TOUCHPAD, LITEST_CLICKPAD);
> diff --git a/test/touchpad-buttons.c b/test/touchpad-buttons.c
> index 080c670..d72278b 100644
> --- a/test/touchpad-buttons.c
> +++ b/test/touchpad-buttons.c
> @@ -1578,6 +1578,232 @@ START_TEST(clickpad_topsoftbuttons_clickfinger_dev_disabled)
>  }
>  END_TEST
>
> +START_TEST(clickpad_middleemulation_config_delayed)
> +{
> +	struct litest_device *dev = litest_current_device();
> +	struct libinput_device *device = dev->libinput_device;
> +	struct libinput *li = dev->libinput;
> +	enum libinput_config_status status;
> +	int enabled;
> +
> +	enabled = libinput_device_config_middle_emulation_get_enabled(device);
> +	ck_assert(!enabled);
> +
> +	litest_touch_down(dev, 0, 30, 95);
> +	litest_event(dev, EV_KEY, BTN_LEFT, 1);
> +	litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +	libinput_dispatch(li);
> +
> +	/* actual config is delayed, but status is immediate */
> +	status = libinput_device_config_middle_emulation_set_enabled(device,
> +				LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
> +	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
> +
> +	enabled = libinput_device_config_middle_emulation_get_enabled(device);
> +	ck_assert(enabled);
> +
> +	status = libinput_device_config_middle_emulation_set_enabled(device,
> +				LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
> +	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
> +	enabled = libinput_device_config_middle_emulation_get_enabled(device);
> +	ck_assert(!enabled);
> +}
> +END_TEST
> +
> +START_TEST(clickpad_middleemulation_click)
> +{
> +	struct litest_device *dev = litest_current_device();
> +	struct libinput *li = dev->libinput;
> +
> +	litest_enable_buttonareas(dev);
> +	litest_enable_middleemu(dev);
> +	litest_drain_events(li);
> +
> +	litest_touch_down(dev, 0, 30, 95);
> +	litest_touch_down(dev, 1, 80, 95);
> +	litest_event(dev, EV_KEY, BTN_LEFT, 1);
> +	litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +
> +	litest_assert_button_event(li,
> +				   BTN_MIDDLE,
> +				   LIBINPUT_BUTTON_STATE_PRESSED);
> +
> +	litest_event(dev, EV_KEY, BTN_LEFT, 0);
> +	litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +	litest_touch_up(dev, 0);
> +	litest_touch_up(dev, 1);
> +
> +	litest_assert_button_event(li,
> +				   BTN_MIDDLE,
> +				   LIBINPUT_BUTTON_STATE_RELEASED);
> +
> +	libinput_dispatch(li);
> +
> +	litest_assert_empty_queue(li);
> +}
> +END_TEST
> +
> +START_TEST(clickpad_middleemulation_click_middle_left)
> +{
> +	struct litest_device *dev = litest_current_device();
> +	struct libinput *li = dev->libinput;
> +
> +	litest_enable_buttonareas(dev);
> +	litest_enable_middleemu(dev);
> +	litest_drain_events(li);
> +
> +	litest_touch_down(dev, 0, 49, 95);
> +	litest_event(dev, EV_KEY, BTN_LEFT, 1);
> +	litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +
> +	litest_assert_button_event(li,
> +				   BTN_LEFT,
> +				   LIBINPUT_BUTTON_STATE_PRESSED);
> +
> +	litest_event(dev, EV_KEY, BTN_LEFT, 0);
> +	litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +	litest_touch_up(dev, 0);
> +
> +	litest_assert_button_event(li,
> +				   BTN_LEFT,
> +				   LIBINPUT_BUTTON_STATE_RELEASED);
> +
> +	libinput_dispatch(li);
> +
> +	litest_assert_empty_queue(li);
> +}
> +END_TEST
> +
> +START_TEST(clickpad_middleemulation_click_middle_right)
> +{
> +	struct litest_device *dev = litest_current_device();
> +	struct libinput *li = dev->libinput;
> +
> +	litest_enable_buttonareas(dev);
> +	litest_enable_middleemu(dev);
> +	litest_drain_events(li);
> +
> +	litest_touch_down(dev, 0, 51, 95);
> +	litest_event(dev, EV_KEY, BTN_LEFT, 1);
> +	litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +
> +	litest_assert_button_event(li,
> +				   BTN_RIGHT,
> +				   LIBINPUT_BUTTON_STATE_PRESSED);
> +
> +	litest_event(dev, EV_KEY, BTN_LEFT, 0);
> +	litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +	litest_touch_up(dev, 0);
> +
> +	litest_assert_button_event(li,
> +				   BTN_RIGHT,
> +				   LIBINPUT_BUTTON_STATE_RELEASED);
> +
> +	libinput_dispatch(li);
> +
> +	litest_assert_empty_queue(li);
> +}
> +END_TEST
> +
> +START_TEST(clickpad_middleemulation_click_enable_while_down)
> +{
> +	struct litest_device *dev = litest_current_device();
> +	struct libinput *li = dev->libinput;
> +
> +	litest_enable_buttonareas(dev);
> +	litest_drain_events(li);
> +
> +	litest_touch_down(dev, 0, 49, 95);
> +	litest_event(dev, EV_KEY, BTN_LEFT, 1);
> +	litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +
> +	litest_assert_button_event(li,
> +				   BTN_MIDDLE,
> +				   LIBINPUT_BUTTON_STATE_PRESSED);
> +
> +	litest_enable_middleemu(dev);
> +
> +	litest_event(dev, EV_KEY, BTN_LEFT, 0);
> +	litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +	litest_touch_up(dev, 0);
> +
> +	litest_assert_button_event(li,
> +				   BTN_MIDDLE,
> +				   LIBINPUT_BUTTON_STATE_RELEASED);
> +
> +	libinput_dispatch(li);
> +
> +	litest_assert_empty_queue(li);
> +
> +	litest_touch_down(dev, 0, 49, 95);
> +	litest_event(dev, EV_KEY, BTN_LEFT, 1);
> +	litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +	litest_event(dev, EV_KEY, BTN_LEFT, 0);
> +	litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +	litest_touch_up(dev, 0);
> +
> +	litest_assert_button_event(li,
> +				   BTN_LEFT,
> +				   LIBINPUT_BUTTON_STATE_PRESSED);
> +	litest_assert_button_event(li,
> +				   BTN_LEFT,
> +				   LIBINPUT_BUTTON_STATE_RELEASED);
> +
> +	libinput_dispatch(li);
> +}
> +END_TEST
> +
> +START_TEST(clickpad_middleemulation_click_disable_while_down)
> +{
> +	struct litest_device *dev = litest_current_device();
> +	struct libinput *li = dev->libinput;
> +
> +	litest_enable_buttonareas(dev);
> +	litest_enable_middleemu(dev);
> +
> +	litest_drain_events(li);
> +
> +	litest_touch_down(dev, 0, 30, 95);
> +	litest_touch_down(dev, 1, 70, 95);
> +	litest_event(dev, EV_KEY, BTN_LEFT, 1);
> +	litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +
> +	litest_assert_button_event(li,
> +				   BTN_MIDDLE,
> +				   LIBINPUT_BUTTON_STATE_PRESSED);
> +
> +	litest_disable_middleemu(dev);
> +
> +	litest_event(dev, EV_KEY, BTN_LEFT, 0);
> +	litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +	litest_touch_up(dev, 0);
> +	litest_touch_up(dev, 1);
> +
> +	litest_assert_button_event(li,
> +				   BTN_MIDDLE,
> +				   LIBINPUT_BUTTON_STATE_RELEASED);
> +	libinput_dispatch(li);
> +
> +	litest_assert_empty_queue(li);
> +
> +	litest_touch_down(dev, 0, 49, 95);
> +	litest_event(dev, EV_KEY, BTN_LEFT, 1);
> +	litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +	litest_event(dev, EV_KEY, BTN_LEFT, 0);
> +	litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +	litest_touch_up(dev, 0);
> +
> +	litest_assert_button_event(li,
> +				   BTN_MIDDLE,
> +				   LIBINPUT_BUTTON_STATE_PRESSED);
> +	litest_assert_button_event(li,
> +				   BTN_MIDDLE,
> +				   LIBINPUT_BUTTON_STATE_RELEASED);
> +
> +	libinput_dispatch(li);
> +}
> +END_TEST
> +
>  void
>  litest_setup_tests(void)
>  {
> @@ -1629,4 +1855,11 @@ litest_setup_tests(void)
>  	litest_add("touchpad:topsoftbuttons", clickpad_topsoftbuttons_move_out_ignore, LITEST_TOPBUTTONPAD, LITEST_ANY);
>  	litest_add("touchpad:topsoftbuttons", clickpad_topsoftbuttons_clickfinger, LITEST_TOPBUTTONPAD, LITEST_ANY);
>  	litest_add("touchpad:topsoftbuttons", clickpad_topsoftbuttons_clickfinger_dev_disabled, LITEST_TOPBUTTONPAD, LITEST_ANY);
> +
> +	litest_add("touchpad:middleemulation", clickpad_middleemulation_config_delayed, LITEST_CLICKPAD, LITEST_ANY);
> +	litest_add("touchpad:middleemulation", clickpad_middleemulation_click, LITEST_CLICKPAD, LITEST_ANY);
> +	litest_add("touchpad:middleemulation", clickpad_middleemulation_click_middle_left, LITEST_CLICKPAD, LITEST_ANY);
> +	litest_add("touchpad:middleemulation", clickpad_middleemulation_click_middle_right, LITEST_CLICKPAD, LITEST_ANY);
> +	litest_add("touchpad:middleemulation", clickpad_middleemulation_click_enable_while_down, LITEST_CLICKPAD, LITEST_ANY);
> +	litest_add("touchpad:middleemulation", clickpad_middleemulation_click_disable_while_down, LITEST_CLICKPAD, LITEST_ANY);
>  }
>


More information about the wayland-devel mailing list