diff --git a/xdg_shell.c b/xdg_shell.c index 783e7f3..2767a18 100644 --- a/xdg_shell.c +++ b/xdg_shell.c @@ -19,21 +19,9 @@ #include "xdg_shell.h" static void -xdg_decoration_handle_destroy(struct wl_listener *listener, void *data) +xdg_decoration_set_mode(struct cg_xdg_decoration *xdg_decoration) { - struct cg_xdg_decoration *xdg_decoration = wl_container_of(listener, xdg_decoration, destroy); - - wl_list_remove(&xdg_decoration->destroy.link); - wl_list_remove(&xdg_decoration->request_mode.link); - free(xdg_decoration); -} - -static void -xdg_decoration_handle_request_mode(struct wl_listener *listener, void *data) -{ - struct cg_xdg_decoration *xdg_decoration = wl_container_of(listener, xdg_decoration, request_mode); enum wlr_xdg_toplevel_decoration_v1_mode mode; - if (xdg_decoration->server->xdg_decoration) { mode = WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE; } else { @@ -42,6 +30,37 @@ xdg_decoration_handle_request_mode(struct wl_listener *listener, void *data) wlr_xdg_toplevel_decoration_v1_set_mode(xdg_decoration->wlr_decoration, mode); } +static void +xdg_decoration_handle_destroy(struct wl_listener *listener, void *data) +{ + struct cg_xdg_decoration *xdg_decoration = wl_container_of(listener, xdg_decoration, destroy); + + wl_list_remove(&xdg_decoration->destroy.link); + wl_list_remove(&xdg_decoration->commit.link); + wl_list_remove(&xdg_decoration->request_mode.link); + free(xdg_decoration); +} + +static void +xdg_decoration_handle_commit(struct wl_listener *listener, void *data) +{ + struct cg_xdg_decoration *xdg_decoration = wl_container_of(listener, xdg_decoration, commit); + + if (xdg_decoration->wlr_decoration->toplevel->base->initial_commit) { + xdg_decoration_set_mode(xdg_decoration); + } +} + +static void +xdg_decoration_handle_request_mode(struct wl_listener *listener, void *data) +{ + struct cg_xdg_decoration *xdg_decoration = wl_container_of(listener, xdg_decoration, request_mode); + + if (xdg_decoration->wlr_decoration->toplevel->base->initialized) { + xdg_decoration_set_mode(xdg_decoration); + } +} + static struct cg_view * popup_get_view(struct wlr_xdg_popup *popup) { @@ -321,8 +340,8 @@ handle_xdg_toplevel_decoration(struct wl_listener *listener, void *data) xdg_decoration->destroy.notify = xdg_decoration_handle_destroy; wl_signal_add(&wlr_decoration->events.destroy, &xdg_decoration->destroy); + xdg_decoration->commit.notify = xdg_decoration_handle_commit; + wl_signal_add(&wlr_decoration->toplevel->base->surface->events.commit, &xdg_decoration->commit); xdg_decoration->request_mode.notify = xdg_decoration_handle_request_mode; wl_signal_add(&wlr_decoration->events.request_mode, &xdg_decoration->request_mode); - - xdg_decoration_handle_request_mode(&xdg_decoration->request_mode, wlr_decoration); } diff --git a/xdg_shell.h b/xdg_shell.h index 077a9ae..d6553f4 100644 --- a/xdg_shell.h +++ b/xdg_shell.h @@ -22,6 +22,7 @@ struct cg_xdg_decoration { struct wlr_xdg_toplevel_decoration_v1 *wlr_decoration; struct cg_server *server; struct wl_listener destroy; + struct wl_listener commit; struct wl_listener request_mode; };