From c6320eec0c4cd37c32516ff19c033b8ad1912f68 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Wed, 24 Sep 2025 17:50:23 -0400 Subject: [PATCH] fix: support per-corner radius also adjusts the radius by half of the outline thickness. I believe this is the radius at the center of the outline. --- src/backend/render/mod.rs | 21 ++++++---- .../render/shaders/rounded_outline.frag | 10 +++-- src/shell/grabs/moving.rs | 17 +++++++-- src/shell/layout/floating/mod.rs | 9 ++++- src/shell/layout/tiling/mod.rs | 38 +++++++++++++------ 5 files changed, 67 insertions(+), 28 deletions(-) diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index 8a4556c6..02b011b2 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -173,7 +173,7 @@ impl From for Key { #[derive(PartialEq)] struct IndicatorSettings { thickness: u8, - radius: u8, + radius: [u8; 4], alpha: f32, color: [f32; 3], } @@ -195,7 +195,7 @@ impl IndicatorShader { key: impl Into, mut element_geo: Rectangle, thickness: u8, - radius: u8, + radius: [u8; 4], alpha: f32, active_window_hint: [f32; 3], ) -> PixelShaderElement { @@ -208,8 +208,7 @@ impl IndicatorShader { key, element_geo, thickness, - // FIXME, this seems to look OK, but I doubt it is correct - radius + thickness, + radius, alpha, active_window_hint, ) @@ -220,7 +219,7 @@ impl IndicatorShader { key: impl Into, geo: Rectangle, thickness: u8, - radius: u8, + radius: [u8; 4], alpha: f32, color: [f32; 3], ) -> PixelShaderElement { @@ -263,7 +262,15 @@ impl IndicatorShader { [color[0] * alpha, color[1] * alpha, color[2] * alpha], ), Uniform::new("thickness", thickness), - Uniform::new("radius", radius as f32), + Uniform::new( + "radius", + [ + radius[0] as f32 + thickness / 2., + radius[1] as f32 + thickness / 2., + radius[2] as f32 + thickness / 2., + radius[3] as f32 + thickness / 2., + ], + ), ], Kind::Unspecified, ); @@ -376,7 +383,7 @@ pub fn init_shaders(renderer: &mut GlesRenderer) -> Result<(), GlesError> { &[ UniformName::new("color", UniformType::_3f), UniformName::new("thickness", UniformType::_1f), - UniformName::new("radius", UniformType::_1f), + UniformName::new("radius", UniformType::_4f), ], )?; let rectangle_shader = renderer.compile_custom_pixel_shader( diff --git a/src/backend/render/shaders/rounded_outline.frag b/src/backend/render/shaders/rounded_outline.frag index 749748f2..75cfeef1 100644 --- a/src/backend/render/shaders/rounded_outline.frag +++ b/src/backend/render/shaders/rounded_outline.frag @@ -8,10 +8,14 @@ varying vec2 v_coords; uniform vec3 color; uniform float thickness; -uniform float radius; +uniform vec4 radius; -float rounded_box(vec2 center, vec2 size, float radius) { - return length(max(abs(center) - size + radius, 0.0)) - radius; +float rounded_box(in vec2 p, in vec2 b, in vec4 r) +{ + r.xy = (p.x > 0.0) ? r.xy : r.zw; + r.x = (p.y > 0.0) ? r.x : r.y; + vec2 q = abs(p) - b + r.x; + return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r.x; } void main() { diff --git a/src/shell/grabs/moving.rs b/src/shell/grabs/moving.rs index 6ae192b7..41ebe267 100644 --- a/src/shell/grabs/moving.rs +++ b/src/shell/grabs/moving.rs @@ -134,12 +134,16 @@ impl MoveGrabState { let guard = corners.lock().unwrap(); // TODO support multiple radius values - Some(guard.top_left) + Some([ + guard.top_right, + guard.bottom_right, + guard.top_left, + guard.bottom_left, + ]) }) }) - .unwrap_or(self.indicator_thickness); + .unwrap_or([self.indicator_thickness; 4]); - tracing::error!("{radius}"); let focus_element = if self.indicator_thickness > 0 { Some( CosmicMappedRenderElement::from(IndicatorShader::focus_element( @@ -188,7 +192,12 @@ impl MoveGrabState { Key::Window(Usage::SnappingIndicator, self.window.key()), overlay_geometry, thickness, - theme.radius_s()[0] as u8, // TODO: Fix once shaders support 4 corner radii customization + [ + theme.radius_s()[0] as u8, + theme.radius_s()[1] as u8, + theme.radius_s()[2] as u8, + theme.radius_s()[3] as u8, + ], 1.0, [ active_window_hint.red, diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index fe4c26eb..895394de 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -1615,10 +1615,15 @@ impl FloatingLayout { let guard = corners.lock().unwrap(); // TODO support multiple radius values - Some(guard.top_left) + Some([ + guard.top_right, + guard.bottom_right, + guard.top_left, + guard.bottom_left, + ]) }) }) - .unwrap_or(indicator_thickness); + .unwrap_or([indicator_thickness; 4]); if indicator_thickness > 0 { let element = IndicatorShader::focus_element( renderer, diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 9dbcd94c..9c87b422 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -4483,7 +4483,7 @@ where Key::Group(Arc::downgrade(alive)), geo, 4, - if render_active_child { 16 } else { 8 }, + [if render_active_child { 16 } else { 8 }; 4], alpha * if render_potential_group { 0.40 } else { 1.0 }, group_color, ) @@ -4500,7 +4500,7 @@ where Key::Group(Arc::downgrade(alive)), geo, 4, - 8, + [8; 4], alpha * 0.40, group_color, ) @@ -4563,7 +4563,7 @@ where Key::Group(Arc::downgrade(alive)), geo, 4, - 8, + [8; 4], alpha * 0.15, group_color, ) @@ -4799,7 +4799,7 @@ where Key::Window(Usage::PotentialGroupIndicator, mapped.key()), geo, 4, - 8, + [8; 4], alpha * 0.40, group_color, ) @@ -5035,10 +5035,15 @@ where let guard = corners.lock().unwrap(); // TODO support multiple radius values - Some(guard.top_left) + Some([ + guard.top_right, + guard.bottom_right, + guard.top_left, + guard.bottom_left, + ]) }) }) - .unwrap_or(indicator_thickness); + .unwrap_or([indicator_thickness; 4]); if is_minimizing && indicator_thickness > 0 { elements.push(CosmicMappedRenderElement::FocusIndicator( IndicatorShader::focus_element( @@ -5323,11 +5328,15 @@ where let guard = corners.lock().unwrap(); - // TODO support multiple radius values - Some(guard.top_left) + Some([ + guard.top_right, + guard.bottom_right, + guard.top_left, + guard.bottom_left, + ]) }) }) - .unwrap_or(indicator_thickness); + .unwrap_or([indicator_thickness; 4]); swap_elements.push(CosmicMappedRenderElement::FocusIndicator( IndicatorShader::focus_element( renderer, @@ -5423,11 +5432,16 @@ where let guard = corners.lock().unwrap(); // TODO support multiple radius values - Some(guard.top_left) + Some([ + guard.top_right, + guard.bottom_right, + guard.top_left, + guard.bottom_left, + ]) }) }) - .unwrap_or(indicator_thickness), - _ => 1, + .unwrap_or([indicator_thickness; 4]), + _ => [1; 4], }; if !swap_desc .as_ref()