wayland: Make use of Wayland event grabbing mechanism

Enable grabbing input for popups, and drag-and-drop. Since the very
switch to using ClutterGrab underneath Wayland grabs will challenge
assumptions in existing code, these had to change in one go. A notable
one is that meta_display_windows_are_interactable() is not 100% true
anymore for xdg_popups, at least not the same.

Another change happening in lockstep is MetaDnD no longer having
to funnel events to Wayland, since the grab triggered by Wayland DnD
is now a cause of "compositor grabs", and will naturally receive events
as long as it hold. while "modal".

A number of ad-hoc checks for grabbing state has also been dropped
from src/wayland/ internals, since again Wayland grabs are a reason
for Clutter grabs, plus the mechanism itself will already take care
of focus loss and restoration.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3420>
This commit is contained in:
Carlos Garnacho 2023-11-17 23:35:41 +01:00 committed by Robert Mader
parent 67773ab88d
commit 2a584a8f01
10 changed files with 4 additions and 109 deletions

View File

@ -256,52 +256,12 @@ static void
meta_dnd_wayland_on_motion_event (MetaDnd *dnd,
const ClutterEvent *event)
{
MetaWaylandDragGrab *current_grab;
gfloat event_x, event_y;
MetaWaylandDataDevice *data_device = data_device_from_dnd (dnd);
g_return_if_fail (event != NULL);
clutter_event_get_coords (event, &event_x, &event_y);
meta_dnd_notify_dnd_position_change (dnd, (int)event_x, (int)event_y);
current_grab = meta_wayland_data_device_get_current_grab (data_device);
if (current_grab)
meta_wayland_drag_grab_update_feedback_actor (current_grab, event);
}
static void
meta_dnd_wayland_end_notify (MetaDnd *dnd)
{
MetaDndPrivate *priv = meta_dnd_get_instance_private (dnd);
MetaWaylandDataDevice *data_device = data_device_from_dnd (dnd);
meta_wayland_data_device_set_dnd_source (data_device, NULL);
meta_wayland_data_device_unset_dnd_selection (data_device);
meta_wayland_data_device_end_drag (data_device);
priv->dnd_during_modal = FALSE;
meta_dnd_notify_dnd_leave (dnd);
}
static void
meta_dnd_wayland_on_button_released (MetaDnd *dnd,
const ClutterEvent *event)
{
meta_dnd_wayland_end_notify (dnd);
}
static void
meta_dnd_wayland_on_key_pressed (MetaDnd *dnd,
const ClutterEvent *event)
{
guint key = clutter_event_get_key_symbol (event);
if (key != CLUTTER_KEY_Escape)
return;
meta_dnd_wayland_end_notify (dnd);
}
void
@ -309,22 +269,15 @@ meta_dnd_wayland_maybe_handle_event (MetaDnd *dnd,
const ClutterEvent *event)
{
MetaWaylandDataDevice *data_device = data_device_from_dnd (dnd);
MetaDndPrivate *priv = meta_dnd_get_instance_private (dnd);
ClutterEventType event_type;
if (!meta_wayland_data_device_get_current_grab (data_device))
return;
g_warn_if_fail (priv->dnd_during_modal);
event_type = clutter_event_type (event);
if (event_type == CLUTTER_MOTION)
meta_dnd_wayland_on_motion_event (dnd, event);
else if (event_type == CLUTTER_BUTTON_RELEASE)
meta_dnd_wayland_on_button_released (dnd, event);
else if (event_type == CLUTTER_KEY_PRESS)
meta_dnd_wayland_on_key_pressed (dnd, event);
}
void

View File

@ -482,13 +482,7 @@ meta_display_handle_event (MetaDisplay *display,
bypass_clutter = !IS_GESTURE_EVENT (event_type);
bypass_wayland = meta_window_has_modals (window);
if (
#ifdef HAVE_WAYLAND
(!wayland_compositor ||
!meta_wayland_compositor_is_grabbed (wayland_compositor)) &&
#endif
!meta_display_is_grabbed (display))
meta_window_handle_ungrabbed_event (window, event);
meta_window_handle_ungrabbed_event (window, event);
/* This might start a grab op. If it does, then filter out the
* event, and if it doesn't, replay the event to release our
@ -532,10 +526,6 @@ meta_display_handle_event (MetaDisplay *display,
out:
#ifdef HAVE_WAYLAND
/* If a Wayland client has a grab, don't pass that through to Clutter */
if (wayland_compositor && meta_wayland_compositor_is_grabbed (wayland_compositor))
bypass_clutter = bypass_clutter || !bypass_wayland;
if (wayland_compositor && !bypass_wayland)
{
if (window && event_type == CLUTTER_MOTION &&

View File

@ -745,7 +745,7 @@ meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data_devic
drag_grab->handler =
meta_wayland_input_attach_event_handler (input,
event_iface,
FALSE,
TRUE,
drag_grab);
meta_wayland_data_source_set_seat (source, seat);
}

View File

@ -298,18 +298,10 @@ surface_get_effective_window (MetaWaylandSurface *surface)
static void
sync_focus_surface (MetaWaylandPointer *pointer)
{
MetaBackend *backend = backend_from_pointer (pointer);
ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
MetaWaylandInputDevice *input_device = META_WAYLAND_INPUT_DEVICE (pointer);
MetaWaylandSeat *seat = meta_wayland_input_device_get_seat (input_device);
MetaWaylandInput *input;
if (clutter_stage_get_grab_actor (stage) != NULL)
{
meta_wayland_pointer_set_focus (pointer, NULL);
return;
}
input = meta_wayland_seat_get_input (seat);
meta_wayland_input_invalidate_focus (input, pointer->device, NULL);
}
@ -1051,15 +1043,10 @@ meta_wayland_pointer_focus_surface (MetaWaylandPointer *pointer,
MetaWaylandSurface *surface)
{
MetaWaylandSeat *seat = meta_wayland_pointer_get_seat (pointer);
MetaBackend *backend = backend_from_pointer (pointer);
ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
if (!meta_wayland_seat_has_pointer (seat))
return;
if (clutter_stage_get_grab_actor (stage) != NULL)
return;
if (surface)
{
MetaWindow *window = NULL;

View File

@ -207,7 +207,7 @@ meta_wayland_popup_grab_create (MetaWaylandSeat *seat,
grab->handler =
meta_wayland_input_attach_event_handler (input,
&popup_event_interface,
FALSE, grab);
TRUE, grab);
return grab;
}

View File

@ -663,16 +663,6 @@ meta_wayland_seat_get_compositor (MetaWaylandSeat *seat)
return seat->compositor;
}
gboolean
meta_wayland_seat_is_grabbed (MetaWaylandSeat *seat)
{
if (!meta_wayland_input_is_current_handler (seat->input_handler,
seat->default_handler))
return TRUE;
return FALSE;
}
gboolean
meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
const ClutterEvent *event)

View File

@ -91,8 +91,6 @@ gboolean meta_wayland_seat_has_touch (MetaWaylandSeat *seat);
MetaWaylandCompositor * meta_wayland_seat_get_compositor (MetaWaylandSeat *seat);
gboolean meta_wayland_seat_is_grabbed (MetaWaylandSeat *seat);
MetaWaylandInput * meta_wayland_seat_get_input (MetaWaylandSeat *seat);
MetaWaylandSurface * meta_wayland_seat_get_current_surface (MetaWaylandSeat *seat,

View File

@ -569,15 +569,6 @@ static void
sync_focus_surface (MetaWaylandTabletTool *tool,
const ClutterEvent *event)
{
MetaBackend *backend = backend_from_tool (tool);
ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
if (clutter_stage_get_grab_actor (stage))
{
meta_wayland_tablet_tool_set_focus (tool, NULL, event);
return;
}
meta_wayland_tablet_tool_set_focus (tool, tool->current, event);
}

View File

@ -1030,12 +1030,6 @@ meta_wayland_compositor_get_context (MetaWaylandCompositor *compositor)
return compositor->context;
}
gboolean
meta_wayland_compositor_is_grabbed (MetaWaylandCompositor *compositor)
{
return meta_wayland_seat_is_grabbed (compositor->seat);
}
/**
* meta_wayland_compositor_get_wayland_display:
* @compositor: The #MetaWaylandCompositor
@ -1067,19 +1061,13 @@ static void
meta_wayland_compositor_update_focus (MetaWaylandCompositor *compositor,
MetaWindow *window)
{
MetaContext *context = meta_wayland_compositor_get_context (compositor);
MetaDisplay *display = meta_context_get_display (context);
MetaWindow *focus_window = NULL;
/* Compositor not ready yet */
if (!compositor->seat)
return;
if (!display || !meta_display_windows_are_interactable (display))
focus_window = NULL;
else if (!window)
focus_window = NULL;
else if (window && meta_window_get_wayland_surface (window))
if (window && meta_window_get_wayland_surface (window))
focus_window = window;
else
meta_topic (META_DEBUG_FOCUS, "Focus change has no effect, because there is no matching wayland surface");

View File

@ -101,8 +101,6 @@ MetaXWaylandManager * meta_wayland_compositor_get_xwayland_manager (MetaWaylan
META_EXPORT_TEST
MetaContext * meta_wayland_compositor_get_context (MetaWaylandCompositor *compositor);
gboolean meta_wayland_compositor_is_grabbed (MetaWaylandCompositor *compositor);
META_EXPORT_TEST
MetaWaylandFilterManager * meta_wayland_compositor_get_filter_manager (MetaWaylandCompositor *compositor);