Per application color saturation support (#21)
* Initial implementation without fullscreen support * Limit saturation to 2 * Fixed saturation not working for fullscreen applications like CSGO * Fixed saturation ignoring border radius * Updated README and sway.5 man page * Rebased from Master * Added command to README * Fixed nitpicks
This commit is contained in:
parent
8c907a0bcb
commit
1881b01d3f
|
@ -5,13 +5,17 @@
|
|||
Sway is an incredible window manager, and certainly one of the most well established wayland window managers. However, it is restricted to only include the functionality that existed in i3. This fork ditches the simple wlr_renderer, and replaces it with our fx_renderer, capable of rendering with fancy GLES2 effects. This, along with a couple of minor changes, expands sway's featureset to include the following:
|
||||
|
||||
+ **Anti-aliased rounded corners, borders, and titlebars**
|
||||
+ **Per application saturation control**: Allows the user to set the saturation (Digital Vibrance) for specific applications. Great for some FPS games!
|
||||
+ **Scratchpad treated as minimize**: Allows docks, or panels with a taskbar, to correctly interpret minimize / unminimize requests ([thanks to LCBCrion](https://github.com/swaywm/sway/issues/6457))
|
||||
+ **Add a nix flake to the repo**: Allows nixos users to easily contribute to and test this project
|
||||
|
||||
## New Configuration Options
|
||||
|
||||
+ Corner radius: `corner_radius <val>`
|
||||
+ Application saturation: `for_window [CRITERIA HERE] saturation <set|plus|minus> <val 0.0 <-> 2.0>`
|
||||
|
||||
## Roadmap
|
||||
|
||||
+ fade in / out animations
|
||||
+ window movement animations
|
||||
+ drop shadows
|
||||
|
|
|
@ -159,6 +159,7 @@ sway_cmd cmd_new_float;
|
|||
sway_cmd cmd_new_window;
|
||||
sway_cmd cmd_nop;
|
||||
sway_cmd cmd_opacity;
|
||||
sway_cmd cmd_saturation;
|
||||
sway_cmd cmd_new_float;
|
||||
sway_cmd cmd_new_window;
|
||||
sway_cmd cmd_no_focus;
|
||||
|
|
|
@ -16,6 +16,7 @@ struct gles2_tex_shader {
|
|||
GLint size;
|
||||
GLint position;
|
||||
GLint radius;
|
||||
GLint saturation;
|
||||
GLint has_titlebar;
|
||||
};
|
||||
|
||||
|
@ -79,10 +80,10 @@ void fx_renderer_scissor(struct wlr_box *box);
|
|||
|
||||
bool fx_render_subtexture_with_matrix(struct fx_renderer *renderer, struct wlr_texture *wlr_texture,
|
||||
const struct wlr_fbox *src_box, const struct wlr_box *dst_box, const float matrix[static 9],
|
||||
float alpha, int radius, const bool has_titlebar);
|
||||
float alpha, int radius, float saturation, const bool has_titlebar);
|
||||
|
||||
bool fx_render_texture_with_matrix(struct fx_renderer *renderer, struct wlr_texture *wlr_texture,
|
||||
const struct wlr_box *dst_box, const float matrix[static 9], float alpha, int radius,
|
||||
const struct wlr_box *dst_box, const float matrix[static 9], float alpha, int radius, float saturation,
|
||||
const bool has_titlebar);
|
||||
|
||||
void fx_render_rect(struct fx_renderer *renderer, const struct wlr_box *box,
|
||||
|
|
|
@ -113,6 +113,8 @@ struct sway_container {
|
|||
// Hidden scratchpad containers have a NULL parent.
|
||||
bool scratchpad;
|
||||
|
||||
float saturation;
|
||||
|
||||
float alpha;
|
||||
|
||||
int corner_radius;
|
||||
|
|
|
@ -127,6 +127,7 @@ static const struct cmd_handler command_handlers[] = {
|
|||
{ "reload", cmd_reload },
|
||||
{ "rename", cmd_rename },
|
||||
{ "resize", cmd_resize },
|
||||
{ "saturation", cmd_saturation },
|
||||
{ "scratchpad", cmd_scratchpad },
|
||||
{ "shortcuts_inhibitor", cmd_shortcuts_inhibitor },
|
||||
{ "split", cmd_split },
|
||||
|
|
43
sway/commands/saturation.c
Normal file
43
sway/commands/saturation.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/tree/view.h"
|
||||
#include "log.h"
|
||||
|
||||
struct cmd_results *cmd_saturation(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
if ((error = checkarg(argc, "saturation", EXPECTED_AT_LEAST, 1))) {
|
||||
return error;
|
||||
}
|
||||
|
||||
struct sway_container *con = config->handler_context.container;
|
||||
|
||||
if (con == NULL) {
|
||||
return cmd_results_new(CMD_FAILURE, "No current container");
|
||||
}
|
||||
|
||||
char *err;
|
||||
float val = strtof(argc == 1 ? argv[0] : argv[1], &err);
|
||||
if (*err) {
|
||||
return cmd_results_new(CMD_INVALID, "saturation float invalid");
|
||||
}
|
||||
|
||||
if (!strcasecmp(argv[0], "plus")) {
|
||||
val = con->saturation + val;
|
||||
} else if (!strcasecmp(argv[0], "minus")) {
|
||||
val = con->saturation - val;
|
||||
} else if (argc > 1 && strcasecmp(argv[0], "set")) {
|
||||
return cmd_results_new(CMD_INVALID,
|
||||
"Expected: set|plus|minus <0..2>: %s", argv[0]);
|
||||
}
|
||||
|
||||
if (val < 0 || val > 2) {
|
||||
return cmd_results_new(CMD_FAILURE, "saturation value out of bounds");
|
||||
}
|
||||
|
||||
con->saturation = val;
|
||||
container_damage_whole(con);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
|
@ -99,6 +99,7 @@ bool init_frag_shader(struct gles2_tex_shader *shader, GLuint prog) {
|
|||
shader->size = glGetUniformLocation(prog, "size");
|
||||
shader->position = glGetUniformLocation(prog, "position");
|
||||
shader->radius = glGetUniformLocation(prog, "radius");
|
||||
shader->saturation = glGetUniformLocation(prog, "saturation");
|
||||
shader->has_titlebar = glGetUniformLocation(prog, "has_titlebar");
|
||||
return true;
|
||||
}
|
||||
|
@ -254,8 +255,7 @@ void fx_renderer_scissor(struct wlr_box *box) {
|
|||
|
||||
bool fx_render_subtexture_with_matrix(struct fx_renderer *renderer, struct wlr_texture *wlr_texture,
|
||||
const struct wlr_fbox *src_box, const struct wlr_box *dst_box, const float matrix[static 9],
|
||||
float alpha, int radius, const bool has_titlebar) {
|
||||
|
||||
float alpha, int radius, float saturation, const bool has_titlebar) {
|
||||
assert(wlr_texture_is_gles2(wlr_texture));
|
||||
struct wlr_gles2_texture_attribs texture_attrs;
|
||||
wlr_gles2_texture_get_attribs(wlr_texture, &texture_attrs);
|
||||
|
@ -312,6 +312,7 @@ bool fx_render_subtexture_with_matrix(struct fx_renderer *renderer, struct wlr_t
|
|||
glUniform1i(shader->tex, 0);
|
||||
glUniform1f(shader->alpha, alpha);
|
||||
glUniform1f(shader->has_titlebar, has_titlebar);
|
||||
glUniform1f(shader->saturation, saturation);
|
||||
|
||||
// rounded corners
|
||||
glUniform2f(shader->size, dst_box->width, dst_box->height);
|
||||
|
@ -347,14 +348,14 @@ bool fx_render_subtexture_with_matrix(struct fx_renderer *renderer, struct wlr_t
|
|||
|
||||
bool fx_render_texture_with_matrix(struct fx_renderer *renderer, struct wlr_texture *wlr_texture,
|
||||
const struct wlr_box *dst_box, const float matrix[static 9], float alpha, int radius,
|
||||
const bool has_titlebar) {
|
||||
float saturation, const bool has_titlebar) {
|
||||
struct wlr_fbox src_box = {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = wlr_texture->width,
|
||||
.height = wlr_texture->height,
|
||||
};
|
||||
return fx_render_subtexture_with_matrix(renderer, wlr_texture, &src_box, dst_box, matrix, alpha, radius, has_titlebar);
|
||||
return fx_render_subtexture_with_matrix(renderer, wlr_texture, &src_box, dst_box, matrix, alpha, radius, saturation, has_titlebar);
|
||||
}
|
||||
|
||||
void fx_render_rect(struct fx_renderer *renderer, const struct wlr_box *box,
|
||||
|
|
|
@ -509,7 +509,9 @@ static int output_repaint_timer_handler(void *data) {
|
|||
fullscreen_con = workspace->current.fullscreen;
|
||||
}
|
||||
|
||||
if (fullscreen_con && fullscreen_con->view && !debug.noscanout) {
|
||||
if (fullscreen_con && fullscreen_con->view && !debug.noscanout
|
||||
// Only output to monitor without compositing when saturation is changed
|
||||
&& fullscreen_con->saturation == 1.0f) {
|
||||
// Try to scan-out the fullscreen view
|
||||
static bool last_scanned_out = false;
|
||||
bool scanned_out =
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -32,6 +33,7 @@
|
|||
struct render_data {
|
||||
pixman_region32_t *damage;
|
||||
float alpha;
|
||||
float saturation;
|
||||
int corner_radius;
|
||||
bool has_titlebar;
|
||||
struct wlr_box *clip_box;
|
||||
|
@ -103,7 +105,7 @@ static void set_scale_filter(struct wlr_output *wlr_output,
|
|||
static void render_texture(struct wlr_output *wlr_output,
|
||||
pixman_region32_t *output_damage, struct wlr_texture *texture,
|
||||
const struct wlr_fbox *src_box, const struct wlr_box *dst_box,
|
||||
const float matrix[static 9], float alpha, int corner_radius, bool has_titlebar) {
|
||||
const float matrix[static 9], float alpha, int corner_radius, float saturation, bool has_titlebar) {
|
||||
struct sway_output *output = wlr_output->data;
|
||||
struct fx_renderer *renderer = output->server->renderer;
|
||||
|
||||
|
@ -123,9 +125,11 @@ static void render_texture(struct wlr_output *wlr_output,
|
|||
scissor_output(wlr_output, &rects[i]);
|
||||
set_scale_filter(wlr_output, texture, output->scale_filter);
|
||||
if (src_box != NULL) {
|
||||
fx_render_subtexture_with_matrix(renderer, texture, src_box, dst_box, matrix, alpha, corner_radius, has_titlebar);
|
||||
fx_render_subtexture_with_matrix(renderer, texture, src_box, dst_box, matrix,
|
||||
alpha, corner_radius, saturation, has_titlebar);
|
||||
} else {
|
||||
fx_render_texture_with_matrix(renderer, texture, dst_box, matrix, alpha, corner_radius, has_titlebar);
|
||||
fx_render_texture_with_matrix(renderer, texture, dst_box, matrix,
|
||||
alpha, corner_radius, saturation, has_titlebar);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,6 +144,7 @@ static void render_surface_iterator(struct sway_output *output,
|
|||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
pixman_region32_t *output_damage = data->damage;
|
||||
float alpha = data->alpha;
|
||||
float saturation = data->saturation;
|
||||
int corner_radius = data->corner_radius;
|
||||
bool has_titlebar = data->has_titlebar;
|
||||
|
||||
|
@ -169,7 +174,7 @@ static void render_surface_iterator(struct sway_output *output,
|
|||
scale_box(&dst_box, wlr_output->scale);
|
||||
|
||||
render_texture(wlr_output, output_damage, texture, &src_box, &dst_box,
|
||||
matrix, alpha, corner_radius * wlr_output->scale, has_titlebar);
|
||||
matrix, alpha, corner_radius * wlr_output->scale, saturation, has_titlebar);
|
||||
|
||||
wlr_presentation_surface_sampled_on_output(server.presentation, surface,
|
||||
wlr_output);
|
||||
|
@ -180,6 +185,7 @@ static void render_layer_toplevel(struct sway_output *output,
|
|||
struct render_data data = {
|
||||
.damage = damage,
|
||||
.alpha = 1.0f,
|
||||
.saturation = 1.0f,
|
||||
.corner_radius = 0,
|
||||
.has_titlebar = false,
|
||||
};
|
||||
|
@ -192,6 +198,7 @@ static void render_layer_popups(struct sway_output *output,
|
|||
struct render_data data = {
|
||||
.damage = damage,
|
||||
.alpha = 1.0f,
|
||||
.saturation = 1.0f,
|
||||
.corner_radius = 0,
|
||||
.has_titlebar = false,
|
||||
};
|
||||
|
@ -205,6 +212,7 @@ static void render_unmanaged(struct sway_output *output,
|
|||
struct render_data data = {
|
||||
.damage = damage,
|
||||
.alpha = 1.0f,
|
||||
.saturation = 1.0f,
|
||||
.corner_radius = 0,
|
||||
.has_titlebar = false,
|
||||
};
|
||||
|
@ -218,6 +226,7 @@ static void render_drag_icons(struct sway_output *output,
|
|||
struct render_data data = {
|
||||
.damage = damage,
|
||||
.alpha = 1.0f,
|
||||
.saturation = 1.0f,
|
||||
.corner_radius = 0,
|
||||
.has_titlebar = false,
|
||||
};
|
||||
|
@ -335,10 +344,12 @@ void premultiply_alpha(float color[4], float opacity) {
|
|||
}
|
||||
|
||||
static void render_view_toplevels(struct sway_view *view, struct sway_output *output,
|
||||
pixman_region32_t *damage, float alpha, int corner_radius, bool has_titlebar) {
|
||||
pixman_region32_t *damage, float alpha, int corner_radius,
|
||||
float saturation, bool has_titlebar) {
|
||||
struct render_data data = {
|
||||
.damage = damage,
|
||||
.alpha = alpha,
|
||||
.saturation = saturation,
|
||||
.corner_radius = corner_radius,
|
||||
.has_titlebar = has_titlebar,
|
||||
};
|
||||
|
@ -360,7 +371,8 @@ static void render_view_toplevels(struct sway_view *view, struct sway_output *ou
|
|||
}
|
||||
|
||||
static void render_view_popups(struct sway_view *view, struct sway_output *output,
|
||||
pixman_region32_t *damage, float alpha, int corner_radius, bool has_titlebar) {
|
||||
pixman_region32_t *damage, float alpha, int corner_radius,
|
||||
float saturation, bool has_titlebar) {
|
||||
struct render_data data = {
|
||||
.damage = damage,
|
||||
.alpha = alpha,
|
||||
|
@ -372,7 +384,8 @@ static void render_view_popups(struct sway_view *view, struct sway_output *outpu
|
|||
}
|
||||
|
||||
static void render_saved_view(struct sway_view *view, struct sway_output *output,
|
||||
pixman_region32_t *damage, float alpha, int corner_radius, bool has_titlebar) {
|
||||
pixman_region32_t *damage, float alpha, int corner_radius,
|
||||
float saturation, bool has_titlebar) {
|
||||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
|
||||
if (wl_list_empty(&view->saved_buffers)) {
|
||||
|
@ -424,7 +437,8 @@ static void render_saved_view(struct sway_view *view, struct sway_output *output
|
|||
scale_box(&dst_box, wlr_output->scale);
|
||||
|
||||
render_texture(wlr_output, damage, saved_buf->buffer->texture,
|
||||
&saved_buf->source_box, &dst_box, matrix, alpha, corner_radius * wlr_output->scale, has_titlebar);
|
||||
&saved_buf->source_box, &dst_box, matrix, alpha, corner_radius * wlr_output->scale,
|
||||
saturation, has_titlebar);
|
||||
}
|
||||
|
||||
// FIXME: we should set the surface that this saved buffer originates from
|
||||
|
@ -439,9 +453,11 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage,
|
|||
struct sway_container *con, struct border_colors *colors, bool has_titlebar) {
|
||||
struct sway_view *view = con->view;
|
||||
if (!wl_list_empty(&view->saved_buffers)) {
|
||||
render_saved_view(view, output, damage, con->alpha, con->corner_radius, has_titlebar);
|
||||
render_saved_view(view, output, damage, con->alpha, con->corner_radius,
|
||||
con->saturation, has_titlebar);
|
||||
} else if (view->surface) {
|
||||
render_view_toplevels(view, output, damage, con->alpha, con->corner_radius, has_titlebar);
|
||||
render_view_toplevels(view, output, damage, con->alpha, con->corner_radius,
|
||||
con->saturation, has_titlebar);
|
||||
}
|
||||
|
||||
if (con->current.border == B_NONE || con->current.border == B_CSD) {
|
||||
|
@ -679,7 +695,7 @@ static void render_titlebar(struct sway_output *output,
|
|||
texture_box.width = ob_inner_width;
|
||||
}
|
||||
render_texture(output->wlr_output, output_damage, marks_texture,
|
||||
NULL, &texture_box, matrix, con->alpha, 0, false);
|
||||
NULL, &texture_box, matrix, con->alpha, 0, 1.0f, false);
|
||||
|
||||
// Padding above
|
||||
memcpy(&color, colors->background, sizeof(float) * 4);
|
||||
|
@ -755,7 +771,7 @@ static void render_titlebar(struct sway_output *output,
|
|||
}
|
||||
|
||||
render_texture(output->wlr_output, output_damage, title_texture,
|
||||
NULL, &texture_box, matrix, con->alpha, 0, false);
|
||||
NULL, &texture_box, matrix, con->alpha, 0, 1.0f, false);
|
||||
|
||||
// Padding above
|
||||
memcpy(&color, colors->background, sizeof(float) * 4);
|
||||
|
@ -1274,9 +1290,11 @@ void output_render(struct sway_output *output, struct timespec *when,
|
|||
|
||||
if (fullscreen_con->view) {
|
||||
if (!wl_list_empty(&fullscreen_con->view->saved_buffers)) {
|
||||
render_saved_view(fullscreen_con->view, output, damage, 1.0f, 0, false);
|
||||
render_saved_view(fullscreen_con->view, output, damage, 1.0f, 0,
|
||||
fullscreen_con->saturation, false);
|
||||
} else if (fullscreen_con->view->surface) {
|
||||
render_view_toplevels(fullscreen_con->view, output, damage, 1.0f, 0, false);
|
||||
render_view_toplevels(fullscreen_con->view, output, damage, 1.0f, 0,
|
||||
fullscreen_con->saturation, false);
|
||||
}
|
||||
} else {
|
||||
render_container(output, damage, fullscreen_con,
|
||||
|
@ -1330,7 +1348,7 @@ void output_render(struct sway_output *output, struct timespec *when,
|
|||
struct sway_container *focus = seat_get_focused_container(seat);
|
||||
if (focus && focus->view) {
|
||||
render_view_popups(focus->view, output, damage, focus->alpha,
|
||||
focus->corner_radius, focus->current.border == B_NORMAL);
|
||||
focus->corner_radius, focus->saturation, focus->current.border == B_NORMAL);
|
||||
}
|
||||
|
||||
render_overlay:
|
||||
|
|
|
@ -9,9 +9,20 @@ uniform vec2 size;
|
|||
uniform vec2 position;
|
||||
uniform float radius;
|
||||
uniform bool has_titlebar;
|
||||
uniform float saturation;
|
||||
const vec3 saturation_weight = vec3(0.2125, 0.7154, 0.0721);
|
||||
|
||||
void main() {
|
||||
// Saturation
|
||||
if (saturation != 1.0) {
|
||||
vec4 pixColor = texture2D(texture0, v_texcoord);
|
||||
vec3 irgb = pixColor.rgb;
|
||||
vec3 target = vec3(dot(irgb, saturation_weight));
|
||||
gl_FragColor = vec4(mix(target, irgb, saturation), pixColor.a) * alpha;
|
||||
} else {
|
||||
gl_FragColor = texture2D(texture0, v_texcoord) * alpha;
|
||||
}
|
||||
|
||||
if (!has_titlebar || gl_FragCoord.y - position.y > radius) {
|
||||
vec2 corner_distance = min(gl_FragCoord.xy - position, size + position - gl_FragCoord.xy);
|
||||
if (max(corner_distance.x, corner_distance.y) < radius) {
|
||||
|
|
|
@ -7,9 +7,20 @@ uniform vec2 size;
|
|||
uniform vec2 position;
|
||||
uniform float radius;
|
||||
uniform bool has_titlebar;
|
||||
uniform float saturation;
|
||||
const vec3 saturation_weight = vec3(0.2125, 0.7154, 0.0721);
|
||||
|
||||
void main() {
|
||||
// Saturation
|
||||
if (saturation != 1.0) {
|
||||
vec4 pixColor = texture2D(tex, v_texcoord);
|
||||
vec3 irgb = pixColor.rgb;
|
||||
vec3 target = vec3(dot(irgb, saturation_weight));
|
||||
gl_FragColor = vec4(mix(target, irgb, saturation), pixColor.a) * alpha;
|
||||
} else {
|
||||
gl_FragColor = texture2D(tex, v_texcoord) * alpha;
|
||||
}
|
||||
|
||||
if (!has_titlebar || gl_FragCoord.y - position.y > radius) {
|
||||
vec2 corner_distance = min(gl_FragCoord.xy - position, size + position - gl_FragCoord.xy);
|
||||
if (max(corner_distance.x, corner_distance.y) < radius) {
|
||||
|
|
|
@ -7,9 +7,19 @@ uniform vec2 size;
|
|||
uniform vec2 position;
|
||||
uniform float radius;
|
||||
uniform bool has_titlebar;
|
||||
uniform float saturation;
|
||||
const vec3 saturation_weight = vec3(0.2125, 0.7154, 0.0721);
|
||||
|
||||
void main() {
|
||||
// Saturation
|
||||
if (saturation != 1.0) {
|
||||
vec3 irgb = texture2D(tex, v_texcoord).rgb;
|
||||
vec3 target = vec3(dot(irgb, saturation_weight));
|
||||
gl_FragColor = vec4(mix(target, irgb, saturation), 1.0) * alpha;
|
||||
} else {
|
||||
gl_FragColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0) * alpha;
|
||||
}
|
||||
|
||||
if (!has_titlebar || gl_FragCoord.y - position.y > radius) {
|
||||
vec2 corner_distance = min(gl_FragCoord.xy - position, size + position - gl_FragCoord.xy);
|
||||
if (max(corner_distance.x, corner_distance.y) < radius) {
|
||||
|
|
|
@ -73,6 +73,7 @@ sway_sources = files(
|
|||
'commands/mark.c',
|
||||
'commands/max_render_time.c',
|
||||
'commands/opacity.c',
|
||||
'commands/saturation.c',
|
||||
'commands/include.c',
|
||||
'commands/input.c',
|
||||
'commands/layout.c',
|
||||
|
|
|
@ -767,6 +767,11 @@ The default colors are:
|
|||
Adjusts the opacity of the window between 0 (completely transparent) and
|
||||
1 (completely opaque). If the operation is omitted, _set_ will be used.
|
||||
|
||||
*saturation* [set|plus|minus] <value>
|
||||
Adjusts the saturation (Digital Vibrance) of the window between 0 (black and
|
||||
white) and 2 (over saturated which is suited for some FPS games) while 1 is
|
||||
the default saturation. If the operation is omitted, _set_ will be used.
|
||||
|
||||
*tiling_drag* enable|disable|toggle
|
||||
Sets whether or not tiling containers can be dragged with the mouse. If
|
||||
_enabled_ (default), the _floating_mod_ can be used to drag tiling, as well
|
||||
|
|
|
@ -40,6 +40,7 @@ struct sway_container *container_create(struct sway_view *view) {
|
|||
c->pending.layout = L_NONE;
|
||||
c->view = view;
|
||||
c->alpha = 1.0f;
|
||||
c->saturation = 1.0f;
|
||||
c->corner_radius = config->corner_radius;
|
||||
|
||||
if (!view) {
|
||||
|
|
Loading…
Reference in a new issue