aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-10-31 21:27:38 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-11-01 18:09:51 +1000
commit9fc736f4e1804b06538191786500f927ba0cda13 (patch)
tree8399de2ba00a8a0dd57f49dfc30455c330500b54
parentMerge pull request #3040 from RyanDwyer/border-props-to-container (diff)
downloadsway-9fc736f4e1804b06538191786500f927ba0cda13.tar.gz
sway-9fc736f4e1804b06538191786500f927ba0cda13.tar.zst
sway-9fc736f4e1804b06538191786500f927ba0cda13.zip
Move view marks properties to container struct
Like border properties, this will be needed to implement layout saving and restoring.
-rw-r--r--include/sway/tree/container.h28
-rw-r--r--include/sway/tree/view.h28
-rw-r--r--sway/commands/client.c4
-rw-r--r--sway/commands/mark.c19
-rw-r--r--sway/commands/move.c6
-rw-r--r--sway/commands/reload.c4
-rw-r--r--sway/commands/show_marks.c4
-rw-r--r--sway/commands/swap.c4
-rw-r--r--sway/commands/unmark.c41
-rw-r--r--sway/criteria.c5
-rw-r--r--sway/desktop/output.c4
-rw-r--r--sway/desktop/render.c30
-rw-r--r--sway/ipc-json.c6
-rw-r--r--sway/ipc-server.c8
-rw-r--r--sway/tree/container.c151
-rw-r--r--sway/tree/view.c155
16 files changed, 236 insertions, 261 deletions
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
index c0c803f1..4366a010 100644
--- a/include/sway/tree/container.h
+++ b/include/sway/tree/container.h
@@ -127,6 +127,12 @@ struct sway_container {
127 size_t title_height; 127 size_t title_height;
128 size_t title_baseline; 128 size_t title_baseline;
129 129
130 list_t *marks; // char *
131 struct wlr_texture *marks_focused;
132 struct wlr_texture *marks_focused_inactive;
133 struct wlr_texture *marks_unfocused;
134 struct wlr_texture *marks_urgent;
135
130 struct { 136 struct {
131 struct wl_signal destroy; 137 struct wl_signal destroy;
132 } events; 138 } events;
@@ -304,4 +310,26 @@ struct sway_container *container_split(struct sway_container *child,
304bool container_is_transient_for(struct sway_container *child, 310bool container_is_transient_for(struct sway_container *child,
305 struct sway_container *ancestor); 311 struct sway_container *ancestor);
306 312
313/**
314 * Find any container that has the given mark and return it.
315 */
316struct sway_container *container_find_mark(char *mark);
317
318/**
319 * Find any container that has the given mark and remove the mark from the
320 * container. Returns true if it matched a container.
321 */
322bool container_find_and_unmark(char *mark);
323
324/**
325 * Remove all marks from the container.
326 */
327void container_clear_marks(struct sway_container *container);
328
329bool container_has_mark(struct sway_container *container, char *mark);
330
331void container_add_mark(struct sway_container *container, char *mark);
332
333void container_update_marks_textures(struct sway_container *container);
334
307#endif 335#endif
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h
index 67f17914..4a8c3cb1 100644
--- a/include/sway/tree/view.h
+++ b/include/sway/tree/view.h
@@ -100,12 +100,6 @@ struct sway_view {
100 bool destroying; 100 bool destroying;
101 101
102 list_t *executed_criteria; // struct criteria * 102 list_t *executed_criteria; // struct criteria *
103 list_t *marks; // char *
104
105 struct wlr_texture *marks_focused;
106 struct wlr_texture *marks_focused_inactive;
107 struct wlr_texture *marks_unfocused;
108 struct wlr_texture *marks_urgent;
109 103
110 union { 104 union {
111 struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6; 105 struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6;
@@ -353,28 +347,6 @@ void view_update_title(struct sway_view *view, bool force);
353void view_execute_criteria(struct sway_view *view); 347void view_execute_criteria(struct sway_view *view);
354 348
355/** 349/**
356 * Find any view that has the given mark and return it.
357 */
358struct sway_view *view_find_mark(char *mark);
359
360/**
361 * Find any view that has the given mark and remove the mark from the view.
362 * Returns true if it matched a view.
363 */
364bool view_find_and_unmark(char *mark);
365
366/**
367 * Remove all marks from the view.
368 */
369void view_clear_marks(struct sway_view *view);
370
371bool view_has_mark(struct sway_view *view, char *mark);
372
373void view_add_mark(struct sway_view *view, char *mark);
374
375void view_update_marks_textures(struct sway_view *view);
376
377/**
378 * Returns true if there's a possibility the view may be rendered on screen. 350 * Returns true if there's a possibility the view may be rendered on screen.
379 * Intended for damage tracking. 351 * Intended for damage tracking.
380 */ 352 */
diff --git a/sway/commands/client.c b/sway/commands/client.c
index 9f54fa94..746e8713 100644
--- a/sway/commands/client.c
+++ b/sway/commands/client.c
@@ -5,9 +5,7 @@
5#include "sway/tree/container.h" 5#include "sway/tree/container.h"
6 6
7static void rebuild_textures_iterator(struct sway_container *con, void *data) { 7static void rebuild_textures_iterator(struct sway_container *con, void *data) {
8 if (con->view) { 8 container_update_marks_textures(con);
9 view_update_marks_textures(con->view);
10 }
11 container_update_title_textures(con); 9 container_update_title_textures(con);
12} 10}
13 11
diff --git a/sway/commands/mark.c b/sway/commands/mark.c
index b1f47be1..c76e1d63 100644
--- a/sway/commands/mark.c
+++ b/sway/commands/mark.c
@@ -19,11 +19,10 @@ struct cmd_results *cmd_mark(int argc, char **argv) {
19 return error; 19 return error;
20 } 20 }
21 struct sway_container *container = config->handler_context.container; 21 struct sway_container *container = config->handler_context.container;
22 if (!container || !container->view) { 22 if (!container) {
23 return cmd_results_new(CMD_INVALID, "mark", 23 return cmd_results_new(CMD_INVALID, "mark",
24 "Only views can have marks"); 24 "Only containers can have marks");
25 } 25 }
26 struct sway_view *view = container->view;
27 26
28 bool add = false, toggle = false; 27 bool add = false, toggle = false;
29 while (argc > 0 && strncmp(*argv, "--", 2) == 0) { 28 while (argc > 0 && strncmp(*argv, "--", 2) == 0) {
@@ -47,22 +46,24 @@ struct cmd_results *cmd_mark(int argc, char **argv) {
47 } 46 }
48 47
49 char *mark = join_args(argv, argc); 48 char *mark = join_args(argv, argc);
50 bool had_mark = view_has_mark(view, mark); 49 bool had_mark = container_has_mark(container, mark);
51 50
52 if (!add) { 51 if (!add) {
53 // Replacing 52 // Replacing
54 view_clear_marks(view); 53 container_clear_marks(container);
55 } 54 }
56 55
57 view_find_and_unmark(mark); 56 container_find_and_unmark(mark);
58 57
59 if (!toggle || !had_mark) { 58 if (!toggle || !had_mark) {
60 view_add_mark(view, mark); 59 container_add_mark(container, mark);
61 } 60 }
62 61
63 free(mark); 62 free(mark);
64 view_update_marks_textures(view); 63 container_update_marks_textures(container);
65 view_execute_criteria(view); 64 if (container->view) {
65 view_execute_criteria(container->view);
66 }
66 67
67 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 68 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
68} 69}
diff --git a/sway/commands/move.c b/sway/commands/move.c
index 9035e3e2..7d8c1f1a 100644
--- a/sway/commands/move.c
+++ b/sway/commands/move.c
@@ -488,12 +488,12 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) {
488 } 488 }
489 destination = seat_get_focus_inactive(seat, &new_output->node); 489 destination = seat_get_focus_inactive(seat, &new_output->node);
490 } else if (strcasecmp(argv[1], "mark") == 0) { 490 } else if (strcasecmp(argv[1], "mark") == 0) {
491 struct sway_view *dest_view = view_find_mark(argv[2]); 491 struct sway_container *dest_con = container_find_mark(argv[2]);
492 if (dest_view == NULL) { 492 if (dest_con == NULL) {
493 return cmd_results_new(CMD_FAILURE, "move", 493 return cmd_results_new(CMD_FAILURE, "move",
494 "Mark '%s' not found", argv[2]); 494 "Mark '%s' not found", argv[2]);
495 } 495 }
496 destination = &dest_view->container->node; 496 destination = &dest_con->node;
497 } else { 497 } else {
498 return cmd_results_new(CMD_INVALID, "move", expected_syntax); 498 return cmd_results_new(CMD_INVALID, "move", expected_syntax);
499 } 499 }
diff --git a/sway/commands/reload.c b/sway/commands/reload.c
index 791081a8..62105cdc 100644
--- a/sway/commands/reload.c
+++ b/sway/commands/reload.c
@@ -10,9 +10,7 @@
10#include "log.h" 10#include "log.h"
11 11
12static void rebuild_textures_iterator(struct sway_container *con, void *data) { 12static void rebuild_textures_iterator(struct sway_container *con, void *data) {
13 if (con->view) { 13 container_update_marks_textures(con);
14 view_update_marks_textures(con->view);
15 }
16 container_update_title_textures(con); 14 container_update_title_textures(con);
17} 15}
18 16
diff --git a/sway/commands/show_marks.c b/sway/commands/show_marks.c
index d501584a..0baf6852 100644
--- a/sway/commands/show_marks.c
+++ b/sway/commands/show_marks.c
@@ -11,9 +11,7 @@
11#include "util.h" 11#include "util.h"
12 12
13static void rebuild_marks_iterator(struct sway_container *con, void *data) { 13static void rebuild_marks_iterator(struct sway_container *con, void *data) {
14 if (con->view) { 14 container_update_marks_textures(con);
15 view_update_marks_textures(con->view);
16 }
17} 15}
18 16
19struct cmd_results *cmd_show_marks(int argc, char **argv) { 17struct cmd_results *cmd_show_marks(int argc, char **argv) {
diff --git a/sway/commands/swap.c b/sway/commands/swap.c
index a70a6cdd..23e8d583 100644
--- a/sway/commands/swap.c
+++ b/sway/commands/swap.c
@@ -159,8 +159,8 @@ static bool test_id(struct sway_container *container, void *id) {
159} 159}
160 160
161static bool test_mark(struct sway_container *container, void *mark) { 161static bool test_mark(struct sway_container *container, void *mark) {
162 if (container->view && container->view->marks->length) { 162 if (container->marks->length) {
163 return !list_seq_find(container->view->marks, 163 return !list_seq_find(container->marks,
164 (int (*)(const void *, const void *))strcmp, mark); 164 (int (*)(const void *, const void *))strcmp, mark);
165 } 165 }
166 return false; 166 return false;
diff --git a/sway/commands/unmark.c b/sway/commands/unmark.c
index c671ed4e..98ac6ff2 100644
--- a/sway/commands/unmark.c
+++ b/sway/commands/unmark.c
@@ -9,10 +9,8 @@
9#include "stringop.h" 9#include "stringop.h"
10 10
11static void remove_all_marks_iterator(struct sway_container *con, void *data) { 11static void remove_all_marks_iterator(struct sway_container *con, void *data) {
12 if (con->view) { 12 container_clear_marks(con);
13 view_clear_marks(con->view); 13 container_update_marks_textures(con);
14 view_update_marks_textures(con->view);
15 }
16} 14}
17 15
18// unmark Remove all marks from all views 16// unmark Remove all marks from all views
@@ -21,15 +19,10 @@ static void remove_all_marks_iterator(struct sway_container *con, void *data) {
21// [criteria] unmark foo Remove single mark from matched view 19// [criteria] unmark foo Remove single mark from matched view
22 20
23struct cmd_results *cmd_unmark(int argc, char **argv) { 21struct cmd_results *cmd_unmark(int argc, char **argv) {
24 // Determine the view 22 // Determine the container
25 struct sway_view *view = NULL; 23 struct sway_container *con = NULL;
26 if (config->handler_context.using_criteria) { 24 if (config->handler_context.using_criteria) {
27 struct sway_container *container = config->handler_context.container; 25 con = config->handler_context.container;
28 if (!container || !container->view) {
29 return cmd_results_new(CMD_INVALID, "unmark",
30 "Only views can have marks");
31 }
32 view = container->view;
33 } 26 }
34 27
35 // Determine the mark 28 // Determine the mark
@@ -38,20 +31,20 @@ struct cmd_results *cmd_unmark(int argc, char **argv) {
38 mark = join_args(argv, argc); 31 mark = join_args(argv, argc);
39 } 32 }
40 33
41 if (view && mark) { 34 if (con && mark) {
42 // Remove the mark from the given view 35 // Remove the mark from the given container
43 if (view_has_mark(view, mark)) { 36 if (container_has_mark(con, mark)) {
44 view_find_and_unmark(mark); 37 container_find_and_unmark(mark);
45 } 38 }
46 } else if (view && !mark) { 39 } else if (con && !mark) {
47 // Clear all marks from the given view 40 // Clear all marks from the given container
48 view_clear_marks(view); 41 container_clear_marks(con);
49 view_update_marks_textures(view); 42 container_update_marks_textures(con);
50 } else if (!view && mark) { 43 } else if (!con && mark) {
51 // Remove mark from whichever view has it 44 // Remove mark from whichever container has it
52 view_find_and_unmark(mark); 45 container_find_and_unmark(mark);
53 } else { 46 } else {
54 // Remove all marks from all views 47 // Remove all marks from all containers
55 root_for_each_container(remove_all_marks_iterator, NULL); 48 root_for_each_container(remove_all_marks_iterator, NULL);
56 } 49 }
57 free(mark); 50 free(mark);
diff --git a/sway/criteria.c b/sway/criteria.c
index 89630d90..2f9992e9 100644
--- a/sway/criteria.c
+++ b/sway/criteria.c
@@ -121,8 +121,9 @@ static bool criteria_matches_view(struct criteria *criteria,
121 121
122 if (criteria->con_mark) { 122 if (criteria->con_mark) {
123 bool exists = false; 123 bool exists = false;
124 for (int i = 0; i < view->marks->length; ++i) { 124 struct sway_container *con = view->container;
125 if (regex_cmp(view->marks->items[i], criteria->con_mark) == 0) { 125 for (int i = 0; i < con->marks->length; ++i) {
126 if (regex_cmp(con->marks->items[i], criteria->con_mark) == 0) {
126 exists = true; 127 exists = true;
127 break; 128 break;
128 } 129 }
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 4d6c0336..2b90f151 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -532,9 +532,7 @@ static void handle_transform(struct wl_listener *listener, void *data) {
532 532
533static void update_textures(struct sway_container *con, void *data) { 533static void update_textures(struct sway_container *con, void *data) {
534 container_update_title_textures(con); 534 container_update_title_textures(con);
535 if (con->view) { 535 container_update_marks_textures(con);
536 view_update_marks_textures(con->view);
537 }
538} 536}
539 537
540static void handle_scale(struct wl_listener *listener, void *data) { 538static void handle_scale(struct wl_listener *listener, void *data) {
diff --git a/sway/desktop/render.c b/sway/desktop/render.c
index 1a72f752..cf6da682 100644
--- a/sway/desktop/render.c
+++ b/sway/desktop/render.c
@@ -625,19 +625,19 @@ static void render_containers_linear(struct sway_output *output,
625 if (view_is_urgent(view)) { 625 if (view_is_urgent(view)) {
626 colors = &config->border_colors.urgent; 626 colors = &config->border_colors.urgent;
627 title_texture = child->title_urgent; 627 title_texture = child->title_urgent;
628 marks_texture = view->marks_urgent; 628 marks_texture = child->marks_urgent;
629 } else if (state->focused || parent->focused) { 629 } else if (state->focused || parent->focused) {
630 colors = &config->border_colors.focused; 630 colors = &config->border_colors.focused;
631 title_texture = child->title_focused; 631 title_texture = child->title_focused;
632 marks_texture = view->marks_focused; 632 marks_texture = child->marks_focused;
633 } else if (child == parent->active_child) { 633 } else if (child == parent->active_child) {
634 colors = &config->border_colors.focused_inactive; 634 colors = &config->border_colors.focused_inactive;
635 title_texture = child->title_focused_inactive; 635 title_texture = child->title_focused_inactive;
636 marks_texture = view->marks_focused_inactive; 636 marks_texture = child->marks_focused_inactive;
637 } else { 637 } else {
638 colors = &config->border_colors.unfocused; 638 colors = &config->border_colors.unfocused;
639 title_texture = child->title_unfocused; 639 title_texture = child->title_unfocused;
640 marks_texture = view->marks_unfocused; 640 marks_texture = child->marks_unfocused;
641 } 641 }
642 642
643 if (state->border == B_NORMAL) { 643 if (state->border == B_NORMAL) {
@@ -681,19 +681,19 @@ static void render_containers_tabbed(struct sway_output *output,
681 if (urgent) { 681 if (urgent) {
682 colors = &config->border_colors.urgent; 682 colors = &config->border_colors.urgent;
683 title_texture = child->title_urgent; 683 title_texture = child->title_urgent;
684 marks_texture = view ? view->marks_urgent : NULL; 684 marks_texture = child->marks_urgent;
685 } else if (cstate->focused || parent->focused) { 685 } else if (cstate->focused || parent->focused) {
686 colors = &config->border_colors.focused; 686 colors = &config->border_colors.focused;
687 title_texture = child->title_focused; 687 title_texture = child->title_focused;
688 marks_texture = view ? view->marks_focused : NULL; 688 marks_texture = child->marks_focused;
689 } else if (child == parent->active_child) { 689 } else if (child == parent->active_child) {
690 colors = &config->border_colors.focused_inactive; 690 colors = &config->border_colors.focused_inactive;
691 title_texture = child->title_focused_inactive; 691 title_texture = child->title_focused_inactive;
692 marks_texture = view ? view->marks_focused_inactive : NULL; 692 marks_texture = child->marks_focused_inactive;
693 } else { 693 } else {
694 colors = &config->border_colors.unfocused; 694 colors = &config->border_colors.unfocused;
695 title_texture = child->title_unfocused; 695 title_texture = child->title_unfocused;
696 marks_texture = view ? view->marks_unfocused : NULL; 696 marks_texture = child->marks_unfocused;
697 } 697 }
698 698
699 int x = cstate->con_x + tab_width * i; 699 int x = cstate->con_x + tab_width * i;
@@ -746,19 +746,19 @@ static void render_containers_stacked(struct sway_output *output,
746 if (urgent) { 746 if (urgent) {
747 colors = &config->border_colors.urgent; 747 colors = &config->border_colors.urgent;
748 title_texture = child->title_urgent; 748 title_texture = child->title_urgent;
749 marks_texture = view ? view->marks_urgent : NULL; 749 marks_texture = child->marks_urgent;
750 } else if (cstate->focused || parent->focused) { 750 } else if (cstate->focused || parent->focused) {
751 colors = &config->border_colors.focused; 751 colors = &config->border_colors.focused;
752 title_texture = child->title_focused; 752 title_texture = child->title_focused;
753 marks_texture = view ? view->marks_focused : NULL; 753 marks_texture = child->marks_focused;
754 } else if (child == parent->active_child) { 754 } else if (child == parent->active_child) {
755 colors = &config->border_colors.focused_inactive; 755 colors = &config->border_colors.focused_inactive;
756 title_texture = child->title_focused_inactive; 756 title_texture = child->title_focused_inactive;
757 marks_texture = view ? view->marks_focused_inactive : NULL; 757 marks_texture = child->marks_focused_inactive;
758 } else { 758 } else {
759 colors = &config->border_colors.unfocused; 759 colors = &config->border_colors.unfocused;
760 title_texture = child->title_unfocused; 760 title_texture = child->title_unfocused;
761 marks_texture = view ? view->marks_unfocused : NULL; 761 marks_texture = child->marks_unfocused;
762 } 762 }
763 763
764 int y = parent->box.y + titlebar_height * i; 764 int y = parent->box.y + titlebar_height * i;
@@ -841,15 +841,15 @@ static void render_floating_container(struct sway_output *soutput,
841 if (view_is_urgent(view)) { 841 if (view_is_urgent(view)) {
842 colors = &config->border_colors.urgent; 842 colors = &config->border_colors.urgent;
843 title_texture = con->title_urgent; 843 title_texture = con->title_urgent;
844 marks_texture = view->marks_urgent; 844 marks_texture = con->marks_urgent;
845 } else if (con->current.focused) { 845 } else if (con->current.focused) {
846 colors = &config->border_colors.focused; 846 colors = &config->border_colors.focused;
847 title_texture = con->title_focused; 847 title_texture = con->title_focused;
848 marks_texture = view->marks_focused; 848 marks_texture = con->marks_focused;
849 } else { 849 } else {
850 colors = &config->border_colors.unfocused; 850 colors = &config->border_colors.unfocused;
851 title_texture = con->title_unfocused; 851 title_texture = con->title_unfocused;
852 marks_texture = view->marks_unfocused; 852 marks_texture = con->marks_unfocused;
853 } 853 }
854 854
855 if (con->current.border == B_NORMAL) { 855 if (con->current.border == B_NORMAL) {
diff --git a/sway/ipc-json.c b/sway/ipc-json.c
index 5c9b3e5a..20ab57b4 100644
--- a/sway/ipc-json.c
+++ b/sway/ipc-json.c
@@ -230,9 +230,9 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object
230 app_id ? json_object_new_string(app_id) : NULL); 230 app_id ? json_object_new_string(app_id) : NULL);
231 231
232 json_object *marks = json_object_new_array(); 232 json_object *marks = json_object_new_array();
233 list_t *view_marks = c->view->marks; 233 list_t *con_marks = c->marks;
234 for (int i = 0; i < view_marks->length; ++i) { 234 for (int i = 0; i < con_marks->length; ++i) {
235 json_object_array_add(marks, json_object_new_string(view_marks->items[i])); 235 json_object_array_add(marks, json_object_new_string(con_marks->items[i]));
236 } 236 }
237 237
238 json_object_object_add(object, "marks", marks); 238 json_object_object_add(object, "marks", marks);
diff --git a/sway/ipc-server.c b/sway/ipc-server.c
index 21f431be..6466d263 100644
--- a/sway/ipc-server.c
+++ b/sway/ipc-server.c
@@ -563,11 +563,9 @@ static void ipc_get_workspaces_callback(struct sway_workspace *workspace,
563 563
564static void ipc_get_marks_callback(struct sway_container *con, void *data) { 564static void ipc_get_marks_callback(struct sway_container *con, void *data) {
565 json_object *marks = (json_object *)data; 565 json_object *marks = (json_object *)data;
566 if (con->view && con->view->marks) { 566 for (int i = 0; i < con->marks->length; ++i) {
567 for (int i = 0; i < con->view->marks->length; ++i) { 567 char *mark = (char *)con->marks->items[i];
568 char *mark = (char *)con->view->marks->items[i]; 568 json_object_array_add(marks, json_object_new_string(mark));
569 json_object_array_add(marks, json_object_new_string(mark));
570 }
571 } 569 }
572} 570}
573 571
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 322f2f67..458ed7ff 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -39,6 +39,7 @@ struct sway_container *container_create(struct sway_view *view) {
39 c->children = create_list(); 39 c->children = create_list();
40 c->current.children = create_list(); 40 c->current.children = create_list();
41 } 41 }
42 c->marks = create_list();
42 c->outputs = create_list(); 43 c->outputs = create_list();
43 44
44 wl_signal_init(&c->events.destroy); 45 wl_signal_init(&c->events.destroy);
@@ -66,6 +67,13 @@ void container_destroy(struct sway_container *con) {
66 list_free(con->current.children); 67 list_free(con->current.children);
67 list_free(con->outputs); 68 list_free(con->outputs);
68 69
70 list_foreach(con->marks, free);
71 list_free(con->marks);
72 wlr_texture_destroy(con->marks_focused);
73 wlr_texture_destroy(con->marks_focused_inactive);
74 wlr_texture_destroy(con->marks_unfocused);
75 wlr_texture_destroy(con->marks_urgent);
76
69 if (con->view) { 77 if (con->view) {
70 if (con->view->container == con) { 78 if (con->view->container == con) {
71 con->view->container = NULL; 79 con->view->container = NULL;
@@ -996,9 +1004,7 @@ void container_discover_outputs(struct sway_container *con) {
996 double new_scale = new_output ? new_output->wlr_output->scale : -1; 1004 double new_scale = new_output ? new_output->wlr_output->scale : -1;
997 if (old_scale != new_scale) { 1005 if (old_scale != new_scale) {
998 container_update_title_textures(con); 1006 container_update_title_textures(con);
999 if (con->view) { 1007 container_update_marks_textures(con);
1000 view_update_marks_textures(con->view);
1001 }
1002 } 1008 }
1003} 1009}
1004 1010
@@ -1218,3 +1224,142 @@ bool container_is_transient_for(struct sway_container *child,
1218 child->view && ancestor->view && 1224 child->view && ancestor->view &&
1219 view_is_transient_for(child->view, ancestor->view); 1225 view_is_transient_for(child->view, ancestor->view);
1220} 1226}
1227
1228static bool find_by_mark_iterator(struct sway_container *con, void *data) {
1229 char *mark = data;
1230 return container_has_mark(con, mark);
1231}
1232
1233struct sway_container *container_find_mark(char *mark) {
1234 return root_find_container(find_by_mark_iterator, mark);
1235}
1236
1237bool container_find_and_unmark(char *mark) {
1238 struct sway_container *con = root_find_container(
1239 find_by_mark_iterator, mark);
1240 if (!con) {
1241 return false;
1242 }
1243
1244 for (int i = 0; i < con->marks->length; ++i) {
1245 char *con_mark = con->marks->items[i];
1246 if (strcmp(con_mark, mark) == 0) {
1247 free(con_mark);
1248 list_del(con->marks, i);
1249 container_update_marks_textures(con);
1250 ipc_event_window(con, "mark");
1251 return true;
1252 }
1253 }
1254 return false;
1255}
1256
1257void container_clear_marks(struct sway_container *con) {
1258 list_foreach(con->marks, free);
1259 con->marks->length = 0;
1260 ipc_event_window(con, "mark");
1261}
1262
1263bool container_has_mark(struct sway_container *con, char *mark) {
1264 for (int i = 0; i < con->marks->length; ++i) {
1265 char *item = con->marks->items[i];
1266 if (strcmp(item, mark) == 0) {
1267 return true;
1268 }
1269 }
1270 return false;
1271}
1272
1273void container_add_mark(struct sway_container *con, char *mark) {
1274 list_add(con->marks, strdup(mark));
1275 ipc_event_window(con, "mark");
1276}
1277
1278static void update_marks_texture(struct sway_container *con,
1279 struct wlr_texture **texture, struct border_colors *class) {
1280 struct sway_output *output = container_get_effective_output(con);
1281 if (!output) {
1282 return;
1283 }
1284 if (*texture) {
1285 wlr_texture_destroy(*texture);
1286 *texture = NULL;
1287 }
1288 if (!con->marks->length) {
1289 return;
1290 }
1291
1292 size_t len = 0;
1293 for (int i = 0; i < con->marks->length; ++i) {
1294 char *mark = con->marks->items[i];
1295 if (mark[0] != '_') {
1296 len += strlen(mark) + 2;
1297 }
1298 }
1299 char *buffer = calloc(len + 1, 1);
1300 char *part = malloc(len + 1);
1301
1302 if (!sway_assert(buffer && part, "Unable to allocate memory")) {
1303 free(buffer);
1304 return;
1305 }
1306
1307 for (int i = 0; i < con->marks->length; ++i) {
1308 char *mark = con->marks->items[i];
1309 if (mark[0] != '_') {
1310 sprintf(part, "[%s]", mark);
1311 strcat(buffer, part);
1312 }
1313 }
1314 free(part);
1315
1316 double scale = output->wlr_output->scale;
1317 int width = 0;
1318 int height = con->title_height * scale;
1319
1320 cairo_t *c = cairo_create(NULL);
1321 get_text_size(c, config->font, &width, NULL, NULL, scale, false,
1322 "%s", buffer);
1323 cairo_destroy(c);
1324
1325 cairo_surface_t *surface = cairo_image_surface_create(
1326 CAIRO_FORMAT_ARGB32, width, height);
1327 cairo_t *cairo = cairo_create(surface);
1328 cairo_set_source_rgba(cairo, class->background[0], class->background[1],
1329 class->background[2], class->background[3]);
1330 cairo_paint(cairo);
1331 PangoContext *pango = pango_cairo_create_context(cairo);
1332 cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST);
1333 cairo_set_source_rgba(cairo, class->text[0], class->text[1],
1334 class->text[2], class->text[3]);
1335 cairo_move_to(cairo, 0, 0);
1336
1337 pango_printf(cairo, config->font, scale, false, "%s", buffer);
1338
1339 cairo_surface_flush(surface);
1340 unsigned char *data = cairo_image_surface_get_data(surface);
1341 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
1342 struct wlr_renderer *renderer = wlr_backend_get_renderer(
1343 output->wlr_output->backend);
1344 *texture = wlr_texture_from_pixels(
1345 renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data);
1346 cairo_surface_destroy(surface);
1347 g_object_unref(pango);
1348 cairo_destroy(cairo);
1349 free(buffer);
1350}
1351
1352void container_update_marks_textures(struct sway_container *con) {
1353 if (!config->show_marks) {
1354 return;
1355 }
1356 update_marks_texture(con, &con->marks_focused,
1357 &config->border_colors.focused);
1358 update_marks_texture(con, &con->marks_focused_inactive,
1359 &config->border_colors.focused_inactive);
1360 update_marks_texture(con, &con->marks_unfocused,
1361 &config->border_colors.unfocused);
1362 update_marks_texture(con, &con->marks_urgent,
1363 &config->border_colors.urgent);
1364 container_damage_whole(con);
1365}
diff --git a/sway/tree/view.c b/sway/tree/view.c
index 9a89b8ea..1aa59e68 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -35,7 +35,6 @@ void view_init(struct sway_view *view, enum sway_view_type type,
35 view->type = type; 35 view->type = type;
36 view->impl = impl; 36 view->impl = impl;
37 view->executed_criteria = create_list(); 37 view->executed_criteria = create_list();
38 view->marks = create_list();
39 view->allow_request_urgent = true; 38 view->allow_request_urgent = true;
40 wl_signal_init(&view->events.unmap); 39 wl_signal_init(&view->events.unmap);
41} 40}
@@ -55,13 +54,6 @@ void view_destroy(struct sway_view *view) {
55 } 54 }
56 list_free(view->executed_criteria); 55 list_free(view->executed_criteria);
57 56
58 list_foreach(view->marks, free);
59 list_free(view->marks);
60
61 wlr_texture_destroy(view->marks_focused);
62 wlr_texture_destroy(view->marks_focused_inactive);
63 wlr_texture_destroy(view->marks_unfocused);
64 wlr_texture_destroy(view->marks_urgent);
65 free(view->title_format); 57 free(view->title_format);
66 58
67 if (view->impl->destroy) { 59 if (view->impl->destroy) {
@@ -937,153 +929,6 @@ void view_update_title(struct sway_view *view, bool force) {
937 ipc_event_window(view->container, "title"); 929 ipc_event_window(view->container, "title");
938} 930}
939 931
940static bool find_by_mark_iterator(struct sway_container *con,
941 void *data) {
942 char *mark = data;
943 return con->view && view_has_mark(con->view, mark);
944}
945
946struct sway_view *view_find_mark(char *mark) {
947 struct sway_container *container = root_find_container(
948 find_by_mark_iterator, mark);
949 if (!container) {
950 return NULL;
951 }
952 return container->view;
953}
954
955bool view_find_and_unmark(char *mark) {
956 struct sway_container *container = root_find_container(
957 find_by_mark_iterator, mark);
958 if (!container) {
959 return false;
960 }
961 struct sway_view *view = container->view;
962
963 for (int i = 0; i < view->marks->length; ++i) {
964 char *view_mark = view->marks->items[i];
965 if (strcmp(view_mark, mark) == 0) {
966 free(view_mark);
967 list_del(view->marks, i);
968 view_update_marks_textures(view);
969 ipc_event_window(container, "mark");
970 return true;
971 }
972 }
973 return false;
974}
975
976void view_clear_marks(struct sway_view *view) {
977 list_foreach(view->marks, free);
978 view->marks->length = 0;
979 ipc_event_window(view->container, "mark");
980}
981
982bool view_has_mark(struct sway_view *view, char *mark) {
983 for (int i = 0; i < view->marks->length; ++i) {
984 char *item = view->marks->items[i];
985 if (strcmp(item, mark) == 0) {
986 return true;
987 }
988 }
989 return false;
990}
991
992void view_add_mark(struct sway_view *view, char *mark) {
993 list_add(view->marks, strdup(mark));
994 ipc_event_window(view->container, "mark");
995}
996
997static void update_marks_texture(struct sway_view *view,
998 struct wlr_texture **texture, struct border_colors *class) {
999 struct sway_output *output =
1000 container_get_effective_output(view->container);
1001 if (!output) {
1002 return;
1003 }
1004 if (*texture) {
1005 wlr_texture_destroy(*texture);
1006 *texture = NULL;
1007 }
1008 if (!view->marks->length) {
1009 return;
1010 }
1011
1012 size_t len = 0;
1013 for (int i = 0; i < view->marks->length; ++i) {
1014 char *mark = view->marks->items[i];
1015 if (mark[0] != '_') {
1016 len += strlen(mark) + 2;
1017 }
1018 }
1019 char *buffer = calloc(len + 1, 1);
1020 char *part = malloc(len + 1);
1021
1022 if (!sway_assert(buffer && part, "Unable to allocate memory")) {
1023 free(buffer);
1024 return;
1025 }
1026
1027 for (int i = 0; i < view->marks->length; ++i) {
1028 char *mark = view->marks->items[i];
1029 if (mark[0] != '_') {
1030 sprintf(part, "[%s]", mark);
1031 strcat(buffer, part);
1032 }
1033 }
1034 free(part);
1035
1036 double scale = output->wlr_output->scale;
1037 int width = 0;
1038 int height = view->container->title_height * scale;
1039
1040 cairo_t *c = cairo_create(NULL);
1041 get_text_size(c, config->font, &width, NULL, NULL, scale, false,
1042 "%s", buffer);
1043 cairo_destroy(c);
1044
1045 cairo_surface_t *surface = cairo_image_surface_create(
1046 CAIRO_FORMAT_ARGB32, width, height);
1047 cairo_t *cairo = cairo_create(surface);
1048 cairo_set_source_rgba(cairo, class->background[0], class->background[1],
1049 class->background[2], class->background[3]);
1050 cairo_paint(cairo);
1051 PangoContext *pango = pango_cairo_create_context(cairo);
1052 cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST);
1053 cairo_set_source_rgba(cairo, class->text[0], class->text[1],
1054 class->text[2], class->text[3]);
1055 cairo_move_to(cairo, 0, 0);
1056
1057 pango_printf(cairo, config->font, scale, false, "%s", buffer);
1058
1059 cairo_surface_flush(surface);
1060 unsigned char *data = cairo_image_surface_get_data(surface);
1061 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
1062 struct wlr_renderer *renderer = wlr_backend_get_renderer(
1063 output->wlr_output->backend);
1064 *texture = wlr_texture_from_pixels(
1065 renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data);
1066 cairo_surface_destroy(surface);
1067 g_object_unref(pango);
1068 cairo_destroy(cairo);
1069 free(buffer);
1070}
1071
1072void view_update_marks_textures(struct sway_view *view) {
1073 if (!config->show_marks) {
1074 return;
1075 }
1076 update_marks_texture(view, &view->marks_focused,
1077 &config->border_colors.focused);
1078 update_marks_texture(view, &view->marks_focused_inactive,
1079 &config->border_colors.focused_inactive);
1080 update_marks_texture(view, &view->marks_unfocused,
1081 &config->border_colors.unfocused);
1082 update_marks_texture(view, &view->marks_urgent,
1083 &config->border_colors.urgent);
1084 container_damage_whole(view->container);
1085}
1086
1087bool view_is_visible(struct sway_view *view) { 932bool view_is_visible(struct sway_view *view) {
1088 if (view->container->node.destroying) { 933 if (view->container->node.destroying) {
1089 return false; 934 return false;