From 56d69320c7b6dc6ec77b2dca89ac9905fb6e11ba Mon Sep 17 00:00:00 2001 From: Kirill Primak Date: Wed, 14 Aug 2024 20:23:45 +0300 Subject: [PATCH] pointer: release pressed buttons on destroy --- backend/libinput/pointer.c | 2 +- backend/wayland/pointer.c | 2 +- backend/x11/input_device.c | 2 +- include/wlr/interfaces/wlr_pointer.h | 3 +++ include/wlr/types/wlr_pointer.h | 5 +++++ include/wlr/types/wlr_seat.h | 2 -- types/wlr_pointer.c | 26 ++++++++++++++++++++++++++ types/wlr_virtual_pointer_v1.c | 2 +- 8 files changed, 38 insertions(+), 6 deletions(-) diff --git a/backend/libinput/pointer.c b/backend/libinput/pointer.c index 703ad7b3..9b999678 100644 --- a/backend/libinput/pointer.c +++ b/backend/libinput/pointer.c @@ -69,7 +69,7 @@ void handle_pointer_button(struct libinput_event *event, wlr_event.state = WL_POINTER_BUTTON_STATE_RELEASED; break; } - wl_signal_emit_mutable(&pointer->events.button, &wlr_event); + wlr_pointer_notify_button(pointer, &wlr_event); wl_signal_emit_mutable(&pointer->events.frame, pointer); } diff --git a/backend/wayland/pointer.c b/backend/wayland/pointer.c index 87383fa8..b61e32cd 100644 --- a/backend/wayland/pointer.c +++ b/backend/wayland/pointer.c @@ -112,7 +112,7 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, .state = state, .time_msec = time, }; - wl_signal_emit_mutable(&pointer->wlr_pointer.events.button, &event); + wlr_pointer_notify_button(&pointer->wlr_pointer, &event); } static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, diff --git a/backend/x11/input_device.c b/backend/x11/input_device.c index c2ed6fd3..8246653b 100644 --- a/backend/x11/input_device.c +++ b/backend/x11/input_device.c @@ -36,7 +36,7 @@ static void send_button_event(struct wlr_x11_output *output, uint32_t key, .button = key, .state = st, }; - wl_signal_emit_mutable(&output->pointer.events.button, &ev); + wlr_pointer_notify_button(&output->pointer, &ev); wl_signal_emit_mutable(&output->pointer.events.frame, &output->pointer); } diff --git a/include/wlr/interfaces/wlr_pointer.h b/include/wlr/interfaces/wlr_pointer.h index 74e0feaf..93adb714 100644 --- a/include/wlr/interfaces/wlr_pointer.h +++ b/include/wlr/interfaces/wlr_pointer.h @@ -19,4 +19,7 @@ void wlr_pointer_init(struct wlr_pointer *pointer, const struct wlr_pointer_impl *impl, const char *name); void wlr_pointer_finish(struct wlr_pointer *pointer); +void wlr_pointer_notify_button(struct wlr_pointer *pointer, + struct wlr_pointer_button_event *event); + #endif diff --git a/include/wlr/types/wlr_pointer.h b/include/wlr/types/wlr_pointer.h index 2fa85138..756ffa1f 100644 --- a/include/wlr/types/wlr_pointer.h +++ b/include/wlr/types/wlr_pointer.h @@ -14,6 +14,8 @@ #include #include +#define WLR_POINTER_BUTTONS_CAP 16 + struct wlr_pointer_impl; struct wlr_pointer { @@ -23,6 +25,9 @@ struct wlr_pointer { char *output_name; + uint32_t buttons[WLR_POINTER_BUTTONS_CAP]; + size_t button_count; + struct { struct wl_signal motion; // struct wlr_pointer_motion_event struct wl_signal motion_absolute; // struct wlr_pointer_motion_absolute_event diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index c04cd5e0..dcb35c62 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -170,8 +170,6 @@ struct wlr_seat_pointer_grab { void *data; }; -#define WLR_POINTER_BUTTONS_CAP 16 - struct wlr_seat_pointer_button { uint32_t button; size_t n_pressed; diff --git a/types/wlr_pointer.c b/types/wlr_pointer.c index 150b9013..e4ee10c8 100644 --- a/types/wlr_pointer.c +++ b/types/wlr_pointer.c @@ -6,6 +6,8 @@ #include #include "interfaces/wlr_input_device.h" +#include "util/set.h" +#include "util/time.h" struct wlr_pointer *wlr_pointer_from_input_device( struct wlr_input_device *input_device) { @@ -36,7 +38,31 @@ void wlr_pointer_init(struct wlr_pointer *pointer, } void wlr_pointer_finish(struct wlr_pointer *pointer) { + int64_t time_msec = get_current_time_msec(); + while (pointer->button_count > 0) { + struct wlr_pointer_button_event event = { + .pointer = pointer, + .time_msec = time_msec, + .button = pointer->buttons[pointer->button_count - 1], + .state = WL_POINTER_BUTTON_STATE_RELEASED, + }; + wlr_pointer_notify_button(pointer, &event); + } + wlr_input_device_finish(&pointer->base); free(pointer->output_name); } + +void wlr_pointer_notify_button(struct wlr_pointer *pointer, + struct wlr_pointer_button_event *event) { + if (event->state == WL_POINTER_BUTTON_STATE_PRESSED) { + set_add(pointer->buttons, &pointer->button_count, + WLR_POINTER_BUTTONS_CAP, event->button); + } else { + set_remove(pointer->buttons, &pointer->button_count, + WLR_POINTER_BUTTONS_CAP, event->button); + } + + wl_signal_emit_mutable(&pointer->events.button, event); +} diff --git a/types/wlr_virtual_pointer_v1.c b/types/wlr_virtual_pointer_v1.c index 2ae39a0a..812e7d56 100644 --- a/types/wlr_virtual_pointer_v1.c +++ b/types/wlr_virtual_pointer_v1.c @@ -73,7 +73,7 @@ static void virtual_pointer_button(struct wl_client *client, .button = button, .state = state ? WL_POINTER_BUTTON_STATE_PRESSED : WL_POINTER_BUTTON_STATE_RELEASED, }; - wl_signal_emit_mutable(&pointer->pointer.events.button, &event); + wlr_pointer_notify_button(&pointer->pointer, &event); } static void virtual_pointer_axis(struct wl_client *client,