From dca4de48a9f159ad55b6c046e086e2ef6b6928fe Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Wed, 11 Aug 2021 21:09:02 +0200 Subject: [PATCH] Use fixed titlebar heights Currently the height of titlebars can vary depending on their text. If the text contains latin characters, then the height of those characters (in whatever font applies) will define the titlebar height. If a text contains CJK characters, the height of that font will determine the height. The same applies for emoji and any other character that's available only in the non-default font. This issue is annoying in itself, but because all existing windows are immediately resized, all applications need to rerender and this frequently results in some of them crashing (Firefox, Chromium and Signal are all curlpits here). I've only been able to reproduce this with many windows open, so I suspect it's a matter of too much load for the system to handle. This quickly escalates to the point where visiting websites with emoji in their title can kill all browser windows. Additionally, when the titlebar of a window grows, it's first rendered cropped, and the actual height only updates when there's a change in the focused window (I'm sure other state changes trigger a redraw too), at which point it's no longer cropped. The approach taken here calculates the expected titlebar height based on a short set of characters. Since these are likely to all use different fonts, titlebars will be big enough to fit latin, CJK or emoji characters without resizing. I'm sure this still leaves out specific languages (e.g.: arabic character bigger?). There's two ways to further improve this situation: - Add a single character of each acceptable family to the same text used. - Make the sample text user-configurable. This would allow a user to configure which font-families he expects to see, any anything bigger will be cropped. I don't feel the benefits are worth the effort here, but have nothing against it. --- sway/config.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/sway/config.c b/sway/config.c index fde386c78..36b58198c 100644 --- a/sway/config.c +++ b/sway/config.c @@ -991,31 +991,18 @@ int workspace_output_cmp_workspace(const void *a, const void *b) { return lenient_strcmp(wsa->workspace, wsb->workspace); } -static void find_font_height_iterator(struct sway_container *con, void *data) { - size_t amount_below_baseline = con->title_height - con->title_baseline; - size_t extended_height = config->font_baseline + amount_below_baseline; - if (extended_height > config->font_height) { - config->font_height = extended_height; - } -} - -static void find_baseline_iterator(struct sway_container *con, void *data) { - bool *recalculate = data; - if (*recalculate) { - container_calculate_title_height(con); - } - if (con->title_baseline > config->font_baseline) { - config->font_baseline = con->title_baseline; - } -} - void config_update_font_height(bool recalculate) { size_t prev_max_height = config->font_height; - config->font_height = 0; - config->font_baseline = 0; - root_for_each_container(find_baseline_iterator, &recalculate); - root_for_each_container(find_font_height_iterator, NULL); + cairo_t *cairo = cairo_create(NULL); + int height; + int baseline; + get_text_size(cairo, config->font, NULL, &height, &baseline, 1, + config->pango_markup, "%s", "Panda 🐼 熊猫 판다"); + cairo_destroy(cairo); + + config->font_height = height; + config->font_baseline = baseline; if (config->font_height != prev_max_height) { arrange_root();