case BTN_TOOL_MOUSE:
case BTN_TOOL_LENS:
type = tablet_evcode_to_tool(e->code);
+ tablet_set_status(tablet, TABLET_TOOL_UPDATED);
if (e->value)
tablet->tool_state |= bit(type);
else
* BTN_TOOL_PEN and the state for the tool was 0, this device will
* never send the event.
* 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) &&
- (tablet->quirks.proximity_out_forced ||
- (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_has_status(tablet, TABLET_AXES_UPDATED)) {
+ if (tablet->quirks.proximity_out_forced) {
+ if (!tablet_has_status(tablet, TABLET_TOOL_UPDATED) ||
+ tablet->tool_state)
+ tablet->tool_state = bit(LIBINPUT_TABLET_TOOL_TYPE_PEN);
+ 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)
memcpy(&tablet->prev_button_state,
&tablet->button_state,
sizeof(tablet->button_state));
+ tablet_unset_status(tablet, TABLET_TOOL_UPDATED);
}
static void
TABLET_AXES_UPDATED = bit(0),
TABLET_BUTTONS_PRESSED = bit(1),
TABLET_BUTTONS_RELEASED = bit(2),
- TABLET_TOOL_IN_CONTACT = bit(3),
- TABLET_TOOL_LEAVING_PROXIMITY = bit(4),
- TABLET_TOOL_OUT_OF_PROXIMITY = bit(5),
- TABLET_TOOL_ENTERING_PROXIMITY = bit(6),
- TABLET_TOOL_ENTERING_CONTACT = bit(7),
- TABLET_TOOL_LEAVING_CONTACT = bit(8),
- TABLET_TOOL_OUT_OF_RANGE = bit(9),
+ TABLET_TOOL_UPDATED = bit(3),
+ TABLET_TOOL_IN_CONTACT = bit(4),
+ TABLET_TOOL_LEAVING_PROXIMITY = bit(5),
+ TABLET_TOOL_OUT_OF_PROXIMITY = bit(6),
+ TABLET_TOOL_ENTERING_PROXIMITY = bit(7),
+ TABLET_TOOL_ENTERING_CONTACT = bit(8),
+ TABLET_TOOL_LEAVING_CONTACT = bit(9),
+ TABLET_TOOL_OUT_OF_RANGE = bit(10),
};
struct button_state {
}
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)
{
struct libinput *li = litest_create_context();
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_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("tablet:button", button_down_up, LITEST_TABLET, LITEST_ANY);
litest_add("tablet:button", button_seat_count, LITEST_TABLET, LITEST_ANY);