wayland/surface: Prepare for decoupled surface & resource lifetimes

Need to deal with surface->resource == NULL and
surface->pending_state == NULL in some places.

v2:
* Avoid expanding conditions to multiple lines.
  (Georges Basile Stavracas Neto)
v3:
* Use a single bailout condition in meta_wayland_client_owns_window as
  well.
v4:
* Remove spare empty line in meta_wayland_surface_apply_state.
  (Robert Mader)
* Add wl_resource_post_error calls in xdg-shell request handlers.
  (Robert Mader)
* Drop checks in functions which can only be called if there's a valid
  resource.
* Drop more checks which are unnecessary due to leaving the
  SURFACE_DESTROY signal emission in wl_surface_destructor later.
v5:
* Move resource = surface->resource assignments to if (!resource) tests.
  (Jonas Ådahl)
v6:
* Fix style issue per check-style.py.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
This commit is contained in:
Michel Dänzer 2021-07-29 18:14:20 +02:00 committed by Michel Dänzer
parent a99198de83
commit 6379e54847
9 changed files with 98 additions and 26 deletions

View File

@ -298,7 +298,7 @@ meta_wayland_client_owns_window (MetaWaylandClient *client,
g_return_val_if_fail (client->process_running, FALSE);
surface = meta_window_get_wayland_surface (window);
if (surface == NULL)
if (surface == NULL || surface->resource == NULL)
return FALSE;
return wl_resource_get_client (surface->resource) == client->wayland_client;

View File

@ -769,10 +769,13 @@ meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
&error))
{
g_warning ("Could not import pending buffer: %s", error->message);
wl_resource_post_error (surface->resource, WL_DISPLAY_ERROR_NO_MEMORY,
"Failed to attach buffer to surface %i: %s",
wl_resource_get_id (surface->resource),
error->message);
if (surface->resource)
{
wl_resource_post_error (surface->resource, WL_DISPLAY_ERROR_NO_MEMORY,
"Failed to attach buffer to surface %i: %s",
wl_resource_get_id (surface->resource),
error->message);
}
g_error_free (error);
goto cleanup;
}
@ -1330,21 +1333,24 @@ static void
surface_entered_output (MetaWaylandSurface *surface,
MetaWaylandOutput *wayland_output)
{
const GList *l;
g_signal_connect (wayland_output, "output-destroyed",
G_CALLBACK (handle_output_destroyed),
surface);
for (l = meta_wayland_output_get_resources (wayland_output); l; l = l->next)
if (surface->resource)
{
struct wl_resource *resource = l->data;
const GList *l;
if (wl_resource_get_client (resource) !=
wl_resource_get_client (surface->resource))
continue;
for (l = meta_wayland_output_get_resources (wayland_output); l; l = l->next)
{
struct wl_resource *resource = l->data;
wl_surface_send_enter (surface->resource, resource);
if (wl_resource_get_client (resource) !=
wl_resource_get_client (surface->resource))
continue;
wl_surface_send_enter (surface->resource, resource);
}
}
g_signal_connect (wayland_output, "output-bound",
@ -1366,6 +1372,9 @@ surface_left_output (MetaWaylandSurface *surface,
G_CALLBACK (handle_output_bound),
surface);
if (!surface->resource)
return;
for (l = meta_wayland_output_get_resources (wayland_output); l; l = l->next)
{
struct wl_resource *resource = l->data;

View File

@ -466,7 +466,7 @@ meta_wayland_tablet_pad_set_focus (MetaWaylandTabletPad *pad,
tablet = meta_wayland_tablet_seat_lookup_paired_tablet (pad->tablet_seat,
pad);
if (tablet != NULL && surface != NULL)
if (tablet != NULL && surface != NULL && surface->resource != NULL)
{
struct wl_client *client;

View File

@ -371,7 +371,7 @@ meta_wayland_text_input_set_focus (MetaWaylandTextInput *text_input,
text_input->surface = NULL;
}
if (surface)
if (surface && surface->resource)
{
struct wl_resource *focus_surface_resource;

View File

@ -227,7 +227,7 @@ meta_wayland_touch_update (MetaWaylandTouch *touch,
if (META_IS_SURFACE_ACTOR_WAYLAND (actor))
surface = meta_surface_actor_wayland_get_surface (META_SURFACE_ACTOR_WAYLAND (actor));
if (!surface)
if (!surface || !surface->resource)
return;
touch_info = touch_get_info (touch, sequence, TRUE);

View File

@ -46,10 +46,13 @@ wp_viewport_destructor (struct wl_resource *resource)
g_clear_signal_handler (&surface->viewport.destroy_handler_id, surface);
pending = meta_wayland_surface_get_pending_state (surface);
pending->viewport_src_rect.size.width = -1;
pending->viewport_dst_width = -1;
pending->has_new_viewport_src_rect = TRUE;
pending->has_new_viewport_dst_size = TRUE;
if (pending)
{
pending->viewport_src_rect.size.width = -1;
pending->viewport_dst_width = -1;
pending->has_new_viewport_src_rect = TRUE;
pending->has_new_viewport_dst_size = TRUE;
}
surface->viewport.resource = NULL;
}
@ -103,6 +106,14 @@ wp_viewport_set_source (struct wl_client *client,
MetaWaylandSurfaceState *pending;
pending = meta_wayland_surface_get_pending_state (surface);
if (!pending)
{
wl_resource_post_error (resource,
WP_VIEWPORT_ERROR_NO_SURFACE,
"wl_surface for this viewport no longer exists");
return;
}
pending->viewport_src_rect.origin.x = new_x;
pending->viewport_src_rect.origin.y = new_y;
pending->viewport_src_rect.size.width = new_width;
@ -142,6 +153,14 @@ wp_viewport_set_destination (struct wl_client *client,
MetaWaylandSurfaceState *pending;
pending = meta_wayland_surface_get_pending_state (surface);
if (!pending)
{
wl_resource_post_error (resource,
WP_VIEWPORT_ERROR_NO_SURFACE,
"wl_surface for this viewport no longer exists");
return;
}
pending->viewport_dst_width = dst_width;
pending->viewport_dst_height = dst_height;
pending->has_new_viewport_dst_size = TRUE;

View File

@ -391,6 +391,14 @@ xdg_toplevel_set_max_size (struct wl_client *client,
pending = meta_wayland_surface_get_pending_state (surface);
if (!pending)
{
wl_resource_post_error (resource,
XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE,
"underlying wl_surface already destroyed");
return;
}
pending->has_new_max_size = TRUE;
pending->new_max_width = width;
pending->new_max_height = height;
@ -416,6 +424,14 @@ xdg_toplevel_set_min_size (struct wl_client *client,
pending = meta_wayland_surface_get_pending_state (surface);
if (!pending)
{
wl_resource_post_error (resource,
XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE,
"underlying wl_surface already destroyed");
return;
}
pending->has_new_min_size = TRUE;
pending->new_min_width = width;
pending->new_min_height = height;
@ -873,9 +889,12 @@ meta_wayland_xdg_toplevel_post_apply_state (MetaWaylandSurfaceRole *surface_rol
}
else
{
wl_resource_post_error (surface->resource,
XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE,
"Invalid min/max size");
if (surface->resource)
{
wl_resource_post_error (surface->resource,
XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE,
"Invalid min/max size");
}
}
}
}
@ -1556,6 +1575,14 @@ xdg_surface_set_window_geometry (struct wl_client *client,
}
pending = meta_wayland_surface_get_pending_state (surface);
if (!pending)
{
wl_resource_post_error (resource,
XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE,
"underlying wl_surface already destroyed");
return;
}
pending->has_new_geometry = TRUE;
pending->new_geometry.x = x;
pending->new_geometry.y = y;
@ -1572,6 +1599,14 @@ xdg_surface_ack_configure (struct wl_client *client,
MetaWaylandSurfaceState *pending;
pending = meta_wayland_surface_get_pending_state (surface);
if (!pending)
{
wl_resource_post_error (resource,
XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE,
"underlying wl_surface already destroyed");
return;
}
pending->has_acked_configure_serial = TRUE;
pending->acked_configure_serial = serial;
}

View File

@ -162,7 +162,11 @@ static void
meta_window_wayland_kill (MetaWindow *window)
{
MetaWaylandSurface *surface = meta_window_get_wayland_surface (window);
struct wl_resource *resource = surface->resource;
struct wl_resource *resource;
resource = surface->resource;
if (!resource)
return;
/* Send the client an unrecoverable error to kill the client. */
wl_resource_post_error (resource,
@ -659,9 +663,13 @@ static pid_t
meta_window_wayland_get_client_pid (MetaWindow *window)
{
MetaWaylandSurface *surface = meta_window_get_wayland_surface (window);
struct wl_resource *resource = surface->resource;
struct wl_resource *resource;
pid_t pid;
resource = surface->resource;
if (!resource)
return 0;
wl_client_get_credentials (wl_resource_get_client (resource), &pid, NULL, NULL);
return pid;
}

View File

@ -137,7 +137,8 @@ meta_xwayland_is_xwayland_surface (MetaWaylandSurface *surface)
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
MetaXWaylandManager *manager = &compositor->xwayland_manager;
return wl_resource_get_client (surface->resource) == manager->client;
return surface->resource != NULL &&
wl_resource_get_client (surface->resource) == manager->client;
}
static gboolean