aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sway/tree/container.h28
-rw-r--r--include/sway/tree/view.h28
-rw-r--r--sway/commands/client.c4
-rw-r--r--sway/commands/mark.c19
-rw-r--r--sway/commands/move.c6
-rw-r--r--sway/commands/reload.c4
-rw-r--r--sway/commands/show_marks.c4
-rw-r--r--sway/commands/swap.c4
-rw-r--r--sway/commands/unmark.c41
-rw-r--r--sway/criteria.c5
-rw-r--r--sway/desktop/output.c4
-rw-r--r--sway/desktop/render.c30
-rw-r--r--sway/ipc-json.c6
-rw-r--r--sway/ipc-server.c8
-rw-r--r--sway/tree/container.c151
-rw-r--r--sway/tree/view.c155
16 files changed, 236 insertions, 261 deletions
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
index c0c803f1..4366a010 100644
--- a/include/sway/tree/container.h
+++ b/include/sway/tree/container.h
@@ -127,6 +127,12 @@ struct sway_container {
size_t title_height;
size_t title_baseline;
+ list_t *marks; // char *
+ struct wlr_texture *marks_focused;
+ struct wlr_texture *marks_focused_inactive;
+ struct wlr_texture *marks_unfocused;
+ struct wlr_texture *marks_urgent;
+
struct {
struct wl_signal destroy;
} events;
@@ -304,4 +310,26 @@ struct sway_container *container_split(struct sway_container *child,
bool container_is_transient_for(struct sway_container *child,
struct sway_container *ancestor);
+/**
+ * Find any container that has the given mark and return it.
+ */
+struct sway_container *container_find_mark(char *mark);
+
+/**
+ * Find any container that has the given mark and remove the mark from the
+ * container. Returns true if it matched a container.
+ */
+bool container_find_and_unmark(char *mark);
+
+/**
+ * Remove all marks from the container.
+ */
+void container_clear_marks(struct sway_container *container);
+
+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);
+
#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 {
bool destroying;
list_t *executed_criteria; // struct criteria *
- list_t *marks; // char *
-
- struct wlr_texture *marks_focused;
- struct wlr_texture *marks_focused_inactive;
- struct wlr_texture *marks_unfocused;
- struct wlr_texture *marks_urgent;
union {
struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6;
@@ -353,28 +347,6 @@ void view_update_title(struct sway_view *view, bool force);
void view_execute_criteria(struct sway_view *view);
/**
- * Find any view that has the given mark and return it.
- */
-struct sway_view *view_find_mark(char *mark);
-
-/**
- * Find any view that has the given mark and remove the mark from the view.
- * Returns true if it matched a view.
- */
-bool view_find_and_unmark(char *mark);
-
-/**
- * Remove all marks from the view.
- */
-void view_clear_marks(struct sway_view *view);
-
-bool view_has_mark(struct sway_view *view, char *mark);
-
-void view_add_mark(struct sway_view *view, char *mark);
-
-void view_update_marks_textures(struct sway_view *view);
-
-/**
* Returns true if there's a possibility the view may be rendered on screen.
* Intended for damage tracking.
*/
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 @@
#include "sway/tree/container.h"
static void rebuild_textures_iterator(struct sway_container *con, void *data) {
- if (con->view) {
- view_update_marks_textures(con->view);
- }
+ container_update_marks_textures(con);
container_update_title_textures(con);
}
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) {
return error;
}
struct sway_container *container = config->handler_context.container;
- if (!container || !container->view) {
+ if (!container) {
return cmd_results_new(CMD_INVALID, "mark",
- "Only views can have marks");
+ "Only containers can have marks");
}
- struct sway_view *view = container->view;
bool add = false, toggle = false;
while (argc > 0 && strncmp(*argv, "--", 2) == 0) {
@@ -47,22 +46,24 @@ struct cmd_results *cmd_mark(int argc, char **argv) {
}
char *mark = join_args(argv, argc);
- bool had_mark = view_has_mark(view, mark);
+ bool had_mark = container_has_mark(container, mark);
if (!add) {
// Replacing
- view_clear_marks(view);
+ container_clear_marks(container);
}
- view_find_and_unmark(mark);
+ container_find_and_unmark(mark);
if (!toggle || !had_mark) {
- view_add_mark(view, mark);
+ container_add_mark(container, mark);
}
free(mark);
- view_update_marks_textures(view);
- view_execute_criteria(view);
+ container_update_marks_textures(container);
+ if (container->view) {
+ view_execute_criteria(container->view);
+ }
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
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) {
}
destination = seat_get_focus_inactive(seat, &new_output->node);
} else if (strcasecmp(argv[1], "mark") == 0) {
- struct sway_view *dest_view = view_find_mark(argv[2]);
- if (dest_view == NULL) {
+ struct sway_container *dest_con = container_find_mark(argv[2]);
+ if (dest_con == NULL) {
return cmd_results_new(CMD_FAILURE, "move",
"Mark '%s' not found", argv[2]);
}
- destination = &dest_view->container->node;
+ destination = &dest_con->node;
} else {
return cmd_results_new(CMD_INVALID, "move", expected_syntax);
}
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 @@
#include "log.h"
static void rebuild_textures_iterator(struct sway_container *con, void *data) {
- if (con->view) {
- view_update_marks_textures(con->view);
- }
+ container_update_marks_textures(con);
container_update_title_textures(con);
}
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 @@
#include "util.h"
static void rebuild_marks_iterator(struct sway_container *con, void *data) {
- if (con->view) {
- view_update_marks_textures(con->view);
- }
+ container_update_marks_textures(con);
}
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) {
}
static bool test_mark(struct sway_container *container, void *mark) {
- if (container->view && container->view->marks->length) {
- return !list_seq_find(container->view->marks,
+ if (container->marks->length) {
+ return !list_seq_find(container->marks,
(int (*)(const void *, const void *))strcmp, mark);
}
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 @@
#include "stringop.h"
static void remove_all_marks_iterator(struct sway_container *con, void *data) {
- if (con->view) {
- view_clear_marks(con->view);
- view_update_marks_textures(con->view);
- }
+ container_clear_marks(con);
+ container_update_marks_textures(con);
}
// unmark Remove all marks from all views
@@ -21,15 +19,10 @@ static void remove_all_marks_iterator(struct sway_container *con, void *data) {
// [criteria] unmark foo Remove single mark from matched view
struct cmd_results *cmd_unmark(int argc, char **argv) {
- // Determine the view
- struct sway_view *view = NULL;
+ // Determine the container
+ struct sway_container *con = NULL;
if (config->handler_context.using_criteria) {
- struct sway_container *container = config->handler_context.container;
- if (!container || !container->view) {
- return cmd_results_new(CMD_INVALID, "unmark",
- "Only views can have marks");
- }
- view = container->view;
+ con = config->handler_context.container;
}
// Determine the mark
@@ -38,20 +31,20 @@ struct cmd_results *cmd_unmark(int argc, char **argv) {
mark = join_args(argv, argc);
}
- if (view && mark) {
- // Remove the mark from the given view
- if (view_has_mark(view, mark)) {
- view_find_and_unmark(mark);
+ if (con && mark) {
+ // Remove the mark from the given container
+ if (container_has_mark(con, mark)) {
+ container_find_and_unmark(mark);
}
- } else if (view && !mark) {
- // Clear all marks from the given view
- view_clear_marks(view);
- view_update_marks_textures(view);
- } else if (!view && mark) {
- // Remove mark from whichever view has it
- view_find_and_unmark(mark);
+ } else if (con && !mark) {
+ // Clear all marks from the given container
+ container_clear_marks(con);
+ container_update_marks_textures(con);
+ } else if (!con && mark) {
+ // Remove mark from whichever container has it
+ container_find_and_unmark(mark);
} else {
- // Remove all marks from all views
+ // Remove all marks from all containers
root_for_each_container(remove_all_marks_iterator, NULL);
}
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,
if (criteria->con_mark) {
bool exists = false;
- for (int i = 0; i < view->marks->length; ++i) {
- if (regex_cmp(view->marks->items[i], criteria->con_mark) == 0) {
+ struct sway_container *con = view->container;
+ for (int i = 0; i < con->marks->length; ++i) {
+ if (regex_cmp(con->marks->items[i], criteria->con_mark) == 0) {
exists = true;
break;
}
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) {
static void update_textures(struct sway_container *con, void *data) {
container_update_title_textures(con);
- if (con->view) {
- view_update_marks_textures(con->view);
- }
+ container_update_marks_textures(con);
}
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,
if (view_is_urgent(view)) {
colors = &config->border_colors.urgent;
title_texture = child->title_urgent;
- marks_texture = view->marks_urgent;
+ marks_texture = child->marks_urgent;
} else if (state->focused || parent->focused) {
colors = &config->border_colors.focused;
title_texture = child->title_focused;
- marks_texture = view->marks_focused;
+ marks_texture = child->marks_focused;
} else if (child == parent->active_child) {
colors = &config->border_colors.focused_inactive;
title_texture = child->title_focused_inactive;
- marks_texture = view->marks_focused_inactive;
+ marks_texture = child->marks_focused_inactive;
} else {
colors = &config->border_colors.unfocused;
title_texture = child->title_unfocused;
- marks_texture = view->marks_unfocused;
+ marks_texture = child->marks_unfocused;
}
if (state->border == B_NORMAL) {
@@ -681,19 +681,19 @@ static void render_containers_tabbed(struct sway_output *output,
if (urgent) {
colors = &config->border_colors.urgent;
title_texture = child->title_urgent;
- marks_texture = view ? view->marks_urgent : NULL;
+ marks_texture = child->marks_urgent;
} else if (cstate->focused || parent->focused) {
colors = &config->border_colors.focused;
title_texture = child->title_focused;
- marks_texture = view ? view->marks_focused : NULL;
+ marks_texture = child->marks_focused;
} else if (child == parent->active_child) {
colors = &config->border_colors.focused_inactive;
title_texture = child->title_focused_inactive;
- marks_texture = view ? view->marks_focused_inactive : NULL;
+ marks_texture = child->marks_focused_inactive;
} else {
colors = &config->border_colors.unfocused;
title_texture = child->title_unfocused;
- marks_texture = view ? view->marks_unfocused : NULL;
+ marks_texture = child->marks_unfocused;
}
int x = cstate->con_x + tab_width * i;
@@ -746,19 +746,19 @@ static void render_containers_stacked(struct sway_output *output,
if (urgent) {
colors = &config->border_colors.urgent;
title_texture = child->title_urgent;
- marks_texture = view ? view->marks_urgent : NULL;
+ marks_texture = child->marks_urgent;
} else if (cstate->focused || parent->focused) {
colors = &config->border_colors.focused;
title_texture = child->title_focused;
- marks_texture = view ? view->marks_focused : NULL;
+ marks_texture = child->marks_focused;
} else if (child == parent->active_child) {
colors = &config->border_colors.focused_inactive;
title_texture = child->title_focused_inactive;
- marks_texture = view ? view->marks_focused_inactive : NULL;
+ marks_texture = child->marks_focused_inactive;
} else {
colors = &config->border_colors.unfocused;
title_texture = child->title_unfocused;
- marks_texture = view ? view->marks_unfocused : NULL;
+ marks_texture = child->marks_unfocused;
}
int y = parent->box.y + titlebar_height * i;
@@ -841,15 +841,15 @@ static void render_floating_container(struct sway_output *soutput,
if (view_is_urgent(view)) {
colors = &config->border_colors.urgent;
title_texture = con->title_urgent;
- marks_texture = view->marks_urgent;
+ marks_texture = con->marks_urgent;
} else if (con->current.focused) {
colors = &config->border_colors.focused;
title_texture = con->title_focused;
- marks_texture = view->marks_focused;
+ marks_texture = con->marks_focused;
} else {
colors = &config->border_colors.unfocused;
title_texture = con->title_unfocused;
- marks_texture = view->marks_unfocused;
+ marks_texture = con->marks_unfocused;
}
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
app_id ? json_object_new_string(app_id) : NULL);
json_object *marks = json_object_new_array();
- list_t *view_marks = c->view->marks;
- for (int i = 0; i < view_marks->length; ++i) {
- json_object_array_add(marks, json_object_new_string(view_marks->items[i]));
+ list_t *con_marks = c->marks;
+ for (int i = 0; i < con_marks->length; ++i) {
+ json_object_array_add(marks, json_object_new_string(con_marks->items[i]));
}
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,
static void ipc_get_marks_callback(struct sway_container *con, void *data) {
json_object *marks = (json_object *)data;
- if (con->view && con->view->marks) {
- for (int i = 0; i < con->view->marks->length; ++i) {
- char *mark = (char *)con->view->marks->items[i];
- json_object_array_add(marks, json_object_new_string(mark));
- }
+ for (int i = 0; i < con->marks->length; ++i) {
+ char *mark = (char *)con->marks->items[i];
+ json_object_array_add(marks, json_object_new_string(mark));
}
}
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) {
c->children = create_list();
c->current.children = create_list();
}
+ c->marks = create_list();
c->outputs = create_list();
wl_signal_init(&c->events.destroy);
@@ -66,6 +67,13 @@ void container_destroy(struct sway_container *con) {
list_free(con->current.children);
list_free(con->outputs);
+ list_foreach(con->marks, free);
+ list_free(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);
+
if (con->view) {
if (con->view->container == con) {
con->view->container = NULL;
@@ -996,9 +1004,7 @@ 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);
- if (con->view) {
- view_update_marks_textures(con->view);
- }
+ container_update_marks_textures(con);
}
}
@@ -1218,3 +1224,142 @@ bool container_is_transient_for(struct sway_container *child,
child->view && ancestor->view &&
view_is_transient_for(child->view, ancestor->view);
}
+
+static bool find_by_mark_iterator(struct sway_container *con, void *data) {
+ char *mark = data;
+ return container_has_mark(con, mark);
+}
+
+struct sway_container *container_find_mark(char *mark) {
+ return root_find_container(find_by_mark_iterator, mark);
+}
+
+bool container_find_and_unmark(char *mark) {
+ struct sway_container *con = root_find_container(
+ find_by_mark_iterator, mark);
+ if (!con) {
+ return false;
+ }
+
+ for (int i = 0; i < con->marks->length; ++i) {
+ char *con_mark = con->marks->items[i];
+ if (strcmp(con_mark, mark) == 0) {
+ free(con_mark);
+ list_del(con->marks, i);
+ container_update_marks_textures(con);
+ ipc_event_window(con, "mark");
+ return true;
+ }
+ }
+ return false;
+}
+
+void container_clear_marks(struct sway_container *con) {
+ list_foreach(con->marks, free);
+ con->marks->length = 0;
+ ipc_event_window(con, "mark");
+}
+
+bool container_has_mark(struct sway_container *con, char *mark) {
+ for (int i = 0; i < con->marks->length; ++i) {
+ char *item = con->marks->items[i];
+ if (strcmp(item, mark) == 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void container_add_mark(struct sway_container *con, char *mark) {
+ list_add(con->marks, strdup(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] != '_') {
+ sprintf(part, "[%s]", mark);
+ strcat(buffer, part);
+ }
+ }
+ free(part);
+
+ double scale = output->wlr_output->scale;
+ int width = 0;
+ int height = con->title_height * scale;
+
+ cairo_t *c = cairo_create(NULL);
+ get_text_size(c, config->font, &width, NULL, NULL, scale, false,
+ "%s", buffer);
+ cairo_destroy(c);
+
+ cairo_surface_t *surface = cairo_image_surface_create(
+ CAIRO_FORMAT_ARGB32, width, height);
+ cairo_t *cairo = cairo_create(surface);
+ 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_antialias(cairo, CAIRO_ANTIALIAS_BEST);
+ cairo_set_source_rgba(cairo, class->text[0], class->text[1],
+ class->text[2], class->text[3]);
+ cairo_move_to(cairo, 0, 0);
+
+ pango_printf(cairo, config->font, scale, false, "%s", buffer);
+
+ cairo_surface_flush(surface);
+ unsigned char *data = cairo_image_surface_get_data(surface);
+ int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
+ struct wlr_renderer *renderer = wlr_backend_get_renderer(
+ output->wlr_output->backend);
+ *texture = wlr_texture_from_pixels(
+ renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data);
+ cairo_surface_destroy(surface);
+ g_object_unref(pango);
+ cairo_destroy(cairo);
+ 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);
+ container_damage_whole(con);
+}
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,
view->type = type;
view->impl = impl;
view->executed_criteria = create_list();
- view->marks = create_list();
view->allow_request_urgent = true;
wl_signal_init(&view->events.unmap);
}
@@ -55,13 +54,6 @@ void view_destroy(struct sway_view *view) {
}
list_free(view->executed_criteria);
- list_foreach(view->marks, free);
- list_free(view->marks);
-
- wlr_texture_destroy(view->marks_focused);
- wlr_texture_destroy(view->marks_focused_inactive);
- wlr_texture_destroy(view->marks_unfocused);
- wlr_texture_destroy(view->marks_urgent);
free(view->title_format);
if (view->impl->destroy) {
@@ -937,153 +929,6 @@ void view_update_title(struct sway_view *view, bool force) {
ipc_event_window(view->container, "title");
}
-static bool find_by_mark_iterator(struct sway_container *con,
- void *data) {
- char *mark = data;
- return con->view && view_has_mark(con->view, mark);
-}
-
-struct sway_view *view_find_mark(char *mark) {
- struct sway_container *container = root_find_container(
- find_by_mark_iterator, mark);
- if (!container) {
- return NULL;
- }
- return container->view;
-}
-
-bool view_find_and_unmark(char *mark) {
- struct sway_container *container = root_find_container(
- find_by_mark_iterator, mark);
- if (!container) {
- return false;
- }
- struct sway_view *view = container->view;
-
- for (int i = 0; i < view->marks->length; ++i) {
- char *view_mark = view->marks->items[i];
- if (strcmp(view_mark, mark) == 0) {
- free(view_mark);
- list_del(view->marks, i);
- view_update_marks_textures(view);
- ipc_event_window(container, "mark");
- return true;
- }
- }
- return false;
-}
-
-void view_clear_marks(struct sway_view *view) {
- list_foreach(view->marks, free);
- view->marks->length = 0;
- ipc_event_window(view->container, "mark");
-}
-
-bool view_has_mark(struct sway_view *view, char *mark) {
- for (int i = 0; i < view->marks->length; ++i) {
- char *item = view->marks->items[i];
- if (strcmp(item, mark) == 0) {
- return true;
- }
- }
- return false;
-}
-
-void view_add_mark(struct sway_view *view, char *mark) {
- list_add(view->marks, strdup(mark));
- ipc_event_window(view->container, "mark");
-}
-
-static void update_marks_texture(struct sway_view *view,
- struct wlr_texture **texture, struct border_colors *class) {
- struct sway_output *output =
- container_get_effective_output(view->container);
- if (!output) {
- return;
- }
- if (*texture) {
- wlr_texture_destroy(*texture);
- *texture = NULL;
- }
- if (!view->marks->length) {
- return;
- }
-
- size_t len = 0;
- for (int i = 0; i < view->marks->length; ++i) {
- char *mark = view->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 < view->marks->length; ++i) {
- char *mark = view->marks->items[i];
- if (mark[0] != '_') {
- sprintf(part, "[%s]", mark);
- strcat(buffer, part);
- }
- }
- free(part);
-
- double scale = output->wlr_output->scale;
- int width = 0;
- int height = view->container->title_height * scale;
-
- cairo_t *c = cairo_create(NULL);
- get_text_size(c, config->font, &width, NULL, NULL, scale, false,
- "%s", buffer);
- cairo_destroy(c);
-
- cairo_surface_t *surface = cairo_image_surface_create(
- CAIRO_FORMAT_ARGB32, width, height);
- cairo_t *cairo = cairo_create(surface);
- 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_antialias(cairo, CAIRO_ANTIALIAS_BEST);
- cairo_set_source_rgba(cairo, class->text[0], class->text[1],
- class->text[2], class->text[3]);
- cairo_move_to(cairo, 0, 0);
-
- pango_printf(cairo, config->font, scale, false, "%s", buffer);
-
- cairo_surface_flush(surface);
- unsigned char *data = cairo_image_surface_get_data(surface);
- int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
- struct wlr_renderer *renderer = wlr_backend_get_renderer(
- output->wlr_output->backend);
- *texture = wlr_texture_from_pixels(
- renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data);
- cairo_surface_destroy(surface);
- g_object_unref(pango);
- cairo_destroy(cairo);
- free(buffer);
-}
-
-void view_update_marks_textures(struct sway_view *view) {
- if (!config->show_marks) {
- return;
- }
- update_marks_texture(view, &view->marks_focused,
- &config->border_colors.focused);
- update_marks_texture(view, &view->marks_focused_inactive,
- &config->border_colors.focused_inactive);
- update_marks_texture(view, &view->marks_unfocused,
- &config->border_colors.unfocused);
- update_marks_texture(view, &view->marks_urgent,
- &config->border_colors.urgent);
- container_damage_whole(view->container);
-}
-
bool view_is_visible(struct sway_view *view) {
if (view->container->node.destroying) {
return false;