diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index fd4c7654..edd2b614 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -182,9 +182,10 @@ impl From for Key { #[derive(PartialEq)] struct IndicatorSettings { thickness: u8, - radius: [u8; 4], + outer_radius: [u8; 4], alpha: f32, color: [f32; 3], + scale: f64, } type IndicatorCache = RefCell>; @@ -204,21 +205,24 @@ impl IndicatorShader { key: impl Into, mut element_geo: Rectangle, thickness: u8, - radius: [u8; 4], + inner_radius: [u8; 4], alpha: f32, + scale: f64, active_window_hint: [f32; 3], ) -> PixelShaderElement { let t = thickness as i32; element_geo.loc -= (t, t).into(); element_geo.size += (t * 2, t * 2).into(); + let outer_radius = inner_radius.map(|r| r + thickness); IndicatorShader::element( renderer, key, element_geo, thickness, - radius, + outer_radius, alpha, + scale, active_window_hint, ) } @@ -228,14 +232,16 @@ impl IndicatorShader { key: impl Into, geo: Rectangle, thickness: u8, - radius: [u8; 4], + outer_radius: [u8; 4], alpha: f32, + scale: f64, color: [f32; 3], ) -> PixelShaderElement { let settings = IndicatorSettings { thickness, - radius, + outer_radius, alpha, + scale, color, }; @@ -257,7 +263,7 @@ impl IndicatorShader { .filter(|(old_settings, _)| &settings == old_settings) .is_none() { - let thickness: f32 = thickness as f32; + let thickness: f32 = ((thickness as f64 * scale).ceil() / scale) as f32; let shader = Self::get(renderer); let elem = PixelShaderElement::new( @@ -274,12 +280,13 @@ impl IndicatorShader { 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., + outer_radius[0] as f32, + outer_radius[1] as f32, + outer_radius[2] as f32, + outer_radius[3] as f32, ], ), + Uniform::new("scale", scale as f32), ], Kind::Unspecified, ); @@ -392,6 +399,7 @@ pub fn init_shaders(renderer: &mut GlesRenderer) -> Result<(), GlesError> { &[ UniformName::new("color", UniformType::_3f), UniformName::new("thickness", UniformType::_1f), + UniformName::new("scale", UniformType::_1f), UniformName::new("radius", UniformType::_4f), ], )?; diff --git a/src/backend/render/shaders/rounded_outline.frag b/src/backend/render/shaders/rounded_outline.frag index 4d1b1ee2..d3266e60 100644 --- a/src/backend/render/shaders/rounded_outline.frag +++ b/src/backend/render/shaders/rounded_outline.frag @@ -9,29 +9,56 @@ varying vec2 v_coords; uniform vec3 color; uniform float thickness; uniform vec4 radius; +uniform float scale; -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; +float rounding_alpha(vec2 coords, vec2 size, vec4 radius) { + vec2 center; + float r; + + if (coords.x < radius.x && coords.y < radius.x) { + r = radius.x; + center = vec2(r, r); + } else if (size.x - radius.y < coords.x && coords.y < radius.y) { + r = radius.y; + center = vec2(size.x - r, r); + } else if (size.x - radius.z < coords.x && size.y - radius.z < coords.y) { + r = radius.z; + center = vec2(size.x - r, size.y - r); + } else if (coords.x < radius.w && size.y - radius.w < coords.y) { + r = radius.w; + center = vec2(r, size.y - r); + } else { + return 1.0; + } + + float dist = distance(coords, center); + float half_px = 0.5 / scale; + return 1.0 - smoothstep(r - half_px, r + half_px, dist); } void main() { - vec2 center = size / 2.0; vec2 location = v_coords * size; - vec4 mix_color; - float distance = rounded_box(location - center, (size / 2.0) - (thickness / 2.0), radius); - float smoothedAlpha = 1.0 - smoothstep(-0.5, 0.5, abs(distance) - (thickness / 2.0)); + float outer_alpha = rounding_alpha(v_coords * size, size, radius); + float inner_alpha = 1.0; - mix_color = mix(vec4(0.0, 0.0, 0.0, 0.0), vec4(color, alpha), smoothedAlpha); - -#if defined(DEBUG_FLAGS) + if (thickness > 0.0) { + location -= vec2(thickness); + vec2 inner_size = size - vec2(thickness * 2.0); + if (0.0 <= location.x && location.x <= inner_size.x + && 0.0 <= location.y && location.y <= inner_size.y) + { + vec4 inner_radius = radius - vec4(thickness); + inner_alpha = 1.0 - rounding_alpha(location, inner_size, inner_radius); + } + } + + vec4 mix_color = mix(vec4(0.0, 0.0, 0.0, 0.0), vec4(color, alpha), outer_alpha * inner_alpha); + + #if defined(DEBUG_FLAGS) if (tint == 1.0) mix_color = vec4(0.0, 0.3, 0.0, 0.2) + mix_color * 0.8; -#endif + #endif gl_FragColor = mix_color; -} \ No newline at end of file +} diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index c9b093f0..139d642a 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -782,6 +782,7 @@ impl CosmicStack { 1, radii.unwrap_or([0, 0, 0, 0]), a * alpha, + scale.x, [r, g, b], )) }); diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 5d302db0..5dcf462b 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -503,6 +503,7 @@ impl CosmicWindow { 1, radii, a * alpha, + scale.x, [r, g, b], )); elements.push(elem); diff --git a/src/shell/grabs/moving.rs b/src/shell/grabs/moving.rs index 03677a55..1078af2b 100644 --- a/src/shell/grabs/moving.rs +++ b/src/shell/grabs/moving.rs @@ -131,6 +131,7 @@ impl MoveGrabState { self.indicator_thickness, radius, alpha, + output_scale.x, [ active_window_hint.red, active_window_hint.green, @@ -167,6 +168,7 @@ impl MoveGrabState { theme.radius_s()[3] as u8, ], 1.0, + output_scale.x, [ active_window_hint.red, active_window_hint.green, diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index b109d6f4..11cc89ec 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -1622,6 +1622,7 @@ impl FloatingLayout { indicator_thickness, radius, alpha, + output_scale, [ active_window_hint.red, active_window_hint.green, diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index f7b1b5fd..b39431ab 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -3400,6 +3400,7 @@ impl TilingLayout { Option::<&mut GlowRenderer>::None, non_exclusive_zone, None, + self.output.current_scale().fractional_scale(), 1.0, overview.alpha().unwrap(), &self.backdrop_id, @@ -4054,6 +4055,7 @@ impl TilingLayout { non_exclusive_zone, seat, // TODO: Would be better to be an old focus, // but for that we have to associate focus with a tree (and animate focus changes properly) + output_scale, 1.0 - transition, transition, &self.backdrop_id, @@ -4091,6 +4093,7 @@ impl TilingLayout { &mut *renderer, non_exclusive_zone, seat, + output_scale, transition, transition, &self.backdrop_id, @@ -4203,6 +4206,7 @@ impl TilingLayout { non_exclusive_zone, seat, // TODO: Would be better to be an old focus, // but for that we have to associate focus with a tree (and animate focus changes properly) + output_scale, 1.0 - transition, transition, &self.backdrop_id, @@ -4238,6 +4242,7 @@ impl TilingLayout { &mut *renderer, non_exclusive_zone, seat, + output_scale, transition, transition, &self.backdrop_id, @@ -4312,6 +4317,7 @@ fn geometries_for_groupview<'a, R>( renderer: impl Into>, non_exclusive_zone: Rectangle, seat: Option<&Seat>, + scale: f64, alpha: f32, transition: f32, backdrop_id: &Id, @@ -4512,6 +4518,7 @@ where 4, [if render_active_child { 16 } else { 8 }; 4], alpha * if render_potential_group { 0.40 } else { 1.0 }, + scale, group_color, ) .into(), @@ -4529,6 +4536,7 @@ where 4, [8; 4], alpha * 0.40, + scale, group_color, ) .into(), @@ -4592,6 +4600,7 @@ where 4, [8; 4], alpha * 0.15, + scale, group_color, ) .into(), @@ -4828,6 +4837,7 @@ where 4, [8; 4], alpha * 0.40, + scale, group_color, ) .into(), @@ -5068,6 +5078,7 @@ where indicator_thickness, radius, alpha, + output_scale, [window_hint.red, window_hint.green, window_hint.blue], ), )); @@ -5347,6 +5358,7 @@ where 4, radius, transition.unwrap_or(1.0), + output_scale, [window_hint.red, window_hint.green, window_hint.blue], ), )); @@ -5464,6 +5476,7 @@ where }, radius, alpha, + output_scale, [window_hint.red, window_hint.green, window_hint.blue], ), ));