summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTarcísio Eduardo Moreira Crocomo <tarcisioe@pm.me>2024-04-09 18:46:42 -0300
committerTarcísio Eduardo Moreira Crocomo <tarcisioe@pm.me>2024-04-09 19:08:17 -0300
commit46d1fff0b0cbefc52fd388ec2f8439655d1b4a5e (patch)
treedfbcdf59c2f0e7c250f99fdbdf4152e3411ab1e9
parent1d5d45a251dd6f384067248db4ea69680995028e (diff)
touchpad: add clickfinger button map
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/988>
-rw-r--r--completion/zsh/_libinput4
-rw-r--r--doc/user/clickpad-softbuttons.rst11
-rw-r--r--doc/user/tapping.rst13
-rw-r--r--src/evdev-mt-touchpad-buttons.c68
-rw-r--r--src/evdev-mt-touchpad.c1
-rw-r--r--src/evdev-mt-touchpad.h6
-rw-r--r--src/libinput-private.h4
-rw-r--r--src/libinput.c40
-rw-r--r--src/libinput.h73
-rw-r--r--src/libinput.sym3
-rw-r--r--test/litest.h12
-rw-r--r--test/test-touchpad-buttons.c161
-rw-r--r--tools/libinput-debug-events.man3
-rw-r--r--tools/shared.c16
-rw-r--r--tools/shared.h3
-rwxr-xr-xtools/test_tool_option_parsing.py1
16 files changed, 385 insertions, 34 deletions
diff --git a/completion/zsh/_libinput b/completion/zsh/_libinput
index 36689d08..58428b36 100644
--- a/completion/zsh/_libinput
+++ b/completion/zsh/_libinput
@@ -50,6 +50,10 @@ __all_seats()
'--apply-to=[Apply configuration options where the device name matches the pattern]:pattern' \
'--disable-sendevents=[Disable send-events option for the devices matching the pattern]:pattern' \
'--set-click-method=[Set the desired click method]:click-method:(none clickfinger buttonareas)' \
+ '--set-clickfinger-map=[Set button mapping for clickfinger]:tap-map:(( \
+ lrm\:2-fingers\ right-click\ /\ 3-fingers\ middle-click \
+ lmr\:2-fingers\ middle-click\ /\ 3-fingers\ right-click \
+ ))' \
'--set-scroll-method=[Set the desired scroll method]:scroll-method:(none twofinger edge button)' \
'--set-scroll-button=[Set the button to the given button code]' \
'--set-profile=[Set pointer acceleration profile]:accel-profile:(adaptive flat)' \
diff --git a/doc/user/clickpad-softbuttons.rst b/doc/user/clickpad-softbuttons.rst
index 781aad94..06b653f6 100644
--- a/doc/user/clickpad-softbuttons.rst
+++ b/doc/user/clickpad-softbuttons.rst
@@ -102,11 +102,12 @@ ignores such button clicks, this behavior is intentional.
Clickfinger behavior
------------------------------------------------------------------------------
-This is the default behavior on Apple touchpads.
-Here, a left, right, middle button event is generated when one, two, or
-three fingers are held down on the touchpad when a physical click is
-generated. The location of the fingers does not matter and there are no
-software-defined button areas.
+This is the default behavior on Apple touchpads. Here, a left, right, middle
+button event is generated when one, two, or three fingers are held down on the
+touchpad when a physical click is generated, given the default mapping. The
+location of the fingers does not matter and there are no software-defined
+button areas. It is possible to swap right and middle buttons, the same way as
+with :ref:`tapping <tapping>`.
.. figure:: clickfinger.svg
:align: center
diff --git a/doc/user/tapping.rst b/doc/user/tapping.rst
index 95b2d49d..85b55f1f 100644
--- a/doc/user/tapping.rst
+++ b/doc/user/tapping.rst
@@ -8,12 +8,13 @@ Tap-to-click behaviour
finger touch down/up sequence maps into a button click. This is most
commonly used on touchpads, but may be available on other devices.
-libinput implements tapping for one, two, and three fingers, where supported
-by the hardware, and maps those taps into a left, right, and middle button
-click, respectively. Not all devices support three fingers, libinput will
-support tapping up to whatever is supported by the hardware. libinput does
-not support four-finger taps or any tapping with more than four fingers,
-even though some hardware can distinguish between that many fingers.
+libinput implements tapping for one, two, and three fingers, where supported by
+the hardware, and maps those taps into a left, right, and middle button click,
+respectively. This mapping can be switched to left, middle and right through
+configuration. Not all devices support three fingers, libinput will support
+tapping up to whatever is supported by the hardware. libinput does not support
+four-finger taps or any tapping with more than four fingers, even though some
+hardware can distinguish between that many fingers.
.. _tapping_default:
diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c
index 08f0a907..0f0a640e 100644
--- a/src/evdev-mt-touchpad-buttons.c
+++ b/src/evdev-mt-touchpad-buttons.c
@@ -958,6 +958,51 @@ tp_guess_clickpad(const struct tp_dispatch *tp, struct evdev_device *device)
return is_clickpad;
}
+static inline void
+tp_button_update_clickfinger_map(struct tp_dispatch *tp)
+{
+ if (tp->buttons.state != BUTTON_STATE_NONE)
+ return;
+
+ if (tp->buttons.map != tp->buttons.want_map)
+ tp->buttons.map = tp->buttons.want_map;
+}
+
+void
+tp_button_post_process_state(struct tp_dispatch *tp)
+{
+ tp_button_update_clickfinger_map(tp);
+}
+
+static enum libinput_config_status
+tp_button_config_set_clickfinger_map(struct libinput_device *device,
+ enum libinput_config_clickfinger_button_map map)
+{
+ struct evdev_dispatch *dispatch = evdev_device(device)->dispatch;
+ struct tp_dispatch *tp = tp_dispatch(dispatch);
+
+ tp->buttons.want_map = map;
+
+ tp_button_update_clickfinger_map(tp);
+
+ return LIBINPUT_CONFIG_STATUS_SUCCESS;
+}
+
+static enum libinput_config_clickfinger_button_map
+tp_button_config_get_clickfinger_map(struct libinput_device *device)
+{
+ struct evdev_dispatch *dispatch = evdev_device(device)->dispatch;
+ struct tp_dispatch *tp = tp_dispatch(dispatch);
+
+ return tp->buttons.want_map;
+}
+
+static enum libinput_config_clickfinger_button_map
+tp_button_config_get_default_clickfinger_map(struct libinput_device *device)
+{
+ return LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM;
+}
+
void
tp_init_buttons(struct tp_dispatch *tp,
struct evdev_device *device)
@@ -982,8 +1027,15 @@ tp_init_buttons(struct tp_dispatch *tp,
tp->buttons.config_method.set_method = tp_button_config_click_set_method;
tp->buttons.config_method.get_method = tp_button_config_click_get_method;
tp->buttons.config_method.get_default_method = tp_button_config_click_get_default_method;
+ tp->buttons.config_method.set_clickfinger_map = tp_button_config_set_clickfinger_map;
+ tp->buttons.config_method.get_clickfinger_map = tp_button_config_get_clickfinger_map;
+ tp->buttons.config_method.get_default_clickfinger_map = tp_button_config_get_default_clickfinger_map;
+
tp->device->base.config.click_method = &tp->buttons.config_method;
+ tp->buttons.map = LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM;
+ tp->buttons.want_map = tp->buttons.map;
+
tp->buttons.click_method = tp_click_get_default_method(tp);
tp_switch_click_method(tp);
@@ -1118,6 +1170,10 @@ tp_clickfinger_set_button(struct tp_dispatch *tp)
struct tp_touch *t;
struct tp_touch *first = NULL,
*second = NULL;
+ int32_t button_map[2][3] = {
+ { BTN_LEFT, BTN_RIGHT, BTN_MIDDLE },
+ { BTN_LEFT, BTN_MIDDLE, BTN_RIGHT },
+ };
tp_for_each_touch(tp, t) {
if (t->state != TOUCH_BEGIN && t->state != TOUCH_UPDATE)
@@ -1148,11 +1204,12 @@ tp_clickfinger_set_button(struct tp_dispatch *tp)
nfingers = 1;
out:
+ nfingers = max(1, nfingers);
+
switch (nfingers) {
- case 0:
- case 1: button = BTN_LEFT; break;
- case 2: button = BTN_RIGHT; break;
- case 3: button = BTN_MIDDLE; break;
+ case 1:
+ case 2:
+ case 3: button = button_map[tp->buttons.map][nfingers-1]; break;
default:
button = 0;
break;
@@ -1326,8 +1383,9 @@ int
tp_post_button_events(struct tp_dispatch *tp, uint64_t time)
{
if (tp->buttons.is_clickpad ||
- tp->device->model_flags & EVDEV_MODEL_APPLE_TOUCHPAD_ONEBUTTON)
+ tp->device->model_flags & EVDEV_MODEL_APPLE_TOUCHPAD_ONEBUTTON) {
return tp_post_clickpadbutton_buttons(tp, time);
+ }
return tp_post_physical_buttons(tp, time);
}
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index d9b7ca5f..845e408d 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -1846,6 +1846,7 @@ tp_post_process_state(struct tp_dispatch *tp, uint64_t time)
tp_thumb_reset(tp);
tp_tap_post_process_state(tp);
+ tp_button_post_process_state(tp);
}
static void
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index bd5eab5f..26588dbb 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -399,6 +399,9 @@ struct tp_dispatch {
enum libinput_config_click_method click_method;
struct libinput_device_config_click_method config_method;
+
+ enum libinput_config_clickfinger_button_map map;
+ enum libinput_config_clickfinger_button_map want_map;
} buttons;
struct {
@@ -626,6 +629,9 @@ void
tp_tap_post_process_state(struct tp_dispatch *tp);
void
+tp_button_post_process_state(struct tp_dispatch *tp);
+
+void
tp_init_tap(struct tp_dispatch *tp);
void
diff --git a/src/libinput-private.h b/src/libinput-private.h
index de1d7d64..dff0aaae 100644
--- a/src/libinput-private.h
+++ b/src/libinput-private.h
@@ -333,6 +333,10 @@ struct libinput_device_config_click_method {
enum libinput_config_click_method method);
enum libinput_config_click_method (*get_method)(struct libinput_device *device);
enum libinput_config_click_method (*get_default_method)(struct libinput_device *device);
+ enum libinput_config_status (*set_clickfinger_map)(struct libinput_device *device,
+ enum libinput_config_clickfinger_button_map map);
+ enum libinput_config_clickfinger_button_map (*get_clickfinger_map)(struct libinput_device *device);
+ enum libinput_config_clickfinger_button_map (*get_default_clickfinger_map)(struct libinput_device *device);
};
struct libinput_device_config_middle_emulation {
diff --git a/src/libinput.c b/src/libinput.c
index 5bebe56b..db16fe3f 100644
--- a/src/libinput.c
+++ b/src/libinput.c
@@ -72,6 +72,7 @@ ASSERT_INT_SIZE(enum libinput_config_drag_lock_state);
ASSERT_INT_SIZE(enum libinput_config_send_events_mode);
ASSERT_INT_SIZE(enum libinput_config_accel_profile);
ASSERT_INT_SIZE(enum libinput_config_click_method);
+ASSERT_INT_SIZE(enum libinput_config_clickfinger_button_map);
ASSERT_INT_SIZE(enum libinput_config_middle_emulation_state);
ASSERT_INT_SIZE(enum libinput_config_scroll_method);
ASSERT_INT_SIZE(enum libinput_config_dwt_state);
@@ -4509,6 +4510,45 @@ libinput_device_config_click_get_default_method(struct libinput_device *device)
return LIBINPUT_CONFIG_CLICK_METHOD_NONE;
}
+LIBINPUT_EXPORT enum libinput_config_status
+libinput_device_config_click_set_clickfinger_button_map(struct libinput_device *device,
+ enum libinput_config_clickfinger_button_map map)
+{
+ switch (map) {
+ case LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM:
+ case LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR:
+ break;
+ default:
+ return LIBINPUT_CONFIG_STATUS_INVALID;
+ }
+
+ if ((libinput_device_config_click_get_methods(device) &
+ LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) != LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER)
+ return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
+
+ return device->config.click_method->set_clickfinger_map(device, map);
+}
+
+LIBINPUT_EXPORT enum libinput_config_clickfinger_button_map
+libinput_device_config_click_get_clickfinger_button_map(struct libinput_device *device)
+{
+ if ((libinput_device_config_click_get_methods(device) &
+ LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) != LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER)
+ return LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM;
+
+ return device->config.click_method->get_clickfinger_map(device);
+}
+
+LIBINPUT_EXPORT enum libinput_config_clickfinger_button_map
+libinput_device_config_click_get_default_clickfinger_button_map(struct libinput_device *device)
+{
+ if ((libinput_device_config_click_get_methods(device) &
+ LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) != LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER)
+ return LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM;
+
+ return device->config.click_method->get_default_clickfinger_map(device);
+}
+
LIBINPUT_EXPORT int
libinput_device_config_middle_emulation_is_available(
struct libinput_device *device)
diff --git a/src/libinput.h b/src/libinput.h
index 85403be5..954ec617 100644
--- a/src/libinput.h
+++ b/src/libinput.h
@@ -4608,6 +4608,7 @@ libinput_device_group_get_user_data(struct libinput_device_group *group);
* - libinput_device_config_tap_set_drag_enabled()
* - libinput_device_config_tap_set_drag_lock_enabled()
* - libinput_device_config_click_set_method()
+ * - libinput_device_config_click_set_clickfinger_button_map()
* - libinput_device_config_scroll_set_method()
* - libinput_device_config_dwt_set_enabled()
* - Touchscreens:
@@ -4749,6 +4750,16 @@ enum libinput_config_tap_button_map {
/**
* @ingroup config
+ */
+enum libinput_config_clickfinger_button_map {
+ /** 1/2/3 finger click maps to left/right/middle */
+ LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM,
+ /** 1/2/3 finger click maps to left/middle/right*/
+ LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR,
+};
+
+/**
+ * @ingroup config
*
* Set the finger number to button number mapping for tap-to-click. The
* default mapping on most devices is to have a 1, 2 and 3 finger tap to map
@@ -5818,6 +5829,68 @@ libinput_device_config_click_get_default_method(struct libinput_device *device);
/**
* @ingroup config
+ *
+ * Set the finger number to button number mapping for clickfinger. The
+ * default mapping on most devices is to have a 1, 2 and 3 finger tap to map
+ * to the left, right and middle button, respectively.
+ * A device may permit changing the button mapping but disallow specific
+ * maps. In this case @ref LIBINPUT_CONFIG_STATUS_UNSUPPORTED is returned,
+ * the caller is expected to handle this case correctly.
+ *
+ * Changing the button mapping may not take effect immediately,
+ * the device may wait until it is in a neutral state before applying any
+ * changes.
+ *
+ * @param device The device to configure
+ * @param map The new finger-to-button number mapping
+ *
+ * @return A config status code. Changing the order on a device that does not
+ * support the clickfinger method always fails with @ref
+ * LIBINPUT_CONFIG_STATUS_UNSUPPORTED.
+ *
+ * @see libinput_device_config_click_get_clickfinger_button_map
+ * @see libinput_device_config_click_get_default_clickfinger_button_map
+ */
+enum libinput_config_status
+libinput_device_config_click_set_clickfinger_button_map(struct libinput_device *device,
+ enum libinput_config_clickfinger_button_map map);
+
+/**
+ * @ingroup config
+ *
+ * Get the finger number to button number mapping for clickfinger.
+ *
+ * The return value for a device that does not support tapping is always
+ * @ref LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM.
+ *
+ * @param device The device to configure
+ * @return The current finger-to-button number mapping
+ *
+ * @see libinput_device_config_click_set_clickfinger_button_map
+ * @see libinput_device_config_click_get_default_clickfinger_button_map
+ */
+enum libinput_config_clickfinger_button_map
+libinput_device_config_click_get_clickfinger_button_map(struct libinput_device *device);
+
+/**
+ * @ingroup config
+ *
+ * Get the default finger number to button number mapping for clickfinger.
+ *
+ * The return value for a device that does not support clickfinger is always
+ * @ref LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM.
+ *
+ * @param device The device to configure
+ * @return The default finger-to-button number mapping
+ *
+ * @see libinput_device_config_click_set_clickfinger_button_map
+ * @see libinput_device_config_click_get_clickfinger_button_map
+ */
+enum libinput_config_clickfinger_button_map
+libinput_device_config_click_get_default_clickfinger_button_map(struct libinput_device *device);
+
+/**
+ * @ingroup config
*/
enum libinput_config_middle_emulation_state {
/**
diff --git a/src/libinput.sym b/src/libinput.sym
index 3624401c..a598f77a 100644
--- a/src/libinput.sym
+++ b/src/libinput.sym
@@ -335,6 +335,9 @@ LIBINPUT_1.23 {
} LIBINPUT_1.21;
LIBINPUT_1.26 {
+ libinput_device_config_click_set_clickfinger_button_map;
+ libinput_device_config_click_get_default_clickfinger_button_map;
+ libinput_device_config_click_get_clickfinger_button_map;
libinput_device_get_id_bustype;
libinput_device_tablet_pad_get_num_dials;
libinput_event_tablet_pad_get_dial_delta_v120;
diff --git a/test/litest.h b/test/litest.h
index 73a4ef9a..6108be50 100644
--- a/test/litest.h
+++ b/test/litest.h
@@ -1156,6 +1156,18 @@ litest_enable_clickfinger(struct litest_device *dev)
}
static inline void
+litest_set_clickfinger_map(struct litest_device *dev,
+ enum libinput_config_clickfinger_button_map map)
+{
+ enum libinput_config_status status, expected;
+ struct libinput_device *device = dev->libinput_device;
+
+ expected = LIBINPUT_CONFIG_STATUS_SUCCESS;
+ status = libinput_device_config_click_set_clickfinger_button_map(device, map);
+ litest_assert_int_eq(status, expected);
+}
+
+static inline void
litest_enable_buttonareas(struct litest_device *dev)
{
enum libinput_config_status status, expected;
diff --git a/test/test-touchpad-buttons.c b/test/test-touchpad-buttons.c
index 8af48c64..3bc9fff4 100644
--- a/test/test-touchpad-buttons.c
+++ b/test/test-touchpad-buttons.c
@@ -82,6 +82,48 @@ START_TEST(touchpad_click_defaults_clickfinger)
}
END_TEST
+START_TEST(touchpad_click_default_clickfinger_map)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput_device *device = dev->libinput_device;
+ enum libinput_config_clickfinger_button_map map;
+
+ map = libinput_device_config_click_get_clickfinger_button_map(device);
+ ck_assert_int_eq(map, LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM);
+ map = libinput_device_config_click_get_default_clickfinger_button_map(device);
+ ck_assert_int_eq(map, LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM);
+}
+END_TEST
+
+START_TEST(touchpad_click_set_clickfinger_map)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput_device *device = dev->libinput_device;
+ enum libinput_config_clickfinger_button_map map;
+ enum libinput_config_status status;
+
+ map = LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM;
+ status = libinput_device_config_click_set_clickfinger_button_map(device, map);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+ map = libinput_device_config_click_get_clickfinger_button_map(dev->libinput_device);
+ ck_assert_int_eq(map, LIBINPUT_CONFIG_TAP_MAP_LRM);
+
+ map = LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR;
+ status = libinput_device_config_click_set_clickfinger_button_map(device, map);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+ map = libinput_device_config_click_get_clickfinger_button_map(dev->libinput_device);
+ ck_assert_int_eq(map, LIBINPUT_CONFIG_TAP_MAP_LMR);
+
+ map = LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM - 1;
+ status = libinput_device_config_click_set_clickfinger_button_map(device, map);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
+
+ map = LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR + 1;
+ status = libinput_device_config_click_set_clickfinger_button_map(device, map);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
+}
+END_TEST
+
START_TEST(touchpad_click_defaults_btnarea)
{
struct litest_device *dev = litest_current_device();
@@ -217,8 +259,22 @@ START_TEST(touchpad_2fg_clickfinger)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
+ enum libinput_config_clickfinger_button_map map = _i; /* ranged test */
+ unsigned int button = 0;
litest_enable_clickfinger(dev);
+ litest_set_clickfinger_map(dev, map);
+
+ switch (map) {
+ case LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM:
+ button = BTN_RIGHT;
+ break;
+ case LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR:
+ button = BTN_MIDDLE;
+ break;
+ default:
+ litest_abort_msg("Invalid map range %d", map);
+ }
litest_drain_events(li);
@@ -233,9 +289,9 @@ START_TEST(touchpad_2fg_clickfinger)
libinput_dispatch(li);
- litest_assert_button_event(li, BTN_RIGHT,
+ litest_assert_button_event(li, button,
LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_RIGHT,
+ litest_assert_button_event(li, button,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
@@ -244,11 +300,25 @@ START_TEST(touchpad_3fg_clickfinger)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
+ enum libinput_config_clickfinger_button_map map = _i; /* ranged test */
+ unsigned int button = 0;
if (litest_slot_count(dev) < 3)
return;
litest_enable_clickfinger(dev);
+ litest_set_clickfinger_map(dev, map);
+
+ switch (map) {
+ case LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM:
+ button = BTN_MIDDLE;
+ break;
+ case LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR:
+ button = BTN_RIGHT;
+ break;
+ default:
+ litest_abort_msg("Invalid map range %d", map);
+ }
litest_drain_events(li);
@@ -266,10 +336,10 @@ START_TEST(touchpad_3fg_clickfinger)
libinput_dispatch(li);
litest_assert_button_event(li,
- BTN_MIDDLE,
+ button,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
- BTN_MIDDLE,
+ button,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
@@ -278,12 +348,26 @@ START_TEST(touchpad_3fg_clickfinger_btntool)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
+ enum libinput_config_clickfinger_button_map map = _i; /* ranged test */
+ unsigned int button = 0;
if (litest_slot_count(dev) >= 3 ||
!libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_TRIPLETAP))
return;
litest_enable_clickfinger(dev);
+ litest_set_clickfinger_map(dev, map);
+
+ switch (map) {
+ case LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM:
+ button = BTN_MIDDLE;
+ break;
+ case LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR:
+ button = BTN_RIGHT;
+ break;
+ default:
+ litest_abort_msg("Invalid map range %d", map);
+ }
litest_drain_events(li);
@@ -305,10 +389,10 @@ START_TEST(touchpad_3fg_clickfinger_btntool)
libinput_dispatch(li);
litest_assert_button_event(li,
- BTN_MIDDLE,
+ button,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
- BTN_MIDDLE,
+ button,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
@@ -418,13 +502,15 @@ START_TEST(touchpad_2fg_clickfinger_distance)
struct libinput *li = dev->libinput;
double w, h;
bool small_touchpad = false;
- unsigned int expected_button;
+ unsigned int expected_button = 0;
+ enum libinput_config_clickfinger_button_map map = _i; /* ranged test */
if (libinput_device_get_size(dev->libinput_device, &w, &h) == 0 &&
h < 50.0)
small_touchpad = true;
litest_enable_clickfinger(dev);
+ litest_set_clickfinger_map(dev, map);
litest_drain_events(li);
@@ -458,7 +544,14 @@ START_TEST(touchpad_2fg_clickfinger_distance)
/* if the touchpad is small enough, we expect all fingers to count
* for clickfinger */
if (small_touchpad)
- expected_button = BTN_RIGHT;
+ switch (map) {
+ case LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM:
+ expected_button = BTN_RIGHT;
+ break;
+ case LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR:
+ expected_button = BTN_MIDDLE;
+ break;
+ }
else
expected_button = BTN_LEFT;
@@ -475,11 +568,25 @@ START_TEST(touchpad_3fg_clickfinger_distance)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
+ enum libinput_config_clickfinger_button_map map = _i; /* ranged test */
+ unsigned int button = 0;
if (litest_slot_count(dev) < 3)
return;
litest_enable_clickfinger(dev);
+ litest_set_clickfinger_map(dev, map);
+
+ switch (map) {
+ case LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM:
+ button = BTN_MIDDLE;
+ break;
+ case LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR:
+ button = BTN_RIGHT;
+ break;
+ default:
+ litest_abort_msg("Invalid map range %d", map);
+ }
litest_drain_events(li);
@@ -496,10 +603,10 @@ START_TEST(touchpad_3fg_clickfinger_distance)
litest_touch_up(dev, 2);
litest_assert_button_event(li,
- BTN_MIDDLE,
+ button,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
- BTN_MIDDLE,
+ button,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
@@ -508,11 +615,25 @@ START_TEST(touchpad_3fg_clickfinger_distance_btntool)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
+ enum libinput_config_clickfinger_button_map map = _i; /* ranged test */
+ unsigned int button = 0;
if (litest_slot_count(dev) > 2)
return;
litest_enable_clickfinger(dev);
+ litest_set_clickfinger_map(dev, map);
+
+ switch (map) {
+ case LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM:
+ button = BTN_MIDDLE;
+ break;
+ case LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR:
+ button = BTN_RIGHT;
+ break;
+ default:
+ litest_abort_msg("Invalid map range %d", map);
+ }
litest_drain_events(li);
@@ -534,10 +655,10 @@ START_TEST(touchpad_3fg_clickfinger_distance_btntool)
litest_touch_up(dev, 1);
litest_assert_button_event(li,
- BTN_MIDDLE,
+ button,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
- BTN_MIDDLE,
+ button,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
@@ -2127,20 +2248,22 @@ END_TEST
TEST_COLLECTION(touchpad_buttons)
{
struct range finger_count = {1, 4};
+ struct range clickfinger_map_range = { LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM,
+ LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR + 1 };
litest_add(touchpad_button, LITEST_TOUCHPAD, LITEST_CLICKPAD);
litest_add(touchpad_1fg_clickfinger, LITEST_CLICKPAD, LITEST_ANY);
litest_add(touchpad_1fg_clickfinger_no_touch, LITEST_CLICKPAD, LITEST_ANY);
- litest_add(touchpad_2fg_clickfinger, LITEST_CLICKPAD, LITEST_ANY);
- litest_add(touchpad_3fg_clickfinger, LITEST_CLICKPAD, LITEST_ANY);
- litest_add(touchpad_3fg_clickfinger_btntool, LITEST_CLICKPAD, LITEST_ANY);
+ litest_add_ranged(touchpad_2fg_clickfinger, LITEST_CLICKPAD, LITEST_ANY, &clickfinger_map_range);
+ litest_add_ranged(touchpad_3fg_clickfinger, LITEST_CLICKPAD, LITEST_ANY, &clickfinger_map_range);
+ litest_add_ranged(touchpad_3fg_clickfinger_btntool, LITEST_CLICKPAD, LITEST_ANY, &clickfinger_map_range);
litest_add(touchpad_4fg_clickfinger, LITEST_CLICKPAD, LITEST_ANY);
litest_add(touchpad_4fg_clickfinger_btntool_2slots, LITEST_CLICKPAD, LITEST_ANY);
litest_add(touchpad_4fg_clickfinger_btntool_3slots, LITEST_CLICKPAD, LITEST_ANY);
- litest_add(touchpad_2fg_clickfinger_distance, LITEST_CLICKPAD, LITEST_ANY);
- litest_add(touchpad_3fg_clickfinger_distance, LITEST_CLICKPAD, LITEST_ANY);
- litest_add(touchpad_3fg_clickfinger_distance_btntool, LITEST_CLICKPAD, LITEST_ANY);
+ litest_add_ranged(touchpad_2fg_clickfinger_distance, LITEST_CLICKPAD, LITEST_ANY, &clickfinger_map_range);
+ litest_add_ranged(touchpad_3fg_clickfinger_distance, LITEST_CLICKPAD, LITEST_ANY, &clickfinger_map_range);
+ litest_add_ranged(touchpad_3fg_clickfinger_distance_btntool, LITEST_CLICKPAD, LITEST_ANY, &clickfinger_map_range);
litest_add_for_device(touchpad_2fg_clickfinger_bottom, LITEST_SYNAPTICS_TOPBUTTONPAD);
litest_add(touchpad_clickfinger_to_area_method, LITEST_CLICKPAD, LITEST_ANY);
litest_add(touchpad_clickfinger_to_area_method_while_down, LITEST_CLICKPAD, LITEST_ANY);
@@ -2161,6 +2284,8 @@ TEST_COLLECTION(touchpad_buttons)
litest_add_ranged(touchpad_clickfinger_click_drag, LITEST_CLICKPAD, LITEST_ANY, &finger_count);
litest_add(touchpad_click_defaults_clickfinger, LITEST_APPLE_CLICKPAD, LITEST_ANY);
+ litest_add(touchpad_click_default_clickfinger_map, LITEST_APPLE_CLICKPAD, LITEST_ANY);
+ litest_add(touchpad_click_set_clickfinger_map, LITEST_APPLE_CLICKPAD, LITEST_ANY);
litest_add(touchpad_click_defaults_btnarea, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
litest_add(touchpad_click_defaults_none, LITEST_TOUCHPAD, LITEST_CLICKPAD);
litest_add(touchpad_click_defaults_none, LITEST_ANY, LITEST_TOUCHPAD);
diff --git a/tools/libinput-debug-events.man b/tools/libinput-debug-events.man
index 2eeefd4b..380312dd 100644
--- a/tools/libinput-debug-events.man
+++ b/tools/libinput-debug-events.man
@@ -88,6 +88,9 @@ Enable or disable the scroll button lock
.B \-\-set\-click\-method=[none|clickfinger|buttonareas]
Set the desired click method
.TP 8
+.B \-\-set\-clickfinger\-map=[lrm|lmr]
+Set button mapping for clickfinger
+.TP 8
.B \-\-set\-scroll\-method=[none|twofinger|edge|button]
Set the desired scroll method
.TP 8
diff --git a/tools/shared.c b/tools/shared.c
index cc8396a7..d8acadcf 100644
--- a/tools/shared.c
+++ b/tools/shared.c
@@ -205,6 +205,18 @@ tools_parse_option(int option,
return 1;
}
break;
+ case OPT_CLICKFINGER_MAP:
+ if (!optarg)
+ return 1;
+
+ if (streq(optarg, "lrm")) {
+ options->clickfinger_map = LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM;
+ } else if (streq(optarg, "lmr")) {
+ options->clickfinger_map = LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR;
+ } else {
+ return 1;
+ }
+ break;
case OPT_SCROLL_METHOD:
if (!optarg)
return 1;
@@ -499,6 +511,10 @@ tools_device_apply_config(struct libinput_device *device,
if (options->click_method != (enum libinput_config_click_method)-1)
libinput_device_config_click_set_method(device, options->click_method);
+ if (options->clickfinger_map != (enum libinput_config_clickfinger_button_map)-1)
+ libinput_device_config_click_set_clickfinger_button_map(device,
+ options->clickfinger_map);
+
if (options->scroll_method != (enum libinput_config_scroll_method)-1)
libinput_device_config_scroll_set_method(device,
options->scroll_method);
diff --git a/tools/shared.h b/tools/shared.h
index 45230741..a34e67bb 100644
--- a/tools/shared.h
+++ b/tools/shared.h
@@ -51,6 +51,7 @@ enum configuration_options {
OPT_DWTP_ENABLE,
OPT_DWTP_DISABLE,
OPT_CLICK_METHOD,
+ OPT_CLICKFINGER_MAP,
OPT_SCROLL_METHOD,
OPT_SCROLL_BUTTON,
OPT_SCROLL_BUTTON_LOCK_ENABLE,
@@ -86,6 +87,7 @@ enum configuration_options {
{ "enable-scroll-button-lock", no_argument, 0, OPT_SCROLL_BUTTON_LOCK_ENABLE }, \
{ "disable-scroll-button-lock",no_argument, 0, OPT_SCROLL_BUTTON_LOCK_DISABLE }, \
{ "set-click-method", required_argument, 0, OPT_CLICK_METHOD }, \
+ { "set-clickfinger-map", required_argument, 0, OPT_CLICKFINGER_MAP }, \
{ "set-scroll-method", required_argument, 0, OPT_SCROLL_METHOD }, \
{ "set-scroll-button", required_argument, 0, OPT_SCROLL_BUTTON }, \
{ "set-profile", required_argument, 0, OPT_PROFILE }, \
@@ -113,6 +115,7 @@ struct tools_options {
int left_handed;
int middlebutton;
enum libinput_config_click_method click_method;
+ enum libinput_config_clickfinger_button_map clickfinger_map;
enum libinput_config_scroll_method scroll_method;
enum libinput_config_tap_button_map tap_map;
int scroll_button;
diff --git a/tools/test_tool_option_parsing.py b/tools/test_tool_option_parsing.py
index 303e3840..9c0f6287 100755
--- a/tools/test_tool_option_parsing.py
+++ b/tools/test_tool_option_parsing.py
@@ -218,6 +218,7 @@ options = {
"set-scroll-method": ["none", "twofinger", "edge", "button"],
"set-profile": ["adaptive", "flat"],
"set-tap-map": ["lrm", "lmr"],
+ "set-clickfinger-map": ["lrm", "lmr"],
},
# options with a range (and increment)
"ranges": {