summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-11-25 22:08:58 -0500
committerLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-11-25 22:08:58 -0500
commite6562c8cd26c2e7caa4c83aaa5d734643fba4015 (patch)
treefb6074dc638c2543e2ed5d3aace86ef74e8d1466
parentMerge pull request #3184 from kupospelov/fix-resize (diff)
downloadsway-e6562c8cd26c2e7caa4c83aaa5d734643fba4015.tar.gz
sway-e6562c8cd26c2e7caa4c83aaa5d734643fba4015.tar.zst
sway-e6562c8cd26c2e7caa4c83aaa5d734643fba4015.zip
Implement title alignment
This adds support for `i3 4.16`'s ability to set the title alignment. The command is `title_align left|center|right`. When the title is on the right, marks are moved to the left. Otherwise, they are on the right.
-rw-r--r--include/sway/commands.h1
-rw-r--r--include/sway/config.h7
-rw-r--r--sway/commands.c1
-rw-r--r--sway/commands/title_align.c30
-rw-r--r--sway/config.c1
-rw-r--r--sway/desktop/render.c101
-rw-r--r--sway/meson.build1
-rw-r--r--sway/sway.5.scd5
8 files changed, 126 insertions, 21 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h
index e6036e51..eb446eae 100644
--- a/include/sway/commands.h
+++ b/include/sway/commands.h
@@ -172,6 +172,7 @@ sway_cmd cmd_swaybg_command;
172sway_cmd cmd_swaynag_command; 172sway_cmd cmd_swaynag_command;
173sway_cmd cmd_swap; 173sway_cmd cmd_swap;
174sway_cmd cmd_tiling_drag; 174sway_cmd cmd_tiling_drag;
175sway_cmd cmd_title_align;
175sway_cmd cmd_title_format; 176sway_cmd cmd_title_format;
176sway_cmd cmd_titlebar_border_thickness; 177sway_cmd cmd_titlebar_border_thickness;
177sway_cmd cmd_titlebar_padding; 178sway_cmd cmd_titlebar_padding;
diff --git a/include/sway/config.h b/include/sway/config.h
index a6920835..1ff9a104 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -357,6 +357,12 @@ enum mouse_warping_mode {
357 WARP_CONTAINER 357 WARP_CONTAINER
358}; 358};
359 359
360enum alignment {
361 ALIGN_LEFT,
362 ALIGN_CENTER,
363 ALIGN_RIGHT
364};
365
360/** 366/**
361 * The configuration struct. The result of loading a config file. 367 * The configuration struct. The result of loading a config file.
362 */ 368 */
@@ -409,6 +415,7 @@ struct sway_config {
409 bool validating; 415 bool validating;
410 bool auto_back_and_forth; 416 bool auto_back_and_forth;
411 bool show_marks; 417 bool show_marks;
418 enum alignment title_align;
412 bool tiling_drag; 419 bool tiling_drag;
413 420
414 bool smart_gaps; 421 bool smart_gaps;
diff --git a/sway/commands.c b/sway/commands.c
index d35658d5..bffc18f6 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -103,6 +103,7 @@ static struct cmd_handler handlers[] = {
103 { "smart_borders", cmd_smart_borders }, 103 { "smart_borders", cmd_smart_borders },
104 { "smart_gaps", cmd_smart_gaps }, 104 { "smart_gaps", cmd_smart_gaps },
105 { "tiling_drag", cmd_tiling_drag }, 105 { "tiling_drag", cmd_tiling_drag },
106 { "title_align", cmd_title_align },
106 { "titlebar_border_thickness", cmd_titlebar_border_thickness }, 107 { "titlebar_border_thickness", cmd_titlebar_border_thickness },
107 { "titlebar_padding", cmd_titlebar_padding }, 108 { "titlebar_padding", cmd_titlebar_padding },
108 { "workspace", cmd_workspace }, 109 { "workspace", cmd_workspace },
diff --git a/sway/commands/title_align.c b/sway/commands/title_align.c
new file mode 100644
index 00000000..82578186
--- /dev/null
+++ b/sway/commands/title_align.c
@@ -0,0 +1,30 @@
1#include "sway/commands.h"
2#include "sway/config.h"
3#include "sway/output.h"
4#include "sway/tree/container.h"
5#include "sway/tree/root.h"
6
7struct cmd_results *cmd_title_align(int argc, char **argv) {
8 struct cmd_results *error = NULL;
9 if ((error = checkarg(argc, "title_align", EXPECTED_AT_LEAST, 1))) {
10 return error;
11 }
12
13 if (strcmp(argv[0], "left") == 0) {
14 config->title_align = ALIGN_LEFT;
15 } else if (strcmp(argv[0], "center") == 0) {
16 config->title_align = ALIGN_CENTER;
17 } else if (strcmp(argv[0], "right") == 0) {
18 config->title_align = ALIGN_RIGHT;
19 } else {
20 return cmd_results_new(CMD_INVALID, "title_align",
21 "Expected 'title_align left|center|right'");
22 }
23
24 for (int i = 0; i < root->outputs->length; ++i) {
25 struct sway_output *output = root->outputs->items[i];
26 output_damage_whole(output);
27 }
28
29 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
30}
diff --git a/sway/config.c b/sway/config.c
index 59edc6d8..675d20e5 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -234,6 +234,7 @@ static void config_defaults(struct sway_config *config) {
234 config->auto_back_and_forth = false; 234 config->auto_back_and_forth = false;
235 config->reading = false; 235 config->reading = false;
236 config->show_marks = true; 236 config->show_marks = true;
237 config->title_align = ALIGN_LEFT;
237 config->tiling_drag = true; 238 config->tiling_drag = true;
238 239
239 config->smart_gaps = false; 240 config->smart_gaps = false;
diff --git a/sway/desktop/render.c b/sway/desktop/render.c
index 51cb8980..eeda496c 100644
--- a/sway/desktop/render.c
+++ b/sway/desktop/render.c
@@ -371,6 +371,7 @@ static void render_titlebar(struct sway_output *output,
371 int titlebar_border_thickness = config->titlebar_border_thickness; 371 int titlebar_border_thickness = config->titlebar_border_thickness;
372 int titlebar_h_padding = config->titlebar_h_padding; 372 int titlebar_h_padding = config->titlebar_h_padding;
373 int titlebar_v_padding = config->titlebar_v_padding; 373 int titlebar_v_padding = config->titlebar_v_padding;
374 enum alignment title_align = config->title_align;
374 375
375 // Single pixel bar above title 376 // Single pixel bar above title
376 memcpy(&color, colors->border, sizeof(float) * 4); 377 memcpy(&color, colors->border, sizeof(float) * 4);
@@ -420,19 +421,25 @@ static void render_titlebar(struct sway_output *output,
420 render_rect(output->wlr_output, output_damage, &box, color); 421 render_rect(output->wlr_output, output_damage, &box, color);
421 } 422 }
422 423
423 size_t inner_width = width - titlebar_h_padding * 2; 424 int inner_x = x - output_x + titlebar_h_padding;
424 int bg_y = y + titlebar_border_thickness; 425 int bg_y = y + titlebar_border_thickness;
426 size_t inner_width = width - titlebar_h_padding * 2;
427
428 // output-buffer local
429 int ob_inner_x = round(inner_x * output_scale);
430 int ob_inner_width = scale_length(inner_width, inner_x, output_scale);
425 int ob_bg_height = scale_length( 431 int ob_bg_height = scale_length(
426 (titlebar_v_padding - titlebar_border_thickness) * 2 + 432 (titlebar_v_padding - titlebar_border_thickness) * 2 +
427 config->font_height, bg_y, output_scale); 433 config->font_height, bg_y, output_scale);
428 434
429 // Marks 435 // Marks
430 int marks_ob_width = 0; // output-buffer-local 436 int ob_marks_x = 0; // output-buffer-local
437 int ob_marks_width = 0; // output-buffer-local
431 if (config->show_marks && marks_texture) { 438 if (config->show_marks && marks_texture) {
432 struct wlr_box texture_box; 439 struct wlr_box texture_box;
433 wlr_texture_get_size(marks_texture, 440 wlr_texture_get_size(marks_texture,
434 &texture_box.width, &texture_box.height); 441 &texture_box.width, &texture_box.height);
435 marks_ob_width = texture_box.width; 442 ob_marks_width = texture_box.width;
436 443
437 // The marks texture might be shorter than the config->font_height, in 444 // The marks texture might be shorter than the config->font_height, in
438 // which case we need to pad it as evenly as possible above and below. 445 // which case we need to pad it as evenly as possible above and below.
@@ -440,9 +447,15 @@ static void render_titlebar(struct sway_output *output,
440 int ob_padding_above = floor(ob_padding_total / 2.0); 447 int ob_padding_above = floor(ob_padding_total / 2.0);
441 int ob_padding_below = ceil(ob_padding_total / 2.0); 448 int ob_padding_below = ceil(ob_padding_total / 2.0);
442 449
443 // Render texture 450 // Render texture. If the title is on the right, the marks will be on
444 texture_box.x = round((x - output_x + width - titlebar_h_padding) 451 // the left. Otherwise, they will be on the right.
445 * output_scale) - texture_box.width; 452 if (title_align == ALIGN_RIGHT || texture_box.width > ob_inner_width) {
453 texture_box.x = ob_inner_x;
454 } else {
455 texture_box.x = ob_inner_x + ob_inner_width - texture_box.width;
456 }
457 ob_marks_x = texture_box.x;
458
446 texture_box.y = round((bg_y - output_y) * output_scale) + 459 texture_box.y = round((bg_y - output_y) * output_scale) +
447 ob_padding_above; 460 ob_padding_above;
448 461
@@ -451,8 +464,8 @@ static void render_titlebar(struct sway_output *output,
451 WL_OUTPUT_TRANSFORM_NORMAL, 464 WL_OUTPUT_TRANSFORM_NORMAL,
452 0.0, output->wlr_output->transform_matrix); 465 0.0, output->wlr_output->transform_matrix);
453 466
454 if (inner_width * output_scale < texture_box.width) { 467 if (ob_inner_width < texture_box.width) {
455 texture_box.width = inner_width * output_scale; 468 texture_box.width = ob_inner_width;
456 } 469 }
457 render_texture(output->wlr_output, output_damage, marks_texture, 470 render_texture(output->wlr_output, output_damage, marks_texture,
458 &texture_box, matrix, con->alpha); 471 &texture_box, matrix, con->alpha);
@@ -473,12 +486,13 @@ static void render_titlebar(struct sway_output *output,
473 } 486 }
474 487
475 // Title text 488 // Title text
476 size_t title_ob_width = 0; // output-buffer-local 489 int ob_title_x = 0; // output-buffer-local
490 int ob_title_width = 0; // output-buffer-local
477 if (title_texture) { 491 if (title_texture) {
478 struct wlr_box texture_box; 492 struct wlr_box texture_box;
479 wlr_texture_get_size(title_texture, 493 wlr_texture_get_size(title_texture,
480 &texture_box.width, &texture_box.height); 494 &texture_box.width, &texture_box.height);
481 title_ob_width = texture_box.width; 495 ob_title_width = texture_box.width;
482 496
483 // The title texture might be shorter than the config->font_height, 497 // The title texture might be shorter than the config->font_height,
484 // in which case we need to pad it above and below. 498 // in which case we need to pad it above and below.
@@ -489,8 +503,26 @@ static void render_titlebar(struct sway_output *output,
489 texture_box.height; 503 texture_box.height;
490 504
491 // Render texture 505 // Render texture
492 texture_box.x = 506 if (texture_box.width > ob_inner_width - ob_marks_width) {
493 round((x - output_x + titlebar_h_padding) * output_scale); 507 texture_box.x = (title_align == ALIGN_RIGHT && ob_marks_width)
508 ? ob_marks_x + ob_marks_width : ob_inner_x;
509 } else if (title_align == ALIGN_LEFT) {
510 texture_box.x = ob_inner_x;
511 } else if (title_align == ALIGN_CENTER) {
512 // If there are marks visible, center between the edge and marks.
513 // Otherwise, center in the inner area.
514 if (ob_marks_width) {
515 texture_box.x = (ob_inner_x + ob_marks_x) / 2
516 - texture_box.width / 2;
517 } else {
518 texture_box.x = ob_inner_x + ob_inner_width / 2
519 - texture_box.width / 2;
520 }
521 } else {
522 texture_box.x = ob_inner_x + ob_inner_width - texture_box.width;
523 }
524 ob_title_x = texture_box.x;
525
494 texture_box.y = 526 texture_box.y =
495 round((bg_y - output_y) * output_scale) + ob_padding_above; 527 round((bg_y - output_y) * output_scale) + ob_padding_above;
496 528
@@ -499,11 +531,10 @@ static void render_titlebar(struct sway_output *output,
499 WL_OUTPUT_TRANSFORM_NORMAL, 531 WL_OUTPUT_TRANSFORM_NORMAL,
500 0.0, output->wlr_output->transform_matrix); 532 0.0, output->wlr_output->transform_matrix);
501 533
502 int inner_x = x - output_x + titlebar_h_padding; 534 if (ob_inner_width - ob_marks_width < texture_box.width) {
503 int ob_inner_width = scale_length(inner_width, inner_x, output_scale); 535 texture_box.width = ob_inner_width - ob_marks_width;
504 if (ob_inner_width - marks_ob_width < texture_box.width) {
505 texture_box.width = ob_inner_width - marks_ob_width;
506 } 536 }
537
507 render_texture(output->wlr_output, output_damage, title_texture, 538 render_texture(output->wlr_output, output_damage, title_texture,
508 &texture_box, matrix, con->alpha); 539 &texture_box, matrix, con->alpha);
509 540
@@ -522,17 +553,36 @@ static void render_titlebar(struct sway_output *output,
522 render_rect(output->wlr_output, output_damage, &box, color); 553 render_rect(output->wlr_output, output_damage, &box, color);
523 } 554 }
524 555
556 // Determine the left + right extends of the textures (output-buffer local)
557 int ob_left_x, ob_left_width, ob_right_x, ob_right_width;
558 if (ob_title_x < ob_marks_x) {
559 ob_left_x = ob_title_x;
560 ob_left_width = ob_title_width;
561 ob_right_x = ob_marks_x;
562 ob_right_width = ob_marks_width;
563 } else {
564 ob_left_x = ob_marks_x;
565 ob_left_width = ob_marks_width;
566 ob_right_x = ob_title_x;
567 ob_right_width = ob_title_width;
568 }
569 if (ob_left_x < ob_inner_x) {
570 ob_left_x = ob_inner_x;
571 } else if (ob_left_x + ob_left_width > ob_right_x + ob_right_width) {
572 ob_right_x = ob_left_x;
573 ob_right_width = ob_left_width;
574 }
575
525 // Filler between title and marks 576 // Filler between title and marks
526 box.width = 577 box.width = ob_right_x - ob_left_x - ob_left_width;
527 round(inner_width * output_scale) - title_ob_width - marks_ob_width;
528 if (box.width > 0) { 578 if (box.width > 0) {
529 box.x = round((x + titlebar_h_padding) * output_scale) + title_ob_width; 579 box.x = ob_left_x + ob_left_width + round(output_x * output_scale);
530 box.y = round(bg_y * output_scale); 580 box.y = round(bg_y * output_scale);
531 box.height = ob_bg_height; 581 box.height = ob_bg_height;
532 render_rect(output->wlr_output, output_damage, &box, color); 582 render_rect(output->wlr_output, output_damage, &box, color);
533 } 583 }
534 584
535 // Padding left of title 585 // Padding on left side
536 left_offset = (layout == L_TABBED) * titlebar_border_thickness; 586 left_offset = (layout == L_TABBED) * titlebar_border_thickness;
537 box.x = x + left_offset; 587 box.x = x + left_offset;
538 box.y = y + titlebar_border_thickness; 588 box.y = y + titlebar_border_thickness;
@@ -540,9 +590,13 @@ static void render_titlebar(struct sway_output *output,
540 box.height = (titlebar_v_padding - titlebar_border_thickness) * 2 + 590 box.height = (titlebar_v_padding - titlebar_border_thickness) * 2 +
541 config->font_height; 591 config->font_height;
542 scale_box(&box, output_scale); 592 scale_box(&box, output_scale);
593 int left_x = ob_left_x + round(output_x * output_scale);
594 if (box.x + box.width < left_x) {
595 box.width += left_x - box.x - box.width;
596 }
543 render_rect(output->wlr_output, output_damage, &box, color); 597 render_rect(output->wlr_output, output_damage, &box, color);
544 598
545 // Padding right of marks 599 // Padding on right side
546 right_offset = (layout == L_TABBED) * titlebar_border_thickness; 600 right_offset = (layout == L_TABBED) * titlebar_border_thickness;
547 box.x = x + width - titlebar_h_padding; 601 box.x = x + width - titlebar_h_padding;
548 box.y = y + titlebar_border_thickness; 602 box.y = y + titlebar_border_thickness;
@@ -550,6 +604,11 @@ static void render_titlebar(struct sway_output *output,
550 box.height = (titlebar_v_padding - titlebar_border_thickness) * 2 + 604 box.height = (titlebar_v_padding - titlebar_border_thickness) * 2 +
551 config->font_height; 605 config->font_height;
552 scale_box(&box, output_scale); 606 scale_box(&box, output_scale);
607 int right_rx = ob_right_x + ob_right_width + round(output_x * output_scale);
608 if (right_rx < box.x) {
609 box.width += box.x - right_rx;
610 box.x = right_rx;
611 }
553 render_rect(output->wlr_output, output_damage, &box, color); 612 render_rect(output->wlr_output, output_damage, &box, color);
554 613
555 if (connects_sides) { 614 if (connects_sides) {
diff --git a/sway/meson.build b/sway/meson.build
index c8c95a96..75131891 100644
--- a/sway/meson.build
+++ b/sway/meson.build
@@ -88,6 +88,7 @@ sway_sources = files(
88 'commands/swaynag_command.c', 88 'commands/swaynag_command.c',
89 'commands/swap.c', 89 'commands/swap.c',
90 'commands/tiling_drag.c', 90 'commands/tiling_drag.c',
91 'commands/title_align.c',
91 'commands/title_format.c', 92 'commands/title_format.c',
92 'commands/titlebar_border_thickness.c', 93 'commands/titlebar_border_thickness.c',
93 'commands/titlebar_padding.c', 94 'commands/titlebar_padding.c',
diff --git a/sway/sway.5.scd b/sway/sway.5.scd
index 6ccb1acf..4edd16bf 100644
--- a/sway/sway.5.scd
+++ b/sway/sway.5.scd
@@ -555,6 +555,11 @@ The default colors are:
555 Set the opacity of the window between 0 (completely transparent) and 1 555 Set the opacity of the window between 0 (completely transparent) and 1
556 (completely opaque). 556 (completely opaque).
557 557
558*title\_align* left|center|right
559 Sets the title alignment. If _right_ is selected and _show\_marks_ is set
560 to _yes_, the marks will be shown on the _left_ side instead of the
561 _right_ side.
562
558*unmark* [<identifier>] 563*unmark* [<identifier>]
559 *unmark* will remove _identifier_ from the list of current marks on a 564 *unmark* will remove _identifier_ from the list of current marks on a
560 window. If _identifier_ is omitted, all marks are removed. 565 window. If _identifier_ is omitted, all marks are removed.