This event is just used to notify the caller when the tool's no longer in proximity. When an event like this occurs, everything from evdev up until the next EV_SYN event is discarded along with any events that occured since the last EV_SYN event. This also silences any tool update events where the tool type is changed to LIBINPUT_TOOL_NONE, so we don't end up filling the tool list with a bunch of tools that aren't actually tools.
Signed-off-by: Stephen Chandler Paul <[email protected]> --- src/evdev-tablet.c | 25 +++++++++++++++++++++---- src/evdev-tablet.h | 3 ++- src/libinput-private.h | 4 ++++ src/libinput.c | 24 ++++++++++++++++++++++++ src/libinput.h | 11 ++++++++--- 5 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c index 52b3c93..278890d 100644 --- a/src/evdev-tablet.c +++ b/src/evdev-tablet.c @@ -78,6 +78,8 @@ tablet_update_tool(struct tablet_dispatch *tablet, tablet->current_tool_type = tool; tablet_set_status(tablet, TABLET_TOOL_UPDATED); } + else if (!enabled) + tablet_set_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY); } static void @@ -189,12 +191,27 @@ tablet_flush(struct tablet_dispatch *tablet, struct evdev_device *device, uint32_t time) { - if (tablet_has_status(tablet, TABLET_TOOL_UPDATED)) - tablet_notify_tool(tablet, device, time); + if (tablet_has_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY)) { + memset(&tablet->changed_axes, 0, sizeof(tablet->changed_axes)); + memset(&tablet->axes, 0, sizeof(tablet->axes)); - if (tablet_has_status(tablet, TABLET_AXES_UPDATED)) { - tablet_notify_axes(tablet, device, time); tablet_unset_status(tablet, TABLET_AXES_UPDATED); + } else { + if (tablet_has_status(tablet, TABLET_TOOL_UPDATED)) { + tablet_notify_tool(tablet, device, time); + tablet_unset_status(tablet, TABLET_TOOL_UPDATED); + } + + if (tablet_has_status(tablet, TABLET_AXES_UPDATED)) { + tablet_notify_axes(tablet, device, time); + tablet_unset_status(tablet, TABLET_AXES_UPDATED); + } + } + + /* We want button releases to be sent before the proximity out event */ + if (tablet_has_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY)) { + tablet_notify_proximity_out(&device->base, time); + tablet_unset_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY); } } diff --git a/src/evdev-tablet.h b/src/evdev-tablet.h index dd5988c..4727ed8 100644 --- a/src/evdev-tablet.h +++ b/src/evdev-tablet.h @@ -30,7 +30,8 @@ enum tablet_status { TABLET_NONE = 0, TABLET_AXES_UPDATED = 1 << 0, - TABLET_TOOL_UPDATED = 1 << 1 + TABLET_TOOL_UPDATED = 1 << 1, + TABLET_TOOL_LEAVING_PROXIMITY = 1 << 2 }; struct tablet_dispatch { diff --git a/src/libinput-private.h b/src/libinput-private.h index c2ff194..2db92cd 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -213,6 +213,10 @@ tablet_notify_tool_update(struct libinput_device *device, struct libinput_tool *tool); void +tablet_notify_proximity_out(struct libinput_device *device, + uint32_t time); + +void touch_notify_frame(struct libinput_device *device, uint32_t time); #endif /* LIBINPUT_PRIVATE_H */ diff --git a/src/libinput.c b/src/libinput.c index d5f4ec3..b37f8f6 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -201,6 +201,7 @@ libinput_event_get_pointer_event(struct libinput_event *event) case LIBINPUT_EVENT_TOUCH_FRAME: case LIBINPUT_EVENT_TABLET_AXIS: case LIBINPUT_EVENT_TABLET_TOOL_UPDATE: + case LIBINPUT_EVENT_TABLET_PROXIMITY_OUT: break; } @@ -229,6 +230,7 @@ libinput_event_get_keyboard_event(struct libinput_event *event) case LIBINPUT_EVENT_TOUCH_FRAME: case LIBINPUT_EVENT_TABLET_AXIS: case LIBINPUT_EVENT_TABLET_TOOL_UPDATE: + case LIBINPUT_EVENT_TABLET_PROXIMITY_OUT: break; } @@ -257,6 +259,7 @@ libinput_event_get_touch_event(struct libinput_event *event) return (struct libinput_event_touch *) event; case LIBINPUT_EVENT_TABLET_AXIS: case LIBINPUT_EVENT_TABLET_TOOL_UPDATE: + case LIBINPUT_EVENT_TABLET_PROXIMITY_OUT: break; } @@ -284,6 +287,7 @@ libinput_event_get_tablet_event(struct libinput_event *event) break; case LIBINPUT_EVENT_TABLET_AXIS: case LIBINPUT_EVENT_TABLET_TOOL_UPDATE: + case LIBINPUT_EVENT_TABLET_PROXIMITY_OUT: return (struct libinput_event_tablet *) event; } @@ -311,6 +315,7 @@ libinput_event_get_device_notify_event(struct libinput_event *event) case LIBINPUT_EVENT_TOUCH_FRAME: case LIBINPUT_EVENT_TABLET_AXIS: case LIBINPUT_EVENT_TABLET_TOOL_UPDATE: + case LIBINPUT_EVENT_TABLET_PROXIMITY_OUT: break; } @@ -1199,6 +1204,25 @@ tablet_notify_tool_update(struct libinput_device *device, &tool_update_event->base); } +void +tablet_notify_proximity_out(struct libinput_device *device, + uint32_t time) +{ + struct libinput_event_tablet *proximity_out_update_event; + + proximity_out_update_event = zalloc(sizeof *proximity_out_update_event); + if (!proximity_out_update_event) + return; + + *proximity_out_update_event = (struct libinput_event_tablet) { + .time = time + }; + + post_device_event(device, + LIBINPUT_EVENT_TABLET_PROXIMITY_OUT, + &proximity_out_update_event->base); +} + static void libinput_post_event(struct libinput *libinput, struct libinput_event *event) diff --git a/src/libinput.h b/src/libinput.h index 9615f1d..73c84be 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -259,7 +259,12 @@ enum libinput_event_type { * Signals that a device with the @ref LIBINPUT_DEVICE_CAP_TABLET * capability has changed its tool. */ - LIBINPUT_EVENT_TABLET_TOOL_UPDATE + LIBINPUT_EVENT_TABLET_TOOL_UPDATE, + /** + * Signals that a device with the @ref LIBINPUT_DEVICE_CAP_TABLET + * capability has detected that there is no longer a tool in use. + */ + LIBINPUT_EVENT_TABLET_PROXIMITY_OUT }; struct libinput; @@ -288,8 +293,8 @@ struct libinput_event_touch; * @struct libinput_event_tablet * * Tablet event representing an axis update, button press, or tool update. Valid - * event types for this event are @ref LIBINPUT_EVENT_TABLET_AXIS, and - * @ref LIBINPUT_EVENT_TABLET_TOOL_UPDATE. + * event types for this event are @ref LIBINPUT_EVENT_TABLET_AXIS, @ref + * LIBINPUT_EVENT_TABLET_TOOL_UPDATE and @ref LIBINPUT_EVENT_TABLET_TOOL_UPDATE. */ struct libinput_event_tablet; -- 1.8.5.5 _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
