From ec67c56c84accdafbe3f099feec150e75e1c4d24 Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Mon, 1 Jul 2024 20:45:29 +0900 Subject: [PATCH] ssd: allow ssd to be smaller than minimal size With 2603dbf labwc refused to update ssd geometry when its geometry is smaller than minimal size in order to prevent passing negative values in wlr_scene_rect_set_size(), but it made ssd for small windows like workrave ugly. So this commit fixes the negative values for each call to wlr_scene_rect_set_size() individually rather than just early-return in ssd_update_geometry(). Co-Authored-By: Consolatis <35009135+Consolatis@users.noreply.github.com> --- include/ssd-internal.h | 2 ++ src/ssd/ssd-border.c | 2 +- src/ssd/ssd-extents.c | 2 +- src/ssd/ssd-shadow.c | 2 +- src/ssd/ssd-titlebar.c | 10 +++++---- src/ssd/ssd.c | 51 +++++++++++++++++++++++++++++++++--------- 6 files changed, 52 insertions(+), 17 deletions(-) diff --git a/include/ssd-internal.h b/include/ssd-internal.h index fda196e6..5a215a52 100644 --- a/include/ssd-internal.h +++ b/include/ssd-internal.h @@ -59,6 +59,8 @@ struct ssd { } title; } state; + struct wlr_scene_rect *view_background; + /* An invisible area around the view which allows resizing */ struct ssd_sub_tree extents; diff --git a/src/ssd/ssd-border.c b/src/ssd/ssd-border.c index 63604244..120c2fba 100644 --- a/src/ssd/ssd-border.c +++ b/src/ssd/ssd-border.c @@ -82,7 +82,7 @@ ssd_border_update(struct ssd *ssd) struct theme *theme = view->server->theme; - int width = view->current.width; + int width = MAX(view->current.width, LAB_MIN_VIEW_WIDTH); int height = view_effective_height(view, /* use_pending */ false); int full_width = width + 2 * theme->border_width; diff --git a/src/ssd/ssd-extents.c b/src/ssd/ssd-extents.c index 4bb5b69d..c8edcd1e 100644 --- a/src/ssd/ssd-extents.c +++ b/src/ssd/ssd-extents.c @@ -104,7 +104,7 @@ ssd_extents_update(struct ssd *ssd) struct theme *theme = view->server->theme; - int width = view->current.width; + int width = MAX(view->current.width, LAB_MIN_VIEW_WIDTH); int height = view_effective_height(view, /* use_pending */ false); int full_height = height + theme->border_width * 2 + ssd->titlebar.height; int full_width = width + 2 * theme->border_width; diff --git a/src/ssd/ssd-shadow.c b/src/ssd/ssd-shadow.c index 3e6227aa..57212866 100644 --- a/src/ssd/ssd-shadow.c +++ b/src/ssd/ssd-shadow.c @@ -169,7 +169,7 @@ set_shadow_geometry(struct ssd *ssd) struct view *view = ssd->view; struct theme *theme = view->server->theme; int titlebar_height = ssd->titlebar.height; - int width = view->current.width; + int width = MAX(view->current.width, LAB_MIN_VIEW_WIDTH); int height = view_effective_height(view, false) + titlebar_height; struct ssd_part *part; diff --git a/src/ssd/ssd-titlebar.c b/src/ssd/ssd-titlebar.c index 32d6131a..26800b89 100644 --- a/src/ssd/ssd-titlebar.c +++ b/src/ssd/ssd-titlebar.c @@ -210,6 +210,8 @@ ssd_titlebar_update(struct ssd *ssd) return; } + int title_bar_width = MAX(0, width - SSD_BUTTON_WIDTH * SSD_BUTTON_COUNT); + struct ssd_part *part; struct ssd_sub_tree *subtree; FOR_EACH_STATE(ssd, subtree) { @@ -218,25 +220,25 @@ ssd_titlebar_update(struct ssd *ssd) case LAB_SSD_PART_TITLEBAR: wlr_scene_rect_set_size( wlr_scene_rect_from_node(part->node), - width - SSD_BUTTON_WIDTH * SSD_BUTTON_COUNT, + title_bar_width, theme->title_height); continue; case LAB_SSD_BUTTON_ICONIFY: if (is_direct_child(part->node, subtree)) { wlr_scene_node_set_position(part->node, - width - SSD_BUTTON_WIDTH * 3, 0); + title_bar_width + 1 * SSD_BUTTON_WIDTH, 0); } continue; case LAB_SSD_BUTTON_MAXIMIZE: if (is_direct_child(part->node, subtree)) { wlr_scene_node_set_position(part->node, - width - SSD_BUTTON_WIDTH * 2, 0); + title_bar_width + 2 * SSD_BUTTON_WIDTH, 0); } continue; case LAB_SSD_PART_CORNER_TOP_RIGHT: if (is_direct_child(part->node, subtree)) { wlr_scene_node_set_position(part->node, - width - SSD_BUTTON_WIDTH * 1, 0); + title_bar_width + 3 * SSD_BUTTON_WIDTH, 0); } continue; default: diff --git a/src/ssd/ssd.c b/src/ssd/ssd.c index 86ac1272..e2da63b2 100644 --- a/src/ssd/ssd.c +++ b/src/ssd/ssd.c @@ -138,6 +138,11 @@ ssd_get_part_type(const struct ssd *ssd, struct wlr_scene_node *node) } } } + + if (ssd->view_background && node == &ssd->view_background->node) { + return LAB_SSD_CLIENT; + } + return LAB_SSD_NONE; } @@ -230,16 +235,6 @@ ssd_update_geometry(struct ssd *ssd) int eff_width = current.width; int eff_height = view_effective_height(ssd->view, /* use_pending */ false); - if (eff_width > 0 && eff_width < LAB_MIN_VIEW_WIDTH) { - /* - * Prevent negative values in calculations like - * `width - SSD_BUTTON_WIDTH * SSD_BUTTON_COUNT` - */ - wlr_log(WLR_ERROR, - "view width is smaller than its minimal value"); - return; - } - if (eff_width == cached.width && eff_height == cached.height) { if (current.x != cached.x || current.y != cached.y) { /* Dynamically resize extents based on position and usable_area */ @@ -267,6 +262,25 @@ ssd_update_geometry(struct ssd *ssd) } return; } + + if (current.width < LAB_MIN_VIEW_WIDTH) { + /* + * This draws a border-colored background behind the + * view for poorly behaving clients that don't follow + * our requested minimal size. + */ + if (!ssd->view_background) { + ssd->view_background = wlr_scene_rect_create(ssd->tree, 0, 0, + ssd->view == ssd->view->server->active_view + ? rc.theme->window_active_border_color + : rc.theme->window_inactive_border_color); + } + wlr_scene_rect_set_size(ssd->view_background, LAB_MIN_VIEW_WIDTH, current.height); + wlr_scene_node_set_enabled(&ssd->view_background->node, true); + } else if (ssd->view_background) { + wlr_scene_node_set_enabled(&ssd->view_background->node, false); + } + ssd_extents_update(ssd); ssd_titlebar_update(ssd); ssd_border_update(ssd); @@ -385,6 +399,11 @@ ssd_set_active(struct ssd *ssd, bool active) wlr_scene_node_set_enabled( &ssd->shadow.inactive.tree->node, !active); } + if (ssd->view_background) { + wlr_scene_rect_set_color(ssd->view_background, active + ? rc.theme->window_active_border_color + : rc.theme->window_inactive_border_color); + } } void @@ -465,5 +484,17 @@ ssd_debug_get_node_name(const struct ssd *ssd, struct wlr_scene_node *node) if (node == &ssd->extents.tree->node) { return "extents"; } + + /* These are only created on demand */ + if (ssd->shadow.active.tree && node == &ssd->shadow.active.tree->node) { + return "shadow.active"; + } + if (ssd->shadow.inactive.tree && node == &ssd->shadow.inactive.tree->node) { + return "shadow.inactive"; + } + if (ssd->view_background && node == &ssd->view_background->node) { + return "view_background"; + } + return NULL; }