diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-05-05 12:36:50 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-05-05 22:29:37 +1000 |
commit | 228c478e8d11dd14972b237574146fd0d2d6b96c (patch) | |
tree | 819dfc4d6151ebb28d7db5b862d0ac4314d82fc3 /sway/tree/view.c | |
parent | Merge pull request #1918 from RyanDwyer/title-scissor (diff) | |
download | sway-228c478e8d11dd14972b237574146fd0d2d6b96c.tar.gz sway-228c478e8d11dd14972b237574146fd0d2d6b96c.tar.zst sway-228c478e8d11dd14972b237574146fd0d2d6b96c.zip |
Implement title_format
This implements the title_format command, with a new placeholder %shell
which gets substituted with the view type (xwayland, xdg_shell_v6 or
wl_shell).
Example config:
for_window [title=".*"] title_format %title (class=%class instance=%instance shell=%shell)
Diffstat (limited to 'sway/tree/view.c')
-rw-r--r-- | sway/tree/view.c | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/sway/tree/view.c b/sway/tree/view.c index 84962306..4a01f096 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
1 | #include <stdlib.h> | 2 | #include <stdlib.h> |
2 | #include <wayland-server.h> | 3 | #include <wayland-server.h> |
3 | #include <wlr/render/wlr_renderer.h> | 4 | #include <wlr/render/wlr_renderer.h> |
@@ -67,6 +68,18 @@ const char *view_get_instance(struct sway_view *view) { | |||
67 | return NULL; | 68 | return NULL; |
68 | } | 69 | } |
69 | 70 | ||
71 | const char *view_get_type(struct sway_view *view) { | ||
72 | switch(view->type) { | ||
73 | case SWAY_VIEW_WL_SHELL: | ||
74 | return "wl_shell"; | ||
75 | case SWAY_VIEW_XDG_SHELL_V6: | ||
76 | return "xdg_shell_v6"; | ||
77 | case SWAY_VIEW_XWAYLAND: | ||
78 | return "xwayland"; | ||
79 | } | ||
80 | return "unknown"; | ||
81 | } | ||
82 | |||
70 | void view_configure(struct sway_view *view, double ox, double oy, int width, | 83 | void view_configure(struct sway_view *view, double ox, double oy, int width, |
71 | int height) { | 84 | int height) { |
72 | if (view->impl->configure) { | 85 | if (view->impl->configure) { |
@@ -348,6 +361,11 @@ void view_unmap(struct sway_view *view) { | |||
348 | view->swayc = NULL; | 361 | view->swayc = NULL; |
349 | view->surface = NULL; | 362 | view->surface = NULL; |
350 | 363 | ||
364 | if (view->title_format) { | ||
365 | free(view->title_format); | ||
366 | view->title_format = NULL; | ||
367 | } | ||
368 | |||
351 | if (parent->type == C_OUTPUT) { | 369 | if (parent->type == C_OUTPUT) { |
352 | arrange_output(parent); | 370 | arrange_output(parent); |
353 | } else { | 371 | } else { |
@@ -475,3 +493,127 @@ void view_child_destroy(struct sway_view_child *child) { | |||
475 | free(child); | 493 | free(child); |
476 | } | 494 | } |
477 | } | 495 | } |
496 | |||
497 | static char *parse_title_format(struct sway_view *view) { | ||
498 | if (!view->title_format || strcmp(view->title_format, "%title") == 0) { | ||
499 | return strdup(view_get_title(view)); | ||
500 | } | ||
501 | const char *title = view_get_title(view); | ||
502 | const char *class = view_get_class(view); | ||
503 | const char *instance = view_get_instance(view); | ||
504 | const char *shell = view_get_type(view); | ||
505 | size_t title_len = title ? strlen(title) : 0; | ||
506 | size_t class_len = class ? strlen(class) : 0; | ||
507 | size_t instance_len = instance ? strlen(instance) : 0; | ||
508 | size_t shell_len = shell ? strlen(shell) : 0; | ||
509 | |||
510 | // First, determine the length | ||
511 | size_t len = 0; | ||
512 | char *format = view->title_format; | ||
513 | char *next = strchr(format, '%'); | ||
514 | while (next) { | ||
515 | len += next - format; | ||
516 | format = next; | ||
517 | |||
518 | if (strncmp(next, "%title", 6) == 0) { | ||
519 | len += title_len; | ||
520 | format += 6; | ||
521 | } else if (strncmp(next, "%class", 6) == 0) { | ||
522 | len += class_len; | ||
523 | format += 6; | ||
524 | } else if (strncmp(next, "%instance", 9) == 0) { | ||
525 | len += instance_len; | ||
526 | format += 9; | ||
527 | } else if (strncmp(next, "%shell", 6) == 0) { | ||
528 | len += shell_len; | ||
529 | format += 6; | ||
530 | } else { | ||
531 | ++format; | ||
532 | ++len; | ||
533 | } | ||
534 | next = strchr(format, '%'); | ||
535 | } | ||
536 | len += strlen(format); | ||
537 | |||
538 | char *buffer = calloc(len + 1, 1); | ||
539 | if (!sway_assert(buffer, "Unable to allocate title string")) { | ||
540 | return NULL; | ||
541 | } | ||
542 | |||
543 | // Now build the title | ||
544 | format = view->title_format; | ||
545 | next = strchr(format, '%'); | ||
546 | while (next) { | ||
547 | // Copy everything up to the % | ||
548 | strncat(buffer, format, next - format); | ||
549 | format = next; | ||
550 | |||
551 | if (strncmp(next, "%title", 6) == 0) { | ||
552 | if (title) { | ||
553 | strcat(buffer, title); | ||
554 | } | ||
555 | format += 6; | ||
556 | } else if (strncmp(next, "%class", 6) == 0) { | ||
557 | if (class) { | ||
558 | strcat(buffer, class); | ||
559 | } | ||
560 | format += 6; | ||
561 | } else if (strncmp(next, "%instance", 9) == 0) { | ||
562 | if (instance) { | ||
563 | strcat(buffer, instance); | ||
564 | } | ||
565 | format += 9; | ||
566 | } else if (strncmp(next, "%shell", 6) == 0) { | ||
567 | strcat(buffer, shell); | ||
568 | format += 6; | ||
569 | } else { | ||
570 | strcat(buffer, "%"); | ||
571 | ++format; | ||
572 | } | ||
573 | next = strchr(format, '%'); | ||
574 | } | ||
575 | strcat(buffer, format); | ||
576 | |||
577 | return buffer; | ||
578 | } | ||
579 | |||
580 | void view_update_title(struct sway_view *view, bool force) { | ||
581 | if (!view->swayc) { | ||
582 | return; | ||
583 | } | ||
584 | const char *title = view_get_title(view); | ||
585 | |||
586 | if (!force) { | ||
587 | if (title && view->swayc->name && strcmp(title, view->swayc->name) == 0) { | ||
588 | return; | ||
589 | } | ||
590 | if (!title && !view->swayc->name) { | ||
591 | return; | ||
592 | } | ||
593 | } | ||
594 | |||
595 | if (title) { | ||
596 | if (view->swayc->name) { | ||
597 | free(view->swayc->name); | ||
598 | } | ||
599 | if (view->swayc->formatted_title) { | ||
600 | free(view->swayc->formatted_title); | ||
601 | } | ||
602 | view->swayc->name = strdup(title); | ||
603 | view->swayc->formatted_title = parse_title_format(view); | ||
604 | } else { | ||
605 | free(view->swayc->name); | ||
606 | free(view->swayc->formatted_title); | ||
607 | view->swayc->name = NULL; | ||
608 | view->swayc->formatted_title = NULL; | ||
609 | } | ||
610 | container_calculate_title_height(view->swayc); | ||
611 | container_update_title_textures(view->swayc); | ||
612 | container_notify_child_title_changed(view->swayc->parent); | ||
613 | |||
614 | size_t prev_max_height = config->font_height; | ||
615 | config_find_font_height(false); | ||
616 | if (config->font_height != prev_max_height) { | ||
617 | arrange_root(); | ||
618 | } | ||
619 | } | ||