mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-02-03 12:30:28 +01:00
Merge branch 'defunct-surfaces-fix' into 'main'
Fixes for xdg-shell when clients are tearing down See merge request wayland/weston!1960
This commit is contained in:
commit
4d3c600b39
5 changed files with 141 additions and 57 deletions
|
|
@ -324,13 +324,15 @@ weston_desktop_surface_add_resource(struct weston_desktop_surface *surface,
|
|||
weston_desktop_client_get_client(surface->client);
|
||||
struct wl_resource *resource;
|
||||
|
||||
if (!client_resource)
|
||||
return NULL;
|
||||
|
||||
resource = wl_resource_create(wl_client,
|
||||
interface,
|
||||
wl_resource_get_version(client_resource),
|
||||
id);
|
||||
if (resource == NULL) {
|
||||
wl_client_post_no_memory(wl_client);
|
||||
weston_desktop_surface_destroy(surface);
|
||||
return NULL;
|
||||
}
|
||||
if (destroy == NULL)
|
||||
|
|
|
|||
|
|
@ -674,9 +674,10 @@ weston_desktop_xdg_toplevel_committed(struct weston_desktop_xdg_toplevel *toplev
|
|||
struct wl_resource *client_resource =
|
||||
weston_desktop_client_get_resource(client);
|
||||
|
||||
wl_resource_post_error(client_resource,
|
||||
ZXDG_SHELL_V6_ERROR_INVALID_SURFACE_STATE,
|
||||
"xdg_surface buffer does not match the configured state");
|
||||
if (client_resource)
|
||||
wl_resource_post_error(client_resource,
|
||||
ZXDG_SHELL_V6_ERROR_INVALID_SURFACE_STATE,
|
||||
"xdg_surface buffer does not match the configured state");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -856,9 +857,10 @@ weston_desktop_xdg_popup_protocol_grab(struct wl_client *wl_client,
|
|||
struct wl_resource *client_resource =
|
||||
weston_desktop_client_get_resource(client);
|
||||
|
||||
wl_resource_post_error(client_resource,
|
||||
ZXDG_SHELL_V6_ERROR_NOT_THE_TOPMOST_POPUP,
|
||||
"xdg_popup was not created on the topmost popup");
|
||||
if (client_resource)
|
||||
wl_resource_post_error(client_resource,
|
||||
ZXDG_SHELL_V6_ERROR_NOT_THE_TOPMOST_POPUP,
|
||||
"xdg_popup was not created on the topmost popup");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -934,9 +936,10 @@ weston_desktop_xdg_popup_destroy(struct weston_desktop_xdg_popup *popup)
|
|||
struct wl_resource *client_resource =
|
||||
weston_desktop_client_get_resource(client);
|
||||
|
||||
wl_resource_post_error(client_resource,
|
||||
ZXDG_SHELL_V6_ERROR_NOT_THE_TOPMOST_POPUP,
|
||||
"xdg_popup was destroyed while it was not the topmost popup.");
|
||||
if (client_resource)
|
||||
wl_resource_post_error(client_resource,
|
||||
ZXDG_SHELL_V6_ERROR_NOT_THE_TOPMOST_POPUP,
|
||||
"xdg_popup was destroyed while it was not the topmost popup.");
|
||||
}
|
||||
|
||||
weston_desktop_surface_popup_ungrab(popup->base.desktop_surface,
|
||||
|
|
@ -1257,9 +1260,11 @@ weston_desktop_xdg_surface_protocol_ack_configure(struct wl_client *wl_client,
|
|||
weston_desktop_surface_get_client(dsurface);
|
||||
struct wl_resource *client_resource =
|
||||
weston_desktop_client_get_resource(client);
|
||||
wl_resource_post_error(client_resource,
|
||||
ZXDG_SHELL_V6_ERROR_INVALID_SURFACE_STATE,
|
||||
"Wrong configure serial: %u", serial);
|
||||
|
||||
if (client_resource)
|
||||
wl_resource_post_error(client_resource,
|
||||
ZXDG_SHELL_V6_ERROR_INVALID_SURFACE_STATE,
|
||||
"Wrong configure serial: %u", serial);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1286,9 +1291,13 @@ weston_desktop_xdg_surface_ping(struct weston_desktop_surface *dsurface,
|
|||
{
|
||||
struct weston_desktop_client *client =
|
||||
weston_desktop_surface_get_client(dsurface);
|
||||
struct wl_resource *client_resource =
|
||||
weston_desktop_client_get_resource(client);
|
||||
|
||||
zxdg_shell_v6_send_ping(weston_desktop_client_get_resource(client),
|
||||
serial);
|
||||
if (!client_resource)
|
||||
return;
|
||||
|
||||
zxdg_shell_v6_send_ping(client_resource, serial);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1492,13 +1501,18 @@ weston_desktop_xdg_shell_protocol_get_xdg_surface(struct wl_client *wl_client,
|
|||
&zxdg_surface_v6_interface,
|
||||
&weston_desktop_xdg_surface_implementation,
|
||||
id, weston_desktop_xdg_surface_resource_destroy);
|
||||
if (surface->resource == NULL)
|
||||
if (surface->resource == NULL) {
|
||||
weston_desktop_surface_destroy(surface->desktop_surface);
|
||||
free(surface);
|
||||
return;
|
||||
}
|
||||
|
||||
if (weston_surface_has_content(wsurface)) {
|
||||
wl_resource_post_error(surface->resource,
|
||||
ZXDG_SURFACE_V6_ERROR_UNCONFIGURED_BUFFER,
|
||||
"xdg_surface must not have a buffer at creation");
|
||||
weston_desktop_surface_destroy(surface->desktop_surface);
|
||||
free(surface);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -1514,8 +1528,27 @@ weston_desktop_xdg_shell_protocol_pong(struct wl_client *wl_client,
|
|||
weston_desktop_client_pong(client, serial);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_xdg_shell_protocol_destroy(struct wl_client *wl_client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
struct weston_desktop_client *client =
|
||||
wl_resource_get_user_data(resource);
|
||||
struct wl_list *surface_list =
|
||||
weston_desktop_client_get_surface_list(client);
|
||||
|
||||
if (!wl_list_empty(surface_list)) {
|
||||
wl_resource_post_error(resource,
|
||||
ZXDG_SHELL_V6_ERROR_DEFUNCT_SURFACES,
|
||||
"xdg_wm_base being destroyed before child surfaces");
|
||||
return;
|
||||
}
|
||||
|
||||
weston_desktop_destroy_request(wl_client, resource);
|
||||
}
|
||||
|
||||
static const struct zxdg_shell_v6_interface weston_desktop_xdg_shell_implementation = {
|
||||
.destroy = weston_desktop_destroy_request,
|
||||
.destroy = weston_desktop_xdg_shell_protocol_destroy,
|
||||
.create_positioner = weston_desktop_xdg_shell_protocol_create_positioner,
|
||||
.get_xdg_surface = weston_desktop_xdg_shell_protocol_get_xdg_surface,
|
||||
.pong = weston_desktop_xdg_shell_protocol_pong,
|
||||
|
|
|
|||
|
|
@ -1082,6 +1082,10 @@ weston_desktop_xdg_toplevel_committed(struct weston_desktop_xdg_toplevel *toplev
|
|||
{
|
||||
struct weston_surface *wsurface =
|
||||
weston_desktop_surface_get_surface(toplevel->base.desktop_surface);
|
||||
struct weston_desktop_client *client =
|
||||
weston_desktop_surface_get_client(toplevel->base.desktop_surface);
|
||||
struct wl_resource *client_resource =
|
||||
weston_desktop_client_get_resource(client);
|
||||
|
||||
if (!weston_surface_has_content(wsurface) && !toplevel->added) {
|
||||
weston_desktop_xdg_toplevel_ensure_added(toplevel);
|
||||
|
|
@ -1101,36 +1105,28 @@ weston_desktop_xdg_toplevel_committed(struct weston_desktop_xdg_toplevel *toplev
|
|||
if (toplevel->next.state.maximized &&
|
||||
(toplevel->next.size.width != geometry.width ||
|
||||
toplevel->next.size.height != geometry.height)) {
|
||||
struct weston_desktop_client *client =
|
||||
weston_desktop_surface_get_client(toplevel->base.desktop_surface);
|
||||
struct wl_resource *client_resource =
|
||||
weston_desktop_client_get_resource(client);
|
||||
|
||||
wl_resource_post_error(client_resource,
|
||||
XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE,
|
||||
"xdg_surface geometry (%" PRIi32 " x %" PRIi32 ") "
|
||||
"does not match the configured maximized state (%" PRIi32 " x %" PRIi32 ")",
|
||||
geometry.width, geometry.height,
|
||||
toplevel->next.size.width,
|
||||
toplevel->next.size.height);
|
||||
if (client_resource)
|
||||
wl_resource_post_error(client_resource,
|
||||
XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE,
|
||||
"xdg_surface geometry (%" PRIi32 " x %" PRIi32 ") "
|
||||
"does not match the configured maximized state (%" PRIi32 " x %" PRIi32 ")",
|
||||
geometry.width, geometry.height,
|
||||
toplevel->next.size.width,
|
||||
toplevel->next.size.height);
|
||||
return;
|
||||
}
|
||||
|
||||
if (toplevel->next.state.fullscreen &&
|
||||
(toplevel->next.size.width < geometry.width ||
|
||||
toplevel->next.size.height < geometry.height)) {
|
||||
struct weston_desktop_client *client =
|
||||
weston_desktop_surface_get_client(toplevel->base.desktop_surface);
|
||||
struct wl_resource *client_resource =
|
||||
weston_desktop_client_get_resource(client);
|
||||
|
||||
wl_resource_post_error(client_resource,
|
||||
XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE,
|
||||
"xdg_surface geometry (%" PRIi32 " x %" PRIi32 ") "
|
||||
"is larger than the configured fullscreen state (%" PRIi32 " x %" PRIi32 ")",
|
||||
geometry.width, geometry.height,
|
||||
toplevel->next.size.width,
|
||||
toplevel->next.size.height);
|
||||
if (client_resource)
|
||||
wl_resource_post_error(client_resource,
|
||||
XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE,
|
||||
"xdg_surface geometry (%" PRIi32 " x %" PRIi32 ") "
|
||||
"is larger than the configured fullscreen state (%" PRIi32 " x %" PRIi32 ")",
|
||||
geometry.width, geometry.height,
|
||||
toplevel->next.size.width,
|
||||
toplevel->next.size.height);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1299,9 +1295,10 @@ weston_desktop_xdg_popup_protocol_grab(struct wl_client *wl_client,
|
|||
struct wl_resource *client_resource =
|
||||
weston_desktop_client_get_resource(client);
|
||||
|
||||
wl_resource_post_error(client_resource,
|
||||
XDG_WM_BASE_ERROR_NOT_THE_TOPMOST_POPUP,
|
||||
"xdg_popup was not created on the topmost popup");
|
||||
if (client_resource)
|
||||
wl_resource_post_error(client_resource,
|
||||
XDG_WM_BASE_ERROR_NOT_THE_TOPMOST_POPUP,
|
||||
"xdg_popup was not created on the topmost popup");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1437,9 +1434,10 @@ weston_desktop_xdg_popup_destroy(struct weston_desktop_xdg_popup *popup)
|
|||
struct wl_resource *client_resource =
|
||||
weston_desktop_client_get_resource(client);
|
||||
|
||||
wl_resource_post_error(client_resource,
|
||||
XDG_WM_BASE_ERROR_NOT_THE_TOPMOST_POPUP,
|
||||
"xdg_popup was destroyed while it was not the topmost popup.");
|
||||
if (client_resource)
|
||||
wl_resource_post_error(client_resource,
|
||||
XDG_WM_BASE_ERROR_NOT_THE_TOPMOST_POPUP,
|
||||
"xdg_popup was destroyed while it was not the topmost popup.");
|
||||
}
|
||||
|
||||
weston_desktop_surface_popup_ungrab(popup->base.desktop_surface,
|
||||
|
|
@ -1830,9 +1828,11 @@ weston_desktop_xdg_surface_protocol_ack_configure(struct wl_client *wl_client,
|
|||
weston_desktop_surface_get_client(dsurface);
|
||||
struct wl_resource *client_resource =
|
||||
weston_desktop_client_get_resource(client);
|
||||
wl_resource_post_error(client_resource,
|
||||
XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE,
|
||||
"Wrong configure serial: %u", serial);
|
||||
|
||||
if (client_resource)
|
||||
wl_resource_post_error(client_resource,
|
||||
XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE,
|
||||
"Wrong configure serial: %u", serial);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1859,9 +1859,13 @@ weston_desktop_xdg_surface_ping(struct weston_desktop_surface *dsurface,
|
|||
{
|
||||
struct weston_desktop_client *client =
|
||||
weston_desktop_surface_get_client(dsurface);
|
||||
struct wl_resource *client_resource =
|
||||
weston_desktop_client_get_resource(client);
|
||||
|
||||
xdg_wm_base_send_ping(weston_desktop_client_get_resource(client),
|
||||
serial);
|
||||
if (!client_resource)
|
||||
return;
|
||||
|
||||
xdg_wm_base_send_ping(client_resource, serial);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2087,8 +2091,11 @@ weston_desktop_xdg_shell_protocol_get_xdg_surface(struct wl_client *wl_client,
|
|||
&xdg_surface_interface,
|
||||
&weston_desktop_xdg_surface_implementation,
|
||||
id, weston_desktop_xdg_surface_resource_destroy);
|
||||
if (surface->resource == NULL)
|
||||
if (surface->resource == NULL) {
|
||||
weston_desktop_surface_destroy(surface->desktop_surface);
|
||||
free(surface);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2102,8 +2109,27 @@ weston_desktop_xdg_shell_protocol_pong(struct wl_client *wl_client,
|
|||
weston_desktop_client_pong(client, serial);
|
||||
}
|
||||
|
||||
static void
|
||||
weston_desktop_xdg_shell_protocol_destroy(struct wl_client *wl_client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
struct weston_desktop_client *client =
|
||||
wl_resource_get_user_data(resource);
|
||||
struct wl_list *surface_list =
|
||||
weston_desktop_client_get_surface_list(client);
|
||||
|
||||
if (!wl_list_empty(surface_list)) {
|
||||
wl_resource_post_error(resource,
|
||||
XDG_WM_BASE_ERROR_DEFUNCT_SURFACES,
|
||||
"xdg_wm_base being destroyed before child surfaces");
|
||||
return;
|
||||
}
|
||||
|
||||
weston_desktop_destroy_request(wl_client, resource);
|
||||
}
|
||||
|
||||
static const struct xdg_wm_base_interface weston_desktop_xdg_shell_implementation = {
|
||||
.destroy = weston_desktop_destroy_request,
|
||||
.destroy = weston_desktop_xdg_shell_protocol_destroy,
|
||||
.create_positioner = weston_desktop_xdg_shell_protocol_create_positioner,
|
||||
.get_xdg_surface = weston_desktop_xdg_shell_protocol_get_xdg_surface,
|
||||
.pong = weston_desktop_xdg_shell_protocol_pong,
|
||||
|
|
|
|||
|
|
@ -372,9 +372,9 @@ if get_option('shell-desktop')
|
|||
],
|
||||
},
|
||||
{
|
||||
'name': 'xdg-shell-initial-commit',
|
||||
'name': 'xdg-shell-test',
|
||||
'sources': [
|
||||
'xdg-shell-intial-commit.c',
|
||||
'xdg-shell-test.c',
|
||||
xdg_shell_client_protocol_h,
|
||||
xdg_shell_protocol_c,
|
||||
],
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ fixture_setup(struct weston_test_harness *harness)
|
|||
setup.renderer = WESTON_RENDERER_PIXMAN;
|
||||
setup.width = 320;
|
||||
setup.height = 240;
|
||||
setup.shell = SHELL_DESKTOP;
|
||||
setup.shell = SHELL_TEST_DESKTOP;
|
||||
setup.logging_scopes = "proto,log,test-harness-plugin";
|
||||
setup.refresh = HIGHEST_OUTPUT_REFRESH;
|
||||
|
||||
|
|
@ -182,3 +182,26 @@ TEST(initial_commit_without_a_buffer_subsurface)
|
|||
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
TEST(defunct_surfaces)
|
||||
{
|
||||
struct xdg_client *xdg_client = create_xdg_client();
|
||||
struct xdg_surface_data *xdg_surface = create_xdg_surface(xdg_client);
|
||||
|
||||
xdg_surface_make_toplevel(xdg_surface, "weston.test", "xdg-test");
|
||||
xdg_surface_wait_configure(xdg_surface);
|
||||
|
||||
xdg_surface_commit_solid(xdg_surface, 255, 128, 255);
|
||||
wl_display_roundtrip(xdg_client->client->wl_display);
|
||||
|
||||
/* Destroy xdg_wm_base without destroying its children. */
|
||||
xdg_wm_base_destroy(xdg_client->xdg_wm_base);
|
||||
expect_protocol_error(xdg_client->client, NULL, XDG_WM_BASE_ERROR_DEFUNCT_SURFACES);
|
||||
|
||||
destroy_xdg_surface(xdg_surface);
|
||||
|
||||
client_destroy(xdg_client->client);
|
||||
free(xdg_client);
|
||||
|
||||
return RESULT_OK;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue