diff --git a/include/wlr/types/wlr_compositor.h b/include/wlr/types/wlr_compositor.h index 9331e8af6..4c7b8f07c 100644 --- a/include/wlr/types/wlr_compositor.h +++ b/include/wlr/types/wlr_compositor.h @@ -250,8 +250,6 @@ struct wlr_surface { int buffer_width, buffer_height; } previous; - bool unmap_commit; - bool opaque; bool handling_commit; diff --git a/include/wlr/types/wlr_layer_shell_v1.h b/include/wlr/types/wlr_layer_shell_v1.h index 4234aa72e..5fa75bb4e 100644 --- a/include/wlr/types/wlr_layer_shell_v1.h +++ b/include/wlr/types/wlr_layer_shell_v1.h @@ -70,6 +70,10 @@ struct wlr_layer_surface_v1_state { uint32_t configure_serial; uint32_t actual_width, actual_height; + + struct { + bool initial_commit; + } WLR_PRIVATE; }; struct wlr_layer_surface_v1_configure { @@ -118,6 +122,8 @@ struct wlr_layer_surface_v1 { struct { struct wlr_surface_synced synced; + + bool client_mapped; } WLR_PRIVATE; }; diff --git a/include/wlr/types/wlr_xdg_shell.h b/include/wlr/types/wlr_xdg_shell.h index 517d77442..bc37999e5 100644 --- a/include/wlr/types/wlr_xdg_shell.h +++ b/include/wlr/types/wlr_xdg_shell.h @@ -258,6 +258,10 @@ struct wlr_xdg_surface_state { struct wlr_box geometry; uint32_t configure_serial; + + struct { + bool initial_commit; + } WLR_PRIVATE; }; /** @@ -319,6 +323,8 @@ struct wlr_xdg_surface { struct wlr_surface_synced synced; struct wl_listener role_resource_destroy; + + bool client_mapped; } WLR_PRIVATE; }; diff --git a/types/wlr_compositor.c b/types/wlr_compositor.c index 6b31ab857..46881e7c6 100644 --- a/types/wlr_compositor.c +++ b/types/wlr_compositor.c @@ -515,10 +515,7 @@ static void surface_commit_state(struct wlr_surface *surface, bool invalid_buffer = next->committed & WLR_SURFACE_STATE_BUFFER; if (invalid_buffer && next->buffer == NULL) { - surface->unmap_commit = surface->mapped; wlr_surface_unmap(surface); - } else { - surface->unmap_commit = false; } surface_update_damage(&surface->buffer_damage, &surface->current, next); diff --git a/types/wlr_layer_shell_v1.c b/types/wlr_layer_shell_v1.c index 2d8384981..de7b195c3 100644 --- a/types/wlr_layer_shell_v1.c +++ b/types/wlr_layer_shell_v1.c @@ -33,6 +33,7 @@ static void layer_surface_configure_destroy( static void layer_surface_reset(struct wlr_layer_surface_v1 *surface) { surface->configured = false; surface->initialized = false; + surface->client_mapped = false; struct wlr_xdg_popup *popup, *popup_tmp; wl_list_for_each_safe(popup, popup_tmp, &surface->popups, link) { @@ -349,7 +350,9 @@ static void layer_surface_role_client_commit(struct wlr_surface *wlr_surface) { return; } - if (wlr_surface_state_has_buffer(&wlr_surface->pending) && !surface->configured) { + bool has_pending_buffer = wlr_surface_state_has_buffer(&wlr_surface->pending); + + if (has_pending_buffer && !surface->configured) { wlr_surface_reject_pending(wlr_surface, surface->resource, ZWLR_LAYER_SHELL_V1_ERROR_ALREADY_CONSTRUCTED, "layer_surface has never been configured"); @@ -380,7 +383,18 @@ static void layer_surface_role_client_commit(struct wlr_surface *wlr_surface) { wlr_surface_reject_pending(wlr_surface, surface->resource, ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_EXCLUSIVE_EDGE, "exclusive edge is invalid given the surface anchors"); + return; } + + if (surface->client_mapped && !has_pending_buffer) { + layer_surface_reset(surface); + surface->pending.initial_commit = false; + } else { + surface->pending.initial_commit = !surface->initialized; + surface->initialized = true; + } + + surface->client_mapped = has_pending_buffer; } static void layer_surface_role_commit(struct wlr_surface *wlr_surface) { @@ -390,15 +404,7 @@ static void layer_surface_role_commit(struct wlr_surface *wlr_surface) { return; } - if (surface->surface->unmap_commit) { - layer_surface_reset(surface); - - assert(!surface->initialized); - surface->initial_commit = false; - } else { - surface->initial_commit = !surface->initialized; - surface->initialized = true; - } + surface->initial_commit = surface->current.initial_commit && surface->initialized; if (wlr_surface_has_buffer(wlr_surface)) { wlr_surface_map(wlr_surface); diff --git a/types/xdg_shell/wlr_xdg_surface.c b/types/xdg_shell/wlr_xdg_surface.c index 8a252d2f8..06dcd713c 100644 --- a/types/xdg_shell/wlr_xdg_surface.c +++ b/types/xdg_shell/wlr_xdg_surface.c @@ -26,6 +26,7 @@ static void xdg_surface_configure_destroy( static void reset_xdg_surface(struct wlr_xdg_surface *surface) { surface->configured = false; surface->initialized = false; + surface->client_mapped = false; struct wlr_xdg_popup *popup, *popup_tmp; wl_list_for_each_safe(popup, popup_tmp, &surface->popups, link) { @@ -283,7 +284,9 @@ static void xdg_surface_role_client_commit(struct wlr_surface *wlr_surface) { struct wlr_xdg_surface *surface = wlr_xdg_surface_try_from_wlr_surface(wlr_surface); assert(surface != NULL); - if (wlr_surface_state_has_buffer(&wlr_surface->pending) && !surface->configured) { + bool has_pending_buffer = wlr_surface_state_has_buffer(&wlr_surface->pending); + + if (has_pending_buffer && !surface->configured) { wlr_surface_reject_pending(wlr_surface, surface->resource, XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER, "xdg_surface has never been configured"); return; @@ -310,22 +313,24 @@ static void xdg_surface_role_client_commit(struct wlr_surface *wlr_surface) { } break; } + + if (surface->client_mapped && !has_pending_buffer) { + reset_xdg_surface_role_object(surface); + reset_xdg_surface(surface); + surface->pending.initial_commit = false; + } else { + surface->pending.initial_commit = !surface->initialized; + surface->initialized = true; + } + + surface->client_mapped = has_pending_buffer; } static void xdg_surface_role_commit(struct wlr_surface *wlr_surface) { struct wlr_xdg_surface *surface = wlr_xdg_surface_try_from_wlr_surface(wlr_surface); assert(surface != NULL); - if (surface->surface->unmap_commit) { - reset_xdg_surface_role_object(surface); - reset_xdg_surface(surface); - - assert(!surface->initial_commit); - surface->initial_commit = false; - } else { - surface->initial_commit = !surface->initialized; - surface->initialized = true; - } + surface->initial_commit = surface->current.initial_commit && surface->initialized; switch (surface->role) { case WLR_XDG_SURFACE_ROLE_NONE: