diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-05-15 13:14:18 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-05-17 08:29:14 +1000 |
commit | 0e2cc0af3049c6d1b91bda3081238e2e723e81b7 (patch) | |
tree | 34a18b12524c8de5bf68712162071abe3e574d71 | |
parent | Merge pull request #1995 from RedSoxFan/fix-1985 (diff) | |
download | sway-0e2cc0af3049c6d1b91bda3081238e2e723e81b7.tar.gz sway-0e2cc0af3049c6d1b91bda3081238e2e723e81b7.tar.zst sway-0e2cc0af3049c6d1b91bda3081238e2e723e81b7.zip |
Implement show_marks
-rw-r--r-- | include/sway/tree/view.h | 7 | ||||
-rw-r--r-- | sway/commands.c | 1 | ||||
-rw-r--r-- | sway/commands/mark.c | 1 | ||||
-rw-r--r-- | sway/commands/show_marks.c | 43 | ||||
-rw-r--r-- | sway/commands/unmark.c | 2 | ||||
-rw-r--r-- | sway/desktop/output.c | 27 | ||||
-rw-r--r-- | sway/meson.build | 1 | ||||
-rw-r--r-- | sway/tree/view.c | 78 |
8 files changed, 158 insertions, 2 deletions
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 7ed4d3df..951912d0 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h | |||
@@ -63,6 +63,11 @@ struct sway_view { | |||
63 | list_t *executed_criteria; // struct criteria * | 63 | list_t *executed_criteria; // struct criteria * |
64 | list_t *marks; // char * | 64 | list_t *marks; // char * |
65 | 65 | ||
66 | struct wlr_texture *marks_focused; | ||
67 | struct wlr_texture *marks_focused_inactive; | ||
68 | struct wlr_texture *marks_unfocused; | ||
69 | struct wlr_texture *marks_urgent; | ||
70 | |||
66 | union { | 71 | union { |
67 | struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6; | 72 | struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6; |
68 | struct wlr_xdg_surface *wlr_xdg_surface; | 73 | struct wlr_xdg_surface *wlr_xdg_surface; |
@@ -267,4 +272,6 @@ void view_clear_marks(struct sway_view *view); | |||
267 | 272 | ||
268 | bool view_has_mark(struct sway_view *view, char *mark); | 273 | bool view_has_mark(struct sway_view *view, char *mark); |
269 | 274 | ||
275 | void view_update_marks_textures(struct sway_view *view); | ||
276 | |||
270 | #endif | 277 | #endif |
diff --git a/sway/commands.c b/sway/commands.c index 9b6d6459..6cba0a1c 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -116,6 +116,7 @@ static struct cmd_handler handlers[] = { | |||
116 | { "mouse_warping", cmd_mouse_warping }, | 116 | { "mouse_warping", cmd_mouse_warping }, |
117 | { "output", cmd_output }, | 117 | { "output", cmd_output }, |
118 | { "seat", cmd_seat }, | 118 | { "seat", cmd_seat }, |
119 | { "show_marks", cmd_show_marks }, | ||
119 | { "workspace", cmd_workspace }, | 120 | { "workspace", cmd_workspace }, |
120 | { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth }, | 121 | { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth }, |
121 | }; | 122 | }; |
diff --git a/sway/commands/mark.c b/sway/commands/mark.c index b131f2f3..5a897e69 100644 --- a/sway/commands/mark.c +++ b/sway/commands/mark.c | |||
@@ -62,6 +62,7 @@ struct cmd_results *cmd_mark(int argc, char **argv) { | |||
62 | } | 62 | } |
63 | 63 | ||
64 | free(mark); | 64 | free(mark); |
65 | view_update_marks_textures(view); | ||
65 | view_execute_criteria(view); | 66 | view_execute_criteria(view); |
66 | 67 | ||
67 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 68 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
diff --git a/sway/commands/show_marks.c b/sway/commands/show_marks.c new file mode 100644 index 00000000..c7fdc538 --- /dev/null +++ b/sway/commands/show_marks.c | |||
@@ -0,0 +1,43 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | ||
3 | #include "sway/commands.h" | ||
4 | #include "sway/config.h" | ||
5 | #include "sway/tree/view.h" | ||
6 | #include "sway/output.h" | ||
7 | #include "list.h" | ||
8 | #include "log.h" | ||
9 | #include "stringop.h" | ||
10 | |||
11 | static void rebuild_marks_iterator(struct sway_container *con, void *data) { | ||
12 | if (con->type == C_VIEW) { | ||
13 | view_update_marks_textures(con->sway_view); | ||
14 | } | ||
15 | } | ||
16 | |||
17 | struct cmd_results *cmd_show_marks(int argc, char **argv) { | ||
18 | struct cmd_results *error = NULL; | ||
19 | if ((error = checkarg(argc, "show_marks", EXPECTED_AT_LEAST, 1))) { | ||
20 | return error; | ||
21 | } | ||
22 | |||
23 | if (strcmp(*argv, "yes") == 0) { | ||
24 | config->show_marks = true; | ||
25 | } else if (strcmp(*argv, "no") == 0) { | ||
26 | config->show_marks = false; | ||
27 | } else { | ||
28 | return cmd_results_new(CMD_INVALID, "show_marks", | ||
29 | "Expected 'show_marks <yes|no>'"); | ||
30 | } | ||
31 | |||
32 | if (config->show_marks) { | ||
33 | container_for_each_descendant_dfs(&root_container, | ||
34 | rebuild_marks_iterator, NULL); | ||
35 | } | ||
36 | |||
37 | for (int i = 0; i < root_container.children->length; ++i) { | ||
38 | struct sway_container *con = root_container.children->items[i]; | ||
39 | output_damage_whole(con->sway_output); | ||
40 | } | ||
41 | |||
42 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
43 | } | ||
diff --git a/sway/commands/unmark.c b/sway/commands/unmark.c index ea2a5709..1ce2c56b 100644 --- a/sway/commands/unmark.c +++ b/sway/commands/unmark.c | |||
@@ -10,6 +10,7 @@ | |||
10 | static void remove_all_marks_iterator(struct sway_container *con, void *data) { | 10 | static void remove_all_marks_iterator(struct sway_container *con, void *data) { |
11 | if (con->type == C_VIEW) { | 11 | if (con->type == C_VIEW) { |
12 | view_clear_marks(con->sway_view); | 12 | view_clear_marks(con->sway_view); |
13 | view_update_marks_textures(con->sway_view); | ||
13 | } | 14 | } |
14 | } | 15 | } |
15 | 16 | ||
@@ -45,6 +46,7 @@ struct cmd_results *cmd_unmark(int argc, char **argv) { | |||
45 | } else if (view && !mark) { | 46 | } else if (view && !mark) { |
46 | // Clear all marks from the given view | 47 | // Clear all marks from the given view |
47 | view_clear_marks(view); | 48 | view_clear_marks(view); |
49 | view_update_marks_textures(view); | ||
48 | } else if (!view && mark) { | 50 | } else if (!view && mark) { |
49 | // Remove mark from whichever view has it | 51 | // Remove mark from whichever view has it |
50 | view_find_and_unmark(mark); | 52 | view_find_and_unmark(mark); |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index b12130d9..57d71d5e 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -317,7 +317,7 @@ damage_finish: | |||
317 | static void render_container_simple_border_normal(struct sway_output *output, | 317 | static void render_container_simple_border_normal(struct sway_output *output, |
318 | pixman_region32_t *output_damage, | 318 | pixman_region32_t *output_damage, |
319 | struct sway_container *con, struct border_colors *colors, | 319 | struct sway_container *con, struct border_colors *colors, |
320 | struct wlr_texture *title_texture) { | 320 | struct wlr_texture *title_texture, struct wlr_texture *marks_texture) { |
321 | struct wlr_box box; | 321 | struct wlr_box box; |
322 | float color[4]; | 322 | float color[4]; |
323 | 323 | ||
@@ -413,6 +413,25 @@ static void render_container_simple_border_normal(struct sway_output *output, | |||
413 | render_texture(output->wlr_output, output_damage, title_texture, | 413 | render_texture(output->wlr_output, output_damage, title_texture, |
414 | &texture_box, matrix, 1.0); | 414 | &texture_box, matrix, 1.0); |
415 | } | 415 | } |
416 | |||
417 | // Marks | ||
418 | if (config->show_marks && marks_texture) { | ||
419 | float output_scale = output->wlr_output->scale; | ||
420 | struct wlr_box texture_box; | ||
421 | wlr_texture_get_size(marks_texture, | ||
422 | &texture_box.width, &texture_box.height); | ||
423 | texture_box.x = (box.x + box.width) * output_scale - texture_box.width; | ||
424 | texture_box.y = (box.y + box.height) | ||
425 | * output_scale - texture_box.height; | ||
426 | |||
427 | float matrix[9]; | ||
428 | wlr_matrix_project_box(matrix, &texture_box, | ||
429 | WL_OUTPUT_TRANSFORM_NORMAL, | ||
430 | 0.0, output->wlr_output->transform_matrix); | ||
431 | |||
432 | render_texture(output->wlr_output, output_damage, marks_texture, | ||
433 | &texture_box, matrix, 1.0); | ||
434 | } | ||
416 | } | 435 | } |
417 | 436 | ||
418 | /** | 437 | /** |
@@ -501,20 +520,24 @@ static void render_container_simple(struct sway_output *output, | |||
501 | if (child->sway_view->border != B_NONE) { | 520 | if (child->sway_view->border != B_NONE) { |
502 | struct border_colors *colors; | 521 | struct border_colors *colors; |
503 | struct wlr_texture *title_texture; | 522 | struct wlr_texture *title_texture; |
523 | struct wlr_texture *marks_texture; | ||
504 | if (focus == child || parent_focused) { | 524 | if (focus == child || parent_focused) { |
505 | colors = &config->border_colors.focused; | 525 | colors = &config->border_colors.focused; |
506 | title_texture = child->title_focused; | 526 | title_texture = child->title_focused; |
527 | marks_texture = child->sway_view->marks_focused; | ||
507 | } else if (seat_get_focus_inactive(seat, con) == child) { | 528 | } else if (seat_get_focus_inactive(seat, con) == child) { |
508 | colors = &config->border_colors.focused_inactive; | 529 | colors = &config->border_colors.focused_inactive; |
509 | title_texture = child->title_focused_inactive; | 530 | title_texture = child->title_focused_inactive; |
531 | marks_texture = child->sway_view->marks_focused_inactive; | ||
510 | } else { | 532 | } else { |
511 | colors = &config->border_colors.unfocused; | 533 | colors = &config->border_colors.unfocused; |
512 | title_texture = child->title_unfocused; | 534 | title_texture = child->title_unfocused; |
535 | marks_texture = child->sway_view->marks_unfocused; | ||
513 | } | 536 | } |
514 | 537 | ||
515 | if (child->sway_view->border == B_NORMAL) { | 538 | if (child->sway_view->border == B_NORMAL) { |
516 | render_container_simple_border_normal(output, damage, | 539 | render_container_simple_border_normal(output, damage, |
517 | child, colors, title_texture); | 540 | child, colors, title_texture, marks_texture); |
518 | } else { | 541 | } else { |
519 | render_container_simple_border_pixel(output, damage, child, | 542 | render_container_simple_border_pixel(output, damage, child, |
520 | colors); | 543 | colors); |
diff --git a/sway/meson.build b/sway/meson.build index ed14b51a..72347d51 100644 --- a/sway/meson.build +++ b/sway/meson.build | |||
@@ -60,6 +60,7 @@ sway_sources = files( | |||
60 | 'commands/seat/cursor.c', | 60 | 'commands/seat/cursor.c', |
61 | 'commands/seat/fallback.c', | 61 | 'commands/seat/fallback.c', |
62 | 'commands/set.c', | 62 | 'commands/set.c', |
63 | 'commands/show_marks.c', | ||
63 | 'commands/split.c', | 64 | 'commands/split.c', |
64 | 'commands/swaybg_command.c', | 65 | 'commands/swaybg_command.c', |
65 | 'commands/title_format.c', | 66 | 'commands/title_format.c', |
diff --git a/sway/tree/view.c b/sway/tree/view.c index 833345c5..e26159d2 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -746,6 +746,7 @@ bool view_find_and_unmark(char *mark) { | |||
746 | if (strcmp(view_mark, mark) == 0) { | 746 | if (strcmp(view_mark, mark) == 0) { |
747 | free(view_mark); | 747 | free(view_mark); |
748 | list_del(view->marks, i); | 748 | list_del(view->marks, i); |
749 | view_update_marks_textures(view); | ||
749 | return true; | 750 | return true; |
750 | } | 751 | } |
751 | } | 752 | } |
@@ -769,3 +770,80 @@ bool view_has_mark(struct sway_view *view, char *mark) { | |||
769 | } | 770 | } |
770 | return false; | 771 | return false; |
771 | } | 772 | } |
773 | |||
774 | static void update_marks_texture(struct sway_view *view, | ||
775 | struct wlr_texture **texture, struct border_colors *class) { | ||
776 | struct sway_container *output = container_parent(view->swayc, C_OUTPUT); | ||
777 | if (!output) { | ||
778 | return; | ||
779 | } | ||
780 | if (*texture) { | ||
781 | wlr_texture_destroy(*texture); | ||
782 | } | ||
783 | if (!view->marks->length) { | ||
784 | return; | ||
785 | } | ||
786 | |||
787 | size_t len = 0; | ||
788 | for (int i = 0; i < view->marks->length; ++i) { | ||
789 | len += strlen((char *)view->marks->items[i]) + 2; | ||
790 | } | ||
791 | char *buffer = calloc(len + 1, 1); | ||
792 | char *part = malloc(len + 1); | ||
793 | |||
794 | for (int i = 0; i < view->marks->length; ++i) { | ||
795 | char *mark = view->marks->items[i]; | ||
796 | sprintf(part, "[%s]", mark); | ||
797 | strcat(buffer, part); | ||
798 | } | ||
799 | free(part); | ||
800 | |||
801 | double scale = output->sway_output->wlr_output->scale; | ||
802 | int width = 0; | ||
803 | int height = config->font_height * scale; | ||
804 | |||
805 | cairo_t *c = cairo_create(NULL); | ||
806 | get_text_size(c, config->font, &width, NULL, scale, false, "%s", buffer); | ||
807 | cairo_destroy(c); | ||
808 | |||
809 | cairo_surface_t *surface = cairo_image_surface_create( | ||
810 | CAIRO_FORMAT_ARGB32, width, height); | ||
811 | cairo_t *cairo = cairo_create(surface); | ||
812 | cairo_set_source_rgba(cairo, class->background[0], class->background[1], | ||
813 | class->background[2], class->background[3]); | ||
814 | cairo_paint(cairo); | ||
815 | PangoContext *pango = pango_cairo_create_context(cairo); | ||
816 | cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); | ||
817 | cairo_set_source_rgba(cairo, class->text[0], class->text[1], | ||
818 | class->text[2], class->text[3]); | ||
819 | cairo_move_to(cairo, 0, 0); | ||
820 | |||
821 | pango_printf(cairo, config->font, scale, false, "%s", buffer); | ||
822 | |||
823 | cairo_surface_flush(surface); | ||
824 | unsigned char *data = cairo_image_surface_get_data(surface); | ||
825 | int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); | ||
826 | struct wlr_renderer *renderer = wlr_backend_get_renderer( | ||
827 | output->sway_output->wlr_output->backend); | ||
828 | *texture = wlr_texture_from_pixels( | ||
829 | renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data); | ||
830 | cairo_surface_destroy(surface); | ||
831 | g_object_unref(pango); | ||
832 | cairo_destroy(cairo); | ||
833 | free(buffer); | ||
834 | } | ||
835 | |||
836 | void view_update_marks_textures(struct sway_view *view) { | ||
837 | if (!config->show_marks) { | ||
838 | return; | ||
839 | } | ||
840 | update_marks_texture(view, &view->marks_focused, | ||
841 | &config->border_colors.focused); | ||
842 | update_marks_texture(view, &view->marks_focused_inactive, | ||
843 | &config->border_colors.focused_inactive); | ||
844 | update_marks_texture(view, &view->marks_unfocused, | ||
845 | &config->border_colors.unfocused); | ||
846 | update_marks_texture(view, &view->marks_urgent, | ||
847 | &config->border_colors.urgent); | ||
848 | container_damage_whole(view->swayc); | ||
849 | } | ||