xdg-toplevel: sync with surface state flow

This commit is contained in:
Kirill Primak 2022-02-04 16:52:05 +03:00
parent b16a95d754
commit cc8b4f8fb2
3 changed files with 63 additions and 3 deletions

View file

@ -106,6 +106,8 @@ struct wlr_xdg_toplevel_state {
uint32_t width, height;
uint32_t max_width, max_height;
uint32_t min_width, min_height;
struct wlr_surface_synced_state synced_state;
};
struct wlr_xdg_toplevel_configure {
@ -141,6 +143,8 @@ struct wlr_xdg_toplevel {
char *title;
char *app_id;
struct wlr_surface_synced synced;
struct {
struct wl_signal request_maximize;
struct wl_signal request_fullscreen;

View file

@ -451,6 +451,7 @@ void reset_xdg_surface(struct wlr_xdg_surface *surface) {
switch (surface->role) {
case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
wlr_surface_synced_finish(&surface->toplevel->synced);
wl_resource_set_user_data(surface->toplevel->resource, NULL);
free(surface->toplevel);
surface->toplevel = NULL;

View file

@ -126,8 +126,6 @@ void handle_xdg_toplevel_committed(struct wlr_xdg_toplevel *toplevel) {
toplevel->added = true;
return;
}
toplevel->current = toplevel->pending;
}
static const struct xdg_toplevel_interface xdg_toplevel_implementation;
@ -150,7 +148,7 @@ void wlr_xdg_toplevel_set_parent(struct wlr_xdg_toplevel *toplevel,
if (toplevel->parent) {
wl_list_remove(&toplevel->parent_unmap.link);
}
toplevel->parent = parent;
if (parent) {
toplevel->parent_unmap.notify = handle_parent_unmap;
@ -426,6 +424,51 @@ const struct wlr_surface_role xdg_toplevel_surface_role = {
.precommit = xdg_surface_role_precommit,
};
static void xdg_toplevel_synced_squash_state(
struct wlr_surface_synced_state *synced_dst,
struct wlr_surface_synced_state *synced_src) {
struct wlr_xdg_toplevel_state *dst =
wl_container_of(synced_dst, dst, synced_state);
struct wlr_xdg_toplevel_state *src =
wl_container_of(synced_src, src, synced_state);
dst->maximized = src->maximized;
dst->fullscreen = src->fullscreen;
dst->resizing = src->resizing;
dst->activated = src->activated;
dst->tiled = src->tiled;
dst->width = src->width;
dst->height = src->height;
dst->max_width = src->max_width;
dst->max_height = src->max_height;
dst->min_width = src->min_width;
dst->min_height = src->min_height;
}
static struct wlr_surface_synced_state *xdg_toplevel_synced_create_state(void) {
struct wlr_xdg_toplevel_state *state = calloc(1, sizeof(*state));
if (!state) {
return NULL;
}
return &state->synced_state;
}
static void xdg_toplevel_synced_destroy_state(
struct wlr_surface_synced_state *synced_state) {
struct wlr_xdg_toplevel_state *state =
wl_container_of(synced_state, state, synced_state);
free(state);
}
static const struct wlr_surface_synced_interface xdg_toplevel_synced_impl = {
.name = "wlr_xdg_toplevel",
.squash_state = xdg_toplevel_synced_squash_state,
.create_state = xdg_toplevel_synced_create_state,
.destroy_state = xdg_toplevel_synced_destroy_state,
};
void create_xdg_toplevel(struct wlr_xdg_surface *surface,
uint32_t id) {
if (!wlr_surface_set_role(surface->surface, &xdg_toplevel_surface_role,
@ -446,6 +489,17 @@ void create_xdg_toplevel(struct wlr_xdg_surface *surface,
wl_resource_post_no_memory(surface->resource);
return;
}
if (!wlr_surface_synced_init(&surface->toplevel->synced,
&xdg_toplevel_synced_impl, surface->surface,
&surface->toplevel->current.synced_state,
&surface->toplevel->pending.synced_state)) {
free(surface->toplevel);
surface->toplevel = NULL;
wl_resource_post_no_memory(surface->resource);
return;
}
surface->toplevel->base = surface;
wl_signal_init(&surface->toplevel->events.request_maximize);
@ -462,6 +516,7 @@ void create_xdg_toplevel(struct wlr_xdg_surface *surface,
surface->client->client, &xdg_toplevel_interface,
wl_resource_get_version(surface->resource), id);
if (surface->toplevel->resource == NULL) {
wlr_surface_synced_finish(&surface->toplevel->synced);
free(surface->toplevel);
surface->toplevel = NULL;
wl_resource_post_no_memory(surface->resource);