diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2021-09-03 23:49:46 +0200 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2021-11-01 18:27:23 +0100 |
commit | 258d5c7d0389722c5ae9b6f8e6891e82f28caac1 (patch) | |
tree | 464c70b08ddcfc9c0b0c39953519ef6cc80d2fbb | |
parent | 2e92eba642d5e203ed4f699f2d2027ac2fa76c40 (diff) | |
download | mutter-wip/carlosg/frozen-app-behavior.tar.gz |
wayland: Make the pointer leave non-alive surfaceswip/carlosg/frozen-app-behavior
Listen to changes in MetaWindow::is-alive, so that the pointer
can logically leave the surface as soon as that happens. This
helps prevent flooding the client socket while it is stalled.
-rw-r--r-- | src/wayland/meta-wayland-pointer.c | 47 | ||||
-rw-r--r-- | src/wayland/meta-wayland-pointer.h | 1 |
2 files changed, 47 insertions, 1 deletions
diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index abd779ad7..aed72a4e4 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -241,6 +241,18 @@ meta_wayland_pointer_unbind_pointer_client_resource (struct wl_resource *resourc client); } +static MetaWindow * +surface_get_effective_window (MetaWaylandSurface *surface) +{ + MetaWaylandSurface *toplevel; + + toplevel = meta_wayland_surface_get_toplevel (surface); + if (!toplevel) + return NULL; + + return meta_wayland_surface_get_window (toplevel); +} + static void sync_focus_surface (MetaWaylandPointer *pointer) { @@ -270,7 +282,15 @@ sync_focus_surface (MetaWaylandPointer *pointer) case META_EVENT_ROUTE_WAYLAND_POPUP: { const MetaWaylandPointerGrabInterface *interface = pointer->grab->interface; - interface->focus (pointer->grab, pointer->current); + MetaWindow *window = NULL; + + if (pointer->current) + window = surface_get_effective_window (pointer->current); + + if (window && meta_window_get_alive (window)) + interface->focus (pointer->grab, pointer->current); + else + meta_wayland_pointer_set_focus (pointer, NULL); } break; @@ -577,23 +597,48 @@ current_surface_destroyed (MetaWaylandSurface *surface, } static void +current_surface_alive_notify (MetaWindow *window, + GParamSpec *pspec, + MetaWaylandPointer *pointer) +{ + sync_focus_surface (pointer); +} + +static void meta_wayland_pointer_set_current (MetaWaylandPointer *pointer, MetaWaylandSurface *surface) { + MetaWindow *window; + if (pointer->current) { + window = surface_get_effective_window (pointer->current); + g_clear_signal_handler (&pointer->current_surface_destroyed_handler_id, pointer->current); + + if (window) + { + g_clear_signal_handler (&pointer->current_surface_alive_notify_id, + window); + } + pointer->current = NULL; } if (surface) { + window = surface_get_effective_window (surface); + pointer->current = surface; pointer->current_surface_destroyed_handler_id = g_signal_connect (surface, "destroy", G_CALLBACK (current_surface_destroyed), pointer); + pointer->current_surface_alive_notify_id = + g_signal_connect (window, "notify::is-alive", + G_CALLBACK (current_surface_alive_notify), + pointer); } } diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h index 5eda5276f..ae18b6a47 100644 --- a/src/wayland/meta-wayland-pointer.h +++ b/src/wayland/meta-wayland-pointer.h @@ -86,6 +86,7 @@ struct _MetaWaylandPointer ClutterInputDevice *device; MetaWaylandSurface *current; gulong current_surface_destroyed_handler_id; + gulong current_surface_alive_notify_id; guint32 button_count; }; |