diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c index da86b057..a00aed1d 100644 --- a/src/evdev-tablet.c +++ b/src/evdev-tablet.c @@ -69,6 +69,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,28 @@ 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)) { + /* FIXME: This behavior is not ideal and this memset should be + * removed */ + 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_check_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_check_notify_axes(tablet, device, time); + tablet_unset_status(tablet, TABLET_AXES_UPDATED); + } + } + + 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 28b7a63e..ee6b3333 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 532ce298..3830bd9a 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -214,6 +214,10 @@ tablet_notify_tool_update(struct libinput_device *device, uint32_t time, 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); diff --git a/src/libinput.c b/src/libinput.c index c7505c02..4b399e11 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 2f272e7a..9cb33a7d 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -259,7 +259,17 @@ 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. When + * this happens, the value of every axis should be assumed to have a + * value of 0 and any buttons that are currently held down on the stylus + * are marked as released. Button release events for each button that + * was held down on the stylus are sent before the initial proximity out + * event. + */ + LIBINPUT_EVENT_TABLET_PROXIMITY_OUT }; struct libinput; @@ -288,8 +298,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;