mirror of
https://github.com/swaywm/sway.git
synced 2024-12-30 17:06:40 +01:00
Merge pull request #2602 from RyanDwyer/fix-title-textures
Fix gaps in title textures and vertically center them
This commit is contained in:
commit
3600b3db57
11 changed files with 111 additions and 48 deletions
|
@ -103,7 +103,7 @@ PangoLayout *get_pango_layout(cairo_t *cairo, const char *font,
|
|||
}
|
||||
|
||||
void get_text_size(cairo_t *cairo, const char *font, int *width, int *height,
|
||||
double scale, bool markup, const char *fmt, ...) {
|
||||
int *baseline, double scale, bool markup, const char *fmt, ...) {
|
||||
static char buf[2048];
|
||||
|
||||
va_list args;
|
||||
|
@ -116,6 +116,9 @@ void get_text_size(cairo_t *cairo, const char *font, int *width, int *height,
|
|||
PangoLayout *layout = get_pango_layout(cairo, font, buf, scale, markup);
|
||||
pango_cairo_update_layout(cairo, layout);
|
||||
pango_layout_get_pixel_size(layout, width, height);
|
||||
if (baseline) {
|
||||
*baseline = pango_layout_get_baseline(layout) / PANGO_SCALE;
|
||||
}
|
||||
g_object_unref(layout);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ int escape_markup_text(const char *src, char *dest, int dest_length);
|
|||
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,
|
||||
double scale, bool markup, const char *fmt, ...);
|
||||
int *baseline, double scale, bool markup, const char *fmt, ...);
|
||||
void pango_printf(cairo_t *cairo, const char *font,
|
||||
double scale, bool markup, const char *fmt, ...);
|
||||
|
||||
|
|
|
@ -349,6 +349,7 @@ struct sway_config {
|
|||
enum sway_container_layout default_layout;
|
||||
char *font;
|
||||
size_t font_height;
|
||||
size_t font_baseline;
|
||||
bool pango_markup;
|
||||
size_t urgent_timeout;
|
||||
enum sway_fowa focus_on_window_activation;
|
||||
|
|
|
@ -117,6 +117,7 @@ struct sway_container {
|
|||
struct wlr_texture *title_unfocused;
|
||||
struct wlr_texture *title_urgent;
|
||||
size_t title_height;
|
||||
size_t title_baseline;
|
||||
|
||||
struct {
|
||||
struct wl_signal destroy;
|
||||
|
|
|
@ -807,22 +807,31 @@ 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 *container,
|
||||
void *data) {
|
||||
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(container);
|
||||
container_calculate_title_height(con);
|
||||
}
|
||||
if (container->title_height > config->font_height) {
|
||||
config->font_height = container->title_height;
|
||||
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_font_height_iterator, &recalculate);
|
||||
root_for_each_container(find_baseline_iterator, &recalculate);
|
||||
root_for_each_container(find_font_height_iterator, NULL);
|
||||
|
||||
if (config->font_height != prev_max_height) {
|
||||
arrange_root();
|
||||
|
|
|
@ -84,7 +84,7 @@ static int draw_node(cairo_t *cairo, struct sway_node *node,
|
|||
struct sway_node *focus, int x, int y) {
|
||||
int text_width, text_height;
|
||||
char *buffer = get_string(node);
|
||||
get_text_size(cairo, "monospace", &text_width, &text_height,
|
||||
get_text_size(cairo, "monospace", &text_width, &text_height, NULL,
|
||||
1, false, buffer);
|
||||
cairo_save(cairo);
|
||||
cairo_rectangle(cairo, x + 2, y, text_width - 2, text_height);
|
||||
|
|
|
@ -146,6 +146,8 @@ static void render_drag_icons(struct sway_output *output,
|
|||
render_surface_iterator, &data);
|
||||
}
|
||||
|
||||
// _box.x and .y are expected to be layout-local
|
||||
// _box.width and .height are expected to be output-buffer-local
|
||||
static void render_rect(struct wlr_output *wlr_output,
|
||||
pixman_region32_t *output_damage, const struct wlr_box *_box,
|
||||
float color[static 4]) {
|
||||
|
@ -404,9 +406,20 @@ static void render_titlebar(struct sway_output *output,
|
|||
struct wlr_box texture_box;
|
||||
wlr_texture_get_size(marks_texture,
|
||||
&texture_box.width, &texture_box.height);
|
||||
marks_ob_width = texture_box.width;
|
||||
|
||||
// The marks texture might be shorter than the config->font_height, in
|
||||
// which case we need to pad it as evenly as possible above and below.
|
||||
int ob_padding_total = config->font_height * output_scale -
|
||||
texture_box.height;
|
||||
int ob_padding_above = floor(ob_padding_total / 2);
|
||||
int ob_padding_below = ceil(ob_padding_total / 2);
|
||||
|
||||
// Render texture
|
||||
texture_box.x = (x - output_x + width - TITLEBAR_H_PADDING)
|
||||
* output_scale - texture_box.width;
|
||||
texture_box.y = (y - output_y + TITLEBAR_V_PADDING) * output_scale;
|
||||
texture_box.y = (y - output_y + TITLEBAR_V_PADDING) * output_scale +
|
||||
ob_padding_above;
|
||||
|
||||
float matrix[9];
|
||||
wlr_matrix_project_box(matrix, &texture_box,
|
||||
|
@ -418,17 +431,29 @@ static void render_titlebar(struct sway_output *output,
|
|||
}
|
||||
render_texture(output->wlr_output, output_damage, marks_texture,
|
||||
&texture_box, matrix, con->alpha);
|
||||
marks_ob_width = texture_box.width;
|
||||
|
||||
// Gap between the marks and bottom padding, for when the marks texture
|
||||
// height is smaller than the config's font height
|
||||
// Padding above
|
||||
if (ob_padding_above > 0) {
|
||||
memcpy(&color, colors->background, sizeof(float) * 4);
|
||||
premultiply_alpha(color, con->alpha);
|
||||
box.x = texture_box.x;
|
||||
box.y = texture_box.y + texture_box.height;
|
||||
box.x = (x + width - TITLEBAR_H_PADDING) * output_scale -
|
||||
texture_box.width;
|
||||
box.y = (y + TITLEBAR_V_PADDING) * output_scale;
|
||||
box.width = texture_box.width;
|
||||
box.height = config->font_height * output_scale - texture_box.height;
|
||||
if (box.height > 0) {
|
||||
box.height = ob_padding_above;
|
||||
render_rect(output->wlr_output, output_damage, &box, color);
|
||||
}
|
||||
|
||||
// Padding below
|
||||
if (ob_padding_below > 0) {
|
||||
memcpy(&color, colors->background, sizeof(float) * 4);
|
||||
premultiply_alpha(color, con->alpha);
|
||||
box.x = (x + width - TITLEBAR_H_PADDING) * output_scale -
|
||||
texture_box.width;
|
||||
box.y = (y + TITLEBAR_V_PADDING) * output_scale +
|
||||
ob_padding_above + texture_box.height;
|
||||
box.width = texture_box.width;
|
||||
box.height = ob_padding_below;
|
||||
render_rect(output->wlr_output, output_damage, &box, color);
|
||||
}
|
||||
}
|
||||
|
@ -439,8 +464,19 @@ static void render_titlebar(struct sway_output *output,
|
|||
struct wlr_box texture_box;
|
||||
wlr_texture_get_size(title_texture,
|
||||
&texture_box.width, &texture_box.height);
|
||||
title_ob_width = texture_box.width;
|
||||
|
||||
// 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 = (config->font_baseline - con->title_baseline)
|
||||
* output_scale;
|
||||
int ob_padding_below = (config->font_height - con->title_height)
|
||||
* output_scale - ob_padding_above;
|
||||
|
||||
// Render texture
|
||||
texture_box.x = (x - output_x + TITLEBAR_H_PADDING) * output_scale;
|
||||
texture_box.y = (y - output_y + TITLEBAR_V_PADDING) * output_scale;
|
||||
texture_box.y = (y - output_y + TITLEBAR_V_PADDING) * output_scale +
|
||||
ob_padding_above;
|
||||
|
||||
float matrix[9];
|
||||
wlr_matrix_project_box(matrix, &texture_box,
|
||||
|
@ -452,17 +488,27 @@ static void render_titlebar(struct sway_output *output,
|
|||
}
|
||||
render_texture(output->wlr_output, output_damage, title_texture,
|
||||
&texture_box, matrix, con->alpha);
|
||||
title_ob_width = texture_box.width;
|
||||
|
||||
// Gap between the title and bottom padding, for when the title texture
|
||||
// height is smaller than the config's font height
|
||||
// Padding above
|
||||
if (ob_padding_above > 0) {
|
||||
memcpy(&color, colors->background, sizeof(float) * 4);
|
||||
premultiply_alpha(color, con->alpha);
|
||||
box.x = texture_box.x;
|
||||
box.y = texture_box.y + texture_box.height;
|
||||
box.x = (x + TITLEBAR_H_PADDING) * output_scale;
|
||||
box.y = (y + TITLEBAR_V_PADDING) * output_scale;
|
||||
box.width = texture_box.width;
|
||||
box.height = config->font_height * output_scale - texture_box.height;
|
||||
if (box.height > 0) {
|
||||
box.height = ob_padding_above;
|
||||
render_rect(output->wlr_output, output_damage, &box, color);
|
||||
}
|
||||
|
||||
// Padding below
|
||||
if (ob_padding_below > 0) {
|
||||
memcpy(&color, colors->background, sizeof(float) * 4);
|
||||
premultiply_alpha(color, con->alpha);
|
||||
box.x = (x + TITLEBAR_H_PADDING) * output_scale;
|
||||
box.y = (y + TITLEBAR_V_PADDING) * output_scale +
|
||||
ob_padding_above + texture_box.height;
|
||||
box.width = texture_box.width;
|
||||
box.height = ob_padding_below;
|
||||
render_rect(output->wlr_output, output_damage, &box, color);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -455,8 +455,8 @@ static void update_title_texture(struct sway_container *con,
|
|||
int height = con->title_height * scale;
|
||||
|
||||
cairo_t *c = cairo_create(NULL);
|
||||
get_text_size(c, config->font, &width, NULL, scale, config->pango_markup,
|
||||
"%s", con->formatted_title);
|
||||
get_text_size(c, config->font, &width, NULL, NULL, scale,
|
||||
config->pango_markup, "%s", con->formatted_title);
|
||||
cairo_destroy(c);
|
||||
|
||||
cairo_surface_t *surface = cairo_image_surface_create(
|
||||
|
@ -505,10 +505,12 @@ void container_calculate_title_height(struct sway_container *container) {
|
|||
}
|
||||
cairo_t *cairo = cairo_create(NULL);
|
||||
int height;
|
||||
get_text_size(cairo, config->font, NULL, &height, 1, config->pango_markup,
|
||||
"%s", container->formatted_title);
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -935,7 +935,8 @@ static void update_marks_texture(struct sway_view *view,
|
|||
int height = view->container->title_height * scale;
|
||||
|
||||
cairo_t *c = cairo_create(NULL);
|
||||
get_text_size(c, config->font, &width, NULL, scale, false, "%s", buffer);
|
||||
get_text_size(c, config->font, &width, NULL, NULL, scale, false,
|
||||
"%s", buffer);
|
||||
cairo_destroy(c);
|
||||
|
||||
cairo_surface_t *surface = cairo_image_surface_create(
|
||||
|
|
|
@ -33,8 +33,8 @@ static uint32_t render_status_line_error(cairo_t *cairo,
|
|||
int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale;
|
||||
|
||||
int text_width, text_height;
|
||||
get_text_size(cairo, config->font,
|
||||
&text_width, &text_height, output->scale, false, "%s", error);
|
||||
get_text_size(cairo, config->font, &text_width, &text_height, NULL,
|
||||
output->scale, false, "%s", error);
|
||||
|
||||
uint32_t ideal_height = text_height + ws_vertical_padding * 2;
|
||||
uint32_t ideal_surface_height = ideal_height / output->scale;
|
||||
|
@ -63,7 +63,7 @@ static uint32_t render_status_line_text(cairo_t *cairo,
|
|||
config->colors.focused_statusline : config->colors.statusline);
|
||||
|
||||
int text_width, text_height;
|
||||
get_text_size(cairo, config->font, &text_width, &text_height,
|
||||
get_text_size(cairo, config->font, &text_width, &text_height, NULL,
|
||||
output->scale, config->pango_markup, "%s", text);
|
||||
|
||||
int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale;
|
||||
|
@ -126,7 +126,7 @@ static uint32_t render_status_block(cairo_t *cairo,
|
|||
uint32_t height = surface_height * output->scale;
|
||||
|
||||
int text_width, text_height;
|
||||
get_text_size(cairo, config->font, &text_width, &text_height,
|
||||
get_text_size(cairo, config->font, &text_width, &text_height, NULL,
|
||||
output->scale, block->markup, "%s", block->full_text);
|
||||
|
||||
int margin = 3 * output->scale;
|
||||
|
@ -157,7 +157,7 @@ static uint32_t render_status_block(cairo_t *cairo,
|
|||
int sep_width, sep_height;
|
||||
if (!edge) {
|
||||
if (config->sep_symbol) {
|
||||
get_text_size(cairo, config->font, &sep_width, &sep_height,
|
||||
get_text_size(cairo, config->font, &sep_width, &sep_height, NULL,
|
||||
output->scale, false, "%s", config->sep_symbol);
|
||||
uint32_t _ideal_height = sep_height + ws_vertical_padding * 2;
|
||||
uint32_t _ideal_surface_height = _ideal_height / output->scale;
|
||||
|
@ -297,7 +297,7 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo,
|
|||
uint32_t height = surface_height * output->scale;
|
||||
|
||||
int text_width, text_height;
|
||||
get_text_size(cairo, config->font, &text_width, &text_height,
|
||||
get_text_size(cairo, config->font, &text_width, &text_height, NULL,
|
||||
output->scale, config->mode_pango_markup,
|
||||
"%s", mode);
|
||||
|
||||
|
@ -379,7 +379,7 @@ static uint32_t render_workspace_button(cairo_t *cairo,
|
|||
uint32_t height = surface_height * output->scale;
|
||||
|
||||
int text_width, text_height;
|
||||
get_text_size(cairo, config->font, &text_width, &text_height,
|
||||
get_text_size(cairo, config->font, &text_width, &text_height, NULL,
|
||||
output->scale, config->pango_markup, "%s", name);
|
||||
|
||||
int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale;
|
||||
|
|
|
@ -12,7 +12,7 @@ static uint32_t render_message(cairo_t *cairo, struct swaynag *swaynag) {
|
|||
height -= swaynag->type->bar_border_thickness * swaynag->scale;
|
||||
|
||||
int text_width, text_height;
|
||||
get_text_size(cairo, swaynag->type->font, &text_width, &text_height,
|
||||
get_text_size(cairo, swaynag->type->font, &text_width, &text_height, NULL,
|
||||
swaynag->scale, true, "%s", swaynag->message);
|
||||
|
||||
int padding = swaynag->type->message_padding * swaynag->scale;
|
||||
|
@ -34,7 +34,7 @@ static uint32_t render_message(cairo_t *cairo, struct swaynag *swaynag) {
|
|||
static void render_details_scroll_button(cairo_t *cairo,
|
||||
struct swaynag *swaynag, struct swaynag_button *button) {
|
||||
int text_width, text_height;
|
||||
get_text_size(cairo, swaynag->type->font, &text_width, &text_height,
|
||||
get_text_size(cairo, swaynag->type->font, &text_width, &text_height, NULL,
|
||||
swaynag->scale, true, "%s", button->text);
|
||||
|
||||
int border = swaynag->type->button_border_thickness * swaynag->scale;
|
||||
|
@ -60,10 +60,10 @@ static void render_details_scroll_button(cairo_t *cairo,
|
|||
static int get_detailed_scroll_button_width(cairo_t *cairo,
|
||||
struct swaynag *swaynag) {
|
||||
int up_width, down_width, temp_height;
|
||||
get_text_size(cairo, swaynag->type->font, &up_width, &temp_height,
|
||||
get_text_size(cairo, swaynag->type->font, &up_width, &temp_height, NULL,
|
||||
swaynag->scale, true,
|
||||
"%s", swaynag->details.button_up.text);
|
||||
get_text_size(cairo, swaynag->type->font, &down_width, &temp_height,
|
||||
get_text_size(cairo, swaynag->type->font, &down_width, &temp_height, NULL,
|
||||
swaynag->scale, true,
|
||||
"%s", swaynag->details.button_down.text);
|
||||
|
||||
|
@ -179,7 +179,7 @@ static uint32_t render_button(cairo_t *cairo, struct swaynag *swaynag,
|
|||
struct swaynag_button *button = swaynag->buttons->items[button_index];
|
||||
|
||||
int text_width, text_height;
|
||||
get_text_size(cairo, swaynag->type->font, &text_width, &text_height,
|
||||
get_text_size(cairo, swaynag->type->font, &text_width, &text_height, NULL,
|
||||
swaynag->scale, true, "%s", button->text);
|
||||
|
||||
int border = swaynag->type->button_border_thickness * swaynag->scale;
|
||||
|
|
Loading…
Reference in a new issue