wayland: Handle event interface changes during focus synchronization
Currently, we don't handle too well the removal of a MetaWaylandEventInterface during meta_wayland_event_interface_invalidate_all_focus(), since the MetaWaylandEventInterface may be freed at an intermediate point in that function while handling the focus change for all input devices. Turn this invalidate_all_focus() function into a MetaWaylandInput method, and always ensure to use the currently effective MetaWaylandEventInterface when resetting the focus for each device. This fixes the situation through handling reentrancy naturally, a focus sync (say, triggered by a grab) would reset a device focus (say, pointer), which would remove an event interface (say, a pointer constraint), which would invalidate_all_focus() again underneath using the new effective MetaWaylandEventInterface. When that is done, the initial invalidate_all_focus() call would re-apply the same focus to the same currently effective MetaWaylandEventInterface, resulting in a no-op for the remainder of the function. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3618>
This commit is contained in:
parent
7fc49f742b
commit
1d5676bc9a
@ -137,9 +137,10 @@ meta_wayland_event_handler_invalidate_focus (MetaWaylandEventHandler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_wayland_event_handler_invalidate_all_focus (MetaWaylandEventHandler *handler)
|
meta_wayland_input_invalidate_all_focus (MetaWaylandInput *input)
|
||||||
{
|
{
|
||||||
MetaWaylandSeat *seat = handler->input->seat;
|
MetaWaylandEventHandler *handler;
|
||||||
|
MetaWaylandSeat *seat = input->seat;
|
||||||
ClutterSeat *clutter_seat =
|
ClutterSeat *clutter_seat =
|
||||||
clutter_backend_get_default_seat (clutter_get_default_backend ());
|
clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||||
ClutterInputDevice *device;
|
ClutterInputDevice *device;
|
||||||
@ -149,12 +150,14 @@ meta_wayland_event_handler_invalidate_all_focus (MetaWaylandEventHandler *handle
|
|||||||
if (meta_wayland_seat_has_pointer (seat))
|
if (meta_wayland_seat_has_pointer (seat))
|
||||||
{
|
{
|
||||||
device = clutter_seat_get_pointer (clutter_seat);
|
device = clutter_seat_get_pointer (clutter_seat);
|
||||||
|
handler = wl_container_of (input->event_handler_list.next, handler, link);
|
||||||
meta_wayland_event_handler_invalidate_focus (handler, device, NULL);
|
meta_wayland_event_handler_invalidate_focus (handler, device, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meta_wayland_seat_has_keyboard (seat))
|
if (meta_wayland_seat_has_keyboard (seat))
|
||||||
{
|
{
|
||||||
device = clutter_seat_get_keyboard (clutter_seat);
|
device = clutter_seat_get_keyboard (clutter_seat);
|
||||||
|
handler = wl_container_of (input->event_handler_list.next, handler, link);
|
||||||
meta_wayland_event_handler_invalidate_focus (handler, device, NULL);
|
meta_wayland_event_handler_invalidate_focus (handler, device, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,11 +166,17 @@ meta_wayland_event_handler_invalidate_all_focus (MetaWaylandEventHandler *handle
|
|||||||
|
|
||||||
g_hash_table_iter_init (&iter, seat->tablet_seat->tablets);
|
g_hash_table_iter_init (&iter, seat->tablet_seat->tablets);
|
||||||
while (g_hash_table_iter_next (&iter, (gpointer*) &device, NULL))
|
while (g_hash_table_iter_next (&iter, (gpointer*) &device, NULL))
|
||||||
meta_wayland_event_handler_invalidate_focus (handler, device, NULL);
|
{
|
||||||
|
handler = wl_container_of (input->event_handler_list.next, handler, link);
|
||||||
|
meta_wayland_event_handler_invalidate_focus (handler, device, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
g_hash_table_iter_init (&iter, seat->tablet_seat->pads);
|
g_hash_table_iter_init (&iter, seat->tablet_seat->pads);
|
||||||
while (g_hash_table_iter_next (&iter, (gpointer*) &device, NULL))
|
while (g_hash_table_iter_next (&iter, (gpointer*) &device, NULL))
|
||||||
meta_wayland_event_handler_invalidate_focus (handler, device, NULL);
|
{
|
||||||
|
handler = wl_container_of (input->event_handler_list.next, handler, link);
|
||||||
|
meta_wayland_event_handler_invalidate_focus (handler, device, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -248,7 +257,7 @@ meta_wayland_input_sync_focus (MetaWaylandInput *input)
|
|||||||
|
|
||||||
g_assert (!wl_list_empty (&input->event_handler_list));
|
g_assert (!wl_list_empty (&input->event_handler_list));
|
||||||
handler = wl_container_of (input->event_handler_list.next, handler, link);
|
handler = wl_container_of (input->event_handler_list.next, handler, link);
|
||||||
meta_wayland_event_handler_invalidate_all_focus (handler);
|
meta_wayland_input_invalidate_all_focus (input);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -299,7 +308,7 @@ meta_wayland_input_attach_event_handler (MetaWaylandInput *input,
|
|||||||
input);
|
input);
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_wayland_event_handler_invalidate_all_focus (handler);
|
meta_wayland_input_invalidate_all_focus (input);
|
||||||
|
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
@ -331,7 +340,7 @@ meta_wayland_input_detach_event_handler (MetaWaylandInput *input,
|
|||||||
wl_container_of (input->event_handler_list.next,
|
wl_container_of (input->event_handler_list.next,
|
||||||
head, link);
|
head, link);
|
||||||
|
|
||||||
meta_wayland_event_handler_invalidate_all_focus (head);
|
meta_wayland_input_invalidate_all_focus (input);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input->grab && !should_be_grabbed (input))
|
if (input->grab && !should_be_grabbed (input))
|
||||||
|
Loading…
Reference in New Issue
Block a user