wayland: Port xwayland key grabs to MetaWaylandEventInterface

This event interface simply enforces key focus to the grab window,
but stands out of the way for every other kind of input.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3420>
This commit is contained in:
Carlos Garnacho 2023-11-08 13:43:50 +01:00 committed by Robert Mader
parent 80ed79a0d3
commit 9da40aa9fd

View File

@ -35,63 +35,23 @@ struct _MetaXwaylandKeyboardActiveGrab
{ {
MetaWaylandSurface *surface; MetaWaylandSurface *surface;
MetaWaylandSeat *seat; MetaWaylandSeat *seat;
MetaWaylandKeyboardGrab keyboard_grab; MetaWaylandEventHandler *handler;
gulong surface_destroyed_handler; gulong surface_destroyed_handler;
gulong shortcuts_restored_handler; gulong shortcuts_restored_handler;
gulong window_associate_handler; gulong window_associate_handler;
struct wl_resource *resource; struct wl_resource *resource;
}; };
static gboolean
meta_xwayland_keyboard_grab_key (MetaWaylandKeyboardGrab *grab,
const ClutterEvent *event)
{
MetaXwaylandKeyboardActiveGrab *active_grab;
MetaWaylandKeyboard *keyboard;
active_grab = wl_container_of (grab, active_grab, keyboard_grab);
keyboard = active_grab->keyboard_grab.keyboard;
/* Force focus onto the surface who has the active grab on the keyboard */
if (active_grab->surface != NULL && keyboard->focus_surface != active_grab->surface)
meta_wayland_keyboard_set_focus (keyboard, active_grab->surface);
/* Chain-up with default keyboard handler */
return keyboard->default_grab.interface->key (&keyboard->default_grab, event);
}
static void
meta_xwayland_keyboard_grab_modifiers (MetaWaylandKeyboardGrab *grab,
ClutterModifierType modifiers)
{
MetaXwaylandKeyboardActiveGrab *active_grab;
MetaWaylandKeyboard *keyboard;
active_grab = wl_container_of (grab, active_grab, keyboard_grab);
keyboard = active_grab->keyboard_grab.keyboard;
/* Force focus onto the surface who has the active grab on the keyboard */
if (active_grab->surface != NULL && keyboard->focus_surface != active_grab->surface)
meta_wayland_keyboard_set_focus (keyboard, active_grab->surface);
/* Chain-up with default keyboard handler */
return keyboard->default_grab.interface->modifiers (&keyboard->default_grab,
modifiers);
}
static void static void
meta_xwayland_keyboard_grab_end (MetaXwaylandKeyboardActiveGrab *active_grab) meta_xwayland_keyboard_grab_end (MetaXwaylandKeyboardActiveGrab *active_grab)
{ {
MetaWaylandSeat *seat = active_grab->seat; if (active_grab->handler)
if (seat->keyboard->grab->interface->key == meta_xwayland_keyboard_grab_key)
{ {
MetaWaylandCompositor *compositor = MetaWaylandInput *input;
meta_wayland_seat_get_compositor (active_grab->seat);
meta_wayland_keyboard_end_grab (active_grab->keyboard_grab.keyboard); input = meta_wayland_seat_get_input (active_grab->seat);
meta_wayland_keyboard_set_focus (active_grab->keyboard_grab.keyboard, NULL); meta_wayland_input_detach_event_handler (input, active_grab->handler);
meta_wayland_compositor_sync_focus (compositor); active_grab->handler = NULL;
} }
if (!active_grab->surface) if (!active_grab->surface)
@ -112,11 +72,45 @@ meta_xwayland_keyboard_grab_end (MetaXwaylandKeyboardActiveGrab *active_grab)
active_grab->surface = NULL; active_grab->surface = NULL;
} }
static const MetaWaylandKeyboardGrabInterface static MetaWaylandSurface *
keyboard_grab_interface = { meta_xwayland_keyboard_grab_get_focus_surface (MetaWaylandEventHandler *handler,
meta_xwayland_keyboard_grab_key, ClutterInputDevice *device,
meta_xwayland_keyboard_grab_modifiers ClutterEventSequence *sequence,
}; gpointer user_data)
{
MetaXwaylandKeyboardActiveGrab *active_grab = user_data;
/* Force focus onto the surface who has the active grab on the keyboard */
if (clutter_input_device_get_capabilities (device) &
CLUTTER_INPUT_CAPABILITY_KEYBOARD)
return active_grab->surface;
return meta_wayland_event_handler_chain_up_get_focus_surface (handler,
device,
sequence);
}
static void
meta_xwayland_keyboard_grab_focus (MetaWaylandEventHandler *handler,
ClutterInputDevice *device,
ClutterEventSequence *sequence,
MetaWaylandSurface *surface,
gpointer user_data)
{
MetaXwaylandKeyboardActiveGrab *active_grab = user_data;
if (clutter_input_device_get_capabilities (device) &
CLUTTER_INPUT_CAPABILITY_KEYBOARD &&
surface != active_grab->surface)
meta_xwayland_keyboard_grab_end (active_grab);
else
meta_wayland_event_handler_chain_up_focus (handler, device, sequence, surface);
}
static const MetaWaylandEventInterface grab_event_interface = {
meta_xwayland_keyboard_grab_get_focus_surface,
meta_xwayland_keyboard_grab_focus,
};
static void static void
zwp_xwayland_keyboard_grab_destructor (struct wl_resource *resource) zwp_xwayland_keyboard_grab_destructor (struct wl_resource *resource)
@ -250,7 +244,15 @@ meta_xwayland_keyboard_grab_activate (MetaXwaylandKeyboardActiveGrab *active_gra
meta_wayland_surface_inhibit_shortcuts (surface, seat); meta_wayland_surface_inhibit_shortcuts (surface, seat);
if (meta_xwayland_grab_should_lock_focus (window)) if (meta_xwayland_grab_should_lock_focus (window))
meta_wayland_keyboard_start_grab (seat->keyboard, &active_grab->keyboard_grab); {
MetaWaylandInput *input;
input = meta_wayland_seat_get_input (seat);
active_grab->handler =
meta_wayland_input_attach_event_handler (input,
&grab_event_interface,
active_grab);
}
} }
g_clear_signal_handler (&active_grab->window_associate_handler, g_clear_signal_handler (&active_grab->window_associate_handler,
@ -286,7 +288,6 @@ zwp_xwayland_keyboard_grab_manager_grab (struct wl_client *client,
active_grab->surface = surface; active_grab->surface = surface;
active_grab->resource = grab_resource; active_grab->resource = grab_resource;
active_grab->seat = seat; active_grab->seat = seat;
active_grab->keyboard_grab.interface = &keyboard_grab_interface;
active_grab->surface_destroyed_handler = active_grab->surface_destroyed_handler =
g_signal_connect (surface, "destroy", g_signal_connect (surface, "destroy",
G_CALLBACK (surface_destroyed_cb), G_CALLBACK (surface_destroyed_cb),