[PATCH libinput] touchpad: fix left-handed top software trackpoint buttons

Peter Hutterer peter.hutterer at who-t.net
Thu Mar 31 01:52:44 UTC 2016


The previous code would swap the top software buttons depending on the
touchpad's left-handed setting, not the trackpoint setting. Changing both
devices to left-handed resulted in a double-swap, i.e. the trackpoint was
always right-handed.

https://bugs.freedesktop.org/show_bug.cgi?id=94733

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev-mt-touchpad-buttons.c |  23 ++++---
 test/trackpoint.c               | 132 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 148 insertions(+), 7 deletions(-)

diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c
index 82c99c7..076eab0 100644
--- a/src/evdev-mt-touchpad-buttons.c
+++ b/src/evdev-mt-touchpad-buttons.c
@@ -963,6 +963,7 @@ tp_post_clickpadbutton_buttons(struct tp_dispatch *tp, uint64_t time)
 	uint32_t current, old, button, is_top;
 	enum libinput_button_state state;
 	enum { AREA = 0x01, LEFT = 0x02, MIDDLE = 0x04, RIGHT = 0x08 };
+	bool want_left_handed = true;
 
 	current = tp->buttons.state;
 	old = tp->buttons.old_state;
@@ -1008,14 +1009,22 @@ tp_post_clickpadbutton_buttons(struct tp_dispatch *tp, uint64_t time)
 			return 0;
 		}
 
-		if ((area & MIDDLE) || ((area & LEFT) && (area & RIGHT)))
-			button = evdev_to_left_handed(tp->device, BTN_MIDDLE);
-		else if (area & RIGHT)
-			button = evdev_to_left_handed(tp->device, BTN_RIGHT);
-		else if (area & LEFT)
-			button = evdev_to_left_handed(tp->device, BTN_LEFT);
-		else /* main or no area (for clickfinger) is always BTN_LEFT */
+		if ((area & MIDDLE) || ((area & LEFT) && (area & RIGHT))) {
+			button = BTN_MIDDLE;
+		} else if (area & RIGHT) {
+			button = BTN_RIGHT;
+		} else if (area & LEFT) {
 			button = BTN_LEFT;
+		} else { /* main or no area (for clickfinger) is always BTN_LEFT */
+			button = BTN_LEFT;
+			want_left_handed = false;
+		}
+
+		if (is_top)
+			want_left_handed = false;
+
+		if (want_left_handed)
+			button = evdev_to_left_handed(tp->device, button);
 
 		tp->buttons.active = button;
 		tp->buttons.active_is_topbutton = is_top;
diff --git a/test/trackpoint.c b/test/trackpoint.c
index 567fba8..5a68b19 100644
--- a/test/trackpoint.c
+++ b/test/trackpoint.c
@@ -150,6 +150,135 @@ START_TEST(trackpoint_scroll_source)
 }
 END_TEST
 
+START_TEST(trackpoint_topsoftbuttons_left_handed_trackpoint)
+{
+	struct litest_device *touchpad = litest_current_device();
+	struct litest_device *trackpoint;
+	struct libinput *li = touchpad->libinput;
+	enum libinput_config_status status;
+	struct libinput_event *event;
+	struct libinput_device *device;
+
+	trackpoint = litest_add_device(li, LITEST_TRACKPOINT);
+	litest_drain_events(li);
+	/* touchpad right-handed, trackpoint left-handed */
+	status = libinput_device_config_left_handed_set(
+					trackpoint->libinput_device, 1);
+	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+
+	litest_touch_down(touchpad, 0, 5, 5);
+	libinput_dispatch(li);
+	litest_button_click(touchpad, BTN_LEFT, true);
+	libinput_dispatch(li);
+
+	event = libinput_get_event(li);
+	litest_is_button_event(event,
+			       BTN_RIGHT,
+			       LIBINPUT_BUTTON_STATE_PRESSED);
+	device = libinput_event_get_device(event);
+	ck_assert(device == trackpoint->libinput_device);
+	libinput_event_destroy(event);
+
+	litest_button_click(touchpad, BTN_LEFT, false);
+	libinput_dispatch(li);
+	event = libinput_get_event(li);
+	litest_is_button_event(event,
+			       BTN_RIGHT,
+			       LIBINPUT_BUTTON_STATE_RELEASED);
+	device = libinput_event_get_device(event);
+	ck_assert(device == trackpoint->libinput_device);
+	libinput_event_destroy(event);
+
+	litest_delete_device(trackpoint);
+}
+END_TEST
+
+START_TEST(trackpoint_topsoftbuttons_left_handed_touchpad)
+{
+	struct litest_device *touchpad = litest_current_device();
+	struct litest_device *trackpoint;
+	struct libinput *li = touchpad->libinput;
+	enum libinput_config_status status;
+	struct libinput_event *event;
+	struct libinput_device *device;
+
+	trackpoint = litest_add_device(li, LITEST_TRACKPOINT);
+	litest_drain_events(li);
+	/* touchpad left-handed, trackpoint right-handed */
+	status = libinput_device_config_left_handed_set(
+					touchpad->libinput_device, 1);
+	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+
+	litest_touch_down(touchpad, 0, 5, 5);
+	libinput_dispatch(li);
+	litest_button_click(touchpad, BTN_LEFT, true);
+	libinput_dispatch(li);
+
+	event = libinput_get_event(li);
+	litest_is_button_event(event, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
+	device = libinput_event_get_device(event);
+	ck_assert(device == trackpoint->libinput_device);
+	libinput_event_destroy(event);
+
+	litest_button_click(touchpad, BTN_LEFT, false);
+	libinput_dispatch(li);
+	event = libinput_get_event(li);
+	litest_is_button_event(event,
+			       BTN_LEFT,
+			       LIBINPUT_BUTTON_STATE_RELEASED);
+	device = libinput_event_get_device(event);
+	ck_assert(device == trackpoint->libinput_device);
+	libinput_event_destroy(event);
+
+	litest_delete_device(trackpoint);
+}
+END_TEST
+
+START_TEST(trackpoint_topsoftbuttons_left_handed_both)
+{
+	struct litest_device *touchpad = litest_current_device();
+	struct litest_device *trackpoint;
+	struct libinput *li = touchpad->libinput;
+	enum libinput_config_status status;
+	struct libinput_event *event;
+	struct libinput_device *device;
+
+	trackpoint = litest_add_device(li, LITEST_TRACKPOINT);
+	litest_drain_events(li);
+	/* touchpad left-handed, trackpoint left-handed */
+	status = libinput_device_config_left_handed_set(
+					touchpad->libinput_device, 1);
+	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+	status = libinput_device_config_left_handed_set(
+					trackpoint->libinput_device, 1);
+	ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+
+	litest_touch_down(touchpad, 0, 5, 5);
+	libinput_dispatch(li);
+	litest_button_click(touchpad, BTN_LEFT, true);
+	libinput_dispatch(li);
+
+	event = libinput_get_event(li);
+	litest_is_button_event(event,
+			       BTN_RIGHT,
+			       LIBINPUT_BUTTON_STATE_PRESSED);
+	device = libinput_event_get_device(event);
+	ck_assert(device == trackpoint->libinput_device);
+	libinput_event_destroy(event);
+
+	litest_button_click(touchpad, BTN_LEFT, false);
+	libinput_dispatch(li);
+	event = libinput_get_event(li);
+	litest_is_button_event(event,
+			       BTN_RIGHT,
+			       LIBINPUT_BUTTON_STATE_RELEASED);
+	device = libinput_event_get_device(event);
+	ck_assert(device == trackpoint->libinput_device);
+	libinput_event_destroy(event);
+
+	litest_delete_device(trackpoint);
+}
+END_TEST
 void
 litest_setup_tests(void)
 {
@@ -157,4 +286,7 @@ litest_setup_tests(void)
 	litest_add("trackpoint:middlebutton", trackpoint_middlebutton_noscroll, LITEST_POINTINGSTICK, LITEST_ANY);
 	litest_add("trackpoint:scroll", trackpoint_scroll, LITEST_POINTINGSTICK, LITEST_ANY);
 	litest_add("trackpoint:scroll", trackpoint_scroll_source, LITEST_POINTINGSTICK, LITEST_ANY);
+	litest_add("trackpoint:left-handed", trackpoint_topsoftbuttons_left_handed_trackpoint, LITEST_TOPBUTTONPAD, LITEST_ANY);
+	litest_add("trackpoint:left-handed", trackpoint_topsoftbuttons_left_handed_touchpad, LITEST_TOPBUTTONPAD, LITEST_ANY);
+	litest_add("trackpoint:left-handed", trackpoint_topsoftbuttons_left_handed_both, LITEST_TOPBUTTONPAD, LITEST_ANY);
 }
-- 
2.5.0



More information about the wayland-devel mailing list