xdg-toplevel: refactor configure/state flow

Previously, `wlr_xdg_toplevel` didn't follow the usual "current state +
pending state" pattern and instead had confusingly named
`client_pending` and `server_pending`. This commit removes them, and
instead introduces `wlr_xdg_toplevel.scheduled` to store the properties
that are yet to be sent to a client, and `wlr_xdg_toplevel.requested`
to store the properties that a client has requested. They have different
types to emphasize that they aren't actual states.
This commit is contained in:
Kirill Primak 2021-09-16 14:04:56 +03:00 committed by Simon Ser
parent 9579d62a16
commit b72a217fcc
3 changed files with 103 additions and 86 deletions

View File

@ -105,10 +105,16 @@ struct wlr_xdg_toplevel_state {
uint32_t width, height; uint32_t width, height;
uint32_t max_width, max_height; uint32_t max_width, max_height;
uint32_t min_width, min_height; uint32_t min_width, min_height;
};
// Since the fullscreen request may be made before the toplevel's surface struct wlr_xdg_toplevel_configure {
// is mapped, this is used to store the requested fullscreen output (if bool maximized, fullscreen, resizing, activated;
// any) for wlr_xdg_toplevel::client_pending. uint32_t tiled; // enum wlr_edges
uint32_t width, height;
};
struct wlr_xdg_toplevel_requested {
bool maximized, minimized, fullscreen;
struct wlr_output *fullscreen_output; struct wlr_output *fullscreen_output;
struct wl_listener fullscreen_output_destroy; struct wl_listener fullscreen_output_destroy;
}; };
@ -121,10 +127,15 @@ struct wlr_xdg_toplevel {
struct wlr_xdg_surface *parent; struct wlr_xdg_surface *parent;
struct wl_listener parent_unmap; struct wl_listener parent_unmap;
struct wlr_xdg_toplevel_state client_pending; struct wlr_xdg_toplevel_state current, pending;
struct wlr_xdg_toplevel_state server_pending;
struct wlr_xdg_toplevel_state last_acked; // Properties to be sent to the client in the next configure event.
struct wlr_xdg_toplevel_state current; struct wlr_xdg_toplevel_configure scheduled;
// Properties that the client has requested. Intended to be checked
// by the compositor on surface map and handled accordingly
// (e.g. a client might want to start already in a fullscreen state).
struct wlr_xdg_toplevel_requested requested;
char *title; char *title;
char *app_id; char *app_id;
@ -147,7 +158,7 @@ struct wlr_xdg_surface_configure {
struct wl_list link; // wlr_xdg_surface::configure_list struct wl_list link; // wlr_xdg_surface::configure_list
uint32_t serial; uint32_t serial;
struct wlr_xdg_toplevel_state *toplevel_state; struct wlr_xdg_toplevel_configure *toplevel_configure;
}; };
/** /**

View File

@ -23,7 +23,7 @@ static void xdg_surface_configure_destroy(
return; return;
} }
wl_list_remove(&configure->link); wl_list_remove(&configure->link);
free(configure->toplevel_state); free(configure->toplevel_configure);
free(configure); free(configure);
} }
@ -487,11 +487,10 @@ void reset_xdg_surface(struct wlr_xdg_surface *xdg_surface) {
case WLR_XDG_SURFACE_ROLE_TOPLEVEL: case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
wl_resource_set_user_data(xdg_surface->toplevel->resource, NULL); wl_resource_set_user_data(xdg_surface->toplevel->resource, NULL);
xdg_surface->toplevel->resource = NULL; xdg_surface->toplevel->resource = NULL;
struct wlr_xdg_toplevel_requested *req =
if (xdg_surface->toplevel->client_pending.fullscreen_output) { &xdg_surface->toplevel->requested;
struct wlr_xdg_toplevel_state *client_pending = if (req->fullscreen_output) {
&xdg_surface->toplevel->client_pending; wl_list_remove(&req->fullscreen_output_destroy.link);
wl_list_remove(&client_pending->fullscreen_output_destroy.link);
} }
free(xdg_surface->toplevel); free(xdg_surface->toplevel);
xdg_surface->toplevel = NULL; xdg_surface->toplevel = NULL;

View File

@ -11,50 +11,67 @@ void handle_xdg_toplevel_ack_configure(
struct wlr_xdg_surface *surface, struct wlr_xdg_surface *surface,
struct wlr_xdg_surface_configure *configure) { struct wlr_xdg_surface_configure *configure) {
assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL); assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
assert(configure->toplevel_state != NULL);
surface->toplevel->last_acked = *configure->toplevel_state; struct wlr_xdg_toplevel_configure *acked = configure->toplevel_configure;
assert(acked != NULL);
surface->toplevel->pending.maximized = acked->maximized;
surface->toplevel->pending.fullscreen = acked->fullscreen;
surface->toplevel->pending.resizing = acked->resizing;
surface->toplevel->pending.activated = acked->activated;
surface->toplevel->pending.tiled = acked->tiled;
surface->toplevel->pending.width = acked->width;
surface->toplevel->pending.height = acked->height;
} }
bool compare_xdg_surface_toplevel_state(struct wlr_xdg_toplevel *state) { bool compare_xdg_surface_toplevel_state(struct wlr_xdg_toplevel *toplevel) {
// is pending state different from current state? // Is the scheduled configure different from the last sent one?
if (!state->base->configured) { if (!toplevel->base->configured) {
return false; return false;
} }
struct wlr_xdg_toplevel_state *configured = NULL; struct wlr_xdg_toplevel_configure last_acked;
if (wl_list_empty(&state->base->configure_list)) { struct wlr_xdg_toplevel_configure *configure = NULL;
if (wl_list_empty(&toplevel->base->configure_list)) {
// There are currently no pending configures, so check against the last // There are currently no pending configures, so check against the last
// state acked by the client. // state acked by the client.
configured = &state->last_acked; last_acked.maximized = toplevel->pending.maximized;
last_acked.fullscreen = toplevel->pending.fullscreen;
last_acked.resizing = toplevel->pending.resizing;
last_acked.activated = toplevel->pending.activated;
last_acked.tiled = toplevel->pending.tiled;
last_acked.width = toplevel->pending.width;
last_acked.height = toplevel->pending.height;
configure = &last_acked;
} else { } else {
struct wlr_xdg_surface_configure *configure = struct wlr_xdg_surface_configure *surface_configure =
wl_container_of(state->base->configure_list.prev, configure, link); wl_container_of(toplevel->base->configure_list.prev, surface_configure, link);
configured = configure->toplevel_state; configure = surface_configure->toplevel_configure;
} }
if (state->server_pending.activated != configured->activated) { if (toplevel->scheduled.activated != configure->activated) {
return false; return false;
} }
if (state->server_pending.fullscreen != configured->fullscreen) { if (toplevel->scheduled.fullscreen != configure->fullscreen) {
return false; return false;
} }
if (state->server_pending.maximized != configured->maximized) { if (toplevel->scheduled.maximized != configure->maximized) {
return false; return false;
} }
if (state->server_pending.resizing != configured->resizing) { if (toplevel->scheduled.resizing != configure->resizing) {
return false; return false;
} }
if (state->server_pending.tiled != configured->tiled) { if (toplevel->scheduled.tiled != configure->tiled) {
return false; return false;
} }
if (state->server_pending.width == configured->width && if (toplevel->scheduled.width == configure->width &&
state->server_pending.height == configured->height) { toplevel->scheduled.height == configure->height) {
return true; return true;
} }
if (state->server_pending.width == 0 && state->server_pending.height == 0) { if (toplevel->scheduled.width == 0 && toplevel->scheduled.height == 0) {
return true; return true;
} }
@ -65,17 +82,17 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
struct wlr_xdg_surface_configure *configure) { struct wlr_xdg_surface_configure *configure) {
assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL); assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
configure->toplevel_state = malloc(sizeof(*configure->toplevel_state)); configure->toplevel_configure = malloc(sizeof(*configure->toplevel_configure));
if (configure->toplevel_state == NULL) { if (configure->toplevel_configure == NULL) {
wlr_log(WLR_ERROR, "Allocation failed"); wlr_log(WLR_ERROR, "Allocation failed");
wl_resource_post_no_memory(surface->toplevel->resource); wl_resource_post_no_memory(surface->toplevel->resource);
return; return;
} }
*configure->toplevel_state = surface->toplevel->server_pending; *configure->toplevel_configure = surface->toplevel->scheduled;
struct wl_array states; struct wl_array states;
wl_array_init(&states); wl_array_init(&states);
if (surface->toplevel->server_pending.maximized) { if (surface->toplevel->scheduled.maximized) {
uint32_t *s = wl_array_add(&states, sizeof(uint32_t)); uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
if (!s) { if (!s) {
wlr_log(WLR_ERROR, "Could not allocate state for maximized xdg_toplevel"); wlr_log(WLR_ERROR, "Could not allocate state for maximized xdg_toplevel");
@ -83,7 +100,7 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
} }
*s = XDG_TOPLEVEL_STATE_MAXIMIZED; *s = XDG_TOPLEVEL_STATE_MAXIMIZED;
} }
if (surface->toplevel->server_pending.fullscreen) { if (surface->toplevel->scheduled.fullscreen) {
uint32_t *s = wl_array_add(&states, sizeof(uint32_t)); uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
if (!s) { if (!s) {
wlr_log(WLR_ERROR, "Could not allocate state for fullscreen xdg_toplevel"); wlr_log(WLR_ERROR, "Could not allocate state for fullscreen xdg_toplevel");
@ -91,7 +108,7 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
} }
*s = XDG_TOPLEVEL_STATE_FULLSCREEN; *s = XDG_TOPLEVEL_STATE_FULLSCREEN;
} }
if (surface->toplevel->server_pending.resizing) { if (surface->toplevel->scheduled.resizing) {
uint32_t *s = wl_array_add(&states, sizeof(uint32_t)); uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
if (!s) { if (!s) {
wlr_log(WLR_ERROR, "Could not allocate state for resizing xdg_toplevel"); wlr_log(WLR_ERROR, "Could not allocate state for resizing xdg_toplevel");
@ -99,7 +116,7 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
} }
*s = XDG_TOPLEVEL_STATE_RESIZING; *s = XDG_TOPLEVEL_STATE_RESIZING;
} }
if (surface->toplevel->server_pending.activated) { if (surface->toplevel->scheduled.activated) {
uint32_t *s = wl_array_add(&states, sizeof(uint32_t)); uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
if (!s) { if (!s) {
wlr_log(WLR_ERROR, "Could not allocate state for activated xdg_toplevel"); wlr_log(WLR_ERROR, "Could not allocate state for activated xdg_toplevel");
@ -107,7 +124,7 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
} }
*s = XDG_TOPLEVEL_STATE_ACTIVATED; *s = XDG_TOPLEVEL_STATE_ACTIVATED;
} }
if (surface->toplevel->server_pending.tiled) { if (surface->toplevel->scheduled.tiled) {
if (wl_resource_get_version(surface->resource) >= if (wl_resource_get_version(surface->resource) >=
XDG_TOPLEVEL_STATE_TILED_LEFT_SINCE_VERSION) { XDG_TOPLEVEL_STATE_TILED_LEFT_SINCE_VERSION) {
const struct { const struct {
@ -121,7 +138,7 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
}; };
for (size_t i = 0; i < sizeof(tiled)/sizeof(tiled[0]); ++i) { for (size_t i = 0; i < sizeof(tiled)/sizeof(tiled[0]); ++i) {
if ((surface->toplevel->server_pending.tiled & if ((surface->toplevel->scheduled.tiled &
tiled[i].edge) == 0) { tiled[i].edge) == 0) {
continue; continue;
} }
@ -134,7 +151,7 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
} }
*s = tiled[i].state; *s = tiled[i].state;
} }
} else if (!surface->toplevel->server_pending.maximized) { } else if (!surface->toplevel->scheduled.maximized) {
// This version doesn't support tiling, best we can do is make the // This version doesn't support tiling, best we can do is make the
// toplevel maximized // toplevel maximized
uint32_t *s = wl_array_add(&states, sizeof(uint32_t)); uint32_t *s = wl_array_add(&states, sizeof(uint32_t));
@ -147,8 +164,8 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
} }
} }
uint32_t width = surface->toplevel->server_pending.width; uint32_t width = surface->toplevel->scheduled.width;
uint32_t height = surface->toplevel->server_pending.height; uint32_t height = surface->toplevel->scheduled.height;
xdg_toplevel_send_configure(surface->toplevel->resource, width, height, xdg_toplevel_send_configure(surface->toplevel->resource, width, height,
&states); &states);
@ -171,18 +188,7 @@ void handle_xdg_surface_toplevel_committed(struct wlr_xdg_surface *surface) {
return; return;
} }
// apply state from the last acked configure now that the client committed surface->toplevel->current = surface->toplevel->pending;
surface->toplevel->current = surface->toplevel->last_acked;
// update state from the client that doesn't need compositor approval
surface->toplevel->current.max_width =
surface->toplevel->client_pending.max_width;
surface->toplevel->current.min_width =
surface->toplevel->client_pending.min_width;
surface->toplevel->current.max_height =
surface->toplevel->client_pending.max_height;
surface->toplevel->current.min_height =
surface->toplevel->client_pending.min_height;
} }
static const struct xdg_toplevel_interface xdg_toplevel_implementation; static const struct xdg_toplevel_interface xdg_toplevel_implementation;
@ -359,23 +365,23 @@ static void xdg_toplevel_handle_set_max_size(struct wl_client *client,
struct wl_resource *resource, int32_t width, int32_t height) { struct wl_resource *resource, int32_t width, int32_t height) {
struct wlr_xdg_surface *surface = struct wlr_xdg_surface *surface =
wlr_xdg_surface_from_toplevel_resource(resource); wlr_xdg_surface_from_toplevel_resource(resource);
surface->toplevel->client_pending.max_width = width; surface->toplevel->pending.max_width = width;
surface->toplevel->client_pending.max_height = height; surface->toplevel->pending.max_height = height;
} }
static void xdg_toplevel_handle_set_min_size(struct wl_client *client, static void xdg_toplevel_handle_set_min_size(struct wl_client *client,
struct wl_resource *resource, int32_t width, int32_t height) { struct wl_resource *resource, int32_t width, int32_t height) {
struct wlr_xdg_surface *surface = struct wlr_xdg_surface *surface =
wlr_xdg_surface_from_toplevel_resource(resource); wlr_xdg_surface_from_toplevel_resource(resource);
surface->toplevel->client_pending.min_width = width; surface->toplevel->pending.min_width = width;
surface->toplevel->client_pending.min_height = height; surface->toplevel->pending.min_height = height;
} }
static void xdg_toplevel_handle_set_maximized(struct wl_client *client, static void xdg_toplevel_handle_set_maximized(struct wl_client *client,
struct wl_resource *resource) { struct wl_resource *resource) {
struct wlr_xdg_surface *surface = struct wlr_xdg_surface *surface =
wlr_xdg_surface_from_toplevel_resource(resource); wlr_xdg_surface_from_toplevel_resource(resource);
surface->toplevel->client_pending.maximized = true; surface->toplevel->requested.maximized = true;
wlr_signal_emit_safe(&surface->toplevel->events.request_maximize, surface); wlr_signal_emit_safe(&surface->toplevel->events.request_maximize, surface);
} }
@ -383,31 +389,31 @@ static void xdg_toplevel_handle_unset_maximized(struct wl_client *client,
struct wl_resource *resource) { struct wl_resource *resource) {
struct wlr_xdg_surface *surface = struct wlr_xdg_surface *surface =
wlr_xdg_surface_from_toplevel_resource(resource); wlr_xdg_surface_from_toplevel_resource(resource);
surface->toplevel->client_pending.maximized = false; surface->toplevel->requested.maximized = false;
wlr_signal_emit_safe(&surface->toplevel->events.request_maximize, surface); wlr_signal_emit_safe(&surface->toplevel->events.request_maximize, surface);
} }
static void handle_fullscreen_output_destroy(struct wl_listener *listener, static void handle_fullscreen_output_destroy(struct wl_listener *listener,
void *data) { void *data) {
struct wlr_xdg_toplevel_state *state = struct wlr_xdg_toplevel_requested *req =
wl_container_of(listener, state, fullscreen_output_destroy); wl_container_of(listener, req, fullscreen_output_destroy);
state->fullscreen_output = NULL; req->fullscreen_output = NULL;
wl_list_remove(&state->fullscreen_output_destroy.link); wl_list_remove(&req->fullscreen_output_destroy.link);
} }
static void store_fullscreen_pending(struct wlr_xdg_surface *surface, static void store_fullscreen_requested(struct wlr_xdg_surface *surface,
bool fullscreen, struct wlr_output *output) { bool fullscreen, struct wlr_output *output) {
struct wlr_xdg_toplevel_state *state = &surface->toplevel->client_pending; struct wlr_xdg_toplevel_requested *req = &surface->toplevel->requested;
state->fullscreen = fullscreen; req->fullscreen = fullscreen;
if (state->fullscreen_output) { if (req->fullscreen_output) {
wl_list_remove(&state->fullscreen_output_destroy.link); wl_list_remove(&req->fullscreen_output_destroy.link);
} }
state->fullscreen_output = output; req->fullscreen_output = output;
if (state->fullscreen_output) { if (req->fullscreen_output) {
state->fullscreen_output_destroy.notify = req->fullscreen_output_destroy.notify =
handle_fullscreen_output_destroy; handle_fullscreen_output_destroy;
wl_signal_add(&state->fullscreen_output->events.destroy, wl_signal_add(&req->fullscreen_output->events.destroy,
&state->fullscreen_output_destroy); &req->fullscreen_output_destroy);
} }
} }
@ -421,7 +427,7 @@ static void xdg_toplevel_handle_set_fullscreen(struct wl_client *client,
output = wlr_output_from_resource(output_resource); output = wlr_output_from_resource(output_resource);
} }
store_fullscreen_pending(surface, true, output); store_fullscreen_requested(surface, true, output);
struct wlr_xdg_toplevel_set_fullscreen_event event = { struct wlr_xdg_toplevel_set_fullscreen_event event = {
.surface = surface, .surface = surface,
@ -437,7 +443,7 @@ static void xdg_toplevel_handle_unset_fullscreen(struct wl_client *client,
struct wlr_xdg_surface *surface = struct wlr_xdg_surface *surface =
wlr_xdg_surface_from_toplevel_resource(resource); wlr_xdg_surface_from_toplevel_resource(resource);
store_fullscreen_pending(surface, false, NULL); store_fullscreen_requested(surface, false, NULL);
struct wlr_xdg_toplevel_set_fullscreen_event event = { struct wlr_xdg_toplevel_set_fullscreen_event event = {
.surface = surface, .surface = surface,
@ -452,6 +458,7 @@ static void xdg_toplevel_handle_set_minimized(struct wl_client *client,
struct wl_resource *resource) { struct wl_resource *resource) {
struct wlr_xdg_surface *surface = struct wlr_xdg_surface *surface =
wlr_xdg_surface_from_toplevel_resource(resource); wlr_xdg_surface_from_toplevel_resource(resource);
surface->toplevel->requested.minimized = true;
wlr_signal_emit_safe(&surface->toplevel->events.request_minimize, surface); wlr_signal_emit_safe(&surface->toplevel->events.request_minimize, surface);
} }
@ -547,8 +554,8 @@ void destroy_xdg_toplevel(struct wlr_xdg_surface *xdg_surface) {
uint32_t wlr_xdg_toplevel_set_size(struct wlr_xdg_surface *surface, uint32_t wlr_xdg_toplevel_set_size(struct wlr_xdg_surface *surface,
uint32_t width, uint32_t height) { uint32_t width, uint32_t height) {
assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL); assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
surface->toplevel->server_pending.width = width; surface->toplevel->scheduled.width = width;
surface->toplevel->server_pending.height = height; surface->toplevel->scheduled.height = height;
return schedule_xdg_surface_configure(surface); return schedule_xdg_surface_configure(surface);
} }
@ -556,7 +563,7 @@ uint32_t wlr_xdg_toplevel_set_size(struct wlr_xdg_surface *surface,
uint32_t wlr_xdg_toplevel_set_activated(struct wlr_xdg_surface *surface, uint32_t wlr_xdg_toplevel_set_activated(struct wlr_xdg_surface *surface,
bool activated) { bool activated) {
assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL); assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
surface->toplevel->server_pending.activated = activated; surface->toplevel->scheduled.activated = activated;
return schedule_xdg_surface_configure(surface); return schedule_xdg_surface_configure(surface);
} }
@ -564,7 +571,7 @@ uint32_t wlr_xdg_toplevel_set_activated(struct wlr_xdg_surface *surface,
uint32_t wlr_xdg_toplevel_set_maximized(struct wlr_xdg_surface *surface, uint32_t wlr_xdg_toplevel_set_maximized(struct wlr_xdg_surface *surface,
bool maximized) { bool maximized) {
assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL); assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
surface->toplevel->server_pending.maximized = maximized; surface->toplevel->scheduled.maximized = maximized;
return schedule_xdg_surface_configure(surface); return schedule_xdg_surface_configure(surface);
} }
@ -572,7 +579,7 @@ uint32_t wlr_xdg_toplevel_set_maximized(struct wlr_xdg_surface *surface,
uint32_t wlr_xdg_toplevel_set_fullscreen(struct wlr_xdg_surface *surface, uint32_t wlr_xdg_toplevel_set_fullscreen(struct wlr_xdg_surface *surface,
bool fullscreen) { bool fullscreen) {
assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL); assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
surface->toplevel->server_pending.fullscreen = fullscreen; surface->toplevel->scheduled.fullscreen = fullscreen;
return schedule_xdg_surface_configure(surface); return schedule_xdg_surface_configure(surface);
} }
@ -580,7 +587,7 @@ uint32_t wlr_xdg_toplevel_set_fullscreen(struct wlr_xdg_surface *surface,
uint32_t wlr_xdg_toplevel_set_resizing(struct wlr_xdg_surface *surface, uint32_t wlr_xdg_toplevel_set_resizing(struct wlr_xdg_surface *surface,
bool resizing) { bool resizing) {
assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL); assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
surface->toplevel->server_pending.resizing = resizing; surface->toplevel->scheduled.resizing = resizing;
return schedule_xdg_surface_configure(surface); return schedule_xdg_surface_configure(surface);
} }
@ -588,7 +595,7 @@ uint32_t wlr_xdg_toplevel_set_resizing(struct wlr_xdg_surface *surface,
uint32_t wlr_xdg_toplevel_set_tiled(struct wlr_xdg_surface *surface, uint32_t wlr_xdg_toplevel_set_tiled(struct wlr_xdg_surface *surface,
uint32_t tiled) { uint32_t tiled) {
assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL); assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
surface->toplevel->server_pending.tiled = tiled; surface->toplevel->scheduled.tiled = tiled;
return schedule_xdg_surface_configure(surface); return schedule_xdg_surface_configure(surface);
} }