Merge pull request #1982 from RyanDwyer/show-marks

Implement show_marks
This commit is contained in:
Drew DeVault 2018-05-16 21:54:16 -04:00 committed by GitHub
commit c2c5a3f5f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 282 additions and 64 deletions

View file

@ -63,6 +63,11 @@ struct sway_view {
list_t *executed_criteria; // struct criteria * list_t *executed_criteria; // struct criteria *
list_t *marks; // char * 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 { union {
struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6; struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6;
struct wlr_xdg_surface *wlr_xdg_surface; struct wlr_xdg_surface *wlr_xdg_surface;
@ -267,4 +272,6 @@ void view_clear_marks(struct sway_view *view);
bool view_has_mark(struct sway_view *view, char *mark); bool view_has_mark(struct sway_view *view, char *mark);
void view_update_marks_textures(struct sway_view *view);
#endif #endif

View file

@ -116,6 +116,7 @@ static struct cmd_handler handlers[] = {
{ "mouse_warping", cmd_mouse_warping }, { "mouse_warping", cmd_mouse_warping },
{ "output", cmd_output }, { "output", cmd_output },
{ "seat", cmd_seat }, { "seat", cmd_seat },
{ "show_marks", cmd_show_marks },
{ "workspace", cmd_workspace }, { "workspace", cmd_workspace },
{ "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth }, { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth },
}; };

View file

@ -62,6 +62,7 @@ struct cmd_results *cmd_mark(int argc, char **argv) {
} }
free(mark); free(mark);
view_update_marks_textures(view);
view_execute_criteria(view); view_execute_criteria(view);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);

View file

@ -0,0 +1,43 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/tree/view.h"
#include "sway/output.h"
#include "list.h"
#include "log.h"
#include "stringop.h"
static void rebuild_marks_iterator(struct sway_container *con, void *data) {
if (con->type == C_VIEW) {
view_update_marks_textures(con->sway_view);
}
}
struct cmd_results *cmd_show_marks(int argc, char **argv) {
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "show_marks", EXPECTED_AT_LEAST, 1))) {
return error;
}
if (strcmp(*argv, "yes") == 0) {
config->show_marks = true;
} else if (strcmp(*argv, "no") == 0) {
config->show_marks = false;
} else {
return cmd_results_new(CMD_INVALID, "show_marks",
"Expected 'show_marks <yes|no>'");
}
if (config->show_marks) {
container_for_each_descendant_dfs(&root_container,
rebuild_marks_iterator, NULL);
}
for (int i = 0; i < root_container.children->length; ++i) {
struct sway_container *con = root_container.children->items[i];
output_damage_whole(con->sway_output);
}
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}

View file

@ -10,6 +10,7 @@
static void remove_all_marks_iterator(struct sway_container *con, void *data) { static void remove_all_marks_iterator(struct sway_container *con, void *data) {
if (con->type == C_VIEW) { if (con->type == C_VIEW) {
view_clear_marks(con->sway_view); view_clear_marks(con->sway_view);
view_update_marks_textures(con->sway_view);
} }
} }
@ -45,6 +46,7 @@ struct cmd_results *cmd_unmark(int argc, char **argv) {
} else if (view && !mark) { } else if (view && !mark) {
// Clear all marks from the given view // Clear all marks from the given view
view_clear_marks(view); view_clear_marks(view);
view_update_marks_textures(view);
} else if (!view && mark) { } else if (!view && mark) {
// Remove mark from whichever view has it // Remove mark from whichever view has it
view_find_and_unmark(mark); view_find_and_unmark(mark);

View file

@ -287,7 +287,6 @@ static void render_rect(struct wlr_output *wlr_output,
wlr_backend_get_renderer(wlr_output->backend); wlr_backend_get_renderer(wlr_output->backend);
struct wlr_box box = *_box; struct wlr_box box = *_box;
scale_box(&box, wlr_output->scale);
pixman_region32_t damage; pixman_region32_t damage;
pixman_region32_init(&damage); pixman_region32_init(&damage);
@ -313,26 +312,33 @@ damage_finish:
/** /**
* Render decorations for a view with "border normal". * Render decorations for a view with "border normal".
*
* Care must be taken not to render over the same pixel multiple times,
* otherwise the colors will be incorrect when using opacity.
*/ */
static void render_container_simple_border_normal(struct sway_output *output, static void render_container_simple_border_normal(struct sway_output *output,
pixman_region32_t *output_damage, pixman_region32_t *output_damage,
struct sway_container *con, struct border_colors *colors, struct sway_container *con, struct border_colors *colors,
struct wlr_texture *title_texture) { struct wlr_texture *title_texture, struct wlr_texture *marks_texture) {
struct wlr_box box; struct wlr_box box;
float color[4]; float color[4];
struct sway_view *view = con->sway_view;
float output_scale = output->wlr_output->scale;
if (con->sway_view->border_left) { if (view->border_left) {
// Child border - left edge // Child border - left edge
memcpy(&color, colors->child_border, sizeof(float) * 4); memcpy(&color, colors->child_border, sizeof(float) * 4);
color[3] *= con->alpha; color[3] *= con->alpha;
box.x = con->x; box.x = con->x;
box.y = con->y + 1; box.y = con->y + 1;
box.width = con->sway_view->border_thickness; box.width = view->border_thickness;
box.height = con->height - 1; box.height = con->height - 1
- view->border_thickness * view->border_bottom;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color); render_rect(output->wlr_output, output_damage, &box, color);
} }
if (con->sway_view->border_right) { if (view->border_right) {
// Child border - right edge // Child border - right edge
if (con->parent->children->length == 1 if (con->parent->children->length == 1
&& con->parent->layout == L_HORIZ) { && con->parent->layout == L_HORIZ) {
@ -341,14 +347,16 @@ static void render_container_simple_border_normal(struct sway_output *output,
memcpy(&color, colors->child_border, sizeof(float) * 4); memcpy(&color, colors->child_border, sizeof(float) * 4);
} }
color[3] *= con->alpha; color[3] *= con->alpha;
box.x = con->x + con->width - con->sway_view->border_thickness; box.x = con->x + con->width - view->border_thickness;
box.y = con->y + 1; box.y = con->y + 1;
box.width = con->sway_view->border_thickness; box.width = view->border_thickness;
box.height = con->height - 1; box.height = con->height - 1
- view->border_thickness * view->border_bottom;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color); render_rect(output->wlr_output, output_damage, &box, color);
} }
if (con->sway_view->border_bottom) { if (view->border_bottom) {
// Child border - bottom edge // Child border - bottom edge
if (con->parent->children->length == 1 if (con->parent->children->length == 1
&& con->parent->layout == L_VERT) { && con->parent->layout == L_VERT) {
@ -358,9 +366,10 @@ static void render_container_simple_border_normal(struct sway_output *output,
} }
color[3] *= con->alpha; color[3] *= con->alpha;
box.x = con->x; box.x = con->x;
box.y = con->y + con->height - con->sway_view->border_thickness; box.y = con->y + con->height - view->border_thickness;
box.width = con->width; box.width = con->width;
box.height = con->sway_view->border_thickness; box.height = view->border_thickness;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color); render_rect(output->wlr_output, output_damage, &box, color);
} }
@ -371,71 +380,118 @@ static void render_container_simple_border_normal(struct sway_output *output,
box.y = con->y; box.y = con->y;
box.width = con->width; box.width = con->width;
box.height = 1; box.height = 1;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color); render_rect(output->wlr_output, output_damage, &box, color);
// Single pixel bar below title // Single pixel bar below title
memcpy(&color, colors->border, sizeof(float) * 4); memcpy(&color, colors->border, sizeof(float) * 4);
color[3] *= con->alpha; color[3] *= con->alpha;
box.x = con->x + con->sway_view->border_thickness; box.x = con->x + view->border_thickness;
box.y = con->sway_view->y - 1; box.y = view->y - 1;
box.width = con->width - con->sway_view->border_thickness * 2; box.width = con->width - view->border_thickness * 2;
box.height = 1; box.height = 1;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color); render_rect(output->wlr_output, output_damage, &box, color);
// Title background // Setting these makes marks and title easier
memcpy(&color, colors->background, sizeof(float) * 4); size_t inner_x = con->x + view->border_thickness * view->border_left;
color[3] *= con->alpha; size_t inner_width = con->width - view->border_thickness * view->border_left
box.x = con->x - view->border_thickness * view->border_right;
+ con->sway_view->border_thickness * con->sway_view->border_left;
box.y = con->y + 1;
box.width = con->width
- con->sway_view->border_thickness * con->sway_view->border_left
- con->sway_view->border_thickness * con->sway_view->border_right;
box.height = con->sway_view->y - con->y - 2;
render_rect(output->wlr_output, output_damage, &box, color);
// Title text // Marks
if (title_texture) { size_t marks_width = 0;
float output_scale = output->wlr_output->scale; if (config->show_marks && marks_texture) {
struct wlr_box texture_box = { struct wlr_box texture_box;
.x = box.x * output_scale, wlr_texture_get_size(marks_texture,
.y = box.y * output_scale,
};
wlr_texture_get_size(title_texture,
&texture_box.width, &texture_box.height); &texture_box.width, &texture_box.height);
texture_box.x = (inner_x + inner_width) * output_scale - texture_box.width;
texture_box.y = (con->y + view->border_thickness) * output_scale;
float matrix[9]; float matrix[9];
wlr_matrix_project_box(matrix, &texture_box, wlr_matrix_project_box(matrix, &texture_box,
WL_OUTPUT_TRANSFORM_NORMAL, WL_OUTPUT_TRANSFORM_NORMAL,
0.0, output->wlr_output->transform_matrix); 0.0, output->wlr_output->transform_matrix);
texture_box.width = box.width * output_scale; render_texture(output->wlr_output, output_damage, marks_texture,
&texture_box, matrix, con->alpha);
marks_width = texture_box.width;
}
// Title text
size_t title_width = 0;
if (title_texture) {
struct wlr_box texture_box;
wlr_texture_get_size(title_texture,
&texture_box.width, &texture_box.height);
texture_box.x = inner_x * output_scale;
texture_box.y = (con->y + view->border_thickness) * output_scale;
float matrix[9];
wlr_matrix_project_box(matrix, &texture_box,
WL_OUTPUT_TRANSFORM_NORMAL,
0.0, output->wlr_output->transform_matrix);
if (inner_width * output_scale - marks_width < texture_box.width) {
texture_box.width = inner_width * output_scale - marks_width;
}
render_texture(output->wlr_output, output_damage, title_texture, render_texture(output->wlr_output, output_damage, title_texture,
&texture_box, matrix, 1.0); &texture_box, matrix, con->alpha);
title_width = texture_box.width;
}
// Title background - above the text
memcpy(&color, colors->background, sizeof(float) * 4);
color[3] *= con->alpha;
box.x = inner_x;
box.y = con->y + 1;
box.width = inner_width;
box.height = view->border_thickness - 1;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color);
// Title background - below the text
box.y = (con->y + view->border_thickness + config->font_height)
* output_scale;
render_rect(output->wlr_output, output_damage, &box, color);
// Title background - filler between title and marks
box.width = inner_width * output_scale - title_width - marks_width;
if (box.width > 0) {
box.x = inner_x * output_scale + title_width;
box.y = (con->y + view->border_thickness) * output_scale;
box.height = config->font_height * output_scale;
render_rect(output->wlr_output, output_damage, &box, color);
} }
} }
/** /**
* Render decorations for a view with "border pixel". * Render decorations for a view with "border pixel".
*
* Care must be taken not to render over the same pixel multiple times,
* otherwise the colors will be incorrect when using opacity.
*/ */
static void render_container_simple_border_pixel(struct sway_output *output, static void render_container_simple_border_pixel(struct sway_output *output,
pixman_region32_t *output_damage, struct sway_container *con, pixman_region32_t *output_damage, struct sway_container *con,
struct border_colors *colors) { struct border_colors *colors) {
struct wlr_box box; struct wlr_box box;
float color[4]; float color[4];
struct sway_view *view = con->sway_view;
float output_scale = output->wlr_output->scale;
if (con->sway_view->border_left) { if (view->border_left) {
// Child border - left edge // Child border - left edge
memcpy(&color, colors->child_border, sizeof(float) * 4); memcpy(&color, colors->child_border, sizeof(float) * 4);
color[3] *= con->alpha; color[3] *= con->alpha;
box.x = con->x; box.x = con->x;
box.y = con->y; box.y = con->y + view->border_thickness * view->border_top;
box.width = con->sway_view->border_thickness; box.width = view->border_thickness;
box.height = con->height; box.height = con->height - view->border_thickness
* (view->border_top + view->border_bottom);
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color); render_rect(output->wlr_output, output_damage, &box, color);
} }
if (con->sway_view->border_right) { if (view->border_right) {
// Child border - right edge // Child border - right edge
if (con->parent->children->length == 1 if (con->parent->children->length == 1
&& con->parent->layout == L_HORIZ) { && con->parent->layout == L_HORIZ) {
@ -444,25 +500,28 @@ static void render_container_simple_border_pixel(struct sway_output *output,
memcpy(&color, colors->child_border, sizeof(float) * 4); memcpy(&color, colors->child_border, sizeof(float) * 4);
} }
color[3] *= con->alpha; color[3] *= con->alpha;
box.x = con->x + con->width - con->sway_view->border_thickness; box.x = con->x + con->width - view->border_thickness;
box.y = con->y; box.y = con->y + view->border_thickness * view->border_top;
box.width = con->sway_view->border_thickness; box.width = view->border_thickness;
box.height = con->height; box.height = con->height - view->border_thickness
* (view->border_top + view->border_bottom);
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color); render_rect(output->wlr_output, output_damage, &box, color);
} }
if (con->sway_view->border_top) { if (view->border_top) {
// Child border - top edge // Child border - top edge
memcpy(&color, colors->child_border, sizeof(float) * 4); memcpy(&color, colors->child_border, sizeof(float) * 4);
color[3] *= con->alpha; color[3] *= con->alpha;
box.x = con->x; box.x = con->x;
box.y = con->y; box.y = con->y;
box.width = con->width; box.width = con->width;
box.height = con->sway_view->border_thickness; box.height = view->border_thickness;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color); render_rect(output->wlr_output, output_damage, &box, color);
} }
if (con->sway_view->border_bottom) { if (view->border_bottom) {
// Child border - bottom edge // Child border - bottom edge
if (con->parent->children->length == 1 if (con->parent->children->length == 1
&& con->parent->layout == L_VERT) { && con->parent->layout == L_VERT) {
@ -472,9 +531,10 @@ static void render_container_simple_border_pixel(struct sway_output *output,
} }
color[3] *= con->alpha; color[3] *= con->alpha;
box.x = con->x; box.x = con->x;
box.y = con->y + con->height - con->sway_view->border_thickness; box.y = con->y + con->height - view->border_thickness;
box.width = con->width; box.width = con->width;
box.height = con->sway_view->border_thickness; box.height = view->border_thickness;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color); render_rect(output->wlr_output, output_damage, &box, color);
} }
} }
@ -501,20 +561,24 @@ static void render_container_simple(struct sway_output *output,
if (child->sway_view->border != B_NONE) { if (child->sway_view->border != B_NONE) {
struct border_colors *colors; struct border_colors *colors;
struct wlr_texture *title_texture; struct wlr_texture *title_texture;
struct wlr_texture *marks_texture;
if (focus == child || parent_focused) { if (focus == child || parent_focused) {
colors = &config->border_colors.focused; colors = &config->border_colors.focused;
title_texture = child->title_focused; title_texture = child->title_focused;
marks_texture = child->sway_view->marks_focused;
} else if (seat_get_focus_inactive(seat, con) == child) { } else if (seat_get_focus_inactive(seat, con) == child) {
colors = &config->border_colors.focused_inactive; colors = &config->border_colors.focused_inactive;
title_texture = child->title_focused_inactive; title_texture = child->title_focused_inactive;
marks_texture = child->sway_view->marks_focused_inactive;
} else { } else {
colors = &config->border_colors.unfocused; colors = &config->border_colors.unfocused;
title_texture = child->title_unfocused; title_texture = child->title_unfocused;
marks_texture = child->sway_view->marks_unfocused;
} }
if (child->sway_view->border == B_NORMAL) { if (child->sway_view->border == B_NORMAL) {
render_container_simple_border_normal(output, damage, render_container_simple_border_normal(output, damage,
child, colors, title_texture); child, colors, title_texture, marks_texture);
} else { } else {
render_container_simple_border_pixel(output, damage, child, render_container_simple_border_pixel(output, damage, child,
colors); colors);
@ -898,10 +962,15 @@ static void handle_transform(struct wl_listener *listener, void *data) {
arrange_output(output->swayc); arrange_output(output->swayc);
} }
static void handle_scale_iterator(struct sway_container *view, void *data) {
view_update_marks_textures(view->sway_view);
}
static void handle_scale(struct wl_listener *listener, void *data) { static void handle_scale(struct wl_listener *listener, void *data) {
struct sway_output *output = wl_container_of(listener, output, scale); struct sway_output *output = wl_container_of(listener, output, scale);
arrange_layers(output); arrange_layers(output);
arrange_output(output->swayc); arrange_output(output->swayc);
container_descendants(output->swayc, C_VIEW, handle_scale_iterator, NULL);
} }
void handle_new_output(struct wl_listener *listener, void *data) { void handle_new_output(struct wl_listener *listener, void *data) {

View file

@ -60,6 +60,7 @@ sway_sources = files(
'commands/seat/cursor.c', 'commands/seat/cursor.c',
'commands/seat/fallback.c', 'commands/seat/fallback.c',
'commands/set.c', 'commands/set.c',
'commands/show_marks.c',
'commands/split.c', 'commands/split.c',
'commands/swaybg_command.c', 'commands/swaybg_command.c',
'commands/title_format.c', 'commands/title_format.c',

View file

@ -174,7 +174,7 @@ runtime.
Assigns views matching _criteria_ (see *CRITERIA* for details) to Assigns views matching _criteria_ (see *CRITERIA* for details) to
_workspace_. The → (U+2192) is optional and cosmetic. This command is _workspace_. The → (U+2192) is optional and cosmetic. This command is
equivalent to: equivalent to:
for\_window <criteria> move container to workspace <workspace> for\_window <criteria> move container to workspace <workspace>
*bindsym* <key combo> <command> *bindsym* <key combo> <command>
@ -238,7 +238,7 @@ The default colors are:
[- *class* [- *class*
:[ _border_ :[ _border_
:[ _background_ :[ _background_
:[ _text_ :[ _text_
:[ _indicator_ :[ _indicator_
:[ _child\_border_ :[ _child\_border_
|[ *background* |[ *background*
@ -451,10 +451,10 @@ You can get a list of output names with *swaymsg -t get\_outputs*. You may also
match any output by using the output name "\*". Be sure to add this output match any output by using the output name "\*". Be sure to add this output
config after the others, or it will be matched instead of the others. config after the others, or it will be matched instead of the others.
*show\_marks* on|off *show\_marks* yes|no
If *show\_marks* is on, marks will be displayed in the window borders. If *show\_marks* is yes, marks will be displayed in the window borders.
Any mark that starts with an underscore will not be drawn even if the Any mark that starts with an underscore will not be drawn even if
option is on. The default is _on_. *show\_marks* is yes. The default is _yes_.
*opacity* <value> *opacity* <value>
Set the opacity of the window between 0 (completely transparent) and 1 Set the opacity of the window between 0 (completely transparent) and 1

View file

@ -123,13 +123,12 @@ static void _container_destroy(struct sway_container *cont) {
if (cont->name) { if (cont->name) {
free(cont->name); free(cont->name);
} }
if (cont->title_focused) {
// If one is set then all of these are set wlr_texture_destroy(cont->title_focused);
wlr_texture_destroy(cont->title_focused); wlr_texture_destroy(cont->title_focused_inactive);
wlr_texture_destroy(cont->title_focused_inactive); wlr_texture_destroy(cont->title_unfocused);
wlr_texture_destroy(cont->title_unfocused); wlr_texture_destroy(cont->title_urgent);
wlr_texture_destroy(cont->title_urgent);
}
list_free(cont->children); list_free(cont->children);
cont->children = NULL; cont->children = NULL;
free(cont); free(cont);
@ -592,6 +591,7 @@ static void update_title_texture(struct sway_container *con,
} }
if (*texture) { if (*texture) {
wlr_texture_destroy(*texture); wlr_texture_destroy(*texture);
*texture = NULL;
} }
if (!con->formatted_title) { if (!con->formatted_title) {
return; return;

View file

@ -43,6 +43,11 @@ void view_destroy(struct sway_view *view) {
} }
list_free(view->marks); 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);
container_destroy(view->swayc); container_destroy(view->swayc);
if (view->impl->destroy) { if (view->impl->destroy) {
@ -746,6 +751,7 @@ bool view_find_and_unmark(char *mark) {
if (strcmp(view_mark, mark) == 0) { if (strcmp(view_mark, mark) == 0) {
free(view_mark); free(view_mark);
list_del(view->marks, i); list_del(view->marks, i);
view_update_marks_textures(view);
return true; return true;
} }
} }
@ -769,3 +775,91 @@ bool view_has_mark(struct sway_view *view, char *mark) {
} }
return false; return false;
} }
static void update_marks_texture(struct sway_view *view,
struct wlr_texture **texture, struct border_colors *class) {
struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
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->sway_output->wlr_output->scale;
int width = 0;
int height = config->font_height * scale;
cairo_t *c = cairo_create(NULL);
get_text_size(c, config->font, &width, 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->sway_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->swayc);
}