From 9da40aa9fd268cd2107fea053cc671728a777106 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 8 Nov 2023 13:43:50 +0100 Subject: [PATCH] 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: --- src/wayland/meta-xwayland-grab-keyboard.c | 107 +++++++++++----------- 1 file changed, 54 insertions(+), 53 deletions(-) diff --git a/src/wayland/meta-xwayland-grab-keyboard.c b/src/wayland/meta-xwayland-grab-keyboard.c index ce555bbe8..88dd8c78e 100644 --- a/src/wayland/meta-xwayland-grab-keyboard.c +++ b/src/wayland/meta-xwayland-grab-keyboard.c @@ -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),