aboutsummaryrefslogtreecommitdiffstats
path: root/swaybar
diff options
context:
space:
mode:
authorLibravatar Dmitri Kourennyi <dkour@mykolab.com>2019-03-22 17:18:21 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2019-04-04 14:14:08 -0600
commit0553e75b53137e6d509b6e336c21586f2b75d527 (patch)
tree8749c2436bfa0ea745304577599e9e02a5f6c6ee /swaybar
parentswaybg: one instance for all outputs (diff)
downloadsway-0553e75b53137e6d509b6e336c21586f2b75d527.tar.gz
sway-0553e75b53137e6d509b6e336c21586f2b75d527.tar.zst
sway-0553e75b53137e6d509b6e336c21586f2b75d527.zip
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.
Diffstat (limited to 'swaybar')
-rw-r--r--swaybar/render.c174
1 files changed, 170 insertions, 4 deletions
diff --git a/swaybar/render.c b/swaybar/render.c
index 116cc595..faf17509 100644
--- a/swaybar/render.c
+++ b/swaybar/render.c
@@ -144,16 +144,21 @@ static void i3bar_block_unref_callback(void *data) {
144 144
145static uint32_t render_status_block(cairo_t *cairo, 145static uint32_t render_status_block(cairo_t *cairo,
146 struct swaybar_output *output, struct i3bar_block *block, double *x, 146 struct swaybar_output *output, struct i3bar_block *block, double *x,
147 bool edge) { 147 bool edge, bool use_short_text) {
148 if (!block->full_text || !*block->full_text) { 148 if (!block->full_text || !*block->full_text) {
149 return 0; 149 return 0;
150 } 150 }
151 151
152 char* text = block->full_text;
153 if (use_short_text && block->short_text && *block->short_text) {
154 text = block->short_text;
155 }
156
152 struct swaybar_config *config = output->bar->config; 157 struct swaybar_config *config = output->bar->config;
153 158
154 int text_width, text_height; 159 int text_width, text_height;
155 get_text_size(cairo, config->font, &text_width, &text_height, NULL, 160 get_text_size(cairo, config->font, &text_width, &text_height, NULL,
156 output->scale, block->markup, "%s", block->full_text); 161 output->scale, block->markup, "%s", text);
157 162
158 int margin = 3 * output->scale; 163 int margin = 3 * output->scale;
159 double ws_vertical_padding = config->status_padding * output->scale; 164 double ws_vertical_padding = config->status_padding * output->scale;
@@ -263,7 +268,7 @@ static uint32_t render_status_block(cairo_t *cairo,
263 color = block->urgent ? config->colors.urgent_workspace.text : color; 268 color = block->urgent ? config->colors.urgent_workspace.text : color;
264 cairo_set_source_u32(cairo, color); 269 cairo_set_source_u32(cairo, color);
265 pango_printf(cairo, config->font, output->scale, 270 pango_printf(cairo, config->font, output->scale,
266 block->markup, "%s", block->full_text); 271 block->markup, "%s", text);
267 x_pos += width; 272 x_pos += width;
268 273
269 if (block->border && block->border_right > 0) { 274 if (block->border && block->border_right > 0) {
@@ -294,13 +299,174 @@ static uint32_t render_status_block(cairo_t *cairo,
294 return output->height; 299 return output->height;
295} 300}
296 301
302static void predict_status_block_pos(cairo_t *cairo,
303 struct swaybar_output *output, struct i3bar_block *block, double *x,
304 bool edge) {
305 if (!block->full_text || !*block->full_text) {
306 return;
307 }
308
309 struct swaybar_config *config = output->bar->config;
310
311 int text_width, text_height;
312 get_text_size(cairo, config->font, &text_width, &text_height, NULL,
313 output->scale, block->markup, "%s", block->full_text);
314
315 int margin = 3 * output->scale;
316 double ws_vertical_padding = config->status_padding * output->scale;
317
318 int width = text_width;
319
320 if (block->min_width_str) {
321 int w;
322 get_text_size(cairo, config->font, &w, NULL, NULL,
323 output->scale, block->markup, "%s", block->min_width_str);
324 block->min_width = w;
325 }
326 if (width < block->min_width) {
327 width = block->min_width;
328 }
329
330 double block_width = width;
331 uint32_t ideal_height = text_height + ws_vertical_padding * 2;
332 uint32_t ideal_surface_height = ideal_height / output->scale;
333 if (!output->bar->config->height &&
334 output->height < ideal_surface_height) {
335 return;
336 }
337
338 *x -= width;
339 if ((block->border || block->urgent) && block->border_left > 0) {
340 *x -= (block->border_left * output->scale + margin);
341 block_width += block->border_left * output->scale + margin;
342 }
343 if ((block->border || block->urgent) && block->border_right > 0) {
344 *x -= (block->border_right * output->scale + margin);
345 block_width += block->border_right * output->scale + margin;
346 }
347
348 int sep_width, sep_height;
349 int sep_block_width = block->separator_block_width;
350 if (!edge) {
351 if (config->sep_symbol) {
352 get_text_size(cairo, config->font, &sep_width, &sep_height, NULL,
353 output->scale, false, "%s", config->sep_symbol);
354 uint32_t _ideal_height = sep_height + ws_vertical_padding * 2;
355 uint32_t _ideal_surface_height = _ideal_height / output->scale;
356 if (!output->bar->config->height &&
357 output->height < _ideal_surface_height) {
358 return;
359 }
360 if (sep_width > sep_block_width) {
361 sep_block_width = sep_width + margin * 2;
362 }
363 }
364 *x -= sep_block_width;
365 } else if (config->status_edge_padding) {
366 *x -= config->status_edge_padding * output->scale;
367 }
368}
369
370static double predict_status_line_pos(cairo_t *cairo,
371 struct swaybar_output *output, double x) {
372 bool edge = x == output->width * output->scale;
373 struct i3bar_block *block;
374 wl_list_for_each(block, &output->bar->status->blocks, link) {
375 predict_status_block_pos(cairo, output, block, &x, edge);
376 edge = false;
377 }
378 return x;
379}
380
381static uint32_t predict_workspace_button_length(cairo_t *cairo,
382 struct swaybar_output *output,
383 struct swaybar_workspace *ws) {
384 struct swaybar_config *config = output->bar->config;
385
386 int text_width, text_height;
387 get_text_size(cairo, config->font, &text_width, &text_height, NULL,
388 output->scale, config->pango_markup, "%s", ws->label);
389
390 int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale;
391 int ws_horizontal_padding = WS_HORIZONTAL_PADDING * output->scale;
392 int border_width = BORDER_WIDTH * output->scale;
393
394 uint32_t ideal_height = ws_vertical_padding * 2 + text_height
395 + border_width * 2;
396 uint32_t ideal_surface_height = ideal_height / output->scale;
397 if (!output->bar->config->height &&
398 output->height < ideal_surface_height) {
399 return 0;
400 }
401
402 return ws_horizontal_padding * 2 + text_width + border_width * 2;
403}
404
405static uint32_t predict_workspace_buttons_length(cairo_t *cairo,
406 struct swaybar_output *output) {
407 uint32_t width = 0;
408 if (output->bar->config->workspace_buttons) {
409 struct swaybar_workspace *ws;
410 wl_list_for_each(ws, &output->workspaces, link) {
411 width += predict_workspace_button_length(cairo, output, ws);
412 }
413 }
414 return width;
415}
416
417static uint32_t predict_binding_mode_indicator_length(cairo_t *cairo,
418 struct swaybar_output *output) {
419 const char *mode = output->bar->mode;
420 if (!mode) {
421 return 0;
422 }
423
424 struct swaybar_config *config = output->bar->config;
425
426 if (!config->binding_mode_indicator) {
427 return 0;
428 }
429
430 int text_width, text_height;
431 get_text_size(cairo, config->font, &text_width, &text_height, NULL,
432 output->scale, output->bar->mode_pango_markup,
433 "%s", mode);
434
435 int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale;
436 int ws_horizontal_padding = WS_HORIZONTAL_PADDING * output->scale;
437 int border_width = BORDER_WIDTH * output->scale;
438
439 uint32_t ideal_height = text_height + ws_vertical_padding * 2
440 + border_width * 2;
441 uint32_t ideal_surface_height = ideal_height / output->scale;
442 if (!output->bar->config->height &&
443 output->height < ideal_surface_height) {
444 return 0;
445 }
446 return text_width + ws_horizontal_padding * 2 + border_width * 2;
447}
448
297static uint32_t render_status_line_i3bar(cairo_t *cairo, 449static uint32_t render_status_line_i3bar(cairo_t *cairo,
298 struct swaybar_output *output, double *x) { 450 struct swaybar_output *output, double *x) {
299 uint32_t max_height = 0; 451 uint32_t max_height = 0;
300 bool edge = *x == output->width * output->scale; 452 bool edge = *x == output->width * output->scale;
301 struct i3bar_block *block; 453 struct i3bar_block *block;
454 bool use_short_text = false;
455
456 // TODO: Add margin here?
457 uint32_t reserved_width = predict_workspace_buttons_length(cairo, output) +
458 predict_binding_mode_indicator_length(cairo, output);
459
460 uint32_t predicted_full_pos =
461 predict_status_line_pos(cairo, output, *x);
462
463 if (predicted_full_pos < reserved_width) {
464 use_short_text = true;
465 }
466
302 wl_list_for_each(block, &output->bar->status->blocks, link) { 467 wl_list_for_each(block, &output->bar->status->blocks, link) {
303 uint32_t h = render_status_block(cairo, output, block, x, edge); 468 uint32_t h = render_status_block(cairo, output, block, x, edge,
469 use_short_text);
304 max_height = h > max_height ? h : max_height; 470 max_height = h > max_height ? h : max_height;
305 edge = false; 471 edge = false;
306 } 472 }