From 59fa3637c348270cd1adb239296be1219538394b Mon Sep 17 00:00:00 2001 From: Kirill Primak Date: Sat, 18 Sep 2021 11:32:23 +0300 Subject: [PATCH] layer-shell: refactor configure/state flow Same logic as xdg-toplevel. --- include/wlr/types/wlr_layer_shell_v1.h | 16 ++-- types/wlr_layer_shell_v1.c | 124 ++++++++----------------- 2 files changed, 46 insertions(+), 94 deletions(-) diff --git a/include/wlr/types/wlr_layer_shell_v1.h b/include/wlr/types/wlr_layer_shell_v1.h index 6f951556..3fa7d6de 100644 --- a/include/wlr/types/wlr_layer_shell_v1.h +++ b/include/wlr/types/wlr_layer_shell_v1.h @@ -53,12 +53,14 @@ struct wlr_layer_surface_v1_state { uint32_t desired_width, desired_height; uint32_t actual_width, actual_height; enum zwlr_layer_shell_v1_layer layer; + uint32_t configure_serial; }; struct wlr_layer_surface_v1_configure { struct wl_list link; // wlr_layer_surface_v1::configure_list uint32_t serial; - struct wlr_layer_surface_v1_state state; + + uint32_t width, height; }; struct wlr_layer_surface_v1 { @@ -71,15 +73,9 @@ struct wlr_layer_surface_v1 { char *namespace; bool added, configured, mapped; - uint32_t configure_serial; - uint32_t configure_next_serial; struct wl_list configure_list; - struct wlr_layer_surface_v1_configure *acked_configure; - - struct wlr_layer_surface_v1_state client_pending; - struct wlr_layer_surface_v1_state server_pending; - struct wlr_layer_surface_v1_state current; + struct wlr_layer_surface_v1_state current, pending; struct wl_listener surface_destroy; @@ -119,9 +115,9 @@ struct wlr_layer_shell_v1 *wlr_layer_shell_v1_create(struct wl_display *display) /** * Notifies the layer surface to configure itself with this width/height. The * layer_surface will signal its map event when the surface is ready to assume - * this size. + * this size. Returns the associated configure serial. */ -void wlr_layer_surface_v1_configure(struct wlr_layer_surface_v1 *surface, +uint32_t wlr_layer_surface_v1_configure(struct wlr_layer_surface_v1 *surface, uint32_t width, uint32_t height); /** diff --git a/types/wlr_layer_shell_v1.c b/types/wlr_layer_shell_v1.c index 46aeaac5..09789ebe 100644 --- a/types/wlr_layer_shell_v1.c +++ b/types/wlr_layer_shell_v1.c @@ -87,12 +87,13 @@ static void layer_surface_handle_ack_configure(struct wl_client *client, layer_surface_configure_destroy(configure); } - if (surface->acked_configure) { - layer_surface_configure_destroy(surface->acked_configure); - } - surface->acked_configure = configure; - wl_list_remove(&configure->link); - wl_list_init(&configure->link); + surface->pending.configure_serial = configure->serial; + surface->pending.actual_width = configure->width; + surface->pending.actual_height = configure->height; + + surface->configured = true; + + layer_surface_configure_destroy(configure); } static void layer_surface_handle_set_size(struct wl_client *client, @@ -102,8 +103,8 @@ static void layer_surface_handle_set_size(struct wl_client *client, if (!surface) { return; } - surface->client_pending.desired_width = width; - surface->client_pending.desired_height = height; + surface->pending.desired_width = width; + surface->pending.desired_height = height; } static void layer_surface_handle_set_anchor(struct wl_client *client, @@ -123,7 +124,7 @@ static void layer_surface_handle_set_anchor(struct wl_client *client, if (!surface) { return; } - surface->client_pending.anchor = anchor; + surface->pending.anchor = anchor; } static void layer_surface_handle_set_exclusive_zone(struct wl_client *client, @@ -133,7 +134,7 @@ static void layer_surface_handle_set_exclusive_zone(struct wl_client *client, if (!surface) { return; } - surface->client_pending.exclusive_zone = zone; + surface->pending.exclusive_zone = zone; } static void layer_surface_handle_set_margin( @@ -144,10 +145,10 @@ static void layer_surface_handle_set_margin( if (!surface) { return; } - surface->client_pending.margin.top = top; - surface->client_pending.margin.right = right; - surface->client_pending.margin.bottom = bottom; - surface->client_pending.margin.left = left; + surface->pending.margin.top = top; + surface->pending.margin.right = right; + surface->pending.margin.bottom = bottom; + surface->pending.margin.left = left; } static void layer_surface_handle_set_keyboard_interactivity( @@ -160,14 +161,14 @@ static void layer_surface_handle_set_keyboard_interactivity( } if (wl_resource_get_version(resource) < ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND_SINCE_VERSION) { - surface->client_pending.keyboard_interactive = !!interactive; + surface->pending.keyboard_interactive = !!interactive; } else { if (interactive > ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND) { wl_resource_post_error(resource, ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_KEYBOARD_INTERACTIVITY, "wrong keyboard interactivity value: %" PRIu32, interactive); } else { - surface->client_pending.keyboard_interactive = interactive; + surface->pending.keyboard_interactive = interactive; } } } @@ -203,7 +204,7 @@ static void layer_surface_set_layer(struct wl_client *client, "Invalid layer %" PRIu32, layer); return; } - surface->client_pending.layer = layer; + surface->pending.layer = layer; } static const struct zwlr_layer_surface_v1_interface layer_surface_implementation = { @@ -233,8 +234,6 @@ static void layer_surface_unmap(struct wlr_layer_surface_v1 *surface) { } surface->configured = surface->mapped = false; - surface->configure_serial = 0; - surface->configure_next_serial = 0; } static void layer_surface_destroy(struct wlr_layer_surface_v1 *surface) { @@ -257,49 +256,24 @@ static void layer_surface_resource_destroy(struct wl_resource *resource) { } } -static bool layer_surface_state_changed(struct wlr_layer_surface_v1 *surface) { - struct wlr_layer_surface_v1_state *state; - if (wl_list_empty(&surface->configure_list)) { - if (surface->acked_configure) { - state = &surface->acked_configure->state; - } else if (!surface->configured) { - return true; - } else { - state = &surface->current; - } - } else { - struct wlr_layer_surface_v1_configure *configure = - wl_container_of(surface->configure_list.prev, configure, link); - state = &configure->state; - } - - bool changed = state->actual_width != surface->server_pending.actual_width - || state->actual_height != surface->server_pending.actual_height; - return changed; -} - -void wlr_layer_surface_v1_configure(struct wlr_layer_surface_v1 *surface, +uint32_t wlr_layer_surface_v1_configure(struct wlr_layer_surface_v1 *surface, uint32_t width, uint32_t height) { - surface->server_pending.actual_width = width; - surface->server_pending.actual_height = height; - if (layer_surface_state_changed(surface)) { - struct wl_display *display = - wl_client_get_display(wl_resource_get_client(surface->resource)); - struct wlr_layer_surface_v1_configure *configure = - calloc(1, sizeof(struct wlr_layer_surface_v1_configure)); - if (configure == NULL) { - wl_client_post_no_memory(wl_resource_get_client(surface->resource)); - return; - } - surface->configure_next_serial = wl_display_next_serial(display); - wl_list_insert(surface->configure_list.prev, &configure->link); - configure->state.actual_width = width; - configure->state.actual_height = height; - configure->serial = surface->configure_next_serial; - zwlr_layer_surface_v1_send_configure(surface->resource, - configure->serial, configure->state.actual_width, - configure->state.actual_height); + struct wl_display *display = + wl_client_get_display(wl_resource_get_client(surface->resource)); + struct wlr_layer_surface_v1_configure *configure = + calloc(1, sizeof(struct wlr_layer_surface_v1_configure)); + if (configure == NULL) { + wl_client_post_no_memory(wl_resource_get_client(surface->resource)); + return surface->pending.configure_serial; } + wl_list_insert(surface->configure_list.prev, &configure->link); + configure->width = width; + configure->height = height; + configure->serial = wl_display_next_serial(display); + zwlr_layer_surface_v1_send_configure(surface->resource, + configure->serial, configure->width, + configure->height); + return configure->serial; } void wlr_layer_surface_v1_destroy(struct wlr_layer_surface_v1 *surface) { @@ -316,8 +290,8 @@ static void layer_surface_role_commit(struct wlr_surface *wlr_surface) { const uint32_t horiz = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; - if (surface->client_pending.desired_width == 0 && - (surface->client_pending.anchor & horiz) != horiz) { + if (surface->pending.desired_width == 0 && + (surface->pending.anchor & horiz) != horiz) { wl_resource_post_error(surface->resource, ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_SIZE, "width 0 requested without setting left and right anchors"); @@ -326,24 +300,15 @@ static void layer_surface_role_commit(struct wlr_surface *wlr_surface) { const uint32_t vert = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; - if (surface->client_pending.desired_height == 0 && - (surface->client_pending.anchor & vert) != vert) { + if (surface->pending.desired_height == 0 && + (surface->pending.anchor & vert) != vert) { wl_resource_post_error(surface->resource, ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_SIZE, "height 0 requested without setting top and bottom anchors"); return; } - if (surface->acked_configure) { - struct wlr_layer_surface_v1_configure *configure = - surface->acked_configure; - surface->configured = true; - surface->configure_serial = configure->serial; - surface->current.actual_width = configure->state.actual_width; - surface->current.actual_height = configure->state.actual_height; - layer_surface_configure_destroy(configure); - surface->acked_configure = NULL; - } + surface->current = surface->pending; if (wlr_surface_has_buffer(surface->surface) && !surface->configured) { wl_resource_post_error(surface->resource, @@ -352,15 +317,6 @@ static void layer_surface_role_commit(struct wlr_surface *wlr_surface) { return; } - surface->current.anchor = surface->client_pending.anchor; - surface->current.exclusive_zone = surface->client_pending.exclusive_zone; - surface->current.margin = surface->client_pending.margin; - surface->current.keyboard_interactive = - surface->client_pending.keyboard_interactive; - surface->current.desired_width = surface->client_pending.desired_width; - surface->current.desired_height = surface->client_pending.desired_height; - surface->current.layer = surface->client_pending.layer; - if (!surface->added) { surface->added = true; assert(!surface->configured); @@ -422,7 +378,7 @@ static void layer_shell_handle_get_layer_surface(struct wl_client *wl_client, if (output_resource) { surface->output = wlr_output_from_resource(output_resource); } - surface->current.layer = surface->client_pending.layer = layer; + surface->current.layer = surface->pending.layer = layer; if (layer > ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY) { free(surface); wl_resource_post_error(client_resource,