Skip to content
This repository has been archived by the owner on Nov 1, 2021. It is now read-only.

Commit

Permalink
layer-shell: implement configure scheduling
Browse files Browse the repository at this point in the history
This commit introduces wlr_layer_surface_v1.scheduled and implements
configure scheduling mechanism used by xdg-surface, unifying the API.
  • Loading branch information
Kirill Primak committed Sep 23, 2021
1 parent df2adff commit 4b659af
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 33 deletions.
8 changes: 6 additions & 2 deletions include/wlr/types/wlr_layer_shell_v1.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ struct wlr_layer_surface_v1 {

struct wlr_layer_surface_v1_state current, pending;

// Properties to be sent to the client in the next configure event.
struct wlr_layer_surface_v1_configure scheduled;
struct wl_event_source *configure_idle;

struct wl_listener surface_destroy;

struct {
Expand Down Expand Up @@ -115,9 +119,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_set_size(struct wlr_layer_surface_v1 *surface,
uint32_t width, uint32_t height);

/**
Expand Down
71 changes: 40 additions & 31 deletions types/wlr_layer_shell_v1.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ static void layer_surface_unmap(struct wlr_layer_surface_v1 *surface) {
}

surface->configured = surface->mapped = false;
if (surface->configure_idle) {
wl_event_source_remove(surface->configure_idle);
surface->configure_idle = NULL;
}
}

static void layer_surface_destroy(struct wlr_layer_surface_v1 *surface) {
Expand All @@ -256,43 +260,48 @@ static void layer_surface_resource_destroy(struct wl_resource *resource) {
}
}

static bool layer_surface_state_changed(struct wlr_layer_surface_v1 *surface,
uint32_t width, uint32_t height) {
struct wlr_layer_surface_v1_configure last_acked;
struct wlr_layer_surface_v1_configure *configure;
if (wl_list_empty(&surface->configure_list)) {
last_acked.width = surface->pending.actual_width;
last_acked.height = surface->pending.actual_height;
configure = &last_acked;
} else {
configure = wl_container_of(surface->configure_list.prev,
configure, link);
static void surface_send_configure(void *data) {
struct wlr_layer_surface_v1 *surface = data;

surface->configure_idle = NULL;

struct wlr_layer_surface_v1_configure *configure =
calloc(1, sizeof(*configure));
if (configure == NULL) {
wl_resource_post_no_memory(surface->resource);
return;
}

bool changed = configure->width != width
|| configure->height != height;
return changed;
wl_list_insert(surface->configure_list.prev, &configure->link);
configure->serial = surface->scheduled.serial;
configure->width = surface->scheduled.width;
configure->height = surface->scheduled.height;

zwlr_layer_surface_v1_send_configure(surface->resource,
configure->serial, configure->width, configure->height);
}

void wlr_layer_surface_v1_configure(struct wlr_layer_surface_v1 *surface,
uint32_t width, uint32_t height) {
if (layer_surface_state_changed(surface, width, 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;
static uint32_t schedule_configure(struct wlr_layer_surface_v1 *surface) {
struct wl_client *client = wl_resource_get_client(surface->resource);
struct wl_display *display = wl_client_get_display(client);
struct wl_event_loop *loop = wl_display_get_event_loop(display);

if (surface->configure_idle == NULL) {
surface->scheduled.serial = wl_display_next_serial(display);
surface->configure_idle = wl_event_loop_add_idle(loop,
surface_send_configure, surface);
if (surface->configure_idle == NULL) {
wl_client_post_no_memory(client);
}
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 surface->scheduled.serial;
}

uint32_t wlr_layer_surface_v1_set_size(struct wlr_layer_surface_v1 *surface,
uint32_t width, uint32_t height) {
surface->scheduled.width = width;
surface->scheduled.height = height;
return schedule_configure(surface);
}

void wlr_layer_surface_v1_destroy(struct wlr_layer_surface_v1 *surface) {
Expand Down

0 comments on commit 4b659af

Please sign in to comment.