mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-25 18:40:05 +01:00
quirks: add trackpoint integration attribute
Some versions [1] of the Lenovo ThinkPad Compact USB Keyboard with TrackPoint USB
have the pointing stick on an event node that has keys but is not a regular
keyboard. Thus the stick falls through the cracks and gets disabled on tablet
mode switch. Instead of adding more hacks let's do this properly: tag the
pointing stick as external and have the code in place to deal with that.
[1] This may be caused by recent kernel changes
Fixes #291
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 8dfe8c68eb)
This commit is contained in:
parent
9694d91f7c
commit
6e60f8fb19
7 changed files with 91 additions and 10 deletions
|
|
@ -183,3 +183,6 @@ AttrEventCodeDisable=EV_ABS;BTN_STYLUS;EV_KEY:0x123;
|
|||
Disables the evdev event type/code tuples on the device. Entries may be
|
||||
a named event type, or a named event code, or a named event type with a
|
||||
hexadecimal event code, separated by a single colon.
|
||||
AttrPointingStickIntegration=internal|external
|
||||
Indicates the integration of the pointing stick. This is a string enum.
|
||||
Only needed for external pointing sticks. These are rare.
|
||||
|
|
|
|||
|
|
@ -76,13 +76,20 @@ MatchName=*TPPS/2 Elan TrackPoint*
|
|||
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX1Carbon6th*
|
||||
AttrTrackpointMultiplier=0.4
|
||||
|
||||
[Lenovo ThinkPad Compact USB Keyboard with TrackPoint]
|
||||
[Lenovo ThinkPad Compact USB Keyboard with TrackPoint (keyboard)]
|
||||
MatchUdevType=keyboard
|
||||
MatchBus=usb
|
||||
MatchVendor=0x17EF
|
||||
MatchProduct=0x6047
|
||||
AttrKeyboardIntegration=external
|
||||
|
||||
[Lenovo ThinkPad Compact USB Keyboard with TrackPoint (trackpoint)]
|
||||
MatchUdevType=pointingstick
|
||||
MatchBus=usb
|
||||
MatchVendor=0x17EF
|
||||
MatchProduct=0x6047
|
||||
AttrPointingStickIntegration=external
|
||||
|
||||
# Lenovo Thinkpad Yoga (not the consumer versions) disables the keyboard
|
||||
# mechanically. We must not disable the keyboard because some keys are
|
||||
# still accessible on the screen and volume rocker.
|
||||
|
|
|
|||
|
|
@ -1382,8 +1382,8 @@ fallback_tablet_mode_switch_event(uint64_t time,
|
|||
}
|
||||
|
||||
static void
|
||||
fallback_keyboard_pair_tablet_mode(struct evdev_device *keyboard,
|
||||
struct evdev_device *tablet_mode_switch)
|
||||
fallback_pair_tablet_mode(struct evdev_device *keyboard,
|
||||
struct evdev_device *tablet_mode_switch)
|
||||
{
|
||||
struct fallback_dispatch *dispatch =
|
||||
fallback_dispatch(keyboard->dispatch);
|
||||
|
|
@ -1391,8 +1391,12 @@ fallback_keyboard_pair_tablet_mode(struct evdev_device *keyboard,
|
|||
if ((keyboard->tags & EVDEV_TAG_EXTERNAL_KEYBOARD))
|
||||
return;
|
||||
|
||||
if ((keyboard->tags &
|
||||
(EVDEV_TAG_TRACKPOINT|EVDEV_TAG_INTERNAL_KEYBOARD)) == 0)
|
||||
if ((keyboard->tags & EVDEV_TAG_TRACKPOINT)) {
|
||||
if (keyboard->tags & EVDEV_TAG_EXTERNAL_MOUSE)
|
||||
return;
|
||||
/* This filters out all internal keyboard-like devices (Video
|
||||
* Switch) */
|
||||
} else if ((keyboard->tags & EVDEV_TAG_INTERNAL_KEYBOARD) == 0)
|
||||
return;
|
||||
|
||||
if (evdev_device_has_model_quirk(keyboard,
|
||||
|
|
@ -1429,7 +1433,7 @@ fallback_interface_device_added(struct evdev_device *device,
|
|||
struct evdev_device *added_device)
|
||||
{
|
||||
fallback_lid_pair_keyboard(device, added_device);
|
||||
fallback_keyboard_pair_tablet_mode(device, added_device);
|
||||
fallback_pair_tablet_mode(device, added_device);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
32
src/evdev.c
32
src/evdev.c
|
|
@ -387,10 +387,34 @@ static void
|
|||
evdev_tag_trackpoint(struct evdev_device *device,
|
||||
struct udev_device *udev_device)
|
||||
{
|
||||
if (libevdev_has_property(device->evdev,
|
||||
INPUT_PROP_POINTING_STICK) ||
|
||||
parse_udev_flag(device, udev_device, "ID_INPUT_POINTINGSTICK"))
|
||||
device->tags |= EVDEV_TAG_TRACKPOINT;
|
||||
struct quirks_context *quirks;
|
||||
struct quirks *q;
|
||||
char *prop;
|
||||
|
||||
if (!libevdev_has_property(device->evdev,
|
||||
INPUT_PROP_POINTING_STICK) &&
|
||||
!parse_udev_flag(device, udev_device, "ID_INPUT_POINTINGSTICK"))
|
||||
return;
|
||||
|
||||
device->tags |= EVDEV_TAG_TRACKPOINT;
|
||||
|
||||
quirks = evdev_libinput_context(device)->quirks;
|
||||
q = quirks_fetch_for_device(quirks, device->udev_device);
|
||||
if (q && quirks_get_string(q, QUIRK_ATTR_TRACKPOINT_INTEGRATION, &prop)) {
|
||||
if (streq(prop, "internal")) {
|
||||
/* noop, this is the default anyway */
|
||||
} else if (streq(prop, "external")) {
|
||||
device->tags |= EVDEV_TAG_EXTERNAL_MOUSE;
|
||||
evdev_log_info(device,
|
||||
"is an external pointing stick\n");
|
||||
} else {
|
||||
evdev_log_info(device,
|
||||
"tagged with unknown value %s\n",
|
||||
prop);
|
||||
}
|
||||
}
|
||||
|
||||
quirks_unref(q);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
|
|||
|
|
@ -261,6 +261,7 @@ quirk_get_name(enum quirk q)
|
|||
case QUIRK_ATTR_PALM_SIZE_THRESHOLD: return "AttrPalmSizeThreshold";
|
||||
case QUIRK_ATTR_LID_SWITCH_RELIABILITY: return "AttrLidSwitchReliability";
|
||||
case QUIRK_ATTR_KEYBOARD_INTEGRATION: return "AttrKeyboardIntegration";
|
||||
case QUIRK_ATTR_TRACKPOINT_INTEGRATION: return "AttrPointingStickIntegration";
|
||||
case QUIRK_ATTR_TPKBCOMBO_LAYOUT: return "AttrTPKComboLayout";
|
||||
case QUIRK_ATTR_PRESSURE_RANGE: return "AttrPressureRange";
|
||||
case QUIRK_ATTR_PALM_PRESSURE_THRESHOLD: return "AttrPalmPressureThreshold";
|
||||
|
|
@ -661,6 +662,13 @@ parse_attr(struct quirks_context *ctx,
|
|||
p->type = PT_STRING;
|
||||
p->value.s = safe_strdup(value);
|
||||
rc = true;
|
||||
} else if (streq(key, quirk_get_name(QUIRK_ATTR_TRACKPOINT_INTEGRATION))) {
|
||||
p->id = QUIRK_ATTR_TRACKPOINT_INTEGRATION;
|
||||
if (!streq(value, "internal") && !streq(value, "external"))
|
||||
goto out;
|
||||
p->type = PT_STRING;
|
||||
p->value.s = safe_strdup(value);
|
||||
rc = true;
|
||||
} else if (streq(key, quirk_get_name(QUIRK_ATTR_TPKBCOMBO_LAYOUT))) {
|
||||
p->id = QUIRK_ATTR_TPKBCOMBO_LAYOUT;
|
||||
if (!streq(value, "below"))
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ enum quirk {
|
|||
QUIRK_ATTR_PALM_SIZE_THRESHOLD,
|
||||
QUIRK_ATTR_LID_SWITCH_RELIABILITY,
|
||||
QUIRK_ATTR_KEYBOARD_INTEGRATION,
|
||||
QUIRK_ATTR_TRACKPOINT_INTEGRATION,
|
||||
QUIRK_ATTR_TPKBCOMBO_LAYOUT,
|
||||
QUIRK_ATTR_PRESSURE_RANGE,
|
||||
QUIRK_ATTR_PALM_PRESSURE_THRESHOLD,
|
||||
|
|
|
|||
|
|
@ -1204,6 +1204,39 @@ START_TEST(quirks_parse_string_attr)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(quirks_parse_integration_attr)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
char *do_not_use; /* freed before we can use it */
|
||||
bool
|
||||
|
||||
rc = test_attr_parse(dev,
|
||||
QUIRK_ATTR_KEYBOARD_INTEGRATION,
|
||||
"internal",
|
||||
(qparsefunc)quirks_get_string,
|
||||
&do_not_use);
|
||||
ck_assert(rc);
|
||||
rc = test_attr_parse(dev,
|
||||
QUIRK_ATTR_KEYBOARD_INTEGRATION,
|
||||
"external",
|
||||
(qparsefunc)quirks_get_string,
|
||||
&do_not_use);
|
||||
ck_assert(rc);
|
||||
rc = test_attr_parse(dev,
|
||||
QUIRK_ATTR_TRACKPOINT_INTEGRATION,
|
||||
"internal",
|
||||
(qparsefunc)quirks_get_string,
|
||||
&do_not_use);
|
||||
ck_assert(rc);
|
||||
rc = test_attr_parse(dev,
|
||||
QUIRK_ATTR_TRACKPOINT_INTEGRATION,
|
||||
"external",
|
||||
(qparsefunc)quirks_get_string,
|
||||
&do_not_use);
|
||||
ck_assert(rc);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(quirks_model_one)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
|
|
@ -1432,6 +1465,7 @@ TEST_COLLECTION(quirks)
|
|||
litest_add_for_device("quirks:parsing", quirks_parse_uint_attr, LITEST_MOUSE);
|
||||
litest_add_for_device("quirks:parsing", quirks_parse_double_attr, LITEST_MOUSE);
|
||||
litest_add_for_device("quirks:parsing", quirks_parse_string_attr, LITEST_MOUSE);
|
||||
litest_add_for_device("quirks:parsing", quirks_parse_integration_attr, LITEST_MOUSE);
|
||||
|
||||
litest_add_for_device("quirks:model", quirks_model_one, LITEST_MOUSE);
|
||||
litest_add_for_device("quirks:model", quirks_model_zero, LITEST_MOUSE);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue