aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Hugo Osvaldo Barrera <hugo@barrera.io>2021-08-18 23:27:01 +0200
committerLibravatar Simon Ser <contact@emersion.fr>2021-08-26 20:16:14 +0200
commit62d90a8e959c6edcc752e124a9928cfa2399fbd1 (patch)
treed7f26db04a7a57b3b304768631348e8450197ba4
parentUpdate Pango font description URL in sway.5.scd (diff)
downloadsway-62d90a8e959c6edcc752e124a9928cfa2399fbd1.tar.gz
sway-62d90a8e959c6edcc752e124a9928cfa2399fbd1.tar.zst
sway-62d90a8e959c6edcc752e124a9928cfa2399fbd1.zip
Use fixed titlebar heights
Use fixed titlebar heights. The default height is calculated based on font metrics for the configured font and current locale. Some testing with titles with emoji and CJK characters (which are substantially higher in my setup) shows that the titlebars retain their initial value, text does shift up or down, and all titlebars always remain aligned. Also drop some also now-unecessary title_height calculations. Makes also needed to be updated, since they should be positioned with the same rules.
-rw-r--r--common/pango.c18
-rw-r--r--include/pango.h1
-rw-r--r--include/sway/config.h13
-rw-r--r--include/sway/tree/container.h7
-rw-r--r--sway/commands/font.c2
-rw-r--r--sway/commands/reload.c2
-rw-r--r--sway/commands/title_format.c2
-rw-r--r--sway/config.c26
-rw-r--r--sway/desktop/render.c3
-rw-r--r--sway/tree/container.c38
-rw-r--r--sway/tree/view.c3
11 files changed, 49 insertions, 66 deletions
diff --git a/common/pango.c b/common/pango.c
index dbc369dc..88932203 100644
--- a/common/pango.c
+++ b/common/pango.c
@@ -109,6 +109,24 @@ void get_text_size(cairo_t *cairo, const char *font, int *width, int *height,
109 free(buf); 109 free(buf);
110} 110}
111 111
112void get_text_metrics(const char *font, int *height, int *baseline) {
113 cairo_t *cairo = cairo_create(NULL);
114 PangoContext *pango = pango_cairo_create_context(cairo);
115 PangoFontDescription *description = pango_font_description_from_string(font);
116 PangoFontMetrics *metrics;
117
118 // When passing NULL as a language, pango uses the current locale.
119 metrics = pango_context_get_metrics(pango, description, NULL);
120
121 *baseline = pango_font_metrics_get_ascent(metrics) / PANGO_SCALE;
122 *height = *baseline + pango_font_metrics_get_descent(metrics) / PANGO_SCALE;
123
124 pango_font_metrics_unref(metrics);
125 pango_font_description_free(description);
126 g_object_unref(pango);
127 cairo_destroy(cairo);
128}
129
112void pango_printf(cairo_t *cairo, const char *font, 130void pango_printf(cairo_t *cairo, const char *font,
113 double scale, bool markup, const char *fmt, ...) { 131 double scale, bool markup, const char *fmt, ...) {
114 va_list args; 132 va_list args;
diff --git a/include/pango.h b/include/pango.h
index 75dbba27..7f41441b 100644
--- a/include/pango.h
+++ b/include/pango.h
@@ -17,6 +17,7 @@ PangoLayout *get_pango_layout(cairo_t *cairo, const char *font,
17 const char *text, double scale, bool markup); 17 const char *text, double scale, bool markup);
18void get_text_size(cairo_t *cairo, const char *font, int *width, int *height, 18void get_text_size(cairo_t *cairo, const char *font, int *width, int *height,
19 int *baseline, double scale, bool markup, const char *fmt, ...); 19 int *baseline, double scale, bool markup, const char *fmt, ...);
20void get_text_metrics(const char *font, int *height, int *baseline);
20void pango_printf(cairo_t *cairo, const char *font, 21void pango_printf(cairo_t *cairo, const char *font,
21 double scale, bool markup, const char *fmt, ...); 22 double scale, bool markup, const char *fmt, ...);
22 23
diff --git a/include/sway/config.h b/include/sway/config.h
index b8327e9c..d6c29fe6 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -486,8 +486,8 @@ struct sway_config {
486 enum sway_container_layout default_orientation; 486 enum sway_container_layout default_orientation;
487 enum sway_container_layout default_layout; 487 enum sway_container_layout default_layout;
488 char *font; 488 char *font;
489 size_t font_height; 489 int font_height;
490 size_t font_baseline; 490 int font_baseline;
491 bool pango_markup; 491 bool pango_markup;
492 int titlebar_border_thickness; 492 int titlebar_border_thickness;
493 int titlebar_h_padding; 493 int titlebar_h_padding;
@@ -696,14 +696,13 @@ void free_bar_binding(struct bar_binding *binding);
696void free_workspace_config(struct workspace_config *wsc); 696void free_workspace_config(struct workspace_config *wsc);
697 697
698/** 698/**
699 * Updates the value of config->font_height based on the max title height 699 * Updates the value of config->font_height based on the metrics for title's
700 * reported by each container. If recalculate is true, the containers will 700 * font as reported by pango.
701 * recalculate their heights before reporting. 701 *
702 *
703 * If the height has changed, all containers will be rearranged to take on the 702 * If the height has changed, all containers will be rearranged to take on the
704 * new size. 703 * new size.
705 */ 704 */
706void config_update_font_height(bool recalculate); 705void config_update_font_height(void);
707 706
708/** 707/**
709 * Convert bindsym into bindcode using the first configured layout. 708 * Convert bindsym into bindcode using the first configured layout.
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
index 38ee68bd..97fa98c1 100644
--- a/include/sway/tree/container.h
+++ b/include/sway/tree/container.h
@@ -119,8 +119,6 @@ struct sway_container {
119 struct wlr_texture *title_focused_inactive; 119 struct wlr_texture *title_focused_inactive;
120 struct wlr_texture *title_unfocused; 120 struct wlr_texture *title_unfocused;
121 struct wlr_texture *title_urgent; 121 struct wlr_texture *title_urgent;
122 size_t title_height;
123 size_t title_baseline;
124 122
125 list_t *marks; // char * 123 list_t *marks; // char *
126 struct wlr_texture *marks_focused; 124 struct wlr_texture *marks_focused;
@@ -183,11 +181,6 @@ struct sway_container *container_flatten(struct sway_container *container);
183 181
184void container_update_title_textures(struct sway_container *container); 182void container_update_title_textures(struct sway_container *container);
185 183
186/**
187 * Calculate the container's title_height property.
188 */
189void container_calculate_title_height(struct sway_container *container);
190
191size_t container_build_representation(enum sway_container_layout layout, 184size_t container_build_representation(enum sway_container_layout layout,
192 list_t *children, char *buffer); 185 list_t *children, char *buffer);
193 186
diff --git a/sway/commands/font.c b/sway/commands/font.c
index c54365b5..cea720f5 100644
--- a/sway/commands/font.c
+++ b/sway/commands/font.c
@@ -22,6 +22,6 @@ struct cmd_results *cmd_font(int argc, char **argv) {
22 } 22 }
23 23
24 free(font); 24 free(font);
25 config_update_font_height(true); 25 config_update_font_height();
26 return cmd_results_new(CMD_SUCCESS, NULL); 26 return cmd_results_new(CMD_SUCCESS, NULL);
27} 27}
diff --git a/sway/commands/reload.c b/sway/commands/reload.c
index 3c994d54..09ccd9d4 100644
--- a/sway/commands/reload.c
+++ b/sway/commands/reload.c
@@ -48,7 +48,7 @@ static void do_reload(void *data) {
48 } 48 }
49 list_free_items_and_destroy(bar_ids); 49 list_free_items_and_destroy(bar_ids);
50 50
51 config_update_font_height(true); 51 config_update_font_height();
52 root_for_each_container(rebuild_textures_iterator, NULL); 52 root_for_each_container(rebuild_textures_iterator, NULL);
53 53
54 arrange_root(); 54 arrange_root();
diff --git a/sway/commands/title_format.c b/sway/commands/title_format.c
index 9d312470..8d907e76 100644
--- a/sway/commands/title_format.c
+++ b/sway/commands/title_format.c
@@ -23,6 +23,6 @@ struct cmd_results *cmd_title_format(int argc, char **argv) {
23 } 23 }
24 view->title_format = format; 24 view->title_format = format;
25 view_update_title(view, true); 25 view_update_title(view, true);
26 config_update_font_height(true); 26 config_update_font_height();
27 return cmd_results_new(CMD_SUCCESS, NULL); 27 return cmd_results_new(CMD_SUCCESS, NULL);
28} 28}
diff --git a/sway/config.c b/sway/config.c
index fde386c7..1ddedc7e 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -991,31 +991,11 @@ int workspace_output_cmp_workspace(const void *a, const void *b) {
991 return lenient_strcmp(wsa->workspace, wsb->workspace); 991 return lenient_strcmp(wsa->workspace, wsb->workspace);
992} 992}
993 993
994static void find_font_height_iterator(struct sway_container *con, void *data) {
995 size_t amount_below_baseline = con->title_height - con->title_baseline;
996 size_t extended_height = config->font_baseline + amount_below_baseline;
997 if (extended_height > config->font_height) {
998 config->font_height = extended_height;
999 }
1000}
1001
1002static void find_baseline_iterator(struct sway_container *con, void *data) {
1003 bool *recalculate = data;
1004 if (*recalculate) {
1005 container_calculate_title_height(con);
1006 }
1007 if (con->title_baseline > config->font_baseline) {
1008 config->font_baseline = con->title_baseline;
1009 }
1010}
1011 994
1012void config_update_font_height(bool recalculate) { 995void config_update_font_height(void) {
1013 size_t prev_max_height = config->font_height; 996 int prev_max_height = config->font_height;
1014 config->font_height = 0;
1015 config->font_baseline = 0;
1016 997
1017 root_for_each_container(find_baseline_iterator, &recalculate); 998 get_text_metrics(config->font, &config->font_height, &config->font_baseline);
1018 root_for_each_container(find_font_height_iterator, NULL);
1019 999
1020 if (config->font_height != prev_max_height) { 1000 if (config->font_height != prev_max_height) {
1021 arrange_root(); 1001 arrange_root();
diff --git a/sway/desktop/render.c b/sway/desktop/render.c
index a5bd8a5f..d25df570 100644
--- a/sway/desktop/render.c
+++ b/sway/desktop/render.c
@@ -559,8 +559,7 @@ static void render_titlebar(struct sway_output *output,
559 559
560 // The title texture might be shorter than the config->font_height, 560 // The title texture might be shorter than the config->font_height,
561 // in which case we need to pad it above and below. 561 // in which case we need to pad it above and below.
562 int ob_padding_above = round((config->font_baseline - 562 int ob_padding_above = round((titlebar_v_padding -
563 con->title_baseline + titlebar_v_padding -
564 titlebar_border_thickness) * output_scale); 563 titlebar_border_thickness) * output_scale);
565 int ob_padding_below = ob_bg_height - ob_padding_above - 564 int ob_padding_below = ob_bg_height - ob_padding_above -
566 texture_box.height; 565 texture_box.height;
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 3b661046..00c40218 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -509,7 +509,8 @@ static void update_title_texture(struct sway_container *con,
509 509
510 double scale = output->wlr_output->scale; 510 double scale = output->wlr_output->scale;
511 int width = 0; 511 int width = 0;
512 int height = con->title_height * scale; 512 int height = config->font_height * scale;
513 int baseline;
513 514
514 // We must use a non-nil cairo_t for cairo_set_font_options to work. 515 // We must use a non-nil cairo_t for cairo_set_font_options to work.
515 // Therefore, we cannot use cairo_create(NULL). 516 // Therefore, we cannot use cairo_create(NULL).
@@ -527,7 +528,7 @@ static void update_title_texture(struct sway_container *con,
527 to_cairo_subpixel_order(output->wlr_output->subpixel)); 528 to_cairo_subpixel_order(output->wlr_output->subpixel));
528 } 529 }
529 cairo_set_font_options(c, fo); 530 cairo_set_font_options(c, fo);
530 get_text_size(c, config->font, &width, NULL, NULL, scale, 531 get_text_size(c, config->font, &width, NULL, &baseline, scale,
531 config->pango_markup, "%s", con->formatted_title); 532 config->pango_markup, "%s", con->formatted_title);
532 cairo_surface_destroy(dummy_surface); 533 cairo_surface_destroy(dummy_surface);
533 cairo_destroy(c); 534 cairo_destroy(c);
@@ -536,6 +537,10 @@ static void update_title_texture(struct sway_container *con,
536 return; 537 return;
537 } 538 }
538 539
540 if (height > config->font_height * scale) {
541 height = config->font_height * scale;
542 }
543
539 cairo_surface_t *surface = cairo_image_surface_create( 544 cairo_surface_t *surface = cairo_image_surface_create(
540 CAIRO_FORMAT_ARGB32, width, height); 545 CAIRO_FORMAT_ARGB32, width, height);
541 cairo_t *cairo = cairo_create(surface); 546 cairo_t *cairo = cairo_create(surface);
@@ -548,7 +553,7 @@ static void update_title_texture(struct sway_container *con,
548 PangoContext *pango = pango_cairo_create_context(cairo); 553 PangoContext *pango = pango_cairo_create_context(cairo);
549 cairo_set_source_rgba(cairo, class->text[0], class->text[1], 554 cairo_set_source_rgba(cairo, class->text[0], class->text[1],
550 class->text[2], class->text[3]); 555 class->text[2], class->text[3]);
551 cairo_move_to(cairo, 0, 0); 556 cairo_move_to(cairo, 0, config->font_baseline * scale - baseline);
552 557
553 pango_printf(cairo, config->font, scale, config->pango_markup, 558 pango_printf(cairo, config->font, scale, config->pango_markup,
554 "%s", con->formatted_title); 559 "%s", con->formatted_title);
@@ -577,21 +582,6 @@ void container_update_title_textures(struct sway_container *container) {
577 container_damage_whole(container); 582 container_damage_whole(container);
578} 583}
579 584
580void container_calculate_title_height(struct sway_container *container) {
581 if (!container->formatted_title) {
582 container->title_height = 0;
583 return;
584 }
585 cairo_t *cairo = cairo_create(NULL);
586 int height;
587 int baseline;
588 get_text_size(cairo, config->font, NULL, &height, &baseline, 1,
589 config->pango_markup, "%s", container->formatted_title);
590 cairo_destroy(cairo);
591 container->title_height = height;
592 container->title_baseline = baseline;
593}
594
595/** 585/**
596 * Calculate and return the length of the tree representation. 586 * Calculate and return the length of the tree representation.
597 * An example tree representation is: V[Terminal, Firefox] 587 * An example tree representation is: V[Terminal, Firefox]
@@ -657,7 +647,6 @@ void container_update_representation(struct sway_container *con) {
657 } 647 }
658 container_build_representation(con->pending.layout, con->pending.children, 648 container_build_representation(con->pending.layout, con->pending.children,
659 con->formatted_title); 649 con->formatted_title);
660 container_calculate_title_height(con);
661 container_update_title_textures(con); 650 container_update_title_textures(con);
662 } 651 }
663 if (con->pending.parent) { 652 if (con->pending.parent) {
@@ -1628,10 +1617,11 @@ static void update_marks_texture(struct sway_container *con,
1628 1617
1629 double scale = output->wlr_output->scale; 1618 double scale = output->wlr_output->scale;
1630 int width = 0; 1619 int width = 0;
1631 int height = con->title_height * scale; 1620 int height = config->font_height * scale;
1621 int baseline;
1632 1622
1633 cairo_t *c = cairo_create(NULL); 1623 cairo_t *c = cairo_create(NULL);
1634 get_text_size(c, config->font, &width, NULL, NULL, scale, false, 1624 get_text_size(c, config->font, &width, NULL, &baseline, scale, false,
1635 "%s", buffer); 1625 "%s", buffer);
1636 cairo_destroy(c); 1626 cairo_destroy(c);
1637 1627
@@ -1639,6 +1629,10 @@ static void update_marks_texture(struct sway_container *con,
1639 return; 1629 return;
1640 } 1630 }
1641 1631
1632 if (height > config->font_height) {
1633 height = config->font_height;
1634 }
1635
1642 cairo_surface_t *surface = cairo_image_surface_create( 1636 cairo_surface_t *surface = cairo_image_surface_create(
1643 CAIRO_FORMAT_ARGB32, width, height); 1637 CAIRO_FORMAT_ARGB32, width, height);
1644 cairo_t *cairo = cairo_create(surface); 1638 cairo_t *cairo = cairo_create(surface);
@@ -1649,7 +1643,7 @@ static void update_marks_texture(struct sway_container *con,
1649 cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); 1643 cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST);
1650 cairo_set_source_rgba(cairo, class->text[0], class->text[1], 1644 cairo_set_source_rgba(cairo, class->text[0], class->text[1],
1651 class->text[2], class->text[3]); 1645 class->text[2], class->text[3]);
1652 cairo_move_to(cairo, 0, 0); 1646 cairo_move_to(cairo, 0, config->font_baseline * scale - baseline);
1653 1647
1654 pango_printf(cairo, config->font, scale, false, "%s", buffer); 1648 pango_printf(cairo, config->font, scale, false, "%s", buffer);
1655 1649
diff --git a/sway/tree/view.c b/sway/tree/view.c
index fcdd06f7..3ab971f7 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -1285,8 +1285,7 @@ void view_update_title(struct sway_view *view, bool force) {
1285 view->container->title = NULL; 1285 view->container->title = NULL;
1286 view->container->formatted_title = NULL; 1286 view->container->formatted_title = NULL;
1287 } 1287 }
1288 container_calculate_title_height(view->container); 1288 config_update_font_height();
1289 config_update_font_height(false);
1290 1289
1291 // Update title after the global font height is updated 1290 // Update title after the global font height is updated
1292 container_update_title_textures(view->container); 1291 container_update_title_textures(view->container);