aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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,
free(buf);
}
+void get_text_metrics(const char *font, int *height, int *baseline) {
+ cairo_t *cairo = cairo_create(NULL);
+ PangoContext *pango = pango_cairo_create_context(cairo);
+ PangoFontDescription *description = pango_font_description_from_string(font);
+ PangoFontMetrics *metrics;
+
+ // When passing NULL as a language, pango uses the current locale.
+ metrics = pango_context_get_metrics(pango, description, NULL);
+
+ *baseline = pango_font_metrics_get_ascent(metrics) / PANGO_SCALE;
+ *height = *baseline + pango_font_metrics_get_descent(metrics) / PANGO_SCALE;
+
+ pango_font_metrics_unref(metrics);
+ pango_font_description_free(description);
+ g_object_unref(pango);
+ cairo_destroy(cairo);
+}
+
void pango_printf(cairo_t *cairo, const char *font,
double scale, bool markup, const char *fmt, ...) {
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,
const char *text, double scale, bool markup);
void get_text_size(cairo_t *cairo, const char *font, int *width, int *height,
int *baseline, double scale, bool markup, const char *fmt, ...);
+void get_text_metrics(const char *font, int *height, int *baseline);
void pango_printf(cairo_t *cairo, const char *font,
double scale, bool markup, const char *fmt, ...);
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 {
enum sway_container_layout default_orientation;
enum sway_container_layout default_layout;
char *font;
- size_t font_height;
- size_t font_baseline;
+ int font_height;
+ int font_baseline;
bool pango_markup;
int titlebar_border_thickness;
int titlebar_h_padding;
@@ -696,14 +696,13 @@ void free_bar_binding(struct bar_binding *binding);
void free_workspace_config(struct workspace_config *wsc);
/**
- * Updates the value of config->font_height based on the max title height
- * reported by each container. If recalculate is true, the containers will
- * recalculate their heights before reporting.
- *
+ * Updates the value of config->font_height based on the metrics for title's
+ * font as reported by pango.
+ *
* If the height has changed, all containers will be rearranged to take on the
* new size.
*/
-void config_update_font_height(bool recalculate);
+void config_update_font_height(void);
/**
* 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 {
struct wlr_texture *title_focused_inactive;
struct wlr_texture *title_unfocused;
struct wlr_texture *title_urgent;
- size_t title_height;
- size_t title_baseline;
list_t *marks; // char *
struct wlr_texture *marks_focused;
@@ -183,11 +181,6 @@ struct sway_container *container_flatten(struct sway_container *container);
void container_update_title_textures(struct sway_container *container);
-/**
- * Calculate the container's title_height property.
- */
-void container_calculate_title_height(struct sway_container *container);
-
size_t container_build_representation(enum sway_container_layout layout,
list_t *children, char *buffer);
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) {
}
free(font);
- config_update_font_height(true);
+ config_update_font_height();
return cmd_results_new(CMD_SUCCESS, NULL);
}
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) {
}
list_free_items_and_destroy(bar_ids);
- config_update_font_height(true);
+ config_update_font_height();
root_for_each_container(rebuild_textures_iterator, NULL);
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) {
}
view->title_format = format;
view_update_title(view, true);
- config_update_font_height(true);
+ config_update_font_height();
return cmd_results_new(CMD_SUCCESS, NULL);
}
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) {
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;
+void config_update_font_height(void) {
+ int prev_max_height = config->font_height;
- root_for_each_container(find_baseline_iterator, &recalculate);
- root_for_each_container(find_font_height_iterator, NULL);
+ get_text_metrics(config->font, &config->font_height, &config->font_baseline);
if (config->font_height != prev_max_height) {
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,
// The title texture might be shorter than the config->font_height,
// in which case we need to pad it above and below.
- int ob_padding_above = round((config->font_baseline -
- con->title_baseline + titlebar_v_padding -
+ int ob_padding_above = round((titlebar_v_padding -
titlebar_border_thickness) * output_scale);
int ob_padding_below = ob_bg_height - ob_padding_above -
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,
double scale = output->wlr_output->scale;
int width = 0;
- int height = con->title_height * scale;
+ int height = config->font_height * scale;
+ int baseline;
// We must use a non-nil cairo_t for cairo_set_font_options to work.
// Therefore, we cannot use cairo_create(NULL).
@@ -527,7 +528,7 @@ static void update_title_texture(struct sway_container *con,
to_cairo_subpixel_order(output->wlr_output->subpixel));
}
cairo_set_font_options(c, fo);
- get_text_size(c, config->font, &width, NULL, NULL, scale,
+ get_text_size(c, config->font, &width, NULL, &baseline, scale,
config->pango_markup, "%s", con->formatted_title);
cairo_surface_destroy(dummy_surface);
cairo_destroy(c);
@@ -536,6 +537,10 @@ static void update_title_texture(struct sway_container *con,
return;
}
+ if (height > config->font_height * scale) {
+ height = config->font_height * scale;
+ }
+
cairo_surface_t *surface = cairo_image_surface_create(
CAIRO_FORMAT_ARGB32, width, height);
cairo_t *cairo = cairo_create(surface);
@@ -548,7 +553,7 @@ static void update_title_texture(struct sway_container *con,
PangoContext *pango = pango_cairo_create_context(cairo);
cairo_set_source_rgba(cairo, class->text[0], class->text[1],
class->text[2], class->text[3]);
- cairo_move_to(cairo, 0, 0);
+ cairo_move_to(cairo, 0, config->font_baseline * scale - baseline);
pango_printf(cairo, config->font, scale, config->pango_markup,
"%s", con->formatted_title);
@@ -577,21 +582,6 @@ void container_update_title_textures(struct sway_container *container) {
container_damage_whole(container);
}
-void container_calculate_title_height(struct sway_container *container) {
- if (!container->formatted_title) {
- container->title_height = 0;
- return;
- }
- cairo_t *cairo = cairo_create(NULL);
- int height;
- int baseline;
- get_text_size(cairo, config->font, NULL, &height, &baseline, 1,
- config->pango_markup, "%s", container->formatted_title);
- cairo_destroy(cairo);
- container->title_height = height;
- container->title_baseline = baseline;
-}
-
/**
* Calculate and return the length of the tree representation.
* An example tree representation is: V[Terminal, Firefox]
@@ -657,7 +647,6 @@ void container_update_representation(struct sway_container *con) {
}
container_build_representation(con->pending.layout, con->pending.children,
con->formatted_title);
- container_calculate_title_height(con);
container_update_title_textures(con);
}
if (con->pending.parent) {
@@ -1628,10 +1617,11 @@ static void update_marks_texture(struct sway_container *con,
double scale = output->wlr_output->scale;
int width = 0;
- int height = con->title_height * scale;
+ int height = config->font_height * scale;
+ int baseline;
cairo_t *c = cairo_create(NULL);
- get_text_size(c, config->font, &width, NULL, NULL, scale, false,
+ get_text_size(c, config->font, &width, NULL, &baseline, scale, false,
"%s", buffer);
cairo_destroy(c);
@@ -1639,6 +1629,10 @@ static void update_marks_texture(struct sway_container *con,
return;
}
+ if (height > config->font_height) {
+ height = config->font_height;
+ }
+
cairo_surface_t *surface = cairo_image_surface_create(
CAIRO_FORMAT_ARGB32, width, height);
cairo_t *cairo = cairo_create(surface);
@@ -1649,7 +1643,7 @@ static void update_marks_texture(struct sway_container *con,
cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST);
cairo_set_source_rgba(cairo, class->text[0], class->text[1],
class->text[2], class->text[3]);
- cairo_move_to(cairo, 0, 0);
+ cairo_move_to(cairo, 0, config->font_baseline * scale - baseline);
pango_printf(cairo, config->font, scale, false, "%s", buffer);
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) {
view->container->title = NULL;
view->container->formatted_title = NULL;
}
- container_calculate_title_height(view->container);
- config_update_font_height(false);
+ config_update_font_height();
// Update title after the global font height is updated
container_update_title_textures(view->container);