mirror of
https://github.com/swaywm/sway.git
synced 2024-12-27 15:36:29 +01:00
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
1 changed files with 170 additions and 4 deletions
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,
|
||||
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) {
|
||||
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;
|
||||
|
||||
int text_width, text_height;
|
||||
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;
|
||||
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;
|
||||
cairo_set_source_u32(cairo, color);
|
||||
pango_printf(cairo, config->font, output->scale,
|
||||
block->markup, "%s", block->full_text);
|
||||
block->markup, "%s", text);
|
||||
x_pos += width;
|
||||
|
||||
if (block->border && block->border_right > 0) {
|
||||
|
@ -294,13 +299,174 @@ static uint32_t render_status_block(cairo_t *cairo,
|
|||
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,
|
||||
struct swaybar_output *output, double *x) {
|
||||
uint32_t max_height = 0;
|
||||
bool edge = *x == output->width * output->scale;
|
||||
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) {
|
||||
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;
|
||||
edge = false;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue