From 7b138e5ef0f679c9bb0078019d7c9c63fef36273 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Mon, 24 Sep 2018 20:54:57 +1000 Subject: Add CSD to border modes This replaces view.using_csd with a new border mode: B_CSD. This also removes sway_xdg_shell{_v6}_view.deco_mode and view->has_client_side_decorations as we can now get these from the border. You can use `border toggle` to cycle through the modes including CSD, or use `border csd` to set it directly. The client must support the xdg-decoration protocol, and the only client I know of that does is the example in wlroots. If the client switches from SSD to CSD without us expecting it (via the server-decoration protocol), we stash the previous border type into view.saved_border so we can restore it if the client returns to SSD. I haven't found a way to test this though. --- sway/xdg_decoration.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 sway/xdg_decoration.c (limited to 'sway/xdg_decoration.c') diff --git a/sway/xdg_decoration.c b/sway/xdg_decoration.c new file mode 100644 index 00000000..2e7e4bd0 --- /dev/null +++ b/sway/xdg_decoration.c @@ -0,0 +1,73 @@ +#include +#include "sway/desktop/transaction.h" +#include "sway/server.h" +#include "sway/tree/arrange.h" +#include "sway/tree/view.h" +#include "sway/xdg_decoration.h" +#include "log.h" + +static void xdg_decoration_handle_destroy(struct wl_listener *listener, + void *data) { + struct sway_xdg_decoration *deco = + wl_container_of(listener, deco, destroy); + deco->view->xdg_decoration = NULL; + wl_list_remove(&deco->destroy.link); + wl_list_remove(&deco->surface_commit.link); + wl_list_remove(&deco->link); + free(deco); +} + +static void xdg_decoration_handle_surface_commit(struct wl_listener *listener, + void *data) { + struct sway_xdg_decoration *decoration = + wl_container_of(listener, decoration, surface_commit); + + bool csd = decoration->wlr_xdg_decoration->current_mode == + WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; + struct sway_view *view = decoration->view; + + view_set_csd_from_client(view, csd); + + arrange_container(view->container); + transaction_commit_dirty(); +} + +void handle_xdg_decoration(struct wl_listener *listener, void *data) { + struct wlr_xdg_toplevel_decoration_v1 *wlr_deco = data; + struct sway_xdg_shell_view *xdg_shell_view = wlr_deco->surface->data; + struct wlr_xdg_surface *wlr_xdg_surface = + xdg_shell_view->view.wlr_xdg_surface; + + struct sway_xdg_decoration *deco = calloc(1, sizeof(*deco)); + if (deco == NULL) { + return; + } + + deco->view = &xdg_shell_view->view; + deco->view->xdg_decoration = deco; + deco->wlr_xdg_decoration = wlr_deco; + + wl_signal_add(&wlr_deco->events.destroy, &deco->destroy); + deco->destroy.notify = xdg_decoration_handle_destroy; + + // Note: We don't listen to the request_mode signal here, effectively + // ignoring any modes the client asks to set. The client can still force a + // mode upon us, in which case we get upset but live with it. + + deco->surface_commit.notify = xdg_decoration_handle_surface_commit; + wl_signal_add(&wlr_xdg_surface->surface->events.commit, + &deco->surface_commit); + + wl_list_insert(&server.xdg_decorations, &deco->link); +} + +struct sway_xdg_decoration *xdg_decoration_from_surface( + struct wlr_surface *surface) { + struct sway_xdg_decoration *deco; + wl_list_for_each(deco, &server.xdg_decorations, link) { + if (deco->wlr_xdg_decoration->surface->surface == surface) { + return deco; + } + } + return NULL; +} -- cgit v1.2.3-54-g00ecf