mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-05-07 06:08:08 +02:00
tablet: always enable the no-proximity-out quirk on HUION tablets
And instead disable it when we do get a proximity out. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
This commit is contained in:
parent
0c6b5c045b
commit
77890ecc8f
7 changed files with 112 additions and 31 deletions
|
|
@ -162,23 +162,4 @@ model quirks hwdb for instructions.
|
||||||
This property must not be used for any other purpose, no specific behavior
|
This property must not be used for any other purpose, no specific behavior
|
||||||
is guaranteed.
|
is guaranteed.
|
||||||
|
|
||||||
@subsection model_specific_configuration_huion_tablets Graphics tablets without BTN_TOOL_PEN proximity events
|
|
||||||
|
|
||||||
On graphics tablets, the <b>BTN_TOOL_PEN</b> bit signals that the pen is in
|
|
||||||
detectable range and will send events. When the pen leaves the sensor range,
|
|
||||||
the bit must be unset to signal that the tablet is out of proximity again.
|
|
||||||
Some HUION PenTablet devices are buggy and do not send this event. To a
|
|
||||||
caller, it thus looks like the pen is constantly in proximity. This causes
|
|
||||||
unexpected behavior in applications that rely on tablet device proximity.
|
|
||||||
|
|
||||||
The property <b>LIBINPUT_MODEL_TABLET_NO_PROXIMITY_OUT</b> may be set
|
|
||||||
by a user in a local hwdb file. This property designates the tablet
|
|
||||||
to be buggy and that libinput should work around this bug.
|
|
||||||
|
|
||||||
Many of the affected tablets cannot be detected automatically by libinput
|
|
||||||
because HUION tablets reuse USB IDs. Local configuration is required to set
|
|
||||||
this property. Refer to the libinput model quirks hwdb for instructions.
|
|
||||||
|
|
||||||
This property must not be used for any other purpose, no specific behavior
|
|
||||||
is guaranteed.
|
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1667,12 +1667,14 @@ tablet_proximity_out_quirk_timer_func(uint64_t now, void *data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tablet->quirks.proximity_out_in_progress = true;
|
||||||
ARRAY_FOR_EACH(events, e) {
|
ARRAY_FOR_EACH(events, e) {
|
||||||
tablet->base.interface->process(&tablet->base,
|
tablet->base.interface->process(&tablet->base,
|
||||||
tablet->device,
|
tablet->device,
|
||||||
e,
|
e,
|
||||||
now);
|
now);
|
||||||
}
|
}
|
||||||
|
tablet->quirks.proximity_out_in_progress = false;
|
||||||
|
|
||||||
tablet->quirks.proximity_out_forced = true;
|
tablet->quirks.proximity_out_forced = true;
|
||||||
}
|
}
|
||||||
|
|
@ -1721,10 +1723,19 @@ tablet_proximity_out_quirk_update(struct tablet_dispatch *tablet,
|
||||||
}
|
}
|
||||||
tablet->quirks.last_event_time = time;
|
tablet->quirks.last_event_time = time;
|
||||||
} else if (e->type == EV_KEY && e->code == BTN_TOOL_PEN) {
|
} else if (e->type == EV_KEY && e->code == BTN_TOOL_PEN) {
|
||||||
if (e->value)
|
if (e->value) {
|
||||||
tablet_proximity_out_quirk_set_timer(tablet, time);
|
tablet_proximity_out_quirk_set_timer(tablet, time);
|
||||||
else
|
} else {
|
||||||
|
/* If we get a BTN_TOOL_PEN 0 when *not* injecting
|
||||||
|
* events it means the tablet will give us the right
|
||||||
|
* events after all and we can disable our
|
||||||
|
* timer-based proximity out.
|
||||||
|
*/
|
||||||
|
if (!tablet->quirks.proximity_out_in_progress)
|
||||||
|
tablet->quirks.need_to_force_prox_out = false;
|
||||||
|
|
||||||
libinput_timer_cancel(&tablet->quirks.prox_out_timer);
|
libinput_timer_cancel(&tablet->quirks.prox_out_timer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,9 @@ struct tablet_dispatch {
|
||||||
struct libinput_timer prox_out_timer;
|
struct libinput_timer prox_out_timer;
|
||||||
bool proximity_out_forced;
|
bool proximity_out_forced;
|
||||||
uint64_t last_event_time;
|
uint64_t last_event_time;
|
||||||
|
|
||||||
|
/* true while injecting BTN_TOOL_PEN events */
|
||||||
|
bool proximity_out_in_progress;
|
||||||
} quirks;
|
} quirks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4445,9 +4445,95 @@ START_TEST(huion_static_btn_tool_pen_no_timeout_during_usage)
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(huion_static_btn_tool_pen_disable_quirk_on_prox_out)
|
||||||
|
{
|
||||||
|
struct litest_device *dev = litest_current_device();
|
||||||
|
struct libinput *li = dev->libinput;
|
||||||
|
bool with_timeout = _i; /* ranged test */
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* test is run twice, once where the real BTN_TOOL_PEN is triggered
|
||||||
|
* during proximity out, one where the real BTN_TOOL_PEN is
|
||||||
|
* triggered after we already triggered the quirk timeout
|
||||||
|
*/
|
||||||
|
|
||||||
|
litest_drain_events(li);
|
||||||
|
|
||||||
|
litest_event(dev, EV_ABS, ABS_X, 20000);
|
||||||
|
litest_event(dev, EV_ABS, ABS_Y, 20000);
|
||||||
|
litest_event(dev, EV_ABS, ABS_PRESSURE, 100);
|
||||||
|
litest_event(dev, EV_KEY, BTN_TOOL_PEN, 1);
|
||||||
|
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||||
|
litest_drain_events(li);
|
||||||
|
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
litest_event(dev, EV_ABS, ABS_X, 20000 + 10 * i);
|
||||||
|
litest_event(dev, EV_ABS, ABS_Y, 20000 - 10 * i);
|
||||||
|
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||||
|
libinput_dispatch(li);
|
||||||
|
}
|
||||||
|
litest_assert_only_typed_events(li,
|
||||||
|
LIBINPUT_EVENT_TABLET_TOOL_AXIS);
|
||||||
|
|
||||||
|
/* Wait past the timeout to expect a proximity out */
|
||||||
|
if (with_timeout) {
|
||||||
|
litest_timeout_tablet_proxout();
|
||||||
|
libinput_dispatch(li);
|
||||||
|
litest_assert_tablet_proximity_event(li,
|
||||||
|
LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send a real prox out, expect quirk to be disabled */
|
||||||
|
litest_event(dev, EV_KEY, BTN_TOOL_PEN, 0);
|
||||||
|
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||||
|
libinput_dispatch(li);
|
||||||
|
|
||||||
|
if (with_timeout) {
|
||||||
|
/* we got the proximity event above already */
|
||||||
|
litest_assert_empty_queue(li);
|
||||||
|
} else {
|
||||||
|
litest_assert_tablet_proximity_event(li,
|
||||||
|
LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
litest_push_event_frame(dev);
|
||||||
|
litest_tablet_proximity_out(dev);
|
||||||
|
litest_event(dev, EV_KEY, BTN_TOOL_PEN, 0);
|
||||||
|
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||||
|
litest_pop_event_frame(dev);
|
||||||
|
|
||||||
|
litest_tablet_proximity_in(dev, 50, 50, NULL);
|
||||||
|
libinput_dispatch(li);
|
||||||
|
litest_assert_tablet_proximity_event(li,
|
||||||
|
LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
|
||||||
|
libinput_dispatch(li);
|
||||||
|
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
litest_tablet_motion(dev, 50 + i, 50 + i, NULL);
|
||||||
|
libinput_dispatch(li);
|
||||||
|
}
|
||||||
|
|
||||||
|
litest_assert_only_typed_events(li,
|
||||||
|
LIBINPUT_EVENT_TABLET_TOOL_AXIS);
|
||||||
|
|
||||||
|
litest_push_event_frame(dev);
|
||||||
|
litest_tablet_proximity_out(dev);
|
||||||
|
litest_event(dev, EV_KEY, BTN_TOOL_PEN, 0);
|
||||||
|
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
||||||
|
litest_pop_event_frame(dev);
|
||||||
|
libinput_dispatch(li);
|
||||||
|
|
||||||
|
litest_assert_tablet_proximity_event(li,
|
||||||
|
LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
|
||||||
|
litest_assert_empty_queue(li);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
void
|
void
|
||||||
litest_setup_tests_tablet(void)
|
litest_setup_tests_tablet(void)
|
||||||
{
|
{
|
||||||
|
struct range with_timeout = { 0, 2 };
|
||||||
|
|
||||||
litest_add("tablet:tool", tool_ref, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);
|
litest_add("tablet:tool", tool_ref, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);
|
||||||
litest_add("tablet:tool", tool_user_data, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);
|
litest_add("tablet:tool", tool_user_data, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);
|
||||||
litest_add("tablet:tool", tool_capability, LITEST_TABLET, LITEST_ANY);
|
litest_add("tablet:tool", tool_capability, LITEST_TABLET, LITEST_ANY);
|
||||||
|
|
@ -4543,4 +4629,5 @@ litest_setup_tests_tablet(void)
|
||||||
|
|
||||||
litest_add_for_device("tablet:quirks", huion_static_btn_tool_pen, LITEST_HUION_TABLET);
|
litest_add_for_device("tablet:quirks", huion_static_btn_tool_pen, LITEST_HUION_TABLET);
|
||||||
litest_add_for_device("tablet:quirks", huion_static_btn_tool_pen_no_timeout_during_usage, LITEST_HUION_TABLET);
|
litest_add_for_device("tablet:quirks", huion_static_btn_tool_pen_no_timeout_during_usage, LITEST_HUION_TABLET);
|
||||||
|
litest_add_ranged_for_device("tablet:quirks", huion_static_btn_tool_pen_disable_quirk_on_prox_out, LITEST_HUION_TABLET, &with_timeout);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -171,15 +171,10 @@ libinput:name:AlpsPS/2 ALPS GlidePoint:dmi:*svnHP:pnHPZBookStudioG3:*
|
||||||
# matching BTN_TOOL_PEN value 0 event. The device appears as if it was
|
# matching BTN_TOOL_PEN value 0 event. The device appears as if it was
|
||||||
# permanently in proximity.
|
# permanently in proximity.
|
||||||
#
|
#
|
||||||
# If the tablet is affected by this bug, copy the two lines below into a new
|
# HUION re-uses USB IDs for its devices, not every HUION tablet is
|
||||||
# file
|
# affected by this bug, libinput will auto-disable this feature
|
||||||
# /etc/udev/hwdb.d/90-libinput-huion-pentablet-proximity-quirk.hwdb, then run
|
libinput:tablet:input:b0003v256Cp*
|
||||||
# sudo udevadm hwdb --update and reboot.
|
LIBINPUT_MODEL_TABLET_NO_PROXIMITY_OUT=1
|
||||||
#
|
|
||||||
# Note that HUION re-uses USB IDs for its devices, not ever HUION tablet is
|
|
||||||
# affected by this bug.
|
|
||||||
#libinput:name:PenTablet Pen:dmi:*
|
|
||||||
# LIBINPUT_MODEL_TABLET_NO_PROXIMITY_OUT=1
|
|
||||||
|
|
||||||
##########################################
|
##########################################
|
||||||
# LENOVO
|
# LENOVO
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,10 @@ KERNELS=="*input*", \
|
||||||
ENV{ID_INPUT_TOUCHPAD}=="1", \
|
ENV{ID_INPUT_TOUCHPAD}=="1", \
|
||||||
IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=libinput:touchpad:"
|
IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=libinput:touchpad:"
|
||||||
|
|
||||||
|
# libinput:tablet:<modalias>
|
||||||
|
ENV{ID_INPUT_TABLET}=="1", \
|
||||||
|
IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=libinput:tablet:"
|
||||||
|
|
||||||
# libinput:mouse:<modalias>
|
# libinput:mouse:<modalias>
|
||||||
ENV{ID_INPUT_MOUSE}=="1", \
|
ENV{ID_INPUT_MOUSE}=="1", \
|
||||||
IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=libinput:mouse:"
|
IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=libinput:mouse:"
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ REAL = Combine((INTEGER + Optional('.' + Optional(INTEGER))) ^ ('.' + INTEGER))
|
||||||
UDEV_TAG = Word(string.ascii_uppercase, alphanums + '_')
|
UDEV_TAG = Word(string.ascii_uppercase, alphanums + '_')
|
||||||
|
|
||||||
TYPES = {
|
TYPES = {
|
||||||
'libinput': ('name', 'touchpad', 'mouse', 'keyboard'),
|
'libinput': ('name', 'touchpad', 'mouse', 'keyboard', 'tablet'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue