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:
parent
80ed79a0d3
commit
9da40aa9fd
@ -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),
|
||||||
|
Loading…
Reference in New Issue
Block a user