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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3420>
This commit is contained in:
Carlos Garnacho 2023-11-08 15:20:34 +01:00 committed by Robert Mader
parent 9da40aa9fd
commit 125ba92169

View File

@ -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);
}