shell: Fix SSD when using scaling

This commit is contained in:
Victoria Brekenfeld 2023-01-25 15:14:18 +01:00
parent 0090122ffe
commit e50bea33bb
3 changed files with 77 additions and 13 deletions

View file

@ -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))
}
}

View file

@ -946,6 +946,9 @@ impl TilingLayout {
}
}
}
for (_, mapped, _) in self.mapped() {
mapped.refresh();
}
TilingLayout::update_space_positions(&mut self.trees, self.gaps);
}

View file

@ -111,6 +111,7 @@ impl<P: Program> IcedProgram for ProgramWrapper<P> {
struct IcedElementInternal<P: Program + Send + 'static> {
// draw buffer
outputs: Vec<Output>,
buffers: HashMap<OrderedFloat<f64>, (MemoryRenderBuffer, bool)>,
// state
@ -180,6 +181,7 @@ impl<P: Program + Send + 'static> IcedElement<P> {
.ok();
let mut internal = IcedElementInternal {
outputs: Vec::new(),
buffers: HashMap::new(),
size,
cursor_pos: None,
@ -471,12 +473,12 @@ impl<P: Program + Send + 'static> SpaceElement for IcedElement<P> {
),
);
}
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<P: Program + Send + 'static> SpaceElement for IcedElement<P> {
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::<Vec<_>>()
.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<P, R> AsRenderElements<R> for IcedElement<P>
@ -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)];