summaryrefslogtreecommitdiff
path: root/sway
diff options
context:
space:
mode:
authorErik Reider <[email protected]>2022-12-07 06:10:11 +0100
committerGitHub <[email protected]>2022-12-07 00:10:11 -0500
commit988fb247107c469bb98ce3088ad189fa12db7cdd (patch)
tree67eafa3aef85ccb450adb3a46ed313c4ae32db6d /sway
parente82e4de37f5c6fe184da62f228329a37517ccd55 (diff)
[Feature] Dim inactive windows (#66)
Diffstat (limited to 'sway')
-rw-r--r--sway/commands.c3
-rw-r--r--sway/commands/dim_inactive.c29
-rw-r--r--sway/commands/dim_inactive_colors.c40
-rw-r--r--sway/config.c3
-rw-r--r--sway/desktop/fx_renderer.c6
-rw-r--r--sway/desktop/render.c22
-rw-r--r--sway/desktop/shaders/tex_external.frag9
-rw-r--r--sway/desktop/shaders/tex_rgba.frag9
-rw-r--r--sway/desktop/shaders/tex_rgbx.frag9
-rw-r--r--sway/meson.build2
-rw-r--r--sway/sway.5.scd10
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.