Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
Add desktop.grid_fade_mode menu key and implement linear, smoothstep, quadratic, and cosine fade modes in quad_round shader
scenefx/include/render/fx_renderer/shaders.h | 1 +
scenefx/render/fx_renderer/fx_pass.c | 5 ++++-
scenefx/render/fx_renderer/shaders.c | 1 +
scenefx/render/fx_renderer/shaders/quad_round.frag | 11 ++++++++++-
src/server/config.rs | 16 ++++++++++++++++
src/server/output.rs | 17 ++++++++++++++++-
src/server/window_manager.rs | 3 +++
7 files changed, 51 insertions(+), 3 deletions(-)
diff --git a/scenefx/include/render/fx_renderer/shaders.h b/scenefx/include/render/fx_renderer/shaders.h
index bd05f70..98656fc 100644
--- a/scenefx/include/render/fx_renderer/shaders.h
+++ b/scenefx/include/render/fx_renderer/shaders.h
@@ -80,6 +80,7 @@ struct quad_round_shader {
GLint clip_position;
struct shader_corner_radii clip_radius;
GLint fade_inset;
+ GLint fade_mode;
};
bool link_quad_round_program(struct quad_round_shader *shader);
diff --git a/scenefx/render/fx_renderer/fx_pass.c b/scenefx/render/fx_renderer/fx_pass.c
index 578ba67..115b751 100644
--- a/scenefx/render/fx_renderer/fx_pass.c
+++ b/scenefx/render/fx_renderer/fx_pass.c
@@ -690,7 +690,10 @@ void fx_render_pass_add_rounded_rect(struct fx_gles_render_pass *pass,
struct fx_corner_fradii corners = fx_options->corners;
uniform_corner_radii_set(&shader.radius, &corners);
- glUniform1f(shader.fade_inset, (float)fx_options->fade_inset / 1000.0f);
+ int fade_mode = fx_options->fade_inset % 10;
+ float fade_inset = (float)(fx_options->fade_inset / 10) / 100.0f;
+ glUniform1f(shader.fade_inset, fade_inset);
+ glUniform1i(shader.fade_mode, fade_mode);
render(&box, &clip_region, renderer->shaders.quad_round.pos_attrib);
pixman_region32_fini(&clip_region);
diff --git a/scenefx/render/fx_renderer/shaders.c b/scenefx/render/fx_renderer/shaders.c
index 7727376..7b8a0d1 100644
--- a/scenefx/render/fx_renderer/shaders.c
+++ b/scenefx/render/fx_renderer/shaders.c
@@ -199,6 +199,7 @@ bool link_quad_round_program(struct quad_round_shader *shader) {
shader->clip_radius.bottom_left = glGetUniformLocation(prog, "clip_radius_bottom_left");
shader->clip_radius.bottom_right = glGetUniformLocation(prog, "clip_radius_bottom_right");
shader->fade_inset = glGetUniformLocation(prog, "fade_inset");
+ shader->fade_mode = glGetUniformLocation(prog, "fade_mode");
return true;
}
diff --git a/scenefx/render/fx_renderer/shaders/quad_round.frag b/scenefx/render/fx_renderer/shaders/quad_round.frag
index e5e7768..3b3a063 100644
--- a/scenefx/render/fx_renderer/shaders/quad_round.frag
+++ b/scenefx/render/fx_renderer/shaders/quad_round.frag
@@ -10,6 +10,7 @@ uniform float radius_top_right;
uniform float radius_bottom_left;
uniform float radius_bottom_right;
uniform float fade_inset;
+uniform int fade_mode;
uniform vec2 clip_size;
uniform vec2 clip_position;
@@ -65,7 +66,15 @@ void main() {
vec4 final_color = v_color;
if (fade_inset > 0.0) {
float inside_dist = 0.5 - dist;
- float fade_factor = clamp(inside_dist / fade_inset, 0.0, 1.0);
+ float factor = clamp(inside_dist / fade_inset, 0.0, 1.0);
+ float fade_factor = factor;
+ if (fade_mode == 1) {
+ fade_factor = smoothstep(0.0, 1.0, factor);
+ } else if (fade_mode == 2) {
+ fade_factor = factor * factor;
+ } else if (fade_mode == 3) {
+ fade_factor = 0.5 - 0.5 * cos(factor * 3.14159265);
+ }
final_color *= fade_factor;
}
diff --git a/src/server/config.rs b/src/server/config.rs
index c7e17df..c8615c4 100644
--- a/src/server/config.rs
+++ b/src/server/config.rs
@@ -47,6 +47,7 @@ pub struct Layout {
pub desktop_gap_width: i32,
pub desktop_cell_corner_radius: i32,
pub desktop_cell_fade_inset: i64,
+ pub desktop_grid_fade_mode: String,
pub desktop_enable_solid_color: bool,
pub desktop_solid_color: [f32; 4],
pub scenefx_optimized_blur: bool,
@@ -97,6 +98,7 @@ impl Default for Layout {
desktop_gap_width: 1,
desktop_cell_corner_radius: 0,
desktop_cell_fade_inset: 0,
+ desktop_grid_fade_mode: "linear".to_string(),
desktop_enable_solid_color: false,
desktop_solid_color: [0.0, 0.0, 0.0, 1.0],
scenefx_optimized_blur: true,
@@ -287,6 +289,8 @@ pub struct SurfaceConfig {
pub desktop_cell_fade_inset: i64,
#[serde(default = "default_desktop_mode")]
pub desktop_mode: String,
+ #[serde(default = "default_desktop_grid_fade_mode")]
+ pub desktop_grid_fade_mode: String,
#[serde(default = "default_desktop_solid_color")]
pub desktop_solid_color: String,
#[serde(default = "default_backplate_color")]
@@ -307,6 +311,7 @@ impl Default for SurfaceConfig {
desktop_cell_corner_radius: default_desktop_cell_corner_radius(),
desktop_cell_fade_inset: default_desktop_cell_fade_inset(),
desktop_mode: default_desktop_mode(),
+ desktop_grid_fade_mode: default_desktop_grid_fade_mode(),
desktop_solid_color: default_desktop_solid_color(),
backplate_color: default_backplate_color(),
backplate_blur: default_backplate_blur(),
@@ -343,6 +348,10 @@ fn default_desktop_mode() -> String {
"solid".to_string()
}
+fn default_desktop_grid_fade_mode() -> String {
+ "linear".to_string()
+}
+
fn default_desktop_solid_color() -> String {
"#000000".to_string()
}
@@ -1251,6 +1260,11 @@ fn parse_kdl_config(content: &str) -> Result<Config, String> {
surface.desktop_cell_fade_inset = val;
}
}
+ "grid_fade_mode" => {
+ if let Some(val) = entry.value().as_string() {
+ surface.desktop_grid_fade_mode = val.to_string();
+ }
+ }
"mode" => {
if let Some(val) = entry.value().as_string() {
surface.desktop_mode = val.to_string();
@@ -1321,6 +1335,7 @@ fn parse_kdl_config(content: &str) -> Result<Config, String> {
surface.desktop_gap_width = get_child_arg_i64(node, "desktop_gap_width", default_desktop_gap_width());
surface.desktop_cell_corner_radius = get_child_arg_i64(node, "desktop_cell_corner_radius", default_desktop_cell_corner_radius());
surface.desktop_cell_fade_inset = get_child_arg_i64(node, "desktop_cell_fade_inset", default_desktop_cell_fade_inset());
+ surface.desktop_grid_fade_mode = get_child_arg_string(node, "grid_fade_mode", &default_desktop_grid_fade_mode());
surface.desktop_mode = get_child_arg_string(node, "desktop_mode", &default_desktop_mode());
surface.desktop_solid_color = get_child_arg_string(node, "desktop_solid_color", &default_desktop_solid_color());
surface.backplate_color = get_child_arg_string(node, "backplate_color", &default_backplate_color());
@@ -1396,6 +1411,7 @@ pub fn parse_config(path: &str, state: &mut crate::window_manager::WindowManager
state.layout.desktop_gap_width = config.surface.desktop_gap_width as i32;
state.layout.desktop_cell_corner_radius = config.surface.desktop_cell_corner_radius as i32;
state.layout.desktop_cell_fade_inset = config.surface.desktop_cell_fade_inset;
+ state.layout.desktop_grid_fade_mode = config.surface.desktop_grid_fade_mode.clone();
state.layout.desktop_enable_solid_color = enable_solid;
state.layout.desktop_solid_color = parse_hex_color_rgba(&config.surface.desktop_solid_color);
diff --git a/src/server/output.rs b/src/server/output.rs
index fac7d7a..d850522 100644
--- a/src/server/output.rs
+++ b/src/server/output.rs
@@ -165,6 +165,7 @@ pub struct Output {
pub last_grid_cell_color: [f32; 4],
pub last_grid_cell_corner_radius: i32,
pub last_grid_cell_fade_inset: i64,
+ pub last_grid_fade_mode: String,
pub last_grid_gap_color: String,
pub last_grid_gap_color_rgba: [f32; 4],
pub grid_is_low_res: bool,
@@ -419,6 +420,7 @@ impl Output {
last_grid_cell_color: [0.0, 0.0, 0.0, 0.0],
last_grid_cell_corner_radius: 0,
last_grid_cell_fade_inset: 0,
+ last_grid_fade_mode: String::new(),
last_grid_gap_color: String::new(),
last_grid_gap_color_rgba: [0.0, 0.0, 0.0, 0.0],
grid_is_low_res: false,
@@ -607,6 +609,7 @@ impl Output {
cell_color[3] *= density_fade as f32;
let cell_corner_radius = wm.layout.desktop_cell_corner_radius;
let cell_fade_inset = wm.layout.desktop_cell_fade_inset;
+ let fade_mode_str = &wm.layout.desktop_grid_fade_mode;
let gap_color = &wm.layout.desktop_gap_color;
// Detect layout or viewport changes to request a redraw.
@@ -618,6 +621,7 @@ impl Output {
|| self.last_grid_cell_color != cell_color
|| self.last_grid_cell_corner_radius != cell_corner_radius
|| self.last_grid_cell_fade_inset != cell_fade_inset
+ || &self.last_grid_fade_mode != fade_mode_str
|| &self.last_grid_gap_color != gap_color;
if structure_changed {
@@ -653,6 +657,7 @@ impl Output {
self.last_grid_cell_color = cell_color;
self.last_grid_cell_corner_radius = cell_corner_radius;
self.last_grid_cell_fade_inset = cell_fade_inset;
+ self.last_grid_fade_mode = fade_mode_str.clone();
self.last_grid_gap_color = gap_color.clone();
self.last_grid_gap_color_rgba = crate::config::parse_hex_color_rgba(&self.last_grid_gap_color);
self.grid_is_low_res = self.last_grid_zoom != zoom;
@@ -700,7 +705,17 @@ impl Output {
let rw = (cell_size * zoom).round() as i32;
let rh = (cell_size * zoom).round() as i32;
let scaled_corner_radius = (cell_corner_radius as f64 * zoom).round() as i32;
- let inset_scaled = (cell_fade_inset as f64 * zoom * 1000.0).round() as i32;
+ let fade_mode = match fade_mode_str.as_str() {
+ "smoothstep" => 1,
+ "quadratic" => 2,
+ "cosine" => 3,
+ _ => 0, // "linear"
+ };
+ let inset_scaled = if cell_fade_inset > 0 {
+ ((cell_fade_inset as f64 * zoom * 100.0).round() as i32) * 10 + fade_mode
+ } else {
+ 0
+ };
if rw > 0 && rh > 0 {
for col in 0..=cols {
diff --git a/src/server/window_manager.rs b/src/server/window_manager.rs
index 5fbc251..a1ab414 100644
--- a/src/server/window_manager.rs
+++ b/src/server/window_manager.rs
@@ -2663,6 +2663,9 @@ fn get_closest_tag(x: f64, y: f64) -> i32 {
self.layout.desktop_cell_fade_inset = v;
}
}
+ "desktop_grid_fade_mode" => {
+ self.layout.desktop_grid_fade_mode = val.to_string();
+ }
"desktop_enable_solid_color" => {
if let Ok(v) = val.parse::<bool>() {
self.layout.desktop_enable_solid_color = v;