diff options
author | Erik Reider <[email protected]> | 2022-12-07 06:10:11 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2022-12-07 00:10:11 -0500 |
commit | 988fb247107c469bb98ce3088ad189fa12db7cdd (patch) | |
tree | 67eafa3aef85ccb450adb3a46ed313c4ae32db6d /sway | |
parent | e82e4de37f5c6fe184da62f228329a37517ccd55 (diff) |
[Feature] Dim inactive windows (#66)
Diffstat (limited to 'sway')
-rw-r--r-- | sway/commands.c | 3 | ||||
-rw-r--r-- | sway/commands/dim_inactive.c | 29 | ||||
-rw-r--r-- | sway/commands/dim_inactive_colors.c | 40 | ||||
-rw-r--r-- | sway/config.c | 3 | ||||
-rw-r--r-- | sway/desktop/fx_renderer.c | 6 | ||||
-rw-r--r-- | sway/desktop/render.c | 22 | ||||
-rw-r--r-- | sway/desktop/shaders/tex_external.frag | 9 | ||||
-rw-r--r-- | sway/desktop/shaders/tex_rgba.frag | 9 | ||||
-rw-r--r-- | sway/desktop/shaders/tex_rgbx.frag | 9 | ||||
-rw-r--r-- | sway/meson.build | 2 | ||||
-rw-r--r-- | sway/sway.5.scd | 10 |
11 files changed, 133 insertions, 9 deletions
diff --git a/sway/commands.c b/sway/commands.c index 986da495..91e559a1 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -58,6 +58,9 @@ static const struct cmd_handler handlers[] = { { "corner_radius", cmd_corner_radius }, { "default_border", cmd_default_border }, { "default_floating_border", cmd_default_floating_border }, + { "dim_inactive", cmd_dim_inactive }, + { "dim_inactive_colors.unfocused", cmd_dim_inactive_colors_unfocused }, + { "dim_inactive_colors.urgent", cmd_dim_inactive_colors_urgent }, { "exec", cmd_exec }, { "exec_always", cmd_exec_always }, { "floating_maximum_size", cmd_floating_maximum_size }, diff --git a/sway/commands/dim_inactive.c b/sway/commands/dim_inactive.c new file mode 100644 index 00000000..c7c03caa --- /dev/null +++ b/sway/commands/dim_inactive.c @@ -0,0 +1,29 @@ +#include <string.h> +#include "sway/commands.h" +#include "sway/config.h" +#include "log.h" +#include "sway/output.h" + +struct cmd_results *cmd_dim_inactive(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "dim_inactive", EXPECTED_EQUAL_TO, 1))) { + return error; + } + + char *err; + float val = strtof(argv[0], &err); + if (*err || val < 0.0f || val > 1.0f) { + return cmd_results_new(CMD_INVALID, "dim_inactive float invalid"); + } + + config->dim_inactive = val; + + if (config->active) { + for (int i = 0; i < root->outputs->length; ++i) { + struct sway_output *output = root->outputs->items[i]; + output_damage_whole(output); + } + } + + return cmd_results_new(CMD_SUCCESS, NULL); +} diff --git a/sway/commands/dim_inactive_colors.c b/sway/commands/dim_inactive_colors.c new file mode 100644 index 00000000..db8cc299 --- /dev/null +++ b/sway/commands/dim_inactive_colors.c @@ -0,0 +1,40 @@ +#include "log.h" +#include "sway/commands.h" +#include "sway/config.h" +#include "sway/output.h" +#include "sway/tree/container.h" +#include "util.h" + +static struct cmd_results *handle_command(int argc, char **argv, char *cmd_name, + float config_option[4]) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, cmd_name, EXPECTED_AT_LEAST, 1))) { + return error; + } + + uint32_t color; + if (!parse_color(argv[0], &color)) { + return cmd_results_new(CMD_INVALID, "Invalid %s color %s", + cmd_name, argv[0]); + } + color_to_rgba(config_option, color); + + if (config->active) { + for (int i = 0; i < root->outputs->length; ++i) { + struct sway_output *output = root->outputs->items[i]; + output_damage_whole(output); + } + } + + return cmd_results_new(CMD_SUCCESS, NULL); +} + +struct cmd_results *cmd_dim_inactive_colors_unfocused(int argc, char **argv) { + return handle_command(argc, argv, "dim_inactive_colors.unfocused", + config->dim_inactive_colors.unfocused); +} + +struct cmd_results *cmd_dim_inactive_colors_urgent(int argc, char **argv) { + return handle_command(argc, argv, "dim_inactive_colors.urgent", + config->dim_inactive_colors.urgent); +} diff --git a/sway/config.c b/sway/config.c index 47f80ce7..a9eaaf82 100644 --- a/sway/config.c +++ b/sway/config.c @@ -327,6 +327,9 @@ static void config_defaults(struct sway_config *config) { // SwayFX defaults config->corner_radius = 0; + config->dim_inactive = 1.0f; + color_to_rgba(config->dim_inactive_colors.unfocused, 0x000000FF); + color_to_rgba(config->dim_inactive_colors.urgent, 0x900000FF); // The keysym to keycode translation struct xkb_rule_names rules = {0}; diff --git a/sway/desktop/fx_renderer.c b/sway/desktop/fx_renderer.c index a8dfa561..f2436e96 100644 --- a/sway/desktop/fx_renderer.c +++ b/sway/desktop/fx_renderer.c @@ -95,6 +95,8 @@ bool init_frag_shader(struct gles2_tex_shader *shader, GLuint prog) { shader->proj = glGetUniformLocation(prog, "proj"); shader->tex = glGetUniformLocation(prog, "tex"); shader->alpha = glGetUniformLocation(prog, "alpha"); + shader->dim = glGetUniformLocation(prog, "dim"); + shader->dim_color = glGetUniformLocation(prog, "dim_color"); shader->pos_attrib = glGetAttribLocation(prog, "pos"); shader->tex_attrib = glGetAttribLocation(prog, "texcoord"); shader->size = glGetUniformLocation(prog, "size"); @@ -345,11 +347,15 @@ bool fx_render_subtexture_with_matrix(struct fx_renderer *renderer, struct wlr_t glUseProgram(shader->program); + float* dim_color = deco_data.dim_color; + glUniformMatrix3fv(shader->proj, 1, GL_FALSE, gl_matrix); glUniform1i(shader->tex, 0); glUniform2f(shader->size, dst_box->width, dst_box->height); glUniform2f(shader->position, dst_box->x, dst_box->y); glUniform1f(shader->alpha, deco_data.alpha); + glUniform1f(shader->dim, deco_data.dim); + glUniform4f(shader->dim_color, dim_color[0], dim_color[1], dim_color[2], dim_color[3]); glUniform1f(shader->has_titlebar, deco_data.has_titlebar); glUniform1f(shader->saturation, deco_data.saturation); glUniform1f(shader->radius, deco_data.corner_radius); diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 3ee719b6..fd42cbbb 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -39,6 +39,8 @@ struct render_data { struct decoration_data get_undecorated_decoration_data() { return (struct decoration_data) { .alpha = 1.0f, + .dim = 0.0f, + .dim_color = config->dim_inactive_colors.unfocused, .corner_radius = 0, .saturation = 1.0f, .has_titlebar = false, @@ -945,6 +947,10 @@ static void render_containers_linear(struct sway_output *output, bool has_titlebar = state->border == B_NORMAL; struct decoration_data deco_data = { .alpha = child->alpha, + .dim_color = view_is_urgent(view) + ? config->dim_inactive_colors.urgent + : config->dim_inactive_colors.unfocused, + .dim = child->current.focused ? 0.0f: config->dim_inactive, // no corner radius if smart gaps are on and only visible view .corner_radius = config->smart_gaps == SMART_GAPS_ON && view_ancestor_is_only_visible(view) ? 0 : child->corner_radius, @@ -1038,6 +1044,10 @@ static void render_containers_tabbed(struct sway_output *output, if (current->view) { struct decoration_data deco_data = { .alpha = current->alpha, + .dim_color = view_is_urgent(current->view) + ? config->dim_inactive_colors.urgent + : config->dim_inactive_colors.unfocused, + .dim = current->current.focused ? 0.0f: config->dim_inactive, .corner_radius = current->corner_radius, .saturation = current->saturation, .has_titlebar = true, @@ -1107,6 +1117,10 @@ static void render_containers_stacked(struct sway_output *output, if (current->view) { struct decoration_data deco_data = { .alpha = current->alpha, + .dim_color = view_is_urgent(current->view) + ? config->dim_inactive_colors.urgent + : config->dim_inactive_colors.unfocused, + .dim = current->current.focused ? 0.0f: config->dim_inactive, .saturation = current->saturation, .corner_radius = current->corner_radius, .has_titlebar = true, @@ -1203,6 +1217,10 @@ static void render_floating_container(struct sway_output *soutput, bool has_titlebar = state->border == B_NORMAL; struct decoration_data deco_data = { .alpha = con->alpha, + .dim_color = view_is_urgent(view) + ? config->dim_inactive_colors.urgent + : config->dim_inactive_colors.unfocused, + .dim = con->current.focused ? 0.0f: config->dim_inactive, .saturation = con->saturation, .corner_radius = con->corner_radius, .has_titlebar = has_titlebar, @@ -1355,6 +1373,10 @@ void output_render(struct sway_output *output, struct timespec *when, if (focus && focus->view) { struct decoration_data deco_data = { .alpha = focus->alpha, + .dim_color = view_is_urgent(focus->view) + ? config->dim_inactive_colors.urgent + : config->dim_inactive_colors.unfocused, + .dim = focus->current.focused ? 0.0f: config->dim_inactive, .corner_radius = focus->corner_radius, .saturation = focus->saturation, .has_titlebar = focus->current.border == B_NORMAL, diff --git a/sway/desktop/shaders/tex_external.frag b/sway/desktop/shaders/tex_external.frag index d31cc990..9976eb51 100644 --- a/sway/desktop/shaders/tex_external.frag +++ b/sway/desktop/shaders/tex_external.frag @@ -4,6 +4,8 @@ precision mediump float; varying vec2 v_texcoord; uniform samplerExternalOES texture0; uniform float alpha; +uniform float dim; +uniform vec4 dim_color; uniform vec2 size; uniform vec2 position; @@ -13,15 +15,16 @@ uniform float saturation; const vec3 saturation_weight = vec3(0.2125, 0.7154, 0.0721); void main() { + vec4 color = texture2D(texture0, v_texcoord); // 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; + color = vec4(mix(target, irgb, saturation), pixColor.a); } + // Dimming + gl_FragColor = mix(color, dim_color, dim) * alpha; if (!has_titlebar || gl_FragCoord.y - position.y > radius) { vec2 corner_distance = min(gl_FragCoord.xy - position, size + position - gl_FragCoord.xy); diff --git a/sway/desktop/shaders/tex_rgba.frag b/sway/desktop/shaders/tex_rgba.frag index 2a9dbccb..b46885b2 100644 --- a/sway/desktop/shaders/tex_rgba.frag +++ b/sway/desktop/shaders/tex_rgba.frag @@ -2,6 +2,8 @@ precision mediump float; varying vec2 v_texcoord; uniform sampler2D tex; uniform float alpha; +uniform float dim; +uniform vec4 dim_color; uniform vec2 size; uniform vec2 position; @@ -11,15 +13,16 @@ uniform float saturation; const vec3 saturation_weight = vec3(0.2125, 0.7154, 0.0721); void main() { + vec4 color = texture2D(tex, v_texcoord); // 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; + color = vec4(mix(target, irgb, saturation), pixColor.a); } + // Dimming + gl_FragColor = mix(color, dim_color, dim) * alpha; if (!has_titlebar || gl_FragCoord.y - position.y > radius) { vec2 corner_distance = min(gl_FragCoord.xy - position, size + position - gl_FragCoord.xy); diff --git a/sway/desktop/shaders/tex_rgbx.frag b/sway/desktop/shaders/tex_rgbx.frag index b31c1bfd..283963f2 100644 --- a/sway/desktop/shaders/tex_rgbx.frag +++ b/sway/desktop/shaders/tex_rgbx.frag @@ -2,6 +2,8 @@ precision mediump float; varying vec2 v_texcoord; uniform sampler2D tex; uniform float alpha; +uniform float dim; +uniform vec4 dim_color; uniform vec2 size; uniform vec2 position; @@ -11,14 +13,15 @@ uniform float saturation; const vec3 saturation_weight = vec3(0.2125, 0.7154, 0.0721); void main() { + vec4 color = vec4(texture2D(tex, v_texcoord).rgb, 1.0); // 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; + color = vec4(mix(target, irgb, saturation), 1.0); } + // Dimming + gl_FragColor = mix(color, dim_color, dim) * alpha; if (!has_titlebar || gl_FragCoord.y - position.y > radius) { vec2 corner_distance = min(gl_FragCoord.xy - position, size + position - gl_FragCoord.xy); diff --git a/sway/meson.build b/sway/meson.build index b740b4af..ac3d408d 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -51,6 +51,8 @@ sway_sources = files( 'commands/default_border.c', 'commands/default_floating_border.c', 'commands/default_orientation.c', + 'commands/dim_inactive.c', + 'commands/dim_inactive_colors.c', 'commands/exit.c', 'commands/exec.c', 'commands/exec_always.c', diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 800c3b2a..bf936a27 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd @@ -588,6 +588,16 @@ The default colors are: *corner_radius* <radius> Set corner radius for new windows. +*dim_inactive* <value> + Adjusts the dimming of inactive windows between 0.0 (no dimming) and 1.0 + (fully dimmed) while 0.0 is the default value. + +*dim_inactive_colors.unfocused* <hex color> + The color to dim inactive windows with. Example color: #000000FF + +*dim_inactive_colors.urgent* <hex color> + The color to dim inactive urgent windows with. Example color: #900000FF + *default_border* normal|none|pixel [<n>] Set default border style for new tiled windows. |