diff options
author | Brian Ashworth <bosrsf04@gmail.com> | 2018-11-25 22:08:58 -0500 |
---|---|---|
committer | Brian Ashworth <bosrsf04@gmail.com> | 2018-11-25 22:08:58 -0500 |
commit | e6562c8cd26c2e7caa4c83aaa5d734643fba4015 (patch) | |
tree | fb6074dc638c2543e2ed5d3aace86ef74e8d1466 /sway | |
parent | Merge pull request #3184 from kupospelov/fix-resize (diff) | |
download | sway-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.
Diffstat (limited to 'sway')
-rw-r--r-- | sway/commands.c | 1 | ||||
-rw-r--r-- | sway/commands/title_align.c | 30 | ||||
-rw-r--r-- | sway/config.c | 1 | ||||
-rw-r--r-- | sway/desktop/render.c | 101 | ||||
-rw-r--r-- | sway/meson.build | 1 | ||||
-rw-r--r-- | sway/sway.5.scd | 5 |
6 files changed, 118 insertions, 21 deletions
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 | |||
7 | struct 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. |