From 125ba92169ee39fe8a694e16ccfd0d7b5c5071a5 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 8 Nov 2023 15:20:34 +0100 Subject: [PATCH] wayland: Port pointer constraints to using MetaWaylandEventInterface Besides the pointer locking/constraining mechanism, these grab interfaces were more of a focus tracking mechanism, revoking the constraints when the conditions didn't meet. This can be handled pretty similarly to keyboard grabs with the new interface, with the added bonus that we can chain up to let the parent/default handler handle the events themselves, without poking at MetaWaylandPointer API. Part-of: --- .../meta-wayland-pointer-constraints.c | 262 ++++++++++-------- 1 file changed, 142 insertions(+), 120 deletions(-) diff --git a/src/wayland/meta-wayland-pointer-constraints.c b/src/wayland/meta-wayland-pointer-constraints.c index 894b2e132..1a1684874 100644 --- a/src/wayland/meta-wayland-pointer-constraints.c +++ b/src/wayland/meta-wayland-pointer-constraints.c @@ -57,7 +57,8 @@ struct _MetaWaylandPointerConstraint gboolean is_enabled; MtkRegion *region; struct wl_resource *resource; - MetaWaylandPointerGrab grab; + const MetaWaylandEventInterface *event_interface; + MetaWaylandEventHandler *handler; MetaWaylandSeat *seat; enum zwp_pointer_constraints_v1_lifetime lifetime; gulong pointer_focus_surface_handler_id; @@ -99,8 +100,6 @@ G_DEFINE_TYPE (MetaWaylandPointerConstraint, meta_wayland_pointer_constraint, static const struct zwp_locked_pointer_v1_interface locked_pointer_interface; static const struct zwp_confined_pointer_v1_interface confined_pointer_interface; -static const MetaWaylandPointerGrabInterface locked_pointer_grab_interface; -static const MetaWaylandPointerGrabInterface confined_pointer_grab_interface; static void meta_wayland_pointer_constraint_destroy (MetaWaylandPointerConstraint *constraint); @@ -112,8 +111,10 @@ static void meta_wayland_pointer_constraint_maybe_enable_for_window (MetaWindow *window); static void -meta_wayland_pointer_constraint_maybe_remove_for_seat (MetaWaylandSeat *seat, - MetaWindow *window); +meta_wayland_pointer_constraint_maybe_disable (MetaWaylandPointerConstraint *constraint); + +static void +meta_wayland_pointer_constraint_maybe_disable_for_window (MetaWindow *window); static MetaWaylandSurfacePointerConstraintsData * get_surface_constraints_data (MetaWaylandSurface *surface) @@ -127,14 +128,7 @@ appears_focused_changed (MetaWindow *window, GParamSpec *pspec, gpointer user_data) { - MetaDisplay *display = meta_window_get_display (window); - MetaContext *context = meta_display_get_context (display); - MetaWaylandCompositor *wayland_compositor = - meta_context_get_wayland_compositor (context); - - meta_wayland_pointer_constraint_maybe_remove_for_seat (wayland_compositor->seat, - window); - + meta_wayland_pointer_constraint_maybe_disable_for_window (window); meta_wayland_pointer_constraint_maybe_enable_for_window (window); } @@ -286,26 +280,19 @@ static void pointer_focus_surface_changed (MetaWaylandPointer *pointer, MetaWaylandPointerConstraint *constraint) { - MetaWindow *window; - - window = meta_wayland_surface_get_window (constraint->surface); - if (window) - { - MetaWaylandSeat *seat = meta_wayland_pointer_get_seat (pointer); - - meta_wayland_pointer_constraint_maybe_remove_for_seat (seat, window); - } + if (meta_wayland_surface_get_window (constraint->surface)) + meta_wayland_pointer_constraint_maybe_disable (constraint); meta_wayland_pointer_constraint_maybe_enable (constraint); } static MetaWaylandPointerConstraint * -meta_wayland_pointer_constraint_new (MetaWaylandSurface *surface, - MetaWaylandSeat *seat, - MetaWaylandRegion *region, - enum zwp_pointer_constraints_v1_lifetime lifetime, - struct wl_resource *resource, - const MetaWaylandPointerGrabInterface *grab_interface) +meta_wayland_pointer_constraint_new (MetaWaylandSurface *surface, + MetaWaylandSeat *seat, + MetaWaylandRegion *region, + enum zwp_pointer_constraints_v1_lifetime lifetime, + struct wl_resource *resource, + const MetaWaylandEventInterface *event_interface) { MetaWaylandPointerConstraint *constraint; @@ -317,7 +304,7 @@ meta_wayland_pointer_constraint_new (MetaWaylandSurface *su constraint->seat = seat; constraint->lifetime = lifetime; constraint->resource = resource; - constraint->grab.interface = grab_interface; + constraint->event_interface = event_interface; if (region) { @@ -401,12 +388,18 @@ meta_wayland_pointer_constraint_create_pointer_constraint (MetaWaylandPointerCon static void meta_wayland_pointer_constraint_enable (MetaWaylandPointerConstraint *constraint) { + MetaWaylandInput *input; + g_assert (!constraint->is_enabled); constraint->is_enabled = TRUE; meta_wayland_pointer_constraint_notify_activated (constraint); - meta_wayland_pointer_start_grab (constraint->seat->pointer, - &constraint->grab); + + input = meta_wayland_seat_get_input (constraint->seat); + constraint->handler = + meta_wayland_input_attach_event_handler (input, + constraint->event_interface, + constraint); constraint->confinement = meta_wayland_pointer_constraint_create_pointer_constraint (constraint); @@ -427,7 +420,15 @@ meta_wayland_pointer_constraint_disable (MetaWaylandPointerConstraint *constrain } meta_wayland_pointer_constraint_notify_deactivated (constraint); - meta_wayland_pointer_end_grab (constraint->grab.pointer); + + if (constraint->handler) + { + MetaWaylandInput *input; + + input = meta_wayland_seat_get_input (constraint->seat); + meta_wayland_input_detach_event_handler (input, constraint->handler); + constraint->handler = NULL; + } } void @@ -482,7 +483,7 @@ should_constraint_be_enabled (MetaWaylandPointerConstraint *constraint) if (window->unmanaging) return FALSE; - if (constraint->seat->pointer->focus_surface != constraint->surface) + if (constraint->seat->pointer->current != constraint->surface) return FALSE; if (meta_wayland_surface_is_xwayland (constraint->surface)) @@ -553,7 +554,8 @@ meta_wayland_pointer_constraint_deactivate (MetaWaylandPointerConstraint *constr break; case ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT: - meta_wayland_pointer_constraint_disable (constraint); + if (meta_wayland_pointer_constraint_is_enabled (constraint)) + meta_wayland_pointer_constraint_disable (constraint); break; default: @@ -561,25 +563,38 @@ meta_wayland_pointer_constraint_deactivate (MetaWaylandPointerConstraint *constr } } -void -meta_wayland_pointer_constraint_maybe_remove_for_seat (MetaWaylandSeat *seat, - MetaWindow *window) +static void +meta_wayland_pointer_constraint_maybe_disable (MetaWaylandPointerConstraint *constraint) { - MetaWaylandPointer *pointer = seat->pointer; - MetaWaylandPointerConstraint *constraint; - - if ((pointer->grab->interface != &confined_pointer_grab_interface && - pointer->grab->interface != &locked_pointer_grab_interface)) - return; - - constraint = wl_container_of (pointer->grab, constraint, grab); - if (should_constraint_be_enabled (constraint)) return; meta_wayland_pointer_constraint_deactivate (constraint); } +static void +meta_wayland_pointer_constraint_maybe_disable_for_window (MetaWindow *window) +{ + MetaWaylandSurface *surface = meta_window_get_wayland_surface (window); + MetaWaylandSurfacePointerConstraintsData *surface_data; + GList *l, *next; + + surface_data = get_surface_constraints_data (surface); + if (!surface_data) + return; + + l = surface_data->pointer_constraints; + + while (l) + { + MetaWaylandPointerConstraint *constraint = l->data; + + next = l->next; + meta_wayland_pointer_constraint_maybe_disable (constraint); + l = next; + } +} + static void meta_wayland_pointer_constraint_maybe_enable_for_window (MetaWindow *window) { @@ -843,15 +858,15 @@ get_pointer_constraint_for_seat (MetaWaylandSurface *surface, } static void -init_pointer_constraint (struct wl_resource *resource, - uint32_t id, - MetaWaylandSurface *surface, - MetaWaylandSeat *seat, - MetaWaylandRegion *region, - enum zwp_pointer_constraints_v1_lifetime lifetime, - const struct wl_interface *interface, - const void *implementation, - const MetaWaylandPointerGrabInterface *grab_interface) +init_pointer_constraint (struct wl_resource *resource, + uint32_t id, + MetaWaylandSurface *surface, + MetaWaylandSeat *seat, + MetaWaylandRegion *region, + enum zwp_pointer_constraints_v1_lifetime lifetime, + const struct wl_interface *interface, + const void *implementation, + const MetaWaylandEventInterface *event_interface) { struct wl_client *client = wl_resource_get_client (resource); struct wl_resource *cr; @@ -891,7 +906,7 @@ init_pointer_constraint (struct wl_resource *resource, constraint = meta_wayland_pointer_constraint_new (surface, seat, region, lifetime, - cr, grab_interface); + cr, event_interface); if (constraint == NULL) { wl_client_post_no_memory (client); @@ -984,41 +999,57 @@ static const struct zwp_locked_pointer_v1_interface locked_pointer_interface = { locked_pointer_set_region, }; -static void -locked_pointer_grab_pointer_focus (MetaWaylandPointerGrab *grab, - MetaWaylandSurface *surface) +static MetaWaylandSurface * +locked_pointer_grab_get_focus_surface (MetaWaylandEventHandler *handler, + ClutterInputDevice *device, + ClutterEventSequence *sequence, + gpointer user_data) { + return meta_wayland_event_handler_chain_up_get_focus_surface (handler, + device, + sequence); } static void -locked_pointer_grab_pointer_motion (MetaWaylandPointerGrab *grab, - const ClutterEvent *event) +locked_pointer_grab_focus (MetaWaylandEventHandler *handler, + ClutterInputDevice *device, + ClutterEventSequence *sequence, + MetaWaylandSurface *surface, + gpointer user_data) { - meta_wayland_pointer_send_relative_motion (grab->pointer, event); - meta_wayland_pointer_broadcast_frame (grab->pointer); + MetaWaylandPointerConstraint *constraint = user_data; + + if (!sequence && + (clutter_input_device_get_capabilities (device) & + CLUTTER_INPUT_CAPABILITY_POINTER) && + surface != constraint->surface) + meta_wayland_pointer_constraint_deactivate (constraint); + else + meta_wayland_event_handler_chain_up_focus (handler, device, sequence, surface); } -static void -locked_pointer_grab_pointer_button (MetaWaylandPointerGrab *grab, - const ClutterEvent *event) +static gboolean +locked_pointer_grab_motion (MetaWaylandEventHandler *handler, + const ClutterEvent *event, + gpointer user_data) { - meta_wayland_pointer_send_button (grab->pointer, event); + MetaWaylandPointerConstraint *constraint = user_data; + + if (clutter_event_type (event) != CLUTTER_MOTION) + return CLUTTER_EVENT_PROPAGATE; + if (clutter_event_get_device_tool (event) != NULL) + return CLUTTER_EVENT_PROPAGATE; + + meta_wayland_pointer_send_relative_motion (constraint->seat->pointer, event); + meta_wayland_pointer_broadcast_frame (constraint->seat->pointer); + + return CLUTTER_EVENT_STOP; } -static void -locked_pointer_grab_pointer_cancel (MetaWaylandPointerGrab *grab) -{ - MetaWaylandPointerConstraint *constraint = - wl_container_of (grab, constraint, grab); - - meta_wayland_pointer_constraint_deactivate (constraint); -} - -static const MetaWaylandPointerGrabInterface locked_pointer_grab_interface = { - locked_pointer_grab_pointer_focus, - locked_pointer_grab_pointer_motion, - locked_pointer_grab_pointer_button, - locked_pointer_grab_pointer_cancel, +static const MetaWaylandEventInterface locked_pointer_event_interface = { + locked_pointer_grab_get_focus_surface, + locked_pointer_grab_focus, + locked_pointer_grab_motion, }; static void @@ -1046,50 +1077,41 @@ pointer_constraints_lock_pointer (struct wl_client *client, init_pointer_constraint (resource, id, surface, seat, region, lifetime, &zwp_locked_pointer_v1_interface, &locked_pointer_interface, - &locked_pointer_grab_interface); + &locked_pointer_event_interface); +} + +static MetaWaylandSurface * +confined_pointer_grab_get_focus_surface (MetaWaylandEventHandler *handler, + ClutterInputDevice *device, + ClutterEventSequence *sequence, + gpointer user_data) +{ + return meta_wayland_event_handler_chain_up_get_focus_surface (handler, + device, + sequence); } static void -confined_pointer_grab_pointer_focus (MetaWaylandPointerGrab *grab, - MetaWaylandSurface *surface) +confined_pointer_grab_focus (MetaWaylandEventHandler *handler, + ClutterInputDevice *device, + ClutterEventSequence *sequence, + MetaWaylandSurface *surface, + gpointer user_data) { + MetaWaylandPointerConstraint *constraint = user_data; + + if (!sequence && + (clutter_input_device_get_capabilities (device) & + CLUTTER_INPUT_CAPABILITY_POINTER) && + surface != constraint->surface) + meta_wayland_pointer_constraint_deactivate (constraint); + else + meta_wayland_event_handler_chain_up_focus (handler, device, sequence, surface); } -static void -confined_pointer_grab_pointer_motion (MetaWaylandPointerGrab *grab, - const ClutterEvent *event) -{ - MetaWaylandPointerConstraint *constraint = - wl_container_of (grab, constraint, grab); - MetaWaylandPointer *pointer = grab->pointer; - - g_assert (pointer->focus_surface); - g_assert (pointer->focus_surface == constraint->surface); - - meta_wayland_pointer_send_motion (pointer, event); -} - -static void -confined_pointer_grab_pointer_button (MetaWaylandPointerGrab *grab, - const ClutterEvent *event) -{ - meta_wayland_pointer_send_button (grab->pointer, event); -} - -static void -confined_pointer_grab_pointer_cancel (MetaWaylandPointerGrab *grab) -{ - MetaWaylandPointerConstraint *constraint = - wl_container_of (grab, constraint, grab); - - meta_wayland_pointer_constraint_deactivate (constraint); -} - -static const MetaWaylandPointerGrabInterface confined_pointer_grab_interface = { - confined_pointer_grab_pointer_focus, - confined_pointer_grab_pointer_motion, - confined_pointer_grab_pointer_button, - confined_pointer_grab_pointer_cancel, +static const MetaWaylandEventInterface confined_pointer_event_interface = { + confined_pointer_grab_get_focus_surface, + confined_pointer_grab_focus, }; static void @@ -1138,7 +1160,7 @@ pointer_constraints_confine_pointer (struct wl_client *client, init_pointer_constraint (resource, id, surface, seat, region, lifetime, &zwp_confined_pointer_v1_interface, &confined_pointer_interface, - &confined_pointer_grab_interface); + &confined_pointer_event_interface); }