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

layer-shell: implement configure scheduling #3212

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion 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 @@ -117,7 +121,7 @@ struct wlr_layer_shell_v1 *wlr_layer_shell_v1_create(struct wl_display *display)
* layer_surface will signal its map event when the surface is ready to assume
* this size. Returns the associated configure serial.
*/
uint32_t 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
50 changes: 37 additions & 13 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,24 +260,44 @@ static void layer_surface_resource_destroy(struct wl_resource *resource) {
}
}

uint32_t wlr_layer_surface_v1_configure(struct wlr_layer_surface_v1 *surface,
uint32_t width, uint32_t height) {
struct wl_display *display =
wl_client_get_display(wl_resource_get_client(surface->resource));
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(struct wlr_layer_surface_v1_configure));
calloc(1, sizeof(*configure));
if (configure == NULL) {
wl_client_post_no_memory(wl_resource_get_client(surface->resource));
return surface->pending.configure_serial;
wl_resource_post_no_memory(surface->resource);
return;
}
*configure = surface->scheduled;
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;
configure->serial, configure->width, configure->height);
}

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);
}
}
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