mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-20 09:10:04 +01:00
tablet: fix double proximity out on slow proximity out pens
Where the proximity out event is delayed by the kernel, libinput would cause an extra proxmity in-out after the forced proximity out event. Event sequence is basically (k: kernel, l: libinput) k: tablet axis events l: tablet axis events k: nothing for $proximity timer milliseconds l: tablet proximity out k: proximity out event l: proximity in event l: proximity out event Fixes #306 Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
ea5b764eb4
commit
ffd8c71e4e
3 changed files with 53 additions and 13 deletions
|
|
@ -806,6 +806,7 @@ tablet_process_key(struct tablet_dispatch *tablet,
|
||||||
case BTN_TOOL_MOUSE:
|
case BTN_TOOL_MOUSE:
|
||||||
case BTN_TOOL_LENS:
|
case BTN_TOOL_LENS:
|
||||||
type = tablet_evcode_to_tool(e->code);
|
type = tablet_evcode_to_tool(e->code);
|
||||||
|
tablet_set_status(tablet, TABLET_TOOL_UPDATED);
|
||||||
if (e->value)
|
if (e->value)
|
||||||
tablet->tool_state |= bit(type);
|
tablet->tool_state |= bit(type);
|
||||||
else
|
else
|
||||||
|
|
@ -1721,13 +1722,22 @@ tablet_update_tool_state(struct tablet_dispatch *tablet,
|
||||||
* BTN_TOOL_PEN and the state for the tool was 0, this device will
|
* BTN_TOOL_PEN and the state for the tool was 0, this device will
|
||||||
* never send the event.
|
* never send the event.
|
||||||
* We don't do this for pure button events because we discard those.
|
* We don't do this for pure button events because we discard those.
|
||||||
|
*
|
||||||
|
* But: on some devices the proximity out is delayed by the kernel,
|
||||||
|
* so we get it after our forced prox-out has triggered. In that
|
||||||
|
* case we need to just ignore the change.
|
||||||
*/
|
*/
|
||||||
if (tablet_has_status(tablet, TABLET_AXES_UPDATED) &&
|
if (tablet_has_status(tablet, TABLET_AXES_UPDATED)) {
|
||||||
(tablet->quirks.proximity_out_forced ||
|
if (tablet->quirks.proximity_out_forced) {
|
||||||
(tablet->tool_state == 0 &&
|
if (!tablet_has_status(tablet, TABLET_TOOL_UPDATED) ||
|
||||||
tablet->current_tool.type == LIBINPUT_TOOL_NONE))) {
|
tablet->tool_state)
|
||||||
tablet->tool_state = bit(LIBINPUT_TABLET_TOOL_TYPE_PEN);
|
tablet->tool_state = bit(LIBINPUT_TABLET_TOOL_TYPE_PEN);
|
||||||
tablet->quirks.proximity_out_forced = false;
|
tablet->quirks.proximity_out_forced = false;
|
||||||
|
} else if (tablet->tool_state == 0 &&
|
||||||
|
tablet->current_tool.type == LIBINPUT_TOOL_NONE) {
|
||||||
|
tablet->tool_state = bit(LIBINPUT_TABLET_TOOL_TYPE_PEN);
|
||||||
|
tablet->quirks.proximity_out_forced = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tablet->tool_state == tablet->prev_tool_state)
|
if (tablet->tool_state == tablet->prev_tool_state)
|
||||||
|
|
@ -1886,6 +1896,7 @@ tablet_reset_state(struct tablet_dispatch *tablet)
|
||||||
memcpy(&tablet->prev_button_state,
|
memcpy(&tablet->prev_button_state,
|
||||||
&tablet->button_state,
|
&tablet->button_state,
|
||||||
sizeof(tablet->button_state));
|
sizeof(tablet->button_state));
|
||||||
|
tablet_unset_status(tablet, TABLET_TOOL_UPDATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
|
|
@ -38,13 +38,14 @@ enum tablet_status {
|
||||||
TABLET_AXES_UPDATED = bit(0),
|
TABLET_AXES_UPDATED = bit(0),
|
||||||
TABLET_BUTTONS_PRESSED = bit(1),
|
TABLET_BUTTONS_PRESSED = bit(1),
|
||||||
TABLET_BUTTONS_RELEASED = bit(2),
|
TABLET_BUTTONS_RELEASED = bit(2),
|
||||||
TABLET_TOOL_IN_CONTACT = bit(3),
|
TABLET_TOOL_UPDATED = bit(3),
|
||||||
TABLET_TOOL_LEAVING_PROXIMITY = bit(4),
|
TABLET_TOOL_IN_CONTACT = bit(4),
|
||||||
TABLET_TOOL_OUT_OF_PROXIMITY = bit(5),
|
TABLET_TOOL_LEAVING_PROXIMITY = bit(5),
|
||||||
TABLET_TOOL_ENTERING_PROXIMITY = bit(6),
|
TABLET_TOOL_OUT_OF_PROXIMITY = bit(6),
|
||||||
TABLET_TOOL_ENTERING_CONTACT = bit(7),
|
TABLET_TOOL_ENTERING_PROXIMITY = bit(7),
|
||||||
TABLET_TOOL_LEAVING_CONTACT = bit(8),
|
TABLET_TOOL_ENTERING_CONTACT = bit(8),
|
||||||
TABLET_TOOL_OUT_OF_RANGE = bit(9),
|
TABLET_TOOL_LEAVING_CONTACT = bit(9),
|
||||||
|
TABLET_TOOL_OUT_OF_RANGE = bit(10),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct button_state {
|
struct button_state {
|
||||||
|
|
|
||||||
|
|
@ -1506,6 +1506,32 @@ START_TEST(proximity_range_button_release)
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(proximity_out_slow_event)
|
||||||
|
{
|
||||||
|
struct litest_device *dev = litest_current_device();
|
||||||
|
struct libinput *li = dev->libinput;
|
||||||
|
struct axis_replacement axes[] = {
|
||||||
|
{ ABS_DISTANCE, 90 },
|
||||||
|
{ -1, -1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
litest_tablet_proximity_in(dev, 10, 10, axes);
|
||||||
|
litest_tablet_motion(dev, 12, 12, axes);
|
||||||
|
litest_drain_events(li);
|
||||||
|
|
||||||
|
litest_timeout_tablet_proxout();
|
||||||
|
libinput_dispatch(li);
|
||||||
|
|
||||||
|
/* The forced prox out */
|
||||||
|
litest_assert_tablet_proximity_event(li,
|
||||||
|
LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
|
||||||
|
litest_assert_empty_queue(li);
|
||||||
|
|
||||||
|
litest_tablet_proximity_out(dev);
|
||||||
|
litest_assert_empty_queue(li);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
START_TEST(proximity_out_on_delete)
|
START_TEST(proximity_out_on_delete)
|
||||||
{
|
{
|
||||||
struct libinput *li = litest_create_context();
|
struct libinput *li = litest_create_context();
|
||||||
|
|
@ -5651,6 +5677,8 @@ TEST_COLLECTION(tablet)
|
||||||
litest_add("tablet:proximity", proximity_range_button_click, LITEST_TABLET | LITEST_DISTANCE | LITEST_TOOL_MOUSE, LITEST_ANY);
|
litest_add("tablet:proximity", proximity_range_button_click, LITEST_TABLET | LITEST_DISTANCE | LITEST_TOOL_MOUSE, LITEST_ANY);
|
||||||
litest_add("tablet:proximity", proximity_range_button_press, LITEST_TABLET | LITEST_DISTANCE | LITEST_TOOL_MOUSE, LITEST_ANY);
|
litest_add("tablet:proximity", proximity_range_button_press, LITEST_TABLET | LITEST_DISTANCE | LITEST_TOOL_MOUSE, LITEST_ANY);
|
||||||
litest_add("tablet:proximity", proximity_range_button_release, LITEST_TABLET | LITEST_DISTANCE | LITEST_TOOL_MOUSE, LITEST_ANY);
|
litest_add("tablet:proximity", proximity_range_button_release, LITEST_TABLET | LITEST_DISTANCE | LITEST_TOOL_MOUSE, LITEST_ANY);
|
||||||
|
litest_add("tablet:proximity", proximity_out_slow_event, LITEST_TABLET | LITEST_DISTANCE, LITEST_ANY);
|
||||||
|
|
||||||
litest_add_no_device("tablet:proximity", proximity_out_on_delete);
|
litest_add_no_device("tablet:proximity", proximity_out_on_delete);
|
||||||
litest_add("tablet:button", button_down_up, LITEST_TABLET, LITEST_ANY);
|
litest_add("tablet:button", button_down_up, LITEST_TABLET, LITEST_ANY);
|
||||||
litest_add("tablet:button", button_seat_count, LITEST_TABLET, LITEST_ANY);
|
litest_add("tablet:button", button_seat_count, LITEST_TABLET, LITEST_ANY);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue