diff options
author | Dmitri Kourennyi <dkour@mykolab.com> | 2019-03-22 17:18:21 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2019-04-04 14:14:08 -0600 |
commit | 0553e75b53137e6d509b6e336c21586f2b75d527 (patch) | |
tree | 8749c2436bfa0ea745304577599e9e02a5f6c6ee | |
parent | swaybg: one instance for all outputs (diff) | |
download | sway-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.
-rw-r--r-- | swaybar/render.c | 174 |
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 | ||
145 | static uint32_t render_status_block(cairo_t *cairo, | 145 | static 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 | ||
302 | static 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 | |||
370 | static 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 | |||
381 | static 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 | |||
405 | static 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 | |||
417 | static 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 | |||
297 | static uint32_t render_status_line_i3bar(cairo_t *cairo, | 449 | static 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 | } |