diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 5f94ad7ea..db188fea4 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -77,8 +77,8 @@ struct sway_container { struct wlr_scene_rect *border; struct wlr_scene_rect *background; - struct wlr_scene_buffer *title_buffer; - struct wlr_scene_buffer *marks_buffer; + struct sway_text_node *title_text; + struct sway_text_node *marks_text; } title_bar; struct { @@ -97,6 +97,7 @@ struct sway_container { char *title; // The view's title (unformatted) char *formatted_title; // The title displayed in the title bar + int title_width; enum sway_container_layout prev_split_layout; @@ -139,18 +140,7 @@ struct sway_container { float alpha; - struct wlr_texture *title_focused; - struct wlr_texture *title_focused_inactive; - struct wlr_texture *title_focused_tab_title; - struct wlr_texture *title_unfocused; - struct wlr_texture *title_urgent; - list_t *marks; // char * - struct wlr_texture *marks_focused; - struct wlr_texture *marks_focused_inactive; - struct wlr_texture *marks_focused_tab_title; - struct wlr_texture *marks_unfocused; - struct wlr_texture *marks_urgent; struct { struct wl_signal destroy; @@ -192,7 +182,9 @@ void container_reap_empty(struct sway_container *con); struct sway_container *container_flatten(struct sway_container *container); -void container_update_title_textures(struct sway_container *container); +void container_update_title_bar(struct sway_container *container); + +void container_update_marks(struct sway_container *container); size_t container_build_representation(enum sway_container_layout layout, list_t *children, char *buffer); @@ -225,11 +217,6 @@ void container_set_geometry_from_content(struct sway_container *con); */ bool container_is_floating(struct sway_container *container); -/** - * Same as above, but for current container state. - */ -bool container_is_current_floating(struct sway_container *container); - /** * Get a container's box in layout coordinates. */ @@ -303,15 +290,10 @@ void container_discover_outputs(struct sway_container *con); enum sway_container_layout container_parent_layout(struct sway_container *con); -enum sway_container_layout container_current_parent_layout( - struct sway_container *con); - list_t *container_get_siblings(struct sway_container *container); int container_sibling_index(struct sway_container *child); -list_t *container_get_current_siblings(struct sway_container *container); - void container_handle_fullscreen_reparent(struct sway_container *con); void container_add_child(struct sway_container *parent, @@ -359,8 +341,6 @@ bool container_has_mark(struct sway_container *container, char *mark); void container_add_mark(struct sway_container *container, char *mark); -void container_update_marks_textures(struct sway_container *container); - void container_raise_floating(struct sway_container *con); bool container_is_scratchpad_hidden(struct sway_container *con); @@ -384,4 +364,10 @@ bool container_is_sticky_or_child(struct sway_container *con); */ int container_squash(struct sway_container *con); +void container_arrange_title_bar(struct sway_container *con); + +void container_update(struct sway_container *con); + +void container_update_itself_and_parents(struct sway_container *con); + #endif diff --git a/include/sway/tree/root.h b/include/sway/tree/root.h index 8e3d45d2d..389bdad09 100644 --- a/include/sway/tree/root.h +++ b/include/sway/tree/root.h @@ -3,7 +3,6 @@ #include #include #include -#include #include #include "sway/tree/container.h" #include "sway/tree/node.h" diff --git a/sway/commands/client.c b/sway/commands/client.c index 772631456..43a573093 100644 --- a/sway/commands/client.c +++ b/sway/commands/client.c @@ -5,9 +5,8 @@ #include "sway/tree/container.h" #include "util.h" -static void rebuild_textures_iterator(struct sway_container *con, void *data) { - container_update_marks_textures(con); - container_update_title_textures(con); +static void title_bar_update_iterator(struct sway_container *con, void *data) { + container_update_title_bar(con); } 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, memcpy(class, &colors, sizeof(struct border_colors)); if (config->active) { - root_for_each_container(rebuild_textures_iterator, NULL); + root_for_each_container(title_bar_update_iterator, NULL); for (int i = 0; i < root->outputs->length; ++i) { struct sway_output *output = root->outputs->items[i]; diff --git a/sway/commands/mark.c b/sway/commands/mark.c index aa5f185c8..30cf458c7 100644 --- a/sway/commands/mark.c +++ b/sway/commands/mark.c @@ -59,7 +59,7 @@ struct cmd_results *cmd_mark(int argc, char **argv) { } free(mark); - container_update_marks_textures(container); + container_update_marks(container); if (container->view) { view_execute_criteria(container->view); } diff --git a/sway/commands/reload.c b/sway/commands/reload.c index 76f14bba3..82967ca7f 100644 --- a/sway/commands/reload.c +++ b/sway/commands/reload.c @@ -9,9 +9,8 @@ #include "list.h" #include "log.h" -static void rebuild_textures_iterator(struct sway_container *con, void *data) { - container_update_marks_textures(con); - container_update_title_textures(con); +static void title_bar_update_iterator(struct sway_container *con, void *data) { + container_update_title_bar(con); } static void do_reload(void *data) { @@ -48,7 +47,7 @@ static void do_reload(void *data) { } list_free_items_and_destroy(bar_ids); - root_for_each_container(rebuild_textures_iterator, NULL); + root_for_each_container(title_bar_update_iterator, NULL); arrange_root(); } diff --git a/sway/commands/show_marks.c b/sway/commands/show_marks.c index 0d373b80c..f738144fe 100644 --- a/sway/commands/show_marks.c +++ b/sway/commands/show_marks.c @@ -10,8 +10,8 @@ #include "stringop.h" #include "util.h" -static void rebuild_marks_iterator(struct sway_container *con, void *data) { - container_update_marks_textures(con); +static void title_bar_update_iterator(struct sway_container *con, void *data) { + container_update_marks(con); } struct cmd_results *cmd_show_marks(int argc, char **argv) { @@ -23,7 +23,7 @@ struct cmd_results *cmd_show_marks(int argc, char **argv) { config->show_marks = parse_boolean(argv[0], config->show_marks); if (config->show_marks) { - root_for_each_container(rebuild_marks_iterator, NULL); + root_for_each_container(title_bar_update_iterator, NULL); } for (int i = 0; i < root->outputs->length; ++i) { diff --git a/sway/commands/title_align.c b/sway/commands/title_align.c index c30355deb..7f5dd3ae5 100644 --- a/sway/commands/title_align.c +++ b/sway/commands/title_align.c @@ -4,6 +4,10 @@ #include "sway/tree/container.h" #include "sway/tree/root.h" +static void arrange_title_bar_iterator(struct sway_container *con, void *data) { + container_arrange_title_bar(con); +} + struct cmd_results *cmd_title_align(int argc, char **argv) { struct cmd_results *error = NULL; if ((error = checkarg(argc, "title_align", EXPECTED_AT_LEAST, 1))) { @@ -21,6 +25,8 @@ struct cmd_results *cmd_title_align(int argc, char **argv) { "Expected 'title_align left|center|right'"); } + root_for_each_container(arrange_title_bar_iterator, NULL); + for (int i = 0; i < root->outputs->length; ++i) { struct sway_output *output = root->outputs->items[i]; output_damage_whole(output); diff --git a/sway/commands/unmark.c b/sway/commands/unmark.c index 19274dfbf..c3a6ac4b9 100644 --- a/sway/commands/unmark.c +++ b/sway/commands/unmark.c @@ -8,9 +8,13 @@ #include "log.h" #include "stringop.h" -static void remove_all_marks_iterator(struct sway_container *con, void *data) { +static void remove_mark(struct sway_container *con) { container_clear_marks(con); - container_update_marks_textures(con); + container_update_marks(con); +} + +static void remove_all_marks_iterator(struct sway_container *con, void *data) { + remove_mark(con); } // unmark Remove all marks from all views @@ -38,8 +42,7 @@ struct cmd_results *cmd_unmark(int argc, char **argv) { } } else if (con && !mark) { // Clear all marks from the given container - container_clear_marks(con); - container_update_marks_textures(con); + remove_mark(con); } else if (!con && mark) { // Remove mark from whichever container has it container_find_and_unmark(mark); diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 62ac30e02..4fd1d2c2d 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -572,7 +572,6 @@ static void handle_mode(struct wl_listener *listener, void *data) { static void update_textures(struct sway_container *con, void *data) { container_update_title_textures(con); - container_update_marks_textures(con); } static void handle_commit(struct wl_listener *listener, void *data) { diff --git a/sway/tree/container.c b/sway/tree/container.c index 01b510a83..da4163a98 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -5,22 +5,23 @@ #include #include #include +#include +#include #include +#include #include #include #include #include #include #include "linux-dmabuf-unstable-v1-protocol.h" -#include "cairo_util.h" -#include "pango.h" #include "sway/config.h" -#include "sway/desktop.h" #include "sway/desktop/transaction.h" #include "sway/input/input-manager.h" #include "sway/input/seat.h" #include "sway/ipc-server.h" #include "sway/scene_descriptor.h" +#include "sway/sway_text_buffer.h" #include "sway/output.h" #include "sway/server.h" #include "sway/tree/arrange.h" @@ -71,12 +72,12 @@ struct sway_container *container_create(struct sway_view *view) { bool alloc_failure = false; c->scene_tree = alloc_scene_tree(root->staging, &alloc_failure); - c->title_bar.tree = alloc_scene_tree(c->scene_node, &alloc_failure); - c->title_bar.border = alloc_rect_node(c->title_bar.node, &alloc_failure); - c->title_bar.background = alloc_rect_node(c->title_bar.node, &alloc_failure); + c->title_bar.tree = alloc_scene_tree(c->scene_tree, &alloc_failure); + c->title_bar.border = alloc_rect_node(c->title_bar.tree, &alloc_failure); + c->title_bar.background = alloc_rect_node(c->title_bar.tree, &alloc_failure); - c->border.tree = alloc_scene_tree(c->scene_node, &alloc_failure); - c->content_tree = alloc_scene_tree(c->border.node, &alloc_failure); + c->border.tree = alloc_scene_tree(c->scene_tree, &alloc_failure); + c->content_tree = alloc_scene_tree(c->border.tree, &alloc_failure); if (view) { // only containers with views can have borders @@ -89,8 +90,8 @@ struct sway_container *container_create(struct sway_view *view) { c->current.children = create_list(); } - scene_descriptor_assign(c->scene_node, SWAY_SCENE_DESC_CONTAINER, c); - if (!c->scene_node->data) { + scene_descriptor_assign(&c->scene_tree->node, SWAY_SCENE_DESC_CONTAINER, c); + if (!c->scene_tree->node.data) { alloc_failure = true; } @@ -98,8 +99,8 @@ struct sway_container *container_create(struct sway_view *view) { // the container will not be part of the scene graph, only the view itself // So to not confuse input logic, we need to assign this. if (view) { - scene_descriptor_assign(view->scene_node, SWAY_SCENE_DESC_CONTAINER, c); - if (!view->scene_node->data) { + scene_descriptor_assign(&view->scene_tree->node, SWAY_SCENE_DESC_CONTAINER, c); + if (!view->scene_tree->node.data) { alloc_failure = true; } } @@ -119,9 +120,244 @@ struct sway_container *container_create(struct sway_view *view) { wl_signal_init(&c->events.destroy); wl_signal_emit(&root->events.new_node, &c->node); + container_update(c); + return c; } +static bool container_is_focused(struct sway_container *con, void *data) { + return con->current.focused; +} + +static bool container_has_focused_child(struct sway_container *con) { + return container_find_child(con, container_is_focused, NULL); +} + +static bool container_is_current_parent_focused(struct sway_container *con) { + if (con->current.parent) { + struct sway_container *parent = con->current.parent; + return parent->current.focused || container_is_current_parent_focused(parent); + } else if (con->current.workspace) { + struct sway_workspace *ws = con->current.workspace; + return ws->current.focused; + } + + return false; +} + +static struct border_colors *container_get_current_colors( + struct sway_container *con) { + struct border_colors *colors; + + bool urgent = con->view ? + view_is_urgent(con->view) : container_has_urgent_child(con); + struct sway_container *active_child; + + if (con->current.parent) { + active_child = con->current.parent->current.focused_inactive_child; + } else if (con->current.workspace) { + active_child = con->current.workspace->current.focused_inactive_child; + } else { + active_child = NULL; + } + + if (urgent) { + colors = &config->border_colors.urgent; + } else if (con->current.focused || container_is_current_parent_focused(con)) { + colors = &config->border_colors.focused; + } else if (config->has_focused_tab_title && container_has_focused_child(con)) { + colors = &config->border_colors.focused_tab_title; + } else if (con == active_child) { + colors = &config->border_colors.focused_inactive; + } else { + colors = &config->border_colors.unfocused; + } + + return colors; +} + +static bool container_is_current_floating(struct sway_container *container) { + if (!container->current.parent && container->current.workspace && + list_find(container->current.workspace->floating, container) != -1) { + return true; + } + if (container->scratchpad) { + return true; + } + return false; +} + +void container_update(struct sway_container *con) { + struct border_colors *colors = container_get_current_colors(con); + list_t *siblings = NULL; + enum sway_container_layout layout = L_NONE; + + if (con->current.parent) { + siblings = con->current.parent->current.children; + layout = con->current.parent->current.layout; + } else if (con->current.workspace) { + siblings = con->current.workspace->current.tiling; + layout = con->current.workspace->current.layout; + } + + const float *bottom, *right; + bottom = (const float *) colors->child_border; + right = (const float *) colors->child_border; + + if (!container_is_current_floating(con) && siblings && siblings->length == 1) { + if (layout == L_HORIZ) { + right = (const float *) colors->indicator; + } else if (layout == L_VERT) { + bottom = (const float *) colors->indicator; + } + } + + wlr_scene_rect_set_color(con->title_bar.border, (const float *) colors->border); + wlr_scene_rect_set_color(con->title_bar.background, (const float *) colors->background); + + if (con->view) { + wlr_scene_rect_set_color(con->border.top, (const float *) colors->child_border); + wlr_scene_rect_set_color(con->border.bottom, bottom); + wlr_scene_rect_set_color(con->border.left, (const float *) colors->child_border); + wlr_scene_rect_set_color(con->border.right, right); + } + + if (con->title_bar.title_text) { + sway_text_node_set_color(con->title_bar.title_text, colors->text); + } + + if (con->title_bar.marks_text) { + sway_text_node_set_color(con->title_bar.marks_text, colors->text); + } +} + +void container_update_itself_and_parents(struct sway_container *con) { + container_update(con); + + if (con->current.parent) { + container_update_itself_and_parents(con->current.parent); + } +} + +void container_arrange_title_bar(struct sway_container *con) { + enum alignment title_align = config->title_align; + int marks_buffer_width = 0; + int width = con->title_width; + int height = container_titlebar_height(); + + if (con->title_bar.marks_text) { + struct sway_text_node *node = con->title_bar.marks_text; + marks_buffer_width = node->width; + + int h_padding; + if (title_align == ALIGN_RIGHT) { + h_padding = config->titlebar_h_padding; + } else { + h_padding = width - config->titlebar_h_padding - marks_buffer_width; + } + + h_padding = MAX(h_padding, 0); + + int alloc_width = MIN((int) node->width, width - h_padding); + sway_text_node_set_max_width(node, alloc_width); + wlr_scene_node_set_position(node->node, + h_padding, (height - node->height) >> 1); + } + + if (con->title_bar.title_text) { + struct sway_text_node *node = con->title_bar.title_text; + + int h_padding; + if (title_align == ALIGN_RIGHT) { + h_padding = width - config->titlebar_h_padding - node->width; + } else if (title_align == ALIGN_CENTER) { + h_padding = ((int) width - marks_buffer_width - node->width) >> 1; + } else { + h_padding = config->titlebar_h_padding; + } + + h_padding = MAX(h_padding, 0); + + int alloc_width = MIN((int) node->width, width - h_padding); + sway_text_node_set_max_width(node, alloc_width); + wlr_scene_node_set_position(node->node, + h_padding, (height - node->height) >> 1); + } +} + +void container_update_marks(struct sway_container *con) { + char *buffer = NULL; + + if (config->show_marks && con->marks->length) { + size_t len = 0; + for (int i = 0; i < con->marks->length; ++i) { + char *mark = con->marks->items[i]; + if (mark[0] != '_') { + len += strlen(mark) + 2; + } + } + buffer = calloc(len + 1, 1); + char *part = malloc(len + 1); + + if (!sway_assert(buffer && part, "Unable to allocate memory")) { + free(buffer); + return; + } + + for (int i = 0; i < con->marks->length; ++i) { + char *mark = con->marks->items[i]; + if (mark[0] != '_') { + snprintf(part, len + 1, "[%s]", mark); + strcat(buffer, part); + } + } + free(part); + } + + if (!buffer) { + if (con->title_bar.marks_text) { + wlr_scene_node_destroy(con->title_bar.marks_text->node); + con->title_bar.marks_text = NULL; + } + } else if (!con->title_bar.marks_text) { + struct border_colors *colors = container_get_current_colors(con); + + con->title_bar.marks_text = sway_text_node_create(con->title_bar.tree, + buffer, colors->text, false); + } else { + sway_text_node_set_text(con->title_bar.marks_text, buffer); + } + + container_arrange_title_bar(con); + free(buffer); +} + +void container_update_title_bar(struct sway_container *con) { + if (!con->formatted_title) { + return; + } + + struct border_colors *colors = container_get_current_colors(con); + + if (con->title_bar.title_text) { + wlr_scene_node_destroy(con->title_bar.title_text->node); + con->title_bar.title_text = NULL; + } + + con->title_bar.title_text = sway_text_node_create(con->title_bar.tree, + con->formatted_title, colors->text, config->pango_markup); + + // we always have to remake these text buffers completely for text font + // changes etc... + if (con->title_bar.marks_text) { + wlr_scene_node_destroy(con->title_bar.marks_text->node); + con->title_bar.marks_text = NULL; + } + + container_update_marks(con); + container_arrange_title_bar(con); +} + void container_destroy(struct sway_container *con) { if (!sway_assert(con->node.destroying, "Tried to free container which wasn't marked as destroying")) { @@ -133,21 +369,11 @@ void container_destroy(struct sway_container *con) { } free(con->title); free(con->formatted_title); - wlr_texture_destroy(con->title_focused); - wlr_texture_destroy(con->title_focused_inactive); - wlr_texture_destroy(con->title_unfocused); - wlr_texture_destroy(con->title_urgent); - wlr_texture_destroy(con->title_focused_tab_title); list_free(con->pending.children); list_free(con->current.children); list_free(con->outputs); list_free_items_and_destroy(con->marks); - wlr_texture_destroy(con->marks_focused); - wlr_texture_destroy(con->marks_focused_inactive); - wlr_texture_destroy(con->marks_unfocused); - wlr_texture_destroy(con->marks_urgent); - wlr_texture_destroy(con->marks_focused_tab_title); if (con->view && con->view->container == con) { con->view->container = NULL; @@ -156,8 +382,8 @@ void container_destroy(struct sway_container *con) { } } - scene_node_disown_children(con->content_node); - wlr_scene_node_destroy(con->scene_node); + scene_node_disown_children(con->content_tree); + wlr_scene_node_destroy(&con->scene_tree->node); free(con); } @@ -306,110 +532,6 @@ struct sway_output *container_get_effective_output(struct sway_container *con) { } return con->outputs->items[con->outputs->length - 1]; } - -static void render_titlebar_text_texture(struct sway_output *output, - struct sway_container *con, struct wlr_texture **texture, - struct border_colors *class, bool pango_markup, char *text) { - double scale = output->wlr_output->scale; - int width = 0; - int height = config->font_height * scale; - int baseline; - - // We must use a non-nil cairo_t for cairo_set_font_options to work. - // Therefore, we cannot use cairo_create(NULL). - cairo_surface_t *dummy_surface = cairo_image_surface_create( - CAIRO_FORMAT_ARGB32, 0, 0); - cairo_t *c = cairo_create(dummy_surface); - cairo_set_antialias(c, CAIRO_ANTIALIAS_BEST); - cairo_font_options_t *fo = cairo_font_options_create(); - cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL); - if (output->wlr_output->subpixel == WL_OUTPUT_SUBPIXEL_NONE) { - cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_GRAY); - } else { - cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_SUBPIXEL); - cairo_font_options_set_subpixel_order(fo, - to_cairo_subpixel_order(output->wlr_output->subpixel)); - } - cairo_set_font_options(c, fo); - get_text_size(c, config->font_description, &width, NULL, &baseline, scale, - config->pango_markup, "%s", text); - cairo_surface_destroy(dummy_surface); - cairo_destroy(c); - - if (width == 0 || height == 0) { - return; - } - - if (height > config->font_height * scale) { - height = config->font_height * scale; - } - - cairo_surface_t *surface = cairo_image_surface_create( - CAIRO_FORMAT_ARGB32, width, height); - cairo_status_t status = cairo_surface_status(surface); - if (status != CAIRO_STATUS_SUCCESS) { - sway_log(SWAY_ERROR, "cairo_image_surface_create failed: %s", - cairo_status_to_string(status)); - return; - } - - cairo_t *cairo = cairo_create(surface); - cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); - cairo_set_font_options(cairo, fo); - cairo_font_options_destroy(fo); - cairo_set_source_rgba(cairo, class->background[0], class->background[1], - class->background[2], class->background[3]); - cairo_paint(cairo); - PangoContext *pango = pango_cairo_create_context(cairo); - cairo_set_source_rgba(cairo, class->text[0], class->text[1], - class->text[2], class->text[3]); - cairo_move_to(cairo, 0, config->font_baseline * scale - baseline); - - render_text(cairo, config->font_description, scale, pango_markup, "%s", text); - - cairo_surface_flush(surface); - unsigned char *data = cairo_image_surface_get_data(surface); - int stride = cairo_image_surface_get_stride(surface); - struct wlr_renderer *renderer = output->wlr_output->renderer; - *texture = wlr_texture_from_pixels( - renderer, DRM_FORMAT_ARGB8888, stride, width, height, data); - cairo_surface_destroy(surface); - g_object_unref(pango); - cairo_destroy(cairo); -} - -static void update_title_texture(struct sway_container *con, - struct wlr_texture **texture, struct border_colors *class) { - struct sway_output *output = container_get_effective_output(con); - if (!output) { - return; - } - if (*texture) { - wlr_texture_destroy(*texture); - *texture = NULL; - } - if (!con->formatted_title) { - return; - } - - render_titlebar_text_texture(output, con, texture, class, - config->pango_markup, con->formatted_title); -} - -void container_update_title_textures(struct sway_container *container) { - update_title_texture(container, &container->title_focused, - &config->border_colors.focused); - update_title_texture(container, &container->title_focused_inactive, - &config->border_colors.focused_inactive); - update_title_texture(container, &container->title_unfocused, - &config->border_colors.unfocused); - update_title_texture(container, &container->title_urgent, - &config->border_colors.urgent); - update_title_texture(container, &container->title_focused_tab_title, - &config->border_colors.focused_tab_title); - container_damage_whole(container); -} - /** * Calculate and return the length of the tree representation. * An example tree representation is: V[Terminal, Firefox] @@ -475,7 +597,12 @@ void container_update_representation(struct sway_container *con) { } container_build_representation(con->pending.layout, con->pending.children, con->formatted_title); - container_update_title_textures(con); + + if (con->title_bar.title_text) { + sway_text_node_set_text(con->title_bar.title_text, con->formatted_title); + } else { + container_update_title_bar(con); + } } if (con->pending.parent) { container_update_representation(con->pending.parent); @@ -746,17 +873,6 @@ bool container_is_floating(struct sway_container *container) { return false; } -bool container_is_current_floating(struct sway_container *container) { - if (!container->current.parent && container->current.workspace && - list_find(container->current.workspace->floating, container) != -1) { - return true; - } - if (container->scratchpad) { - return true; - } - return false; -} - void container_get_box(struct sway_container *container, struct wlr_box *box) { box->x = container->pending.x; box->y = container->pending.y; @@ -1192,7 +1308,6 @@ void container_discover_outputs(struct sway_container *con) { double new_scale = new_output ? new_output->wlr_output->scale : -1; if (old_scale != new_scale) { container_update_title_textures(con); - container_update_marks_textures(con); } } @@ -1206,14 +1321,6 @@ enum sway_container_layout container_parent_layout(struct sway_container *con) { return L_NONE; } -enum sway_container_layout container_current_parent_layout( - struct sway_container *con) { - if (con->current.parent) { - return con->current.parent->current.layout; - } - return con->current.workspace->current.layout; -} - list_t *container_get_siblings(struct sway_container *container) { if (container->pending.parent) { return container->pending.parent->pending.children; @@ -1231,13 +1338,6 @@ int container_sibling_index(struct sway_container *child) { return list_find(container_get_siblings(child), child); } -list_t *container_get_current_siblings(struct sway_container *container) { - if (container->current.parent) { - return container->current.parent->current.children; - } - return container->current.workspace->current.tiling; -} - void container_handle_fullscreen_reparent(struct sway_container *con) { if (con->pending.fullscreen_mode != FULLSCREEN_WORKSPACE || !con->pending.workspace || con->pending.workspace->fullscreen == con) { @@ -1452,7 +1552,7 @@ bool container_find_and_unmark(char *mark) { if (strcmp(con_mark, mark) == 0) { free(con_mark); list_del(con->marks, i); - container_update_marks_textures(con); + container_update_marks(con); ipc_event_window(con, "mark"); return true; } @@ -1483,70 +1583,15 @@ void container_add_mark(struct sway_container *con, char *mark) { ipc_event_window(con, "mark"); } -static void update_marks_texture(struct sway_container *con, - struct wlr_texture **texture, struct border_colors *class) { - struct sway_output *output = container_get_effective_output(con); - if (!output) { - return; - } - if (*texture) { - wlr_texture_destroy(*texture); - *texture = NULL; - } - if (!con->marks->length) { - return; - } - - size_t len = 0; - for (int i = 0; i < con->marks->length; ++i) { - char *mark = con->marks->items[i]; - if (mark[0] != '_') { - len += strlen(mark) + 2; - } - } - char *buffer = calloc(len + 1, 1); - char *part = malloc(len + 1); - - if (!sway_assert(buffer && part, "Unable to allocate memory")) { - free(buffer); - return; - } - - for (int i = 0; i < con->marks->length; ++i) { - char *mark = con->marks->items[i]; - if (mark[0] != '_') { - snprintf(part, len + 1, "[%s]", mark); - strcat(buffer, part); - } - } - free(part); - - render_titlebar_text_texture(output, con, texture, class, false, buffer); - - free(buffer); -} - -void container_update_marks_textures(struct sway_container *con) { - if (!config->show_marks) { - return; - } - update_marks_texture(con, &con->marks_focused, - &config->border_colors.focused); - update_marks_texture(con, &con->marks_focused_inactive, - &config->border_colors.focused_inactive); - update_marks_texture(con, &con->marks_unfocused, - &config->border_colors.unfocused); - update_marks_texture(con, &con->marks_urgent, - &config->border_colors.urgent); - update_marks_texture(con, &con->marks_focused_tab_title, - &config->border_colors.focused_tab_title); - container_damage_whole(con); -} - void container_raise_floating(struct sway_container *con) { // Bring container to front by putting it at the end of the floating list. struct sway_container *floater = container_toplevel_ancestor(con); if (container_is_floating(floater) && floater->pending.workspace) { + // it's okay to just raise the scene directly instead of waiting + // for the transaction to go through. We won't be reconfiguring + // surfaces + wlr_scene_node_raise_to_top(&floater->scene_tree->node); + list_move_to_end(floater->pending.workspace->floating, floater); node_set_dirty(&floater->pending.workspace->node); } diff --git a/sway/tree/view.c b/sway/tree/view.c index ac6993ffd..8185666cc 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -24,6 +24,7 @@ #include "sway/output.h" #include "sway/input/seat.h" #include "sway/server.h" +#include "sway/sway_text_buffer.h" #include "sway/tree/arrange.h" #include "sway/tree/container.h" #include "sway/tree/view.h" @@ -1310,7 +1311,13 @@ void view_update_title(struct sway_view *view, bool force) { view->container->title = title ? strdup(title) : NULL; // Update title after the global font height is updated - container_update_title_textures(view->container); + if (view->container->title_bar.title_text && len) { + sway_text_node_set_text(view->container->title_bar.title_text, + view->container->formatted_title); + container_arrange_title_bar(view->container); + } else { + container_update_title_bar(view->container); + } ipc_event_window(view->container, "title"); @@ -1377,6 +1384,7 @@ void view_set_urgent(struct sway_view *view, bool enable) { return; } clock_gettime(CLOCK_MONOTONIC, &view->urgent); + container_update_itself_and_parents(view->container); } else { view->urgent = (struct timespec){ 0 }; if (view->urgent_timer) {