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.
This commit is contained in:
Hugo Osvaldo Barrera 2021-08-11 21:09:02 +02:00
parent b345d6e5d2
commit dca4de48a9

View file

@ -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();