diff --git a/src/shell/element/surface.rs b/src/shell/element/surface.rs index 381c4d99..9c624958 100644 --- a/src/shell/element/surface.rs +++ b/src/shell/element/surface.rs @@ -127,10 +127,10 @@ impl CosmicSurface { } } - pub fn corner_radius(&self) -> Option<[u8; 4]> { + pub fn corner_radius(&self, geometry_size: Size) -> Option<[u8; 4]> { self.wl_surface().and_then(|surface| { - with_states(&surface, |s| { - let d = s + with_states(&surface, |states| { + let d = states .data_map .get::>>()?; let guard = d.lock().unwrap(); @@ -141,16 +141,18 @@ impl CosmicSurface { let guard = corners.lock().unwrap(); - let size = ::geometry(self).size; // guard against corner radius being too large, potentially disconnecting the outline - let half_min_dim = u8::try_from(size.w.min(size.h) / 2).unwrap_or(u8::MAX); + let half_min_dim = + u8::try_from(geometry_size.w.min(geometry_size.h) / 2).unwrap_or(u8::MAX); - Some([ - guard.top_right.min(half_min_dim), - guard.bottom_right.min(half_min_dim), - guard.top_left.min(half_min_dim), - guard.bottom_left.min(half_min_dim), - ]) + guard.corners.map(|corners| { + [ + corners.top_right.min(half_min_dim), + corners.bottom_right.min(half_min_dim), + corners.top_left.min(half_min_dim), + corners.bottom_left.min(half_min_dim), + ] + }) }) }) } diff --git a/src/shell/grabs/moving.rs b/src/shell/grabs/moving.rs index 0e742fc0..972ab04b 100644 --- a/src/shell/grabs/moving.rs +++ b/src/shell/grabs/moving.rs @@ -111,7 +111,7 @@ impl MoveGrabState { let active_window_hint = crate::theme::active_window_hint(theme); let radius = self .window() - .corner_radius() + .corner_radius(window_geo.size) .unwrap_or([self.indicator_thickness; 4]); let focus_element = if self.indicator_thickness > 0 { diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index 6a29628c..06ccd7b3 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -1591,7 +1591,7 @@ impl FloatingLayout { let active_window_hint = crate::theme::active_window_hint(theme); let radius = elem .active_window() - .corner_radius() + .corner_radius(geometry.size.as_logical()) .unwrap_or([indicator_thickness; 4]); if indicator_thickness > 0 { let element = IndicatorShader::focus_element( diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 6cbbdd8e..caf7c29d 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -5017,7 +5017,7 @@ where })); let radius = mapped .active_window() - .corner_radius() + .corner_radius(geo.size.as_logical()) .unwrap_or([indicator_thickness; 4]); if is_minimizing && indicator_thickness > 0 { elements.push(CosmicMappedRenderElement::FocusIndicator( @@ -5288,7 +5288,9 @@ where ) .unwrap(); - let radius = window.corner_radius().unwrap_or([indicator_thickness; 4]); + let radius = window + .corner_radius(swap_geo.size.as_logical()) + .unwrap_or([indicator_thickness; 4]); swap_elements.push(CosmicMappedRenderElement::FocusIndicator( IndicatorShader::focus_element( renderer, @@ -5369,7 +5371,7 @@ where let radius = match data { Data::Mapped { mapped, .. } => mapped .active_window() - .corner_radius() + .corner_radius(geo.size.as_logical()) .unwrap_or([indicator_thickness; 4]), _ => [1; 4], }; diff --git a/src/wayland/protocols/corner_radius.rs b/src/wayland/protocols/corner_radius.rs index c732e824..be0937d5 100644 --- a/src/wayland/protocols/corner_radius.rs +++ b/src/wayland/protocols/corner_radius.rs @@ -108,10 +108,7 @@ where cosmic_corner_radius_manager_v1::Request::GetCornerRadius { id, toplevel } => { let data = Mutex::new(CornerRadiusInternal { toplevel: toplevel.downgrade(), - top_left: 0, - top_right: 0, - bottom_right: 0, - bottom_left: 0, + corners: None, }); let instance = data_init.init(id, data); @@ -151,7 +148,7 @@ where + 'static, { fn request( - _state: &mut D, + state: &mut D, _client: &Client, resource: &cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1, request: ::Request, @@ -161,8 +158,11 @@ where ) { match request { cosmic_corner_radius_toplevel_v1::Request::Destroy => { - // TODO do we want to unset it after it is destroyed or just leave it? - _state.unset_corner_radius(resource, data); + let mut guard = data.lock().unwrap(); + guard.corners = None; + drop(guard); + + state.unset_corner_radius(resource, data); } cosmic_corner_radius_toplevel_v1::Request::SetRadius { top_left, @@ -170,20 +170,18 @@ where bottom_right, bottom_left, } => { - { - let mut guard = data.lock().unwrap(); - guard.set_corner_radius( - top_left as u8, - top_right as u8, - bottom_right as u8, - bottom_left as u8, - ); - } + let mut guard = data.lock().unwrap(); + guard.set_corner_radius(top_left, top_right, bottom_right, bottom_left); + drop(guard); - _state.set_corner_radius(resource, data); + state.set_corner_radius(resource, data); } cosmic_corner_radius_toplevel_v1::Request::UnsetRadius => { - _state.unset_corner_radius(resource, data); + let mut guard = data.lock().unwrap(); + guard.corners = None; + drop(guard); + + state.unset_corner_radius(resource, data); } _ => unimplemented!(), } @@ -195,6 +193,11 @@ pub type CornerRadiusData = Mutex; #[derive(Debug)] pub struct CornerRadiusInternal { pub toplevel: Weak, + pub corners: Option, +} + +#[derive(Debug, Copy, Clone)] +pub struct Corners { pub top_left: u8, pub top_right: u8, pub bottom_right: u8, @@ -204,15 +207,18 @@ pub struct CornerRadiusInternal { impl CornerRadiusInternal { fn set_corner_radius( &mut self, - top_left: u8, - top_right: u8, - bottom_right: u8, - bottom_left: u8, + top_left: u32, + top_right: u32, + bottom_right: u32, + bottom_left: u32, ) { - self.top_left = top_left; - self.top_right = top_right; - self.bottom_right = bottom_right; - self.bottom_left = bottom_left; + let corners = Corners { + top_left: top_left.clamp(u8::MIN as u32, u8::MAX as u32) as u8, + top_right: top_right.clamp(u8::MIN as u32, u8::MAX as u32) as u8, + bottom_right: bottom_right.clamp(u8::MIN as u32, u8::MAX as u32) as u8, + bottom_left: bottom_left.clamp(u8::MIN as u32, u8::MAX as u32) as u8, + }; + self.corners = Some(corners); } }