diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index d34654fd4..1f70b193d 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -443,12 +443,15 @@ static void handle_map(struct wl_listener *listener, void *data) { bool csd = false; - if (!view->xdg_decoration) { + if (view->xdg_decoration) { + enum wlr_xdg_toplevel_decoration_v1_mode mode = + view->xdg_decoration->wlr_xdg_decoration->client_pending_mode; + csd = mode == WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; + } else { struct sway_server_decoration *deco = decoration_from_surface(xdg_surface->surface); csd = !deco || deco->wlr_server_decoration->mode == WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT; - } view_map(view, view->wlr_xdg_surface->surface, diff --git a/sway/tree/container.c b/sway/tree/container.c index 1e84e6034..3b6610464 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -20,6 +20,7 @@ #include "sway/tree/arrange.h" #include "sway/tree/view.h" #include "sway/tree/workspace.h" +#include "sway/xdg_decoration.h" #include "list.h" #include "log.h" #include "stringop.h" @@ -835,7 +836,13 @@ void container_set_floating(struct sway_container *container, bool enable) { if (container->view) { view_set_tiled(container->view, false); if (container->view->using_csd) { + container->saved_border = container->pending.border; container->pending.border = B_CSD; + if (container->view->xdg_decoration) { + struct sway_xdg_decoration *deco = container->view->xdg_decoration; + wlr_xdg_toplevel_decoration_v1_set_mode(deco->wlr_xdg_decoration, + WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE); + } } } container_floating_set_default_size(container); @@ -873,6 +880,11 @@ void container_set_floating(struct sway_container *container, bool enable) { view_set_tiled(container->view, true); if (container->view->using_csd) { container->pending.border = container->saved_border; + if (container->view->xdg_decoration) { + struct sway_xdg_decoration *deco = container->view->xdg_decoration; + wlr_xdg_toplevel_decoration_v1_set_mode(deco->wlr_xdg_decoration, + WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); + } } } container->width_fraction = 0; diff --git a/sway/xdg_decoration.c b/sway/xdg_decoration.c index e7c3ea73d..8a9a9a286 100644 --- a/sway/xdg_decoration.c +++ b/sway/xdg_decoration.c @@ -10,7 +10,7 @@ static void xdg_decoration_handle_destroy(struct wl_listener *listener, void *data) { struct sway_xdg_decoration *deco = wl_container_of(listener, deco, destroy); - if(deco->view) { + if (deco->view) { deco->view->xdg_decoration = NULL; } wl_list_remove(&deco->destroy.link); @@ -23,8 +23,32 @@ static void xdg_decoration_handle_request_mode(struct wl_listener *listener, void *data) { struct sway_xdg_decoration *deco = wl_container_of(listener, deco, request_mode); + struct sway_view *view = deco->view; + enum wlr_xdg_toplevel_decoration_v1_mode mode = + WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE; + enum wlr_xdg_toplevel_decoration_v1_mode client_mode = + deco->wlr_xdg_decoration->client_pending_mode; + + bool floating; + if (view->container) { + floating = container_is_floating(view->container); + bool csd = false; + csd = client_mode == + WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; + view_update_csd_from_client(view, csd); + arrange_container(view->container); + transaction_commit_dirty(); + } else { + floating = view->impl->wants_floating && + view->impl->wants_floating(view); + } + + if (floating && client_mode) { + mode = client_mode; + } + wlr_xdg_toplevel_decoration_v1_set_mode(deco->wlr_xdg_decoration, - WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); + mode); } void handle_xdg_decoration(struct wl_listener *listener, void *data) {