sway

i3-compatible Wayland compositor
git clone https://git.awy.one/sway
Log | Files | Refs | README | LICENSE

commit acf946fe4c495b47c5a76230ba98f9b973bec96d
parent 7a15e715b7c5c91b12f82b3e94230b6644d3893d
Author: Dudemanguy <random342@airmail.cc>
Date:   Tue, 10 Aug 2021 12:01:37 -0500

xdg-decoration: let floating clients set borders

The xdg-decoration protocol allows clients to request whether they want
to use server side decorations or client side decorations. Currently,
sway ignores this and always enforces whatever the server is currently
set to. Although tiled clients cannot be allowed to set borders, there
is no harm in listening requests from floating clients. Sidenote: also
fix an unrelated style error.

Diffstat:
Msway/desktop/xdg_shell.c | 7+++++--
Msway/tree/container.c | 12++++++++++++
Msway/xdg_decoration.c | 28++++++++++++++++++++++++++--
3 files changed, 43 insertions(+), 4 deletions(-)

diff --git 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 @@ -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 @@ -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) {