Implement handling of short_text field of i3 input protocol.
Matches i3bar behavior of setting all blocks to use the short_text if the full text width does not fit.
This commit is contained in:
parent
75e7bd24cc
commit
0553e75b53
174
swaybar/render.c
174
swaybar/render.c
|
@ -144,16 +144,21 @@ static void i3bar_block_unref_callback(void *data) {
|
||||||
|
|
||||||
static uint32_t render_status_block(cairo_t *cairo,
|
static uint32_t render_status_block(cairo_t *cairo,
|
||||||
struct swaybar_output *output, struct i3bar_block *block, double *x,
|
struct swaybar_output *output, struct i3bar_block *block, double *x,
|
||||||
bool edge) {
|
bool edge, bool use_short_text) {
|
||||||
if (!block->full_text || !*block->full_text) {
|
if (!block->full_text || !*block->full_text) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* text = block->full_text;
|
||||||
|
if (use_short_text && block->short_text && *block->short_text) {
|
||||||
|
text = block->short_text;
|
||||||
|
}
|
||||||
|
|
||||||
struct swaybar_config *config = output->bar->config;
|
struct swaybar_config *config = output->bar->config;
|
||||||
|
|
||||||
int text_width, text_height;
|
int text_width, text_height;
|
||||||
get_text_size(cairo, config->font, &text_width, &text_height, NULL,
|
get_text_size(cairo, config->font, &text_width, &text_height, NULL,
|
||||||
output->scale, block->markup, "%s", block->full_text);
|
output->scale, block->markup, "%s", text);
|
||||||
|
|
||||||
int margin = 3 * output->scale;
|
int margin = 3 * output->scale;
|
||||||
double ws_vertical_padding = config->status_padding * output->scale;
|
double ws_vertical_padding = config->status_padding * output->scale;
|
||||||
|
@ -263,7 +268,7 @@ static uint32_t render_status_block(cairo_t *cairo,
|
||||||
color = block->urgent ? config->colors.urgent_workspace.text : color;
|
color = block->urgent ? config->colors.urgent_workspace.text : color;
|
||||||
cairo_set_source_u32(cairo, color);
|
cairo_set_source_u32(cairo, color);
|
||||||
pango_printf(cairo, config->font, output->scale,
|
pango_printf(cairo, config->font, output->scale,
|
||||||
block->markup, "%s", block->full_text);
|
block->markup, "%s", text);
|
||||||
x_pos += width;
|
x_pos += width;
|
||||||
|
|
||||||
if (block->border && block->border_right > 0) {
|
if (block->border && block->border_right > 0) {
|
||||||
|
@ -294,13 +299,174 @@ static uint32_t render_status_block(cairo_t *cairo,
|
||||||
return output->height;
|
return output->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void predict_status_block_pos(cairo_t *cairo,
|
||||||
|
struct swaybar_output *output, struct i3bar_block *block, double *x,
|
||||||
|
bool edge) {
|
||||||
|
if (!block->full_text || !*block->full_text) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct swaybar_config *config = output->bar->config;
|
||||||
|
|
||||||
|
int 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;
|
||||||
|
double ws_vertical_padding = config->status_padding * output->scale;
|
||||||
|
|
||||||
|
int width = text_width;
|
||||||
|
|
||||||
|
if (block->min_width_str) {
|
||||||
|
int w;
|
||||||
|
get_text_size(cairo, config->font, &w, NULL, NULL,
|
||||||
|
output->scale, block->markup, "%s", block->min_width_str);
|
||||||
|
block->min_width = w;
|
||||||
|
}
|
||||||
|
if (width < block->min_width) {
|
||||||
|
width = block->min_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
double block_width = width;
|
||||||
|
uint32_t ideal_height = text_height + ws_vertical_padding * 2;
|
||||||
|
uint32_t ideal_surface_height = ideal_height / output->scale;
|
||||||
|
if (!output->bar->config->height &&
|
||||||
|
output->height < ideal_surface_height) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*x -= width;
|
||||||
|
if ((block->border || block->urgent) && block->border_left > 0) {
|
||||||
|
*x -= (block->border_left * output->scale + margin);
|
||||||
|
block_width += block->border_left * output->scale + margin;
|
||||||
|
}
|
||||||
|
if ((block->border || block->urgent) && block->border_right > 0) {
|
||||||
|
*x -= (block->border_right * output->scale + margin);
|
||||||
|
block_width += block->border_right * output->scale + margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sep_width, sep_height;
|
||||||
|
int sep_block_width = block->separator_block_width;
|
||||||
|
if (!edge) {
|
||||||
|
if (config->sep_symbol) {
|
||||||
|
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;
|
||||||
|
if (!output->bar->config->height &&
|
||||||
|
output->height < _ideal_surface_height) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sep_width > sep_block_width) {
|
||||||
|
sep_block_width = sep_width + margin * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*x -= sep_block_width;
|
||||||
|
} else if (config->status_edge_padding) {
|
||||||
|
*x -= config->status_edge_padding * output->scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static double predict_status_line_pos(cairo_t *cairo,
|
||||||
|
struct swaybar_output *output, double x) {
|
||||||
|
bool edge = x == output->width * output->scale;
|
||||||
|
struct i3bar_block *block;
|
||||||
|
wl_list_for_each(block, &output->bar->status->blocks, link) {
|
||||||
|
predict_status_block_pos(cairo, output, block, &x, edge);
|
||||||
|
edge = false;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t predict_workspace_button_length(cairo_t *cairo,
|
||||||
|
struct swaybar_output *output,
|
||||||
|
struct swaybar_workspace *ws) {
|
||||||
|
struct swaybar_config *config = output->bar->config;
|
||||||
|
|
||||||
|
int text_width, text_height;
|
||||||
|
get_text_size(cairo, config->font, &text_width, &text_height, NULL,
|
||||||
|
output->scale, config->pango_markup, "%s", ws->label);
|
||||||
|
|
||||||
|
int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale;
|
||||||
|
int ws_horizontal_padding = WS_HORIZONTAL_PADDING * output->scale;
|
||||||
|
int border_width = BORDER_WIDTH * output->scale;
|
||||||
|
|
||||||
|
uint32_t ideal_height = ws_vertical_padding * 2 + text_height
|
||||||
|
+ border_width * 2;
|
||||||
|
uint32_t ideal_surface_height = ideal_height / output->scale;
|
||||||
|
if (!output->bar->config->height &&
|
||||||
|
output->height < ideal_surface_height) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ws_horizontal_padding * 2 + text_width + border_width * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t predict_workspace_buttons_length(cairo_t *cairo,
|
||||||
|
struct swaybar_output *output) {
|
||||||
|
uint32_t width = 0;
|
||||||
|
if (output->bar->config->workspace_buttons) {
|
||||||
|
struct swaybar_workspace *ws;
|
||||||
|
wl_list_for_each(ws, &output->workspaces, link) {
|
||||||
|
width += predict_workspace_button_length(cairo, output, ws);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t predict_binding_mode_indicator_length(cairo_t *cairo,
|
||||||
|
struct swaybar_output *output) {
|
||||||
|
const char *mode = output->bar->mode;
|
||||||
|
if (!mode) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct swaybar_config *config = output->bar->config;
|
||||||
|
|
||||||
|
if (!config->binding_mode_indicator) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int text_width, text_height;
|
||||||
|
get_text_size(cairo, config->font, &text_width, &text_height, NULL,
|
||||||
|
output->scale, output->bar->mode_pango_markup,
|
||||||
|
"%s", mode);
|
||||||
|
|
||||||
|
int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale;
|
||||||
|
int ws_horizontal_padding = WS_HORIZONTAL_PADDING * output->scale;
|
||||||
|
int border_width = BORDER_WIDTH * output->scale;
|
||||||
|
|
||||||
|
uint32_t ideal_height = text_height + ws_vertical_padding * 2
|
||||||
|
+ border_width * 2;
|
||||||
|
uint32_t ideal_surface_height = ideal_height / output->scale;
|
||||||
|
if (!output->bar->config->height &&
|
||||||
|
output->height < ideal_surface_height) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return text_width + ws_horizontal_padding * 2 + border_width * 2;
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t render_status_line_i3bar(cairo_t *cairo,
|
static uint32_t render_status_line_i3bar(cairo_t *cairo,
|
||||||
struct swaybar_output *output, double *x) {
|
struct swaybar_output *output, double *x) {
|
||||||
uint32_t max_height = 0;
|
uint32_t max_height = 0;
|
||||||
bool edge = *x == output->width * output->scale;
|
bool edge = *x == output->width * output->scale;
|
||||||
struct i3bar_block *block;
|
struct i3bar_block *block;
|
||||||
|
bool use_short_text = false;
|
||||||
|
|
||||||
|
// TODO: Add margin here?
|
||||||
|
uint32_t reserved_width = predict_workspace_buttons_length(cairo, output) +
|
||||||
|
predict_binding_mode_indicator_length(cairo, output);
|
||||||
|
|
||||||
|
uint32_t predicted_full_pos =
|
||||||
|
predict_status_line_pos(cairo, output, *x);
|
||||||
|
|
||||||
|
if (predicted_full_pos < reserved_width) {
|
||||||
|
use_short_text = true;
|
||||||
|
}
|
||||||
|
|
||||||
wl_list_for_each(block, &output->bar->status->blocks, link) {
|
wl_list_for_each(block, &output->bar->status->blocks, link) {
|
||||||
uint32_t h = render_status_block(cairo, output, block, x, edge);
|
uint32_t h = render_status_block(cairo, output, block, x, edge,
|
||||||
|
use_short_text);
|
||||||
max_height = h > max_height ? h : max_height;
|
max_height = h > max_height ? h : max_height;
|
||||||
edge = false;
|
edge = false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue