diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-11-01 13:01:15 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-01 13:01:15 +0100 |
commit | 8ad06f0ec554da0ded551fc1b83f9cd0b3fa2a27 (patch) | |
tree | 8399de2ba00a8a0dd57f49dfc30455c330500b54 | |
parent | Merge pull request #3040 from RyanDwyer/border-props-to-container (diff) | |
parent | Move view marks properties to container struct (diff) | |
download | sway-8ad06f0ec554da0ded551fc1b83f9cd0b3fa2a27.tar.gz sway-8ad06f0ec554da0ded551fc1b83f9cd0b3fa2a27.tar.zst sway-8ad06f0ec554da0ded551fc1b83f9cd0b3fa2a27.zip |
Merge pull request #3041 from RyanDwyer/marks-props-to-container
Move view marks properties to container struct
-rw-r--r-- | include/sway/tree/container.h | 28 | ||||
-rw-r--r-- | include/sway/tree/view.h | 28 | ||||
-rw-r--r-- | sway/commands/client.c | 4 | ||||
-rw-r--r-- | sway/commands/mark.c | 19 | ||||
-rw-r--r-- | sway/commands/move.c | 6 | ||||
-rw-r--r-- | sway/commands/reload.c | 4 | ||||
-rw-r--r-- | sway/commands/show_marks.c | 4 | ||||
-rw-r--r-- | sway/commands/swap.c | 4 | ||||
-rw-r--r-- | sway/commands/unmark.c | 41 | ||||
-rw-r--r-- | sway/criteria.c | 5 | ||||
-rw-r--r-- | sway/desktop/output.c | 4 | ||||
-rw-r--r-- | sway/desktop/render.c | 30 | ||||
-rw-r--r-- | sway/ipc-json.c | 6 | ||||
-rw-r--r-- | sway/ipc-server.c | 8 | ||||
-rw-r--r-- | sway/tree/container.c | 151 | ||||
-rw-r--r-- | sway/tree/view.c | 155 |
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, | |||
304 | bool container_is_transient_for(struct sway_container *child, | 310 | bool 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 | */ | ||
316 | struct 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 | */ | ||
322 | bool container_find_and_unmark(char *mark); | ||
323 | |||
324 | /** | ||
325 | * Remove all marks from the container. | ||
326 | */ | ||
327 | void container_clear_marks(struct sway_container *container); | ||
328 | |||
329 | bool container_has_mark(struct sway_container *container, char *mark); | ||
330 | |||
331 | void container_add_mark(struct sway_container *container, char *mark); | ||
332 | |||
333 | void 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); | |||
353 | void view_execute_criteria(struct sway_view *view); | 347 | void view_execute_criteria(struct sway_view *view); |
354 | 348 | ||
355 | /** | 349 | /** |
356 | * Find any view that has the given mark and return it. | ||
357 | */ | ||
358 | struct 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 | */ | ||
364 | bool view_find_and_unmark(char *mark); | ||
365 | |||
366 | /** | ||
367 | * Remove all marks from the view. | ||
368 | */ | ||
369 | void view_clear_marks(struct sway_view *view); | ||
370 | |||
371 | bool view_has_mark(struct sway_view *view, char *mark); | ||
372 | |||
373 | void view_add_mark(struct sway_view *view, char *mark); | ||
374 | |||
375 | void 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 | ||
7 | static void rebuild_textures_iterator(struct sway_container *con, void *data) { | 7 | static 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 | ||
12 | static void rebuild_textures_iterator(struct sway_container *con, void *data) { | 12 | static 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 | ||
13 | static void rebuild_marks_iterator(struct sway_container *con, void *data) { | 13 | static 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 | ||
19 | struct cmd_results *cmd_show_marks(int argc, char **argv) { | 17 | struct 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 | ||
161 | static bool test_mark(struct sway_container *container, void *mark) { | 161 | static 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 | ||
11 | static void remove_all_marks_iterator(struct sway_container *con, void *data) { | 11 | static 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 | ||
23 | struct cmd_results *cmd_unmark(int argc, char **argv) { | 21 | struct 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 | ||
533 | static void update_textures(struct sway_container *con, void *data) { | 533 | static 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 | ||
540 | static void handle_scale(struct wl_listener *listener, void *data) { | 538 | static 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 | ||
564 | static void ipc_get_marks_callback(struct sway_container *con, void *data) { | 564 | static 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 | |||
1228 | static bool find_by_mark_iterator(struct sway_container *con, void *data) { | ||
1229 | char *mark = data; | ||
1230 | return container_has_mark(con, mark); | ||
1231 | } | ||
1232 | |||
1233 | struct sway_container *container_find_mark(char *mark) { | ||
1234 | return root_find_container(find_by_mark_iterator, mark); | ||
1235 | } | ||
1236 | |||
1237 | bool 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 | |||
1257 | void 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 | |||
1263 | bool 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 | |||
1273 | void container_add_mark(struct sway_container *con, char *mark) { | ||
1274 | list_add(con->marks, strdup(mark)); | ||
1275 | ipc_event_window(con, "mark"); | ||
1276 | } | ||
1277 | |||
1278 | static 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 | |||
1352 | void 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 | ||
940 | static 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 | |||
946 | struct 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 | |||
955 | bool 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 | |||
976 | void 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 | |||
982 | bool 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 | |||
992 | void 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 | |||
997 | static 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 | |||
1072 | void 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 | |||
1087 | bool view_is_visible(struct sway_view *view) { | 932 | bool 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; |