From e50bea33bb237d23aa931722321740083edabe9d Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Wed, 25 Jan 2023 15:14:18 +0100 Subject: [PATCH] shell: Fix SSD when using scaling --- src/shell/element/window.rs | 25 +++++++++++++- src/shell/layout/tiling/mod.rs | 3 ++ src/utils/iced.rs | 62 +++++++++++++++++++++++++++------- 3 files changed, 77 insertions(+), 13 deletions(-) diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 786d89b0..4831631d 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -128,7 +128,7 @@ impl CosmicWindow { ); let size = ( geo.size.w, - geo.size.h - if p.has_ssd() { SSD_HEIGHT } else { 0 }, + std::cmp::max(geo.size.h - if p.has_ssd() { SSD_HEIGHT } else { 0 }, 0), ); p.window .set_geometry(Rectangle::from_loc_and_size(loc, size)); @@ -233,6 +233,8 @@ impl Program for CosmicWindowInternal { } else { target.clear(SolidSource::from_unpremultiplied_argb(u8::MAX, 39, 39, 39)); } + + target.pop_clip(); } fn view(&self) -> Element<'_, Self::Message> { @@ -246,7 +248,27 @@ impl Program for CosmicWindowInternal { fn foreground(&self, target: &mut DrawTarget<&mut [u32]>) { if !self.window.is_activated() { + let radius = 8.; let (w, h) = (target.width() as f32, target.height() as f32); + + if !(self.window.is_maximized() || self.window.is_fullscreen()) { + let mut pb = PathBuilder::new(); + pb.move_to(0., h); // lower-left + + // upper-left rounded corner + pb.line_to(0., radius); + pb.quad_to(0., 0., radius, 0.); + + // upper-right rounded corner + pb.line_to(w - radius, 0.); + pb.quad_to(w, 0., w, radius); + + pb.line_to(w, h); // lower-right + + let path = pb.finish(); + target.push_clip(&path); + } + let mut options = DrawOptions::new(); options.alpha = 0.4; target.fill_rect( @@ -318,6 +340,7 @@ impl SpaceElement for CosmicWindow { self.0.with_program(|p| SpaceElement::z_index(&p.window)) } fn refresh(&self) { + SpaceElement::refresh(&self.0); self.0.with_program(|p| SpaceElement::refresh(&p.window)) } } diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index a192e120..90521aeb 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -946,6 +946,9 @@ impl TilingLayout { } } } + for (_, mapped, _) in self.mapped() { + mapped.refresh(); + } TilingLayout::update_space_positions(&mut self.trees, self.gaps); } diff --git a/src/utils/iced.rs b/src/utils/iced.rs index ac212ee3..7bea2043 100644 --- a/src/utils/iced.rs +++ b/src/utils/iced.rs @@ -111,6 +111,7 @@ impl IcedProgram for ProgramWrapper

{ struct IcedElementInternal { // draw buffer + outputs: Vec, buffers: HashMap, (MemoryRenderBuffer, bool)>, // state @@ -180,6 +181,7 @@ impl IcedElement

{ .ok(); let mut internal = IcedElementInternal { + outputs: Vec::new(), buffers: HashMap::new(), size, cursor_pos: None, @@ -471,12 +473,12 @@ impl SpaceElement for IcedElement

{ ), ); } + internal.outputs.push(output.clone()); } fn output_leave(&self, output: &Output) { - let mut internal = self.0.lock().unwrap(); - let scale = output.current_scale().fractional_scale(); - internal.buffers.remove(&OrderedFloat(scale)); + self.0.lock().unwrap().outputs.retain(|o| o != output); + self.refresh(); } fn z_index(&self) -> u8 { @@ -484,7 +486,38 @@ impl SpaceElement for IcedElement

{ RenderZindex::Shell as u8 } - fn refresh(&self) {} + fn refresh(&self) { + let mut internal = self.0.lock().unwrap(); + // makes partial borrows easier + let internal_ref = &mut *internal; + internal_ref.buffers.retain(|scale, _| { + internal_ref + .outputs + .iter() + .any(|o| o.current_scale().fractional_scale() == **scale) + }); + for scale in internal_ref + .outputs + .iter() + .map(|o| OrderedFloat(o.current_scale().fractional_scale())) + .filter(|scale| !internal_ref.buffers.contains_key(scale)) + .collect::>() + .into_iter() + { + let buffer_size = internal_ref + .size + .to_f64() + .to_buffer(*scale, Transform::Normal) + .to_i32_round(); + internal_ref.buffers.insert( + scale, + ( + MemoryRenderBuffer::new(buffer_size, 1, Transform::Normal, None), + true, + ), + ); + } + } } impl AsRenderElements for IcedElement

@@ -504,18 +537,20 @@ where let mut internal = self.0.lock().unwrap(); let _ = internal.update(false); // TODO - // makes partial borrows easier + + // makes partial borrows easier let internal_ref = &mut *internal; if let Some((buffer, ref mut needs_redraw)) = internal_ref.buffers.get_mut(&OrderedFloat(scale.x)) { + let size = internal_ref + .size + .to_f64() + .to_buffer(scale.x, Transform::Normal) + .to_i32_round(); + if *needs_redraw { let renderer = &mut internal_ref.renderer; - let size = internal_ref - .size - .to_f64() - .to_buffer(scale.x, Transform::Normal) - .to_i32_round(); let state_ref = &internal_ref.state; buffer .render() @@ -565,8 +600,11 @@ where location.to_f64(), &buffer, None, - None, - None, + Some(Rectangle::from_loc_and_size( + (0., 0.), + size.to_f64().to_logical(1.0, Transform::Normal), + )), + Some(internal_ref.size), slog_scope::logger(), ) { return vec![C::from(buffer)];