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;
MetaWaylandSeat *seat;
MetaWaylandKeyboardGrab keyboard_grab;
MetaWaylandEventHandler *handler;
gulong surface_destroyed_handler;
gulong shortcuts_restored_handler;
gulong window_associate_handler;
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
meta_xwayland_keyboard_grab_end (MetaXwaylandKeyboardActiveGrab *active_grab)
{
MetaWaylandSeat *seat = active_grab->seat;
if (seat->keyboard->grab->interface->key == meta_xwayland_keyboard_grab_key)
if (active_grab->handler)
{
MetaWaylandCompositor *compositor =
meta_wayland_seat_get_compositor (active_grab->seat);
MetaWaylandInput *input;
meta_wayland_keyboard_end_grab (active_grab->keyboard_grab.keyboard);
meta_wayland_keyboard_set_focus (active_grab->keyboard_grab.keyboard, NULL);
meta_wayland_compositor_sync_focus (compositor);
input = meta_wayland_seat_get_input (active_grab->seat);
meta_wayland_input_detach_event_handler (input, active_grab->handler);
active_grab->handler = NULL;
}
if (!active_grab->surface)
@ -112,11 +72,45 @@ meta_xwayland_keyboard_grab_end (MetaXwaylandKeyboardActiveGrab *active_grab)
active_grab->surface = NULL;
}
static const MetaWaylandKeyboardGrabInterface
keyboard_grab_interface = {
meta_xwayland_keyboard_grab_key,
meta_xwayland_keyboard_grab_modifiers
};
static MetaWaylandSurface *
meta_xwayland_keyboard_grab_get_focus_surface (MetaWaylandEventHandler *handler,
ClutterInputDevice *device,
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
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);
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,
@ -286,7 +288,6 @@ zwp_xwayland_keyboard_grab_manager_grab (struct wl_client *client,
active_grab->surface = surface;
active_grab->resource = grab_resource;
active_grab->seat = seat;
active_grab->keyboard_grab.interface = &keyboard_grab_interface;
active_grab->surface_destroyed_handler =
g_signal_connect (surface, "destroy",
G_CALLBACK (surface_destroyed_cb),