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, meta_dnd_wayland_on_motion_event (MetaDnd *dnd,
const ClutterEvent *event) const ClutterEvent *event)
{ {
MetaWaylandDragGrab *current_grab;
gfloat event_x, event_y; gfloat event_x, event_y;
MetaWaylandDataDevice *data_device = data_device_from_dnd (dnd);
g_return_if_fail (event != NULL); g_return_if_fail (event != NULL);
clutter_event_get_coords (event, &event_x, &event_y); clutter_event_get_coords (event, &event_x, &event_y);
meta_dnd_notify_dnd_position_change (dnd, (int)event_x, (int)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 void
@ -309,22 +269,15 @@ meta_dnd_wayland_maybe_handle_event (MetaDnd *dnd,
const ClutterEvent *event) const ClutterEvent *event)
{ {
MetaWaylandDataDevice *data_device = data_device_from_dnd (dnd); MetaWaylandDataDevice *data_device = data_device_from_dnd (dnd);
MetaDndPrivate *priv = meta_dnd_get_instance_private (dnd);
ClutterEventType event_type; ClutterEventType event_type;
if (!meta_wayland_data_device_get_current_grab (data_device)) if (!meta_wayland_data_device_get_current_grab (data_device))
return; return;
g_warn_if_fail (priv->dnd_during_modal);
event_type = clutter_event_type (event); event_type = clutter_event_type (event);
if (event_type == CLUTTER_MOTION) if (event_type == CLUTTER_MOTION)
meta_dnd_wayland_on_motion_event (dnd, event); 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 void

View File

@ -482,13 +482,7 @@ meta_display_handle_event (MetaDisplay *display,
bypass_clutter = !IS_GESTURE_EVENT (event_type); bypass_clutter = !IS_GESTURE_EVENT (event_type);
bypass_wayland = meta_window_has_modals (window); bypass_wayland = meta_window_has_modals (window);
if ( meta_window_handle_ungrabbed_event (window, event);
#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);
/* This might start a grab op. If it does, then filter out the /* 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 * event, and if it doesn't, replay the event to release our
@ -532,10 +526,6 @@ meta_display_handle_event (MetaDisplay *display,
out: out:
#ifdef HAVE_WAYLAND #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 (wayland_compositor && !bypass_wayland)
{ {
if (window && event_type == CLUTTER_MOTION && if (window && event_type == CLUTTER_MOTION &&

View File

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

View File

@ -298,18 +298,10 @@ surface_get_effective_window (MetaWaylandSurface *surface)
static void static void
sync_focus_surface (MetaWaylandPointer *pointer) 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); MetaWaylandInputDevice *input_device = META_WAYLAND_INPUT_DEVICE (pointer);
MetaWaylandSeat *seat = meta_wayland_input_device_get_seat (input_device); MetaWaylandSeat *seat = meta_wayland_input_device_get_seat (input_device);
MetaWaylandInput *input; 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); input = meta_wayland_seat_get_input (seat);
meta_wayland_input_invalidate_focus (input, pointer->device, NULL); meta_wayland_input_invalidate_focus (input, pointer->device, NULL);
} }
@ -1051,15 +1043,10 @@ meta_wayland_pointer_focus_surface (MetaWaylandPointer *pointer,
MetaWaylandSurface *surface) MetaWaylandSurface *surface)
{ {
MetaWaylandSeat *seat = meta_wayland_pointer_get_seat (pointer); 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)) if (!meta_wayland_seat_has_pointer (seat))
return; return;
if (clutter_stage_get_grab_actor (stage) != NULL)
return;
if (surface) if (surface)
{ {
MetaWindow *window = NULL; MetaWindow *window = NULL;

View File

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

View File

@ -663,16 +663,6 @@ meta_wayland_seat_get_compositor (MetaWaylandSeat *seat)
return seat->compositor; 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 gboolean
meta_wayland_seat_handle_event (MetaWaylandSeat *seat, meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
const ClutterEvent *event) 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); MetaWaylandCompositor * meta_wayland_seat_get_compositor (MetaWaylandSeat *seat);
gboolean meta_wayland_seat_is_grabbed (MetaWaylandSeat *seat);
MetaWaylandInput * meta_wayland_seat_get_input (MetaWaylandSeat *seat); MetaWaylandInput * meta_wayland_seat_get_input (MetaWaylandSeat *seat);
MetaWaylandSurface * meta_wayland_seat_get_current_surface (MetaWaylandSeat *seat, MetaWaylandSurface * meta_wayland_seat_get_current_surface (MetaWaylandSeat *seat,

View File

@ -569,15 +569,6 @@ static void
sync_focus_surface (MetaWaylandTabletTool *tool, sync_focus_surface (MetaWaylandTabletTool *tool,
const ClutterEvent *event) 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); 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; 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: * meta_wayland_compositor_get_wayland_display:
* @compositor: The #MetaWaylandCompositor * @compositor: The #MetaWaylandCompositor
@ -1067,19 +1061,13 @@ static void
meta_wayland_compositor_update_focus (MetaWaylandCompositor *compositor, meta_wayland_compositor_update_focus (MetaWaylandCompositor *compositor,
MetaWindow *window) MetaWindow *window)
{ {
MetaContext *context = meta_wayland_compositor_get_context (compositor);
MetaDisplay *display = meta_context_get_display (context);
MetaWindow *focus_window = NULL; MetaWindow *focus_window = NULL;
/* Compositor not ready yet */ /* Compositor not ready yet */
if (!compositor->seat) if (!compositor->seat)
return; return;
if (!display || !meta_display_windows_are_interactable (display)) if (window && meta_window_get_wayland_surface (window))
focus_window = NULL;
else if (!window)
focus_window = NULL;
else if (window && meta_window_get_wayland_surface (window))
focus_window = window; focus_window = window;
else else
meta_topic (META_DEBUG_FOCUS, "Focus change has no effect, because there is no matching wayland surface"); 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 META_EXPORT_TEST
MetaContext * meta_wayland_compositor_get_context (MetaWaylandCompositor *compositor); MetaContext * meta_wayland_compositor_get_context (MetaWaylandCompositor *compositor);
gboolean meta_wayland_compositor_is_grabbed (MetaWaylandCompositor *compositor);
META_EXPORT_TEST META_EXPORT_TEST
MetaWaylandFilterManager * meta_wayland_compositor_get_filter_manager (MetaWaylandCompositor *compositor); MetaWaylandFilterManager * meta_wayland_compositor_get_filter_manager (MetaWaylandCompositor *compositor);