input: Introduce weston_pointer_button_event

Similar to 29001fbc96, "input: Introduce weston_key_event struct", this
adds a way to store all required information with a common struct event
to be able to pass it down and to allow also pass additonal information
like Perfetto's flow IDs.

Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
This commit is contained in:
Marius Vlad 2026-04-02 20:49:56 +03:00
parent e9bdb3701d
commit bb4e88ed36
14 changed files with 133 additions and 90 deletions

View file

@ -928,12 +928,12 @@ move_grab_motion(struct weston_pointer_grab *grab,
static void
move_grab_button(struct weston_pointer_grab *grab,
const struct timespec *time, uint32_t button, uint32_t state_w)
const struct weston_pointer_button_event *button_event)
{
struct shell_grab *shell_grab = container_of(grab, struct shell_grab,
grab);
struct weston_pointer *pointer = grab->pointer;
enum wl_pointer_button_state state = state_w;
enum wl_pointer_button_state state = button_event->button_state;
if (pointer->button_count == 0 &&
state == WL_POINTER_BUTTON_STATE_RELEASED) {
@ -1198,12 +1198,11 @@ resize_grab_motion(struct weston_pointer_grab *grab,
static void
resize_grab_button(struct weston_pointer_grab *grab,
const struct timespec *time,
uint32_t button, uint32_t state_w)
const struct weston_pointer_button_event *button_event)
{
struct weston_resize_grab *resize = (struct weston_resize_grab *) grab;
struct weston_pointer *pointer = grab->pointer;
enum wl_pointer_button_state state = state_w;
enum wl_pointer_button_state state = button_event->button_state;
if (pointer->button_count == 0 &&
state == WL_POINTER_BUTTON_STATE_RELEASED) {
@ -1316,19 +1315,20 @@ busy_cursor_grab_motion(struct weston_pointer_grab *grab,
static void
busy_cursor_grab_button(struct weston_pointer_grab *base,
const struct timespec *time,
uint32_t button, uint32_t state)
const struct weston_pointer_button_event *button_event)
{
struct shell_grab *grab = (struct shell_grab *) base;
struct shell_surface *shsurf = grab->shsurf;
struct weston_pointer *pointer = grab->grab.pointer;
struct weston_seat *seat = pointer->seat;
if (shsurf && button == BTN_LEFT && state) {
if (shsurf && button_event->button == BTN_LEFT &&
button_event->button_state) {
activate(shsurf->shell, shsurf->view, seat,
WESTON_ACTIVATE_FLAG_CONFIGURE);
surface_move(shsurf, pointer, false);
} else if (shsurf && button == BTN_RIGHT && state) {
} else if (shsurf && button_event->button == BTN_RIGHT &&
button_event->button_state) {
activate(shsurf->shell, shsurf->view, seat,
WESTON_ACTIVATE_FLAG_CONFIGURE);
surface_rotate(shsurf, pointer);
@ -3283,14 +3283,13 @@ rotate_grab_motion(struct weston_pointer_grab *grab,
static void
rotate_grab_button(struct weston_pointer_grab *grab,
const struct timespec *time,
uint32_t button, uint32_t state_w)
const struct weston_pointer_button_event *button_event)
{
struct rotate_grab *rotate =
container_of(grab, struct rotate_grab, base.grab);
struct weston_pointer *pointer = grab->pointer;
struct shell_surface *shsurf = rotate->base.shsurf;
enum wl_pointer_button_state state = state_w;
enum wl_pointer_button_state state = button_event->button_state;
if (pointer->button_count == 0 &&
state == WL_POINTER_BUTTON_STATE_RELEASED) {

View file

@ -619,6 +619,12 @@ struct weston_pointer_motion_event {
const struct weston_coord *rel_unaccel;
};
struct weston_pointer_button_event {
struct weston_input_event base;
uint32_t button;
enum wl_pointer_button_state button_state;
};
struct weston_pointer_axis_event {
uint32_t axis;
double value;
@ -640,8 +646,7 @@ struct weston_pointer_grab_interface {
void (*motion)(struct weston_pointer_grab *grab,
const struct weston_pointer_motion_event *event);
void (*button)(struct weston_pointer_grab *grab,
const struct timespec *time,
uint32_t button, uint32_t state);
const struct weston_pointer_button_event *button_event);
void (*axis)(struct weston_pointer_grab *grab,
const struct timespec *time,
struct weston_pointer_axis_event *event);
@ -975,9 +980,7 @@ bool
weston_pointer_has_focus_resource(struct weston_pointer *pointer);
void
weston_pointer_send_button(struct weston_pointer *pointer,
const struct timespec *time,
uint32_t button,
enum wl_pointer_button_state state);
const struct weston_pointer_button_event *button_event);
void
weston_pointer_send_axis(struct weston_pointer *pointer,
const struct timespec *time,
@ -1037,6 +1040,10 @@ weston_pointer_motion_event_init(struct weston_pointer_motion_event *event,
const struct weston_coord *rel,
const struct weston_coord *rel_unaccel);
void
weston_pointer_button_event_init(struct weston_pointer_button_event *event,
uint32_t button, enum wl_pointer_button_state button_state);
void
weston_keyboard_send_modifiers(struct weston_keyboard *keyboard,
uint32_t serial, uint32_t mods_depressed,

View file

@ -1755,11 +1755,10 @@ touch_move_grab_motion(struct weston_touch_grab *grab,
static void
pointer_move_workspace_grab_button(struct weston_pointer_grab *grab,
const struct timespec *time, uint32_t button,
uint32_t state_w)
const struct weston_pointer_button_event *button_event)
{
if (BTN_LEFT == button &&
WL_POINTER_BUTTON_STATE_RELEASED == state_w) {
if (BTN_LEFT == button_event->button &&
WL_POINTER_BUTTON_STATE_RELEASED == button_event->button_state) {
struct pointer_grab *pg = (struct pointer_grab *)grab;
pointer_move_workspace_grab_end(pg);

View file

@ -93,13 +93,12 @@ pointer_move_grab_motion(struct weston_pointer_grab *pointer_grab,
static void
pointer_move_grab_button(struct weston_pointer_grab *pointer_grab,
const struct timespec *time,
uint32_t button, uint32_t state_w)
const struct weston_pointer_button_event *button_event)
{
struct kiosk_shell_grab *shgrab =
container_of(pointer_grab, struct kiosk_shell_grab, pointer_grab);
struct weston_pointer *pointer = pointer_grab->pointer;
enum wl_pointer_button_state state = state_w;
enum wl_pointer_button_state state = button_event->button_state;
if (pointer->button_count == 0 &&
state == WL_POINTER_BUTTON_STATE_RELEASED)

View file

@ -1465,10 +1465,17 @@ xf_mouseEvent(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y)
}
if (button) {
struct weston_pointer_button_event button_event;
weston_compositor_get_time(&time);
notify_button(peerContext->item.seat, &time, button,
(flags & PTR_FLAGS_DOWN) ? WL_POINTER_BUTTON_STATE_PRESSED : WL_POINTER_BUTTON_STATE_RELEASED
);
weston_input_event_init(&button_event.base, &time,
peerContext->item.seat);
weston_pointer_button_event_init(&button_event, button,
(flags & PTR_FLAGS_DOWN) ?
WL_POINTER_BUTTON_STATE_PRESSED :
WL_POINTER_BUTTON_STATE_RELEASED);
notify_button(peerContext->item.seat, &button_event);
need_frame = true;
}
@ -1513,9 +1520,16 @@ xf_extendedMouseEvent(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y)
}
if (button) {
struct weston_pointer_button_event button_event;
weston_compositor_get_time(&time);
notify_button(peerContext->item.seat, &time, button,
(flags & PTR_XFLAGS_DOWN) ? WL_POINTER_BUTTON_STATE_PRESSED : WL_POINTER_BUTTON_STATE_RELEASED);
weston_input_event_init(&button_event.base, &time,
peerContext->item.seat);
weston_pointer_button_event_init(&button_event, button,
(flags & PTR_XFLAGS_DOWN) ?
WL_POINTER_BUTTON_STATE_PRESSED :
WL_POINTER_BUTTON_STATE_RELEASED);
notify_button(peerContext->item.seat, &button_event);
need_frame = true;
}

View file

@ -442,6 +442,7 @@ vnc_pointer_event(struct nvnc_client *client, uint16_t x, uint16_t y,
struct vnc_output *output = peer->backend->output;
struct timespec time;
enum nvnc_button_mask changed_button_mask;
struct weston_pointer_button_event button_event;
weston_compositor_get_time(&time);
@ -459,23 +460,31 @@ vnc_pointer_event(struct nvnc_client *client, uint16_t x, uint16_t y,
changed_button_mask = peer->last_button_mask ^ button_mask;
if (changed_button_mask & NVNC_BUTTON_LEFT)
notify_button(peer->seat, &time, BTN_LEFT,
(button_mask & NVNC_BUTTON_LEFT) ?
WL_POINTER_BUTTON_STATE_PRESSED :
WL_POINTER_BUTTON_STATE_RELEASED);
weston_input_event_init(&button_event.base, &time, peer->seat);
if (changed_button_mask & NVNC_BUTTON_LEFT) {
weston_pointer_button_event_init(&button_event, BTN_LEFT,
(button_mask & NVNC_BUTTON_LEFT) ?
WL_POINTER_BUTTON_STATE_PRESSED :
WL_POINTER_BUTTON_STATE_RELEASED);
notify_button(peer->seat, &button_event);
}
if (changed_button_mask & NVNC_BUTTON_MIDDLE)
notify_button(peer->seat, &time, BTN_MIDDLE,
(button_mask & NVNC_BUTTON_MIDDLE) ?
WL_POINTER_BUTTON_STATE_PRESSED :
WL_POINTER_BUTTON_STATE_RELEASED);
if (changed_button_mask & NVNC_BUTTON_MIDDLE) {
weston_pointer_button_event_init(&button_event, BTN_MIDDLE,
(button_mask & NVNC_BUTTON_MIDDLE) ?
WL_POINTER_BUTTON_STATE_PRESSED :
WL_POINTER_BUTTON_STATE_RELEASED);
notify_button(peer->seat, &button_event);
}
if (changed_button_mask & NVNC_BUTTON_RIGHT) {
weston_pointer_button_event_init(&button_event, BTN_RIGHT,
(button_mask & NVNC_BUTTON_RIGHT) ?
WL_POINTER_BUTTON_STATE_PRESSED :
WL_POINTER_BUTTON_STATE_RELEASED);
notify_button(peer->seat, &button_event);
}
if (changed_button_mask & NVNC_BUTTON_RIGHT)
notify_button(peer->seat, &time, BTN_RIGHT,
(button_mask & NVNC_BUTTON_RIGHT) ?
WL_POINTER_BUTTON_STATE_PRESSED :
WL_POINTER_BUTTON_STATE_RELEASED);
if ((button_mask & NVNC_SCROLL_UP) ||
(button_mask & NVNC_SCROLL_DOWN)) {

View file

@ -1738,6 +1738,7 @@ input_handle_button(void *data, struct wl_pointer *pointer,
struct wayland_input *input = data;
enum theme_location location;
struct timespec ts;
struct weston_pointer_button_event button_event;
if (!input->output)
return;
@ -1781,7 +1782,11 @@ input_handle_button(void *data, struct wl_pointer *pointer,
if (location == THEME_LOCATION_CLIENT_AREA) {
timespec_from_msec(&ts, time);
notify_button(&input->base, &ts, button, state);
weston_input_event_init(&button_event.base, &ts, &input->base);
weston_pointer_button_event_init(&button_event, button, state);
notify_button(&input->base, &button_event);
if (input->seat_version < WL_POINTER_FRAME_SINCE_VERSION)
notify_pointer_frame(&input->base);
}

View file

@ -1414,6 +1414,7 @@ x11_backend_deliver_button_event(struct x11_backend *b,
uint32_t button;
struct x11_output *output;
struct weston_pointer_axis_event weston_event;
struct weston_pointer_button_event b_event;
bool is_button_pressed = event->response_type == XCB_BUTTON_PRESS;
struct timespec time = { 0 };
@ -1507,10 +1508,13 @@ x11_backend_deliver_button_event(struct x11_backend *b,
}
weston_compositor_get_time(&time);
weston_input_event_init(&b_event.base, &time, &b->core_seat);
weston_pointer_button_event_init(&b_event, button,
is_button_pressed ?
WL_POINTER_BUTTON_STATE_PRESSED :
WL_POINTER_BUTTON_STATE_RELEASED);
notify_button(&b->core_seat, &time, button,
is_button_pressed ? WL_POINTER_BUTTON_STATE_PRESSED :
WL_POINTER_BUTTON_STATE_RELEASED);
notify_button(&b->core_seat, &b_event);
notify_pointer_frame(&b->core_seat);
}

View file

@ -238,8 +238,7 @@ void
notify_axis_source(struct weston_seat *seat, uint32_t source);
void
notify_button(struct weston_seat *seat, const struct timespec *time,
int32_t button, enum wl_pointer_button_state state);
notify_button(struct weston_seat *seat, struct weston_pointer_button_event *b_event);
void
notify_key(struct weston_seat *seat, const struct weston_key_event *key_event);

View file

@ -652,17 +652,16 @@ data_device_end_pointer_drag_grab(struct weston_pointer_drag *drag)
static void
drag_grab_button(struct weston_pointer_grab *grab,
const struct timespec *time,
uint32_t button, uint32_t state_w)
const struct weston_pointer_button_event *button_event)
{
struct weston_pointer_drag *drag =
container_of(grab, struct weston_pointer_drag, grab);
struct weston_pointer *pointer = drag->grab.pointer;
enum wl_pointer_button_state state = state_w;
enum wl_pointer_button_state state = button_event->button_state;
struct weston_data_source *data_source = drag->base.data_source;
if (data_source &&
pointer->grab_button == button &&
pointer->grab_button == button_event->button &&
state == WL_POINTER_BUTTON_STATE_RELEASED) {
if (drag->base.focus_resource &&
data_source->accepted &&

View file

@ -124,23 +124,23 @@ weston_desktop_seat_popup_grab_pointer_motion(struct weston_pointer_grab *grab,
static void
weston_desktop_seat_popup_grab_pointer_button(struct weston_pointer_grab *grab,
const struct timespec *time,
uint32_t button,
enum wl_pointer_button_state state)
const struct weston_pointer_button_event *button_event)
{
struct weston_desktop_seat *seat =
wl_container_of(grab, seat, popup_grab.pointer);
struct weston_pointer *pointer = grab->pointer;
bool initial_up = seat->popup_grab.initial_up;
enum wl_pointer_button_state state = button_event->button_state;
struct timespec time = button_event->base.ts;
if (state == WL_POINTER_BUTTON_STATE_RELEASED)
seat->popup_grab.initial_up = true;
if (weston_pointer_has_focus_resource(pointer))
weston_pointer_send_button(pointer, time, button, state);
weston_pointer_send_button(pointer, button_event);
else if (state == WL_POINTER_BUTTON_STATE_RELEASED &&
(initial_up ||
(timespec_sub_to_msec(time, &grab->pointer->grab_time) > 500)))
(timespec_sub_to_msec(&time, &grab->pointer->grab_time) > 500)))
weston_desktop_seat_popup_grab_end(seat);
}

View file

@ -673,9 +673,7 @@ weston_pointer_has_focus_resource(struct weston_pointer *pointer)
/** Send wl_pointer.button events to focused resources.
*
* \param pointer The pointer where the button events originates from.
* \param time The timestamp of the event
* \param button The button value of the event
* \param state The state enum value of the event
* \param button_event A pointer to weston_pointer_button_event
*
* For every resource that is currently in focus, send a wl_pointer.button event
* with the passed parameters. The focused resources are the wl_pointer
@ -683,39 +681,41 @@ weston_pointer_has_focus_resource(struct weston_pointer *pointer)
*/
WL_EXPORT void
weston_pointer_send_button(struct weston_pointer *pointer,
const struct timespec *time, uint32_t button,
enum wl_pointer_button_state state)
const struct weston_pointer_button_event *button_event)
{
struct wl_display *display = pointer->seat->compositor->wl_display;
struct wl_list *resource_list;
struct wl_resource *resource;
uint32_t serial;
uint32_t msecs;
struct timespec time = button_event->base.ts;
uint32_t button = button_event->button;
enum wl_pointer_button_state state = button_event->button_state;
if (!weston_pointer_has_focus_resource(pointer))
return;
resource_list = &pointer->focus_client->pointer_resources;
serial = wl_display_next_serial(display);
msecs = timespec_to_msec(time);
msecs = timespec_to_msec(&time);
wl_resource_for_each(resource, resource_list) {
send_timestamps_for_input_resource(resource,
&pointer->timestamps_list,
time);
&time);
wl_pointer_send_button(resource, serial, msecs, button, state);
}
}
static void
default_grab_pointer_button(struct weston_pointer_grab *grab,
const struct timespec *time, uint32_t button,
enum wl_pointer_button_state state)
const struct weston_pointer_button_event *button_event)
{
struct weston_pointer *pointer = grab->pointer;
struct weston_compositor *compositor = pointer->seat->compositor;
struct weston_view *view;
enum wl_pointer_button_state state = button_event->button_state;
weston_pointer_send_button(pointer, time, button, state);
weston_pointer_send_button(pointer, button_event);
if (pointer->button_count == 0 &&
state == WL_POINTER_BUTTON_STATE_RELEASED) {
@ -2325,17 +2325,16 @@ weston_view_activate_input(struct weston_view *view,
}
WL_EXPORT void
notify_button(struct weston_seat *seat, const struct timespec *time,
int32_t button, enum wl_pointer_button_state state)
notify_button(struct weston_seat *seat, struct weston_pointer_button_event *event)
{
struct weston_compositor *compositor = seat->compositor;
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
if (event->button_state == WL_POINTER_BUTTON_STATE_PRESSED) {
weston_compositor_idle_inhibit(compositor);
if (pointer->button_count == 0) {
pointer->grab_button = button;
pointer->grab_time = *time;
pointer->grab_button = event->button;
pointer->grab_time = event->base.ts;
pointer->grab_pos = pointer->pos;
}
pointer->button_count++;
@ -2344,10 +2343,10 @@ notify_button(struct weston_seat *seat, const struct timespec *time,
pointer->button_count--;
}
weston_compositor_run_button_binding(compositor, pointer, time, button,
state);
weston_compositor_run_button_binding(compositor, pointer, &event->base.ts,
event->button, event->button_state);
pointer->grab->interface->button(pointer->grab, time, button, state);
pointer->grab->interface->button(pointer->grab, event);
if (pointer->button_count == 1)
pointer->grab_serial =
@ -4719,11 +4718,9 @@ locked_pointer_grab_pointer_motion(struct weston_pointer_grab *grab,
static void
locked_pointer_grab_pointer_button(struct weston_pointer_grab *grab,
const struct timespec *time,
uint32_t button,
uint32_t state_w)
const struct weston_pointer_button_event *button_event)
{
weston_pointer_send_button(grab->pointer, time, button, state_w);
weston_pointer_send_button(grab->pointer, button_event);
}
static void
@ -5721,11 +5718,9 @@ confined_pointer_grab_pointer_motion(struct weston_pointer_grab *grab,
static void
confined_pointer_grab_pointer_button(struct weston_pointer_grab *grab,
const struct timespec *time,
uint32_t button,
uint32_t state_w)
const struct weston_pointer_button_event *button_event)
{
weston_pointer_send_button(grab->pointer, time, button, state_w);
weston_pointer_send_button(grab->pointer, button_event);
}
static void
@ -6043,3 +6038,11 @@ weston_pointer_motion_event_init(struct weston_pointer_motion_event *event,
event->rel = rel;
event->rel_unaccel = rel_unaccel;
}
WL_EXPORT void
weston_pointer_button_event_init(struct weston_pointer_button_event *event,
uint32_t button, enum wl_pointer_button_state button_state)
{
event->button = button;
event->button_state = button_state;
}

View file

@ -194,6 +194,7 @@ handle_pointer_button(struct libinput_device *libinput_device,
int seat_button_count =
libinput_event_pointer_get_seat_button_count(pointer_event);
struct timespec time;
struct weston_pointer_button_event button_event;
ensure_pointer_capability(libinput_device);
@ -207,9 +208,11 @@ handle_pointer_button(struct libinput_device *libinput_device,
timespec_from_usec(&time,
libinput_event_pointer_get_time_usec(pointer_event));
notify_button(device->seat, &time,
libinput_event_pointer_get_button(pointer_event),
button_state);
weston_input_event_init(&button_event.base, &time, device->seat);
weston_pointer_button_event_init(&button_event,
libinput_event_pointer_get_button(pointer_event),
button_state);
notify_button(device->seat, &button_event);
return true;
}

View file

@ -434,14 +434,17 @@ send_button(struct wl_client *client, struct wl_resource *resource,
uint32_t tv_sec_hi, uint32_t tv_sec_lo, uint32_t tv_nsec,
int32_t button, uint32_t state)
{
struct timespec time;
struct weston_pointer_button_event button_event;
struct weston_test *test = wl_resource_get_user_data(resource);
struct weston_seat *seat = get_seat(test);
struct timespec time;
timespec_from_proto(&time, tv_sec_hi, tv_sec_lo, tv_nsec);
weston_input_event_init(&button_event.base, &time, seat);
weston_pointer_button_event_init(&button_event, button, state);
notify_button(seat, &time, button, state);
notify_button(seat, &button_event);
}
static void