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.
master
Hugo Osvaldo Barrera 3 years ago committed by Simon Ser
parent bb3fd0abc5
commit 62d90a8e95

@ -109,6 +109,24 @@ void get_text_size(cairo_t *cairo, const char *font, int *width, int *height,
free(buf); 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, void pango_printf(cairo_t *cairo, const char *font,
double scale, bool markup, const char *fmt, ...) { double scale, bool markup, const char *fmt, ...) {
va_list args; va_list args;

@ -17,6 +17,7 @@ PangoLayout *get_pango_layout(cairo_t *cairo, const char *font,
const char *text, double scale, bool markup); const char *text, double scale, bool markup);
void get_text_size(cairo_t *cairo, const char *font, int *width, int *height, void get_text_size(cairo_t *cairo, const char *font, int *width, int *height,
int *baseline, double scale, bool markup, const char *fmt, ...); 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, void pango_printf(cairo_t *cairo, const char *font,
double scale, bool markup, const char *fmt, ...); double scale, bool markup, const char *fmt, ...);

@ -486,8 +486,8 @@ struct sway_config {
enum sway_container_layout default_orientation; enum sway_container_layout default_orientation;
enum sway_container_layout default_layout; enum sway_container_layout default_layout;
char *font; char *font;
size_t font_height; int font_height;
size_t font_baseline; int font_baseline;
bool pango_markup; bool pango_markup;
int titlebar_border_thickness; int titlebar_border_thickness;
int titlebar_h_padding; int titlebar_h_padding;
@ -696,14 +696,13 @@ void free_bar_binding(struct bar_binding *binding);
void free_workspace_config(struct workspace_config *wsc); void free_workspace_config(struct workspace_config *wsc);
/** /**
* Updates the value of config->font_height based on the max title height * Updates the value of config->font_height based on the metrics for title's
* reported by each container. If recalculate is true, the containers will * font as reported by pango.
* recalculate their heights before reporting.
* *
* If the height has changed, all containers will be rearranged to take on the * If the height has changed, all containers will be rearranged to take on the
* new size. * new size.
*/ */
void config_update_font_height(bool recalculate); void config_update_font_height(void);
/** /**
* Convert bindsym into bindcode using the first configured layout. * Convert bindsym into bindcode using the first configured layout.

@ -119,8 +119,6 @@ struct sway_container {
struct wlr_texture *title_focused_inactive; struct wlr_texture *title_focused_inactive;
struct wlr_texture *title_unfocused; struct wlr_texture *title_unfocused;
struct wlr_texture *title_urgent; struct wlr_texture *title_urgent;
size_t title_height;
size_t title_baseline;
list_t *marks; // char * list_t *marks; // char *
struct wlr_texture *marks_focused; 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); 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, size_t container_build_representation(enum sway_container_layout layout,
list_t *children, char *buffer); list_t *children, char *buffer);

@ -22,6 +22,6 @@ struct cmd_results *cmd_font(int argc, char **argv) {
} }
free(font); free(font);
config_update_font_height(true); config_update_font_height();
return cmd_results_new(CMD_SUCCESS, NULL); return cmd_results_new(CMD_SUCCESS, NULL);
} }

@ -48,7 +48,7 @@ static void do_reload(void *data) {
} }
list_free_items_and_destroy(bar_ids); list_free_items_and_destroy(bar_ids);
config_update_font_height(true); config_update_font_height();
root_for_each_container(rebuild_textures_iterator, NULL); root_for_each_container(rebuild_textures_iterator, NULL);
arrange_root(); arrange_root();

@ -23,6 +23,6 @@ struct cmd_results *cmd_title_format(int argc, char **argv) {
} }
view->title_format = format; view->title_format = format;
view_update_title(view, true); view_update_title(view, true);
config_update_font_height(true); config_update_font_height();
return cmd_results_new(CMD_SUCCESS, NULL); return cmd_results_new(CMD_SUCCESS, NULL);
} }

@ -991,31 +991,11 @@ int workspace_output_cmp_workspace(const void *a, const void *b) {
return lenient_strcmp(wsa->workspace, wsb->workspace); 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) { void config_update_font_height(void) {
size_t prev_max_height = config->font_height; int prev_max_height = config->font_height;
config->font_height = 0;
config->font_baseline = 0;
root_for_each_container(find_baseline_iterator, &recalculate); get_text_metrics(config->font, &config->font_height, &config->font_baseline);
root_for_each_container(find_font_height_iterator, NULL);
if (config->font_height != prev_max_height) { if (config->font_height != prev_max_height) {
arrange_root(); arrange_root();

@ -559,8 +559,7 @@ static void render_titlebar(struct sway_output *output,
// The title texture might be shorter than the config->font_height, // The title texture might be shorter than the config->font_height,
// in which case we need to pad it above and below. // in which case we need to pad it above and below.
int ob_padding_above = round((config->font_baseline - int ob_padding_above = round((titlebar_v_padding -
con->title_baseline + titlebar_v_padding -
titlebar_border_thickness) * output_scale); titlebar_border_thickness) * output_scale);
int ob_padding_below = ob_bg_height - ob_padding_above - int ob_padding_below = ob_bg_height - ob_padding_above -
texture_box.height; texture_box.height;

@ -509,7 +509,8 @@ static void update_title_texture(struct sway_container *con,
double scale = output->wlr_output->scale; double scale = output->wlr_output->scale;
int width = 0; 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. // We must use a non-nil cairo_t for cairo_set_font_options to work.
// Therefore, we cannot use cairo_create(NULL). // 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)); to_cairo_subpixel_order(output->wlr_output->subpixel));
} }
cairo_set_font_options(c, fo); 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); config->pango_markup, "%s", con->formatted_title);
cairo_surface_destroy(dummy_surface); cairo_surface_destroy(dummy_surface);
cairo_destroy(c); cairo_destroy(c);
@ -536,6 +537,10 @@ static void update_title_texture(struct sway_container *con,
return; return;
} }
if (height > config->font_height * scale) {
height = config->font_height * scale;
}
cairo_surface_t *surface = cairo_image_surface_create( cairo_surface_t *surface = cairo_image_surface_create(
CAIRO_FORMAT_ARGB32, width, height); CAIRO_FORMAT_ARGB32, width, height);
cairo_t *cairo = cairo_create(surface); 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); PangoContext *pango = pango_cairo_create_context(cairo);
cairo_set_source_rgba(cairo, class->text[0], class->text[1], cairo_set_source_rgba(cairo, class->text[0], class->text[1],
class->text[2], class->text[3]); 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, pango_printf(cairo, config->font, scale, config->pango_markup,
"%s", con->formatted_title); "%s", con->formatted_title);
@ -577,21 +582,6 @@ void container_update_title_textures(struct sway_container *container) {
container_damage_whole(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. * Calculate and return the length of the tree representation.
* An example tree representation is: V[Terminal, Firefox] * 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, container_build_representation(con->pending.layout, con->pending.children,
con->formatted_title); con->formatted_title);
container_calculate_title_height(con);
container_update_title_textures(con); container_update_title_textures(con);
} }
if (con->pending.parent) { if (con->pending.parent) {
@ -1628,10 +1617,11 @@ static void update_marks_texture(struct sway_container *con,
double scale = output->wlr_output->scale; double scale = output->wlr_output->scale;
int width = 0; int width = 0;
int height = con->title_height * scale; int height = config->font_height * scale;
int baseline;
cairo_t *c = cairo_create(NULL); 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); "%s", buffer);
cairo_destroy(c); cairo_destroy(c);
@ -1639,6 +1629,10 @@ static void update_marks_texture(struct sway_container *con,
return; return;
} }
if (height > config->font_height) {
height = config->font_height;
}
cairo_surface_t *surface = cairo_image_surface_create( cairo_surface_t *surface = cairo_image_surface_create(
CAIRO_FORMAT_ARGB32, width, height); CAIRO_FORMAT_ARGB32, width, height);
cairo_t *cairo = cairo_create(surface); 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_antialias(cairo, CAIRO_ANTIALIAS_BEST);
cairo_set_source_rgba(cairo, class->text[0], class->text[1], cairo_set_source_rgba(cairo, class->text[0], class->text[1],
class->text[2], class->text[3]); 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); pango_printf(cairo, config->font, scale, false, "%s", buffer);

@ -1285,8 +1285,7 @@ void view_update_title(struct sway_view *view, bool force) {
view->container->title = NULL; view->container->title = NULL;
view->container->formatted_title = NULL; view->container->formatted_title = NULL;
} }
container_calculate_title_height(view->container); config_update_font_height();
config_update_font_height(false);
// Update title after the global font height is updated // Update title after the global font height is updated
container_update_title_textures(view->container); container_update_title_textures(view->container);

Loading…
Cancel
Save