diff options
-rw-r--r-- | include/sway/tree/container.h | 37 | ||||
-rw-r--r-- | sway/commands/client.c | 7 | ||||
-rw-r--r-- | sway/commands/mark.c | 2 | ||||
-rw-r--r-- | sway/commands/reload.c | 7 | ||||
-rw-r--r-- | sway/commands/show_marks.c | 6 | ||||
-rw-r--r-- | sway/commands/title_align.c | 6 | ||||
-rw-r--r-- | sway/commands/unmark.c | 11 | ||||
-rw-r--r-- | sway/tree/container.c | 545 | ||||
-rw-r--r-- | sway/tree/view.c | 10 |
9 files changed, 378 insertions, 253 deletions
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 6f72439c..4920e064 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h | |||
@@ -76,6 +76,9 @@ struct sway_container { | |||
76 | 76 | ||
77 | struct wlr_scene_tree *border; | 77 | struct wlr_scene_tree *border; |
78 | struct wlr_scene_tree *background; | 78 | struct wlr_scene_tree *background; |
79 | |||
80 | struct sway_text_node *title_text; | ||
81 | struct sway_text_node *marks_text; | ||
79 | } title_bar; | 82 | } title_bar; |
80 | 83 | ||
81 | struct { | 84 | struct { |
@@ -94,6 +97,7 @@ struct sway_container { | |||
94 | 97 | ||
95 | char *title; // The view's title (unformatted) | 98 | char *title; // The view's title (unformatted) |
96 | char *formatted_title; // The title displayed in the title bar | 99 | char *formatted_title; // The title displayed in the title bar |
100 | int title_width; | ||
97 | 101 | ||
98 | enum sway_container_layout prev_split_layout; | 102 | enum sway_container_layout prev_split_layout; |
99 | 103 | ||
@@ -141,18 +145,7 @@ struct sway_container { | |||
141 | 145 | ||
142 | float alpha; | 146 | float alpha; |
143 | 147 | ||
144 | struct wlr_texture *title_focused; | ||
145 | struct wlr_texture *title_focused_inactive; | ||
146 | struct wlr_texture *title_focused_tab_title; | ||
147 | struct wlr_texture *title_unfocused; | ||
148 | struct wlr_texture *title_urgent; | ||
149 | |||
150 | list_t *marks; // char * | 148 | list_t *marks; // char * |
151 | struct wlr_texture *marks_focused; | ||
152 | struct wlr_texture *marks_focused_inactive; | ||
153 | struct wlr_texture *marks_focused_tab_title; | ||
154 | struct wlr_texture *marks_unfocused; | ||
155 | struct wlr_texture *marks_urgent; | ||
156 | 149 | ||
157 | struct { | 150 | struct { |
158 | struct wl_signal destroy; | 151 | struct wl_signal destroy; |
@@ -194,7 +187,9 @@ void container_reap_empty(struct sway_container *con); | |||
194 | 187 | ||
195 | struct sway_container *container_flatten(struct sway_container *container); | 188 | struct sway_container *container_flatten(struct sway_container *container); |
196 | 189 | ||
197 | void container_update_title_textures(struct sway_container *container); | 190 | void container_update_title_bar(struct sway_container *container); |
191 | |||
192 | void container_update_marks(struct sway_container *container); | ||
198 | 193 | ||
199 | size_t container_build_representation(enum sway_container_layout layout, | 194 | size_t container_build_representation(enum sway_container_layout layout, |
200 | list_t *children, char *buffer); | 195 | list_t *children, char *buffer); |
@@ -231,11 +226,6 @@ void container_set_geometry_from_content(struct sway_container *con); | |||
231 | bool container_is_floating(struct sway_container *container); | 226 | bool container_is_floating(struct sway_container *container); |
232 | 227 | ||
233 | /** | 228 | /** |
234 | * Same as above, but for current container state. | ||
235 | */ | ||
236 | bool container_is_current_floating(struct sway_container *container); | ||
237 | |||
238 | /** | ||
239 | * Get a container's box in layout coordinates. | 229 | * Get a container's box in layout coordinates. |
240 | */ | 230 | */ |
241 | void container_get_box(struct sway_container *container, struct wlr_box *box); | 231 | void container_get_box(struct sway_container *container, struct wlr_box *box); |
@@ -308,15 +298,10 @@ void container_discover_outputs(struct sway_container *con); | |||
308 | 298 | ||
309 | enum sway_container_layout container_parent_layout(struct sway_container *con); | 299 | enum sway_container_layout container_parent_layout(struct sway_container *con); |
310 | 300 | ||
311 | enum sway_container_layout container_current_parent_layout( | ||
312 | struct sway_container *con); | ||
313 | |||
314 | list_t *container_get_siblings(struct sway_container *container); | 301 | list_t *container_get_siblings(struct sway_container *container); |
315 | 302 | ||
316 | int container_sibling_index(struct sway_container *child); | 303 | int container_sibling_index(struct sway_container *child); |
317 | 304 | ||
318 | list_t *container_get_current_siblings(struct sway_container *container); | ||
319 | |||
320 | void container_handle_fullscreen_reparent(struct sway_container *con); | 305 | void container_handle_fullscreen_reparent(struct sway_container *con); |
321 | 306 | ||
322 | void container_add_child(struct sway_container *parent, | 307 | void container_add_child(struct sway_container *parent, |
@@ -364,8 +349,6 @@ bool container_has_mark(struct sway_container *container, char *mark); | |||
364 | 349 | ||
365 | void container_add_mark(struct sway_container *container, char *mark); | 350 | void container_add_mark(struct sway_container *container, char *mark); |
366 | 351 | ||
367 | void container_update_marks_textures(struct sway_container *container); | ||
368 | |||
369 | void container_raise_floating(struct sway_container *con); | 352 | void container_raise_floating(struct sway_container *con); |
370 | 353 | ||
371 | bool container_is_scratchpad_hidden(struct sway_container *con); | 354 | bool container_is_scratchpad_hidden(struct sway_container *con); |
@@ -389,4 +372,10 @@ bool container_is_sticky_or_child(struct sway_container *con); | |||
389 | */ | 372 | */ |
390 | int container_squash(struct sway_container *con); | 373 | int container_squash(struct sway_container *con); |
391 | 374 | ||
375 | void container_arrange_title_bar(struct sway_container *con); | ||
376 | |||
377 | void container_update(struct sway_container *con); | ||
378 | |||
379 | void container_update_itself_and_parents(struct sway_container *con); | ||
380 | |||
392 | #endif | 381 | #endif |
diff --git a/sway/commands/client.c b/sway/commands/client.c index 77263145..7a9cff2c 100644 --- a/sway/commands/client.c +++ b/sway/commands/client.c | |||
@@ -5,9 +5,8 @@ | |||
5 | #include "sway/tree/container.h" | 5 | #include "sway/tree/container.h" |
6 | #include "util.h" | 6 | #include "util.h" |
7 | 7 | ||
8 | static void rebuild_textures_iterator(struct sway_container *con, void *data) { | 8 | static void container_update_iterator(struct sway_container *con, void *data) { |
9 | container_update_marks_textures(con); | 9 | container_update(con); |
10 | container_update_title_textures(con); | ||
11 | } | 10 | } |
12 | 11 | ||
13 | static struct cmd_results *handle_command(int argc, char **argv, char *cmd_name, | 12 | static struct cmd_results *handle_command(int argc, char **argv, char *cmd_name, |
@@ -51,7 +50,7 @@ static struct cmd_results *handle_command(int argc, char **argv, char *cmd_name, | |||
51 | memcpy(class, &colors, sizeof(struct border_colors)); | 50 | memcpy(class, &colors, sizeof(struct border_colors)); |
52 | 51 | ||
53 | if (config->active) { | 52 | if (config->active) { |
54 | root_for_each_container(rebuild_textures_iterator, NULL); | 53 | root_for_each_container(container_update_iterator, NULL); |
55 | 54 | ||
56 | for (int i = 0; i < root->outputs->length; ++i) { | 55 | for (int i = 0; i < root->outputs->length; ++i) { |
57 | struct sway_output *output = root->outputs->items[i]; | 56 | struct sway_output *output = root->outputs->items[i]; |
diff --git a/sway/commands/mark.c b/sway/commands/mark.c index aa5f185c..30cf458c 100644 --- a/sway/commands/mark.c +++ b/sway/commands/mark.c | |||
@@ -59,7 +59,7 @@ struct cmd_results *cmd_mark(int argc, char **argv) { | |||
59 | } | 59 | } |
60 | 60 | ||
61 | free(mark); | 61 | free(mark); |
62 | container_update_marks_textures(container); | 62 | container_update_marks(container); |
63 | if (container->view) { | 63 | if (container->view) { |
64 | view_execute_criteria(container->view); | 64 | view_execute_criteria(container->view); |
65 | } | 65 | } |
diff --git a/sway/commands/reload.c b/sway/commands/reload.c index 76f14bba..82967ca7 100644 --- a/sway/commands/reload.c +++ b/sway/commands/reload.c | |||
@@ -9,9 +9,8 @@ | |||
9 | #include "list.h" | 9 | #include "list.h" |
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 title_bar_update_iterator(struct sway_container *con, void *data) { |
13 | container_update_marks_textures(con); | 13 | container_update_title_bar(con); |
14 | container_update_title_textures(con); | ||
15 | } | 14 | } |
16 | 15 | ||
17 | static void do_reload(void *data) { | 16 | static void do_reload(void *data) { |
@@ -48,7 +47,7 @@ static void do_reload(void *data) { | |||
48 | } | 47 | } |
49 | list_free_items_and_destroy(bar_ids); | 48 | list_free_items_and_destroy(bar_ids); |
50 | 49 | ||
51 | root_for_each_container(rebuild_textures_iterator, NULL); | 50 | root_for_each_container(title_bar_update_iterator, NULL); |
52 | 51 | ||
53 | arrange_root(); | 52 | arrange_root(); |
54 | } | 53 | } |
diff --git a/sway/commands/show_marks.c b/sway/commands/show_marks.c index 0d373b80..f738144f 100644 --- a/sway/commands/show_marks.c +++ b/sway/commands/show_marks.c | |||
@@ -10,8 +10,8 @@ | |||
10 | #include "stringop.h" | 10 | #include "stringop.h" |
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 title_bar_update_iterator(struct sway_container *con, void *data) { |
14 | container_update_marks_textures(con); | 14 | container_update_marks(con); |
15 | } | 15 | } |
16 | 16 | ||
17 | struct cmd_results *cmd_show_marks(int argc, char **argv) { | 17 | struct cmd_results *cmd_show_marks(int argc, char **argv) { |
@@ -23,7 +23,7 @@ struct cmd_results *cmd_show_marks(int argc, char **argv) { | |||
23 | config->show_marks = parse_boolean(argv[0], config->show_marks); | 23 | config->show_marks = parse_boolean(argv[0], config->show_marks); |
24 | 24 | ||
25 | if (config->show_marks) { | 25 | if (config->show_marks) { |
26 | root_for_each_container(rebuild_marks_iterator, NULL); | 26 | root_for_each_container(title_bar_update_iterator, NULL); |
27 | } | 27 | } |
28 | 28 | ||
29 | for (int i = 0; i < root->outputs->length; ++i) { | 29 | for (int i = 0; i < root->outputs->length; ++i) { |
diff --git a/sway/commands/title_align.c b/sway/commands/title_align.c index c30355de..7f5dd3ae 100644 --- a/sway/commands/title_align.c +++ b/sway/commands/title_align.c | |||
@@ -4,6 +4,10 @@ | |||
4 | #include "sway/tree/container.h" | 4 | #include "sway/tree/container.h" |
5 | #include "sway/tree/root.h" | 5 | #include "sway/tree/root.h" |
6 | 6 | ||
7 | static void arrange_title_bar_iterator(struct sway_container *con, void *data) { | ||
8 | container_arrange_title_bar(con); | ||
9 | } | ||
10 | |||
7 | struct cmd_results *cmd_title_align(int argc, char **argv) { | 11 | struct cmd_results *cmd_title_align(int argc, char **argv) { |
8 | struct cmd_results *error = NULL; | 12 | struct cmd_results *error = NULL; |
9 | if ((error = checkarg(argc, "title_align", EXPECTED_AT_LEAST, 1))) { | 13 | if ((error = checkarg(argc, "title_align", EXPECTED_AT_LEAST, 1))) { |
@@ -21,6 +25,8 @@ struct cmd_results *cmd_title_align(int argc, char **argv) { | |||
21 | "Expected 'title_align left|center|right'"); | 25 | "Expected 'title_align left|center|right'"); |
22 | } | 26 | } |
23 | 27 | ||
28 | root_for_each_container(arrange_title_bar_iterator, NULL); | ||
29 | |||
24 | for (int i = 0; i < root->outputs->length; ++i) { | 30 | for (int i = 0; i < root->outputs->length; ++i) { |
25 | struct sway_output *output = root->outputs->items[i]; | 31 | struct sway_output *output = root->outputs->items[i]; |
26 | output_damage_whole(output); | 32 | output_damage_whole(output); |
diff --git a/sway/commands/unmark.c b/sway/commands/unmark.c index 19274dfb..c3a6ac4b 100644 --- a/sway/commands/unmark.c +++ b/sway/commands/unmark.c | |||
@@ -8,9 +8,13 @@ | |||
8 | #include "log.h" | 8 | #include "log.h" |
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_mark(struct sway_container *con) { |
12 | container_clear_marks(con); | 12 | container_clear_marks(con); |
13 | container_update_marks_textures(con); | 13 | container_update_marks(con); |
14 | } | ||
15 | |||
16 | static void remove_all_marks_iterator(struct sway_container *con, void *data) { | ||
17 | remove_mark(con); | ||
14 | } | 18 | } |
15 | 19 | ||
16 | // unmark Remove all marks from all views | 20 | // unmark Remove all marks from all views |
@@ -38,8 +42,7 @@ struct cmd_results *cmd_unmark(int argc, char **argv) { | |||
38 | } | 42 | } |
39 | } else if (con && !mark) { | 43 | } else if (con && !mark) { |
40 | // Clear all marks from the given container | 44 | // Clear all marks from the given container |
41 | container_clear_marks(con); | 45 | remove_mark(con); |
42 | container_update_marks_textures(con); | ||
43 | } else if (!con && mark) { | 46 | } else if (!con && mark) { |
44 | // Remove mark from whichever container has it | 47 | // Remove mark from whichever container has it |
45 | container_find_and_unmark(mark); | 48 | container_find_and_unmark(mark); |
diff --git a/sway/tree/container.c b/sway/tree/container.c index 8fca6a12..4aae4d32 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -8,15 +8,13 @@ | |||
8 | #include <wlr/types/wlr_output_layout.h> | 8 | #include <wlr/types/wlr_output_layout.h> |
9 | #include <wlr/types/wlr_subcompositor.h> | 9 | #include <wlr/types/wlr_subcompositor.h> |
10 | #include "linux-dmabuf-unstable-v1-protocol.h" | 10 | #include "linux-dmabuf-unstable-v1-protocol.h" |
11 | #include "cairo_util.h" | ||
12 | #include "pango.h" | ||
13 | #include "sway/config.h" | 11 | #include "sway/config.h" |
14 | #include "sway/desktop.h" | ||
15 | #include "sway/desktop/transaction.h" | 12 | #include "sway/desktop/transaction.h" |
16 | #include "sway/input/input-manager.h" | 13 | #include "sway/input/input-manager.h" |
17 | #include "sway/input/seat.h" | 14 | #include "sway/input/seat.h" |
18 | #include "sway/ipc-server.h" | 15 | #include "sway/ipc-server.h" |
19 | #include "sway/scene_descriptor.h" | 16 | #include "sway/scene_descriptor.h" |
17 | #include "sway/sway_text_node.h" | ||
20 | #include "sway/output.h" | 18 | #include "sway/output.h" |
21 | #include "sway/server.h" | 19 | #include "sway/server.h" |
22 | #include "sway/surface.h" | 20 | #include "sway/surface.h" |
@@ -120,9 +118,328 @@ struct sway_container *container_create(struct sway_view *view) { | |||
120 | wl_signal_init(&c->events.destroy); | 118 | wl_signal_init(&c->events.destroy); |
121 | wl_signal_emit_mutable(&root->events.new_node, &c->node); | 119 | wl_signal_emit_mutable(&root->events.new_node, &c->node); |
122 | 120 | ||
121 | container_update(c); | ||
122 | |||
123 | return c; | 123 | return c; |
124 | } | 124 | } |
125 | 125 | ||
126 | static bool container_is_focused(struct sway_container *con, void *data) { | ||
127 | return con->current.focused; | ||
128 | } | ||
129 | |||
130 | static bool container_has_focused_child(struct sway_container *con) { | ||
131 | return container_find_child(con, container_is_focused, NULL); | ||
132 | } | ||
133 | |||
134 | static bool container_is_current_parent_focused(struct sway_container *con) { | ||
135 | if (con->current.parent) { | ||
136 | struct sway_container *parent = con->current.parent; | ||
137 | return parent->current.focused || container_is_current_parent_focused(parent); | ||
138 | } else if (con->current.workspace) { | ||
139 | struct sway_workspace *ws = con->current.workspace; | ||
140 | return ws->current.focused; | ||
141 | } | ||
142 | |||
143 | return false; | ||
144 | } | ||
145 | |||
146 | static struct border_colors *container_get_current_colors( | ||
147 | struct sway_container *con) { | ||
148 | struct border_colors *colors; | ||
149 | |||
150 | bool urgent = con->view ? | ||
151 | view_is_urgent(con->view) : container_has_urgent_child(con); | ||
152 | struct sway_container *active_child; | ||
153 | |||
154 | if (con->current.parent) { | ||
155 | active_child = con->current.parent->current.focused_inactive_child; | ||
156 | } else if (con->current.workspace) { | ||
157 | active_child = con->current.workspace->current.focused_inactive_child; | ||
158 | } else { | ||
159 | active_child = NULL; | ||
160 | } | ||
161 | |||
162 | if (urgent) { | ||
163 | colors = &config->border_colors.urgent; | ||
164 | } else if (con->current.focused || container_is_current_parent_focused(con)) { | ||
165 | colors = &config->border_colors.focused; | ||
166 | } else if (config->has_focused_tab_title && container_has_focused_child(con)) { | ||
167 | colors = &config->border_colors.focused_tab_title; | ||
168 | } else if (con == active_child) { | ||
169 | colors = &config->border_colors.focused_inactive; | ||
170 | } else { | ||
171 | colors = &config->border_colors.unfocused; | ||
172 | } | ||
173 | |||
174 | return colors; | ||
175 | } | ||
176 | |||
177 | static bool container_is_current_floating(struct sway_container *container) { | ||
178 | if (!container->current.parent && container->current.workspace && | ||
179 | list_find(container->current.workspace->floating, container) != -1) { | ||
180 | return true; | ||
181 | } | ||
182 | if (container->scratchpad) { | ||
183 | return true; | ||
184 | } | ||
185 | return false; | ||
186 | } | ||
187 | |||
188 | // scene rect wants premultiplied colors | ||
189 | static void scene_rect_set_color(struct wlr_scene_rect *rect, | ||
190 | const float color[4], float opacity) { | ||
191 | const float premultiplied[] = { | ||
192 | color[0] * color[3] * opacity, | ||
193 | color[1] * color[3] * opacity, | ||
194 | color[2] * color[3] * opacity, | ||
195 | color[3] * opacity, | ||
196 | }; | ||
197 | |||
198 | wlr_scene_rect_set_color(rect, premultiplied); | ||
199 | } | ||
200 | |||
201 | void container_update(struct sway_container *con) { | ||
202 | struct border_colors *colors = container_get_current_colors(con); | ||
203 | list_t *siblings = NULL; | ||
204 | enum sway_container_layout layout = L_NONE; | ||
205 | float alpha = con->alpha; | ||
206 | |||
207 | if (con->current.parent) { | ||
208 | siblings = con->current.parent->current.children; | ||
209 | layout = con->current.parent->current.layout; | ||
210 | } else if (con->current.workspace) { | ||
211 | siblings = con->current.workspace->current.tiling; | ||
212 | layout = con->current.workspace->current.layout; | ||
213 | } | ||
214 | |||
215 | float bottom[4], right[4]; | ||
216 | memcpy(bottom, colors->child_border, sizeof(bottom)); | ||
217 | memcpy(right, colors->child_border, sizeof(right)); | ||
218 | |||
219 | if (!container_is_current_floating(con) && siblings && siblings->length == 1) { | ||
220 | if (layout == L_HORIZ) { | ||
221 | memcpy(right, colors->indicator, sizeof(right)); | ||
222 | } else if (layout == L_VERT) { | ||
223 | memcpy(bottom, colors->indicator, sizeof(bottom)); | ||
224 | } | ||
225 | } | ||
226 | |||
227 | struct wlr_scene_node *node; | ||
228 | wl_list_for_each(node, &con->title_bar.border->children, link) { | ||
229 | struct wlr_scene_rect *rect = wlr_scene_rect_from_node(node); | ||
230 | scene_rect_set_color(rect, colors->border, alpha); | ||
231 | } | ||
232 | |||
233 | wl_list_for_each(node, &con->title_bar.background->children, link) { | ||
234 | struct wlr_scene_rect *rect = wlr_scene_rect_from_node(node); | ||
235 | scene_rect_set_color(rect, colors->background, alpha); | ||
236 | } | ||
237 | |||
238 | if (con->view) { | ||
239 | scene_rect_set_color(con->border.top, colors->child_border, alpha); | ||
240 | scene_rect_set_color(con->border.bottom, bottom, alpha); | ||
241 | scene_rect_set_color(con->border.left, colors->child_border, alpha); | ||
242 | scene_rect_set_color(con->border.right, right, alpha); | ||
243 | } | ||
244 | |||
245 | if (con->title_bar.title_text) { | ||
246 | sway_text_node_set_color(con->title_bar.title_text, colors->text); | ||
247 | sway_text_node_set_background(con->title_bar.title_text, colors->background); | ||
248 | } | ||
249 | |||
250 | if (con->title_bar.marks_text) { | ||
251 | sway_text_node_set_color(con->title_bar.marks_text, colors->text); | ||
252 | sway_text_node_set_background(con->title_bar.marks_text, colors->background); | ||
253 | } | ||
254 | } | ||
255 | |||
256 | void container_update_itself_and_parents(struct sway_container *con) { | ||
257 | container_update(con); | ||
258 | |||
259 | if (con->current.parent) { | ||
260 | container_update_itself_and_parents(con->current.parent); | ||
261 | } | ||
262 | } | ||
263 | |||
264 | static void update_rect_list(struct wlr_scene_tree *tree, pixman_region32_t *region) { | ||
265 | int len; | ||
266 | const pixman_box32_t *rects = pixman_region32_rectangles(region, &len); | ||
267 | |||
268 | wlr_scene_node_set_enabled(&tree->node, len > 0); | ||
269 | if (len == 0) { | ||
270 | return; | ||
271 | } | ||
272 | |||
273 | int i = 0; | ||
274 | struct wlr_scene_node *node; | ||
275 | wl_list_for_each(node, &tree->children, link) { | ||
276 | struct wlr_scene_rect *rect = wlr_scene_rect_from_node(node); | ||
277 | wlr_scene_node_set_enabled(&rect->node, i < len); | ||
278 | |||
279 | if (i < len) { | ||
280 | const pixman_box32_t *box = &rects[i++]; | ||
281 | wlr_scene_node_set_position(&rect->node, box->x1, box->y1); | ||
282 | wlr_scene_rect_set_size(rect, box->x2 - box->x1, box->y2 - box->y1); | ||
283 | } | ||
284 | } | ||
285 | } | ||
286 | |||
287 | void container_arrange_title_bar(struct sway_container *con) { | ||
288 | enum alignment title_align = config->title_align; | ||
289 | int marks_buffer_width = 0; | ||
290 | int width = con->title_width; | ||
291 | int height = container_titlebar_height(); | ||
292 | |||
293 | pixman_region32_t text_area; | ||
294 | pixman_region32_init(&text_area); | ||
295 | |||
296 | if (con->title_bar.marks_text) { | ||
297 | struct sway_text_node *node = con->title_bar.marks_text; | ||
298 | marks_buffer_width = node->width; | ||
299 | |||
300 | int h_padding; | ||
301 | if (title_align == ALIGN_RIGHT) { | ||
302 | h_padding = config->titlebar_h_padding; | ||
303 | } else { | ||
304 | h_padding = width - config->titlebar_h_padding - marks_buffer_width; | ||
305 | } | ||
306 | |||
307 | h_padding = MAX(h_padding, 0); | ||
308 | |||
309 | int alloc_width = MIN((int)node->width, | ||
310 | width - h_padding - config->titlebar_h_padding); | ||
311 | sway_text_node_set_max_width(node, alloc_width); | ||
312 | wlr_scene_node_set_position(node->node, | ||
313 | h_padding, (height - node->height) >> 1); | ||
314 | |||
315 | pixman_region32_union_rect(&text_area, &text_area, | ||
316 | node->node->x, node->node->y, alloc_width, node->height); | ||
317 | } | ||
318 | |||
319 | if (con->title_bar.title_text) { | ||
320 | struct sway_text_node *node = con->title_bar.title_text; | ||
321 | |||
322 | int h_padding; | ||
323 | if (title_align == ALIGN_RIGHT) { | ||
324 | h_padding = width - config->titlebar_h_padding - node->width; | ||
325 | } else if (title_align == ALIGN_CENTER) { | ||
326 | h_padding = ((int)width - marks_buffer_width - node->width) >> 1; | ||
327 | } else { | ||
328 | h_padding = config->titlebar_h_padding; | ||
329 | } | ||
330 | |||
331 | h_padding = MAX(h_padding, 0); | ||
332 | |||
333 | int alloc_width = MIN((int) node->width, | ||
334 | width - h_padding - config->titlebar_h_padding); | ||
335 | sway_text_node_set_max_width(node, alloc_width); | ||
336 | wlr_scene_node_set_position(node->node, | ||
337 | h_padding, (height - node->height) >> 1); | ||
338 | |||
339 | pixman_region32_union_rect(&text_area, &text_area, | ||
340 | node->node->x, node->node->y, alloc_width, node->height); | ||
341 | } | ||
342 | |||
343 | // silence pixman errors | ||
344 | if (width <= 0 || height <= 0) { | ||
345 | pixman_region32_fini(&text_area); | ||
346 | return; | ||
347 | } | ||
348 | |||
349 | pixman_region32_t background, border; | ||
350 | |||
351 | int thickness = config->titlebar_border_thickness; | ||
352 | pixman_region32_init_rect(&background, | ||
353 | thickness, thickness, | ||
354 | width - thickness * 2, height - thickness * 2); | ||
355 | pixman_region32_init_rect(&border, 0, 0, width, height); | ||
356 | pixman_region32_subtract(&border, &border, &background); | ||
357 | |||
358 | pixman_region32_subtract(&background, &background, &text_area); | ||
359 | pixman_region32_fini(&text_area); | ||
360 | |||
361 | update_rect_list(con->title_bar.background, &background); | ||
362 | pixman_region32_fini(&background); | ||
363 | |||
364 | update_rect_list(con->title_bar.border, &border); | ||
365 | pixman_region32_fini(&border); | ||
366 | |||
367 | container_update(con); | ||
368 | } | ||
369 | |||
370 | void container_update_marks(struct sway_container *con) { | ||
371 | char *buffer = NULL; | ||
372 | |||
373 | if (config->show_marks && con->marks->length) { | ||
374 | size_t len = 0; | ||
375 | for (int i = 0; i < con->marks->length; ++i) { | ||
376 | char *mark = con->marks->items[i]; | ||
377 | if (mark[0] != '_') { | ||
378 | len += strlen(mark) + 2; | ||
379 | } | ||
380 | } | ||
381 | buffer = calloc(len + 1, 1); | ||
382 | char *part = malloc(len + 1); | ||
383 | |||
384 | if (!sway_assert(buffer && part, "Unable to allocate memory")) { | ||
385 | free(buffer); | ||
386 | return; | ||
387 | } | ||
388 | |||
389 | for (int i = 0; i < con->marks->length; ++i) { | ||
390 | char *mark = con->marks->items[i]; | ||
391 | if (mark[0] != '_') { | ||
392 | snprintf(part, len + 1, "[%s]", mark); | ||
393 | strcat(buffer, part); | ||
394 | } | ||
395 | } | ||
396 | free(part); | ||
397 | } | ||
398 | |||
399 | if (!buffer) { | ||
400 | if (con->title_bar.marks_text) { | ||
401 | wlr_scene_node_destroy(con->title_bar.marks_text->node); | ||
402 | con->title_bar.marks_text = NULL; | ||
403 | } | ||
404 | } else if (!con->title_bar.marks_text) { | ||
405 | struct border_colors *colors = container_get_current_colors(con); | ||
406 | |||
407 | con->title_bar.marks_text = sway_text_node_create(con->title_bar.tree, | ||
408 | buffer, colors->text, false); | ||
409 | } else { | ||
410 | sway_text_node_set_text(con->title_bar.marks_text, buffer); | ||
411 | } | ||
412 | |||
413 | container_arrange_title_bar(con); | ||
414 | free(buffer); | ||
415 | } | ||
416 | |||
417 | void container_update_title_bar(struct sway_container *con) { | ||
418 | if (!con->formatted_title) { | ||
419 | return; | ||
420 | } | ||
421 | |||
422 | struct border_colors *colors = container_get_current_colors(con); | ||
423 | |||
424 | if (con->title_bar.title_text) { | ||
425 | wlr_scene_node_destroy(con->title_bar.title_text->node); | ||
426 | con->title_bar.title_text = NULL; | ||
427 | } | ||
428 | |||
429 | con->title_bar.title_text = sway_text_node_create(con->title_bar.tree, | ||
430 | con->formatted_title, colors->text, config->pango_markup); | ||
431 | |||
432 | // we always have to remake these text buffers completely for text font | ||
433 | // changes etc... | ||
434 | if (con->title_bar.marks_text) { | ||
435 | wlr_scene_node_destroy(con->title_bar.marks_text->node); | ||
436 | con->title_bar.marks_text = NULL; | ||
437 | } | ||
438 | |||
439 | container_update_marks(con); | ||
440 | container_arrange_title_bar(con); | ||
441 | } | ||
442 | |||
126 | void container_destroy(struct sway_container *con) { | 443 | void container_destroy(struct sway_container *con) { |
127 | if (!sway_assert(con->node.destroying, | 444 | if (!sway_assert(con->node.destroying, |
128 | "Tried to free container which wasn't marked as destroying")) { | 445 | "Tried to free container which wasn't marked as destroying")) { |
@@ -134,21 +451,11 @@ void container_destroy(struct sway_container *con) { | |||
134 | } | 451 | } |
135 | free(con->title); | 452 | free(con->title); |
136 | free(con->formatted_title); | 453 | free(con->formatted_title); |
137 | wlr_texture_destroy(con->title_focused); | ||
138 | wlr_texture_destroy(con->title_focused_inactive); | ||
139 | wlr_texture_destroy(con->title_unfocused); | ||
140 | wlr_texture_destroy(con->title_urgent); | ||
141 | wlr_texture_destroy(con->title_focused_tab_title); | ||
142 | list_free(con->pending.children); | 454 | list_free(con->pending.children); |
143 | list_free(con->current.children); | 455 | list_free(con->current.children); |
144 | list_free(con->outputs); | 456 | list_free(con->outputs); |
145 | 457 | ||
146 | list_free_items_and_destroy(con->marks); | 458 | list_free_items_and_destroy(con->marks); |
147 | wlr_texture_destroy(con->marks_focused); | ||
148 | wlr_texture_destroy(con->marks_focused_inactive); | ||
149 | wlr_texture_destroy(con->marks_unfocused); | ||
150 | wlr_texture_destroy(con->marks_urgent); | ||
151 | wlr_texture_destroy(con->marks_focused_tab_title); | ||
152 | 459 | ||
153 | if (con->view && con->view->container == con) { | 460 | if (con->view && con->view->container == con) { |
154 | con->view->container = NULL; | 461 | con->view->container = NULL; |
@@ -308,108 +615,6 @@ struct sway_output *container_get_effective_output(struct sway_container *con) { | |||
308 | return con->outputs->items[con->outputs->length - 1]; | 615 | return con->outputs->items[con->outputs->length - 1]; |
309 | } | 616 | } |
310 | 617 | ||
311 | static void render_titlebar_text_texture(struct sway_output *output, | ||
312 | struct sway_container *con, struct wlr_texture **texture, | ||
313 | struct border_colors *class, bool pango_markup, char *text) { | ||
314 | double scale = output->wlr_output->scale; | ||
315 | int width = 0; | ||
316 | int height = config->font_height * scale; | ||
317 | int baseline; | ||
318 | |||
319 | // We must use a non-nil cairo_t for cairo_set_font_options to work. | ||
320 | // Therefore, we cannot use cairo_create(NULL). | ||
321 | cairo_surface_t *dummy_surface = cairo_image_surface_create( | ||
322 | CAIRO_FORMAT_ARGB32, 0, 0); | ||
323 | cairo_t *c = cairo_create(dummy_surface); | ||
324 | cairo_set_antialias(c, CAIRO_ANTIALIAS_BEST); | ||
325 | cairo_font_options_t *fo = cairo_font_options_create(); | ||
326 | if (output->wlr_output->subpixel == WL_OUTPUT_SUBPIXEL_NONE) { | ||
327 | cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_GRAY); | ||
328 | } else { | ||
329 | cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_SUBPIXEL); | ||
330 | cairo_font_options_set_subpixel_order(fo, | ||
331 | to_cairo_subpixel_order(output->wlr_output->subpixel)); | ||
332 | } | ||
333 | cairo_set_font_options(c, fo); | ||
334 | get_text_size(c, config->font_description, &width, NULL, &baseline, scale, | ||
335 | config->pango_markup, "%s", text); | ||
336 | cairo_surface_destroy(dummy_surface); | ||
337 | cairo_destroy(c); | ||
338 | |||
339 | if (width == 0 || height == 0) { | ||
340 | return; | ||
341 | } | ||
342 | |||
343 | if (height > config->font_height * scale) { | ||
344 | height = config->font_height * scale; | ||
345 | } | ||
346 | |||
347 | cairo_surface_t *surface = cairo_image_surface_create( | ||
348 | CAIRO_FORMAT_ARGB32, width, height); | ||
349 | cairo_status_t status = cairo_surface_status(surface); | ||
350 | if (status != CAIRO_STATUS_SUCCESS) { | ||
351 | sway_log(SWAY_ERROR, "cairo_image_surface_create failed: %s", | ||
352 | cairo_status_to_string(status)); | ||
353 | return; | ||
354 | } | ||
355 | |||
356 | cairo_t *cairo = cairo_create(surface); | ||
357 | cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); | ||
358 | cairo_set_font_options(cairo, fo); | ||
359 | cairo_font_options_destroy(fo); | ||
360 | cairo_set_source_rgba(cairo, class->background[0], class->background[1], | ||
361 | class->background[2], class->background[3]); | ||
362 | cairo_paint(cairo); | ||
363 | PangoContext *pango = pango_cairo_create_context(cairo); | ||
364 | cairo_set_source_rgba(cairo, class->text[0], class->text[1], | ||
365 | class->text[2], class->text[3]); | ||
366 | cairo_move_to(cairo, 0, config->font_baseline * scale - baseline); | ||
367 | |||
368 | render_text(cairo, config->font_description, scale, pango_markup, "%s", text); | ||
369 | |||
370 | cairo_surface_flush(surface); | ||
371 | unsigned char *data = cairo_image_surface_get_data(surface); | ||
372 | int stride = cairo_image_surface_get_stride(surface); | ||
373 | struct wlr_renderer *renderer = output->wlr_output->renderer; | ||
374 | *texture = wlr_texture_from_pixels( | ||
375 | renderer, DRM_FORMAT_ARGB8888, stride, width, height, data); | ||
376 | cairo_surface_destroy(surface); | ||
377 | g_object_unref(pango); | ||
378 | cairo_destroy(cairo); | ||
379 | } | ||
380 | |||
381 | static void update_title_texture(struct sway_container *con, | ||
382 | struct wlr_texture **texture, struct border_colors *class) { | ||
383 | struct sway_output *output = container_get_effective_output(con); | ||
384 | if (!output) { | ||
385 | return; | ||
386 | } | ||
387 | if (*texture) { | ||
388 | wlr_texture_destroy(*texture); | ||
389 | *texture = NULL; | ||
390 | } | ||
391 | if (!con->formatted_title) { | ||
392 | return; | ||
393 | } | ||
394 | |||
395 | render_titlebar_text_texture(output, con, texture, class, | ||
396 | config->pango_markup, con->formatted_title); | ||
397 | } | ||
398 | |||
399 | void container_update_title_textures(struct sway_container *container) { | ||
400 | update_title_texture(container, &container->title_focused, | ||
401 | &config->border_colors.focused); | ||
402 | update_title_texture(container, &container->title_focused_inactive, | ||
403 | &config->border_colors.focused_inactive); | ||
404 | update_title_texture(container, &container->title_unfocused, | ||
405 | &config->border_colors.unfocused); | ||
406 | update_title_texture(container, &container->title_urgent, | ||
407 | &config->border_colors.urgent); | ||
408 | update_title_texture(container, &container->title_focused_tab_title, | ||
409 | &config->border_colors.focused_tab_title); | ||
410 | container_damage_whole(container); | ||
411 | } | ||
412 | |||
413 | /** | 618 | /** |
414 | * Calculate and return the length of the tree representation. | 619 | * Calculate and return the length of the tree representation. |
415 | * An example tree representation is: V[Terminal, Firefox] | 620 | * An example tree representation is: V[Terminal, Firefox] |
@@ -475,7 +680,13 @@ void container_update_representation(struct sway_container *con) { | |||
475 | } | 680 | } |
476 | container_build_representation(con->pending.layout, con->pending.children, | 681 | container_build_representation(con->pending.layout, con->pending.children, |
477 | con->formatted_title); | 682 | con->formatted_title); |
478 | container_update_title_textures(con); | 683 | |
684 | if (con->title_bar.title_text) { | ||
685 | sway_text_node_set_text(con->title_bar.title_text, con->formatted_title); | ||
686 | container_arrange_title_bar(con); | ||
687 | } else { | ||
688 | container_update_title_bar(con); | ||
689 | } | ||
479 | } | 690 | } |
480 | if (con->pending.parent) { | 691 | if (con->pending.parent) { |
481 | container_update_representation(con->pending.parent); | 692 | container_update_representation(con->pending.parent); |
@@ -761,17 +972,6 @@ bool container_is_floating(struct sway_container *container) { | |||
761 | return false; | 972 | return false; |
762 | } | 973 | } |
763 | 974 | ||
764 | bool container_is_current_floating(struct sway_container *container) { | ||
765 | if (!container->current.parent && container->current.workspace && | ||
766 | list_find(container->current.workspace->floating, container) != -1) { | ||
767 | return true; | ||
768 | } | ||
769 | if (container->scratchpad) { | ||
770 | return true; | ||
771 | } | ||
772 | return false; | ||
773 | } | ||
774 | |||
775 | void container_get_box(struct sway_container *container, struct wlr_box *box) { | 975 | void container_get_box(struct sway_container *container, struct wlr_box *box) { |
776 | box->x = container->pending.x; | 976 | box->x = container->pending.x; |
777 | box->y = container->pending.y; | 977 | box->y = container->pending.y; |
@@ -1092,7 +1292,6 @@ void container_discover_outputs(struct sway_container *con) { | |||
1092 | .width = con->current.width, | 1292 | .width = con->current.width, |
1093 | .height = con->current.height, | 1293 | .height = con->current.height, |
1094 | }; | 1294 | }; |
1095 | struct sway_output *old_output = container_get_effective_output(con); | ||
1096 | 1295 | ||
1097 | for (int i = 0; i < root->outputs->length; ++i) { | 1296 | for (int i = 0; i < root->outputs->length; ++i) { |
1098 | struct sway_output *output = root->outputs->items[i]; | 1297 | struct sway_output *output = root->outputs->items[i]; |
@@ -1129,14 +1328,6 @@ void container_discover_outputs(struct sway_container *con) { | |||
1129 | list_del(con->outputs, index); | 1328 | list_del(con->outputs, index); |
1130 | } | 1329 | } |
1131 | } | 1330 | } |
1132 | struct sway_output *new_output = container_get_effective_output(con); | ||
1133 | double old_scale = old_output && old_output->enabled ? | ||
1134 | old_output->wlr_output->scale : -1; | ||
1135 | double new_scale = new_output ? new_output->wlr_output->scale : -1; | ||
1136 | if (old_scale != new_scale) { | ||
1137 | container_update_title_textures(con); | ||
1138 | container_update_marks_textures(con); | ||
1139 | } | ||
1140 | } | 1331 | } |
1141 | 1332 | ||
1142 | enum sway_container_layout container_parent_layout(struct sway_container *con) { | 1333 | enum sway_container_layout container_parent_layout(struct sway_container *con) { |
@@ -1149,14 +1340,6 @@ enum sway_container_layout container_parent_layout(struct sway_container *con) { | |||
1149 | return L_NONE; | 1340 | return L_NONE; |
1150 | } | 1341 | } |
1151 | 1342 | ||
1152 | enum sway_container_layout container_current_parent_layout( | ||
1153 | struct sway_container *con) { | ||
1154 | if (con->current.parent) { | ||
1155 | return con->current.parent->current.layout; | ||
1156 | } | ||
1157 | return con->current.workspace->current.layout; | ||
1158 | } | ||
1159 | |||
1160 | list_t *container_get_siblings(struct sway_container *container) { | 1343 | list_t *container_get_siblings(struct sway_container *container) { |
1161 | if (container->pending.parent) { | 1344 | if (container->pending.parent) { |
1162 | return container->pending.parent->pending.children; | 1345 | return container->pending.parent->pending.children; |
@@ -1174,13 +1357,6 @@ int container_sibling_index(struct sway_container *child) { | |||
1174 | return list_find(container_get_siblings(child), child); | 1357 | return list_find(container_get_siblings(child), child); |
1175 | } | 1358 | } |
1176 | 1359 | ||
1177 | list_t *container_get_current_siblings(struct sway_container *container) { | ||
1178 | if (container->current.parent) { | ||
1179 | return container->current.parent->current.children; | ||
1180 | } | ||
1181 | return container->current.workspace->current.tiling; | ||
1182 | } | ||
1183 | |||
1184 | void container_handle_fullscreen_reparent(struct sway_container *con) { | 1360 | void container_handle_fullscreen_reparent(struct sway_container *con) { |
1185 | if (con->pending.fullscreen_mode != FULLSCREEN_WORKSPACE || !con->pending.workspace || | 1361 | if (con->pending.fullscreen_mode != FULLSCREEN_WORKSPACE || !con->pending.workspace || |
1186 | con->pending.workspace->fullscreen == con) { | 1362 | con->pending.workspace->fullscreen == con) { |
@@ -1395,7 +1571,7 @@ bool container_find_and_unmark(char *mark) { | |||
1395 | if (strcmp(con_mark, mark) == 0) { | 1571 | if (strcmp(con_mark, mark) == 0) { |
1396 | free(con_mark); | 1572 | free(con_mark); |
1397 | list_del(con->marks, i); | 1573 | list_del(con->marks, i); |
1398 | container_update_marks_textures(con); | 1574 | container_update_marks(con); |
1399 | ipc_event_window(con, "mark"); | 1575 | ipc_event_window(con, "mark"); |
1400 | return true; | 1576 | return true; |
1401 | } | 1577 | } |
@@ -1426,70 +1602,15 @@ void container_add_mark(struct sway_container *con, char *mark) { | |||
1426 | ipc_event_window(con, "mark"); | 1602 | ipc_event_window(con, "mark"); |
1427 | } | 1603 | } |
1428 | 1604 | ||
1429 | static void update_marks_texture(struct sway_container *con, | ||
1430 | struct wlr_texture **texture, struct border_colors *class) { | ||
1431 | struct sway_output *output = container_get_effective_output(con); | ||
1432 | if (!output) { | ||
1433 | return; | ||
1434 | } | ||
1435 | if (*texture) { | ||
1436 | wlr_texture_destroy(*texture); | ||
1437 | *texture = NULL; | ||
1438 | } | ||
1439 | if (!con->marks->length) { | ||
1440 | return; | ||
1441 | } | ||
1442 | |||
1443 | size_t len = 0; | ||
1444 | for (int i = 0; i < con->marks->length; ++i) { | ||
1445 | char *mark = con->marks->items[i]; | ||
1446 | if (mark[0] != '_') { | ||
1447 | len += strlen(mark) + 2; | ||
1448 | } | ||
1449 | } | ||
1450 | char *buffer = calloc(len + 1, 1); | ||
1451 | char *part = malloc(len + 1); | ||
1452 | |||
1453 | if (!sway_assert(buffer && part, "Unable to allocate memory")) { | ||
1454 | free(buffer); | ||
1455 | return; | ||
1456 | } | ||
1457 | |||
1458 | for (int i = 0; i < con->marks->length; ++i) { | ||
1459 | char *mark = con->marks->items[i]; | ||
1460 | if (mark[0] != '_') { | ||
1461 | snprintf(part, len + 1, "[%s]", mark); | ||
1462 | strcat(buffer, part); | ||
1463 | } | ||
1464 | } | ||
1465 | free(part); | ||
1466 | |||
1467 | render_titlebar_text_texture(output, con, texture, class, false, buffer); | ||
1468 | |||
1469 | free(buffer); | ||
1470 | } | ||
1471 | |||
1472 | void container_update_marks_textures(struct sway_container *con) { | ||
1473 | if (!config->show_marks) { | ||
1474 | return; | ||
1475 | } | ||
1476 | update_marks_texture(con, &con->marks_focused, | ||
1477 | &config->border_colors.focused); | ||
1478 | update_marks_texture(con, &con->marks_focused_inactive, | ||
1479 | &config->border_colors.focused_inactive); | ||
1480 | update_marks_texture(con, &con->marks_unfocused, | ||
1481 | &config->border_colors.unfocused); | ||
1482 | update_marks_texture(con, &con->marks_urgent, | ||
1483 | &config->border_colors.urgent); | ||
1484 | update_marks_texture(con, &con->marks_focused_tab_title, | ||
1485 | &config->border_colors.focused_tab_title); | ||
1486 | container_damage_whole(con); | ||
1487 | } | ||
1488 | |||
1489 | void container_raise_floating(struct sway_container *con) { | 1605 | void container_raise_floating(struct sway_container *con) { |
1490 | // Bring container to front by putting it at the end of the floating list. | 1606 | // Bring container to front by putting it at the end of the floating list. |
1491 | struct sway_container *floater = container_toplevel_ancestor(con); | 1607 | struct sway_container *floater = container_toplevel_ancestor(con); |
1492 | if (container_is_floating(floater) && floater->pending.workspace) { | 1608 | if (container_is_floating(floater) && floater->pending.workspace) { |
1609 | // it's okay to just raise the scene directly instead of waiting | ||
1610 | // for the transaction to go through. We won't be reconfiguring | ||
1611 | // surfaces | ||
1612 | wlr_scene_node_raise_to_top(&floater->scene_tree->node); | ||
1613 | |||
1493 | list_move_to_end(floater->pending.workspace->floating, floater); | 1614 | list_move_to_end(floater->pending.workspace->floating, floater); |
1494 | node_set_dirty(&floater->pending.workspace->node); | 1615 | node_set_dirty(&floater->pending.workspace->node); |
1495 | } | 1616 | } |
diff --git a/sway/tree/view.c b/sway/tree/view.c index d349e5fa..7af2fd3f 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "sway/scene_descriptor.h" | 27 | #include "sway/scene_descriptor.h" |
28 | #include "sway/server.h" | 28 | #include "sway/server.h" |
29 | #include "sway/surface.h" | 29 | #include "sway/surface.h" |
30 | #include "sway/sway_text_node.h" | ||
30 | #include "sway/tree/arrange.h" | 31 | #include "sway/tree/arrange.h" |
31 | #include "sway/tree/container.h" | 32 | #include "sway/tree/container.h" |
32 | #include "sway/tree/view.h" | 33 | #include "sway/tree/view.h" |
@@ -1337,7 +1338,13 @@ void view_update_title(struct sway_view *view, bool force) { | |||
1337 | view->container->title = title ? strdup(title) : NULL; | 1338 | view->container->title = title ? strdup(title) : NULL; |
1338 | 1339 | ||
1339 | // Update title after the global font height is updated | 1340 | // Update title after the global font height is updated |
1340 | container_update_title_textures(view->container); | 1341 | if (view->container->title_bar.title_text && len) { |
1342 | sway_text_node_set_text(view->container->title_bar.title_text, | ||
1343 | view->container->formatted_title); | ||
1344 | container_arrange_title_bar(view->container); | ||
1345 | } else { | ||
1346 | container_update_title_bar(view->container); | ||
1347 | } | ||
1341 | 1348 | ||
1342 | ipc_event_window(view->container, "title"); | 1349 | ipc_event_window(view->container, "title"); |
1343 | 1350 | ||
@@ -1404,6 +1411,7 @@ void view_set_urgent(struct sway_view *view, bool enable) { | |||
1404 | return; | 1411 | return; |
1405 | } | 1412 | } |
1406 | clock_gettime(CLOCK_MONOTONIC, &view->urgent); | 1413 | clock_gettime(CLOCK_MONOTONIC, &view->urgent); |
1414 | container_update_itself_and_parents(view->container); | ||
1407 | } else { | 1415 | } else { |
1408 | view->urgent = (struct timespec){ 0 }; | 1416 | view->urgent = (struct timespec){ 0 }; |
1409 | if (view->urgent_timer) { | 1417 | if (view->urgent_timer) { |