From 042c157378428dc6cee4140a8c048e8d36e6874c Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Thu, 6 Aug 2020 14:51:45 +0100 Subject: [PATCH] Track server-side-decoration per view --- include/labwc.h | 1 + src/deco.c | 1 - src/output.c | 2 +- src/view.c | 44 +++++++++++--------------------------------- src/xdg.c | 20 +++++++++++++++++++- src/xwl.c | 14 +++++++++++++- 6 files changed, 45 insertions(+), 37 deletions(-) diff --git a/include/labwc.h b/include/labwc.h index aec9fded..c3a3a615 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -121,6 +121,7 @@ struct view { bool mapped; bool been_mapped; int x, y; + bool show_server_side_deco; }; struct keyboard { diff --git a/src/deco.c b/src/deco.c index 50a4c332..1acb117b 100644 --- a/src/deco.c +++ b/src/deco.c @@ -8,7 +8,6 @@ #include "theme/theme.h" #include "config/rcxml.h" -/* Based on expected font height of Sans 8 */ #define BORDER_WIDTH (1) struct wlr_box deco_max_extents(struct view *view) diff --git a/src/output.c b/src/output.c index dc0faf93..71708789 100644 --- a/src/output.c +++ b/src/output.c @@ -49,7 +49,7 @@ static void render_icon(struct draw_data *d, struct wlr_box box, static void render_decorations(struct wlr_output *output, struct view *view) { - if (!view_want_deco(view)) + if (!view->show_server_side_deco) return; struct draw_data ddata = { .renderer = view->server->renderer, diff --git a/src/view.c b/src/view.c index ba067bd3..0d7b72ce 100644 --- a/src/view.c +++ b/src/view.c @@ -16,18 +16,20 @@ void view_init_position(struct view *view) /* If surface already has a 'desired' position, don't touch it */ if (view->x || view->y) return; - if (!is_toplevel(view)) + + /* Do not touch xwayland surfaces like menus and apps like dmenu */ + if (view->type == LAB_XWAYLAND_VIEW && !view->show_server_side_deco) return; + struct wlr_box box; - if (view->type == LAB_XDG_SHELL_VIEW && rc.client_side_decorations) { - /* CSD */ + if (view->type == LAB_XDG_SHELL_VIEW && !view->show_server_side_deco) + /* + * We're here either because rc.xml says yes to CSD or + * because the XDG shell won't allow CSD to be turned off + */ wlr_xdg_surface_get_geometry(view->xdg_surface, &box); - } else if (!view_want_deco(view)) { - return; - } else { - /* SSD */ + else box = deco_max_extents(view); - } view->x -= box.x; view->y -= box.y; if (view->type != LAB_XWAYLAND_VIEW) @@ -83,30 +85,6 @@ void view_resize(struct view *view, struct wlr_box geo) } } -/* Do we want _server_ side decoration? */ -bool view_want_deco(struct view *view) -{ - if (view->type == LAB_XDG_SHELL_VIEW && rc.client_side_decorations) - return false; - - /* - * Some XDG shells refuse to give us their CSD in which case their - * geometry.{x,y} seems to be greater than zero, so filter on that. - */ - if (view->type == LAB_XDG_SHELL_VIEW && !rc.client_side_decorations && - view->xdg_surface->geometry.x) - return false; - - if (view->type == LAB_XDG_SHELL_VIEW) - return true; - if (view->xwayland_surface->override_redirect) - return false; - if (view->xwayland_surface->decorations != - WLR_XWAYLAND_SURFACE_DECORATIONS_ALL) - return false; - return true; -} - static void move_to_front(struct view *view) { wl_list_remove(&view->link); @@ -250,7 +228,7 @@ struct view *view_at(struct server *server, double lx, double ly, wl_list_for_each (view, &server->views, link) { if (_view_at(view, lx, ly, surface, sx, sy)) return view; - if (!view_want_deco(view)) + if (!view->show_server_side_deco) continue; if (deco_at(view, lx, ly) == LAB_DECO_PART_TITLE) { *view_area = LAB_DECO_PART_TITLE; diff --git a/src/xdg.c b/src/xdg.c index b208f309..7c53d6be 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -47,13 +47,31 @@ void xdg_toplevel_decoration(struct wl_listener *listener, void *data) xdg_deco_request_mode(&xdg_deco->request_mode, wlr_decoration); } +static bool has_ssd(struct view *view) +{ + if (rc.client_side_decorations) + return false; + + /* + * Some XDG shells refuse to disable CSD in which case their + * geometry.{x,y} seems to be greater. We filter on that on the + * assumption that this will remain true. + */ + if (view->xdg_surface->geometry.x || view->xdg_surface->geometry.y) + return false; + + return true; +} + void xdg_surface_map(struct wl_listener *listener, void *data) { struct view *view = wl_container_of(listener, view, map); view->mapped = true; view->surface = view->xdg_surface->surface; - if (!view->been_mapped) + if (!view->been_mapped) { + view->show_server_side_deco = has_ssd(view); view_init_position(view); + } view->been_mapped = true; view_focus(view); } diff --git a/src/xwl.c b/src/xwl.c index 4eaa17d5..29b938ec 100644 --- a/src/xwl.c +++ b/src/xwl.c @@ -16,6 +16,16 @@ int xwl_nr_parents(struct view *view) return i; } +static bool has_ssd(struct view *view) +{ + if (view->xwayland_surface->override_redirect) + return false; + if (view->xwayland_surface->decorations != + WLR_XWAYLAND_SURFACE_DECORATIONS_ALL) + return false; + return true; +} + void xwl_surface_map(struct wl_listener *listener, void *data) { struct view *view = wl_container_of(listener, view, map); @@ -23,8 +33,10 @@ void xwl_surface_map(struct wl_listener *listener, void *data) view->x = view->xwayland_surface->x; view->y = view->xwayland_surface->y; view->surface = view->xwayland_surface->surface; - if (!view->been_mapped) + if (!view->been_mapped) { + view->show_server_side_deco = has_ssd(view); view_init_position(view); + } view->been_mapped = true; view_focus(view); } -- 2.52.0