From 7aea0095e991a7b5b52e6109ee79a9deb8550d7b Mon Sep 17 00:00:00 2001 From: atagen Date: Tue, 7 Apr 2026 20:05:14 +1000 Subject: [PATCH] renderer: draw surface at full size unconditionally w/ edge clamping --- src/gfx_api.rs | 2 ++ src/renderer.rs | 31 ++++++++++++++++++++++++++++--- src/state.rs | 1 + src/tree/container.rs | 10 ++++++++-- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/gfx_api.rs b/src/gfx_api.rs index 413d1401..afad137c 100644 --- a/src/gfx_api.rs +++ b/src/gfx_api.rs @@ -706,6 +706,7 @@ impl dyn GfxFramebuffer { Rect::new_saturating(0, 0, width, height) }, icons: None, + stretch: None, }; cursor.render_hardware_cursor(&mut renderer); self.render( @@ -1039,6 +1040,7 @@ pub fn create_render_pass( Rect::new_saturating(0, 0, width, height) }, icons: state.icons.get(state, scale), + stretch: None, }; node.node_render(&mut renderer, 0, 0, None); if let Some(rect) = cursor_rect { diff --git a/src/renderer.rs b/src/renderer.rs index d158ef29..6875f253 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -30,6 +30,7 @@ pub struct Renderer<'a> { pub logical_extents: Rect, pub pixel_extents: Rect, pub icons: Option>, + pub stretch: Option<(i32, i32)>, } impl Renderer<'_> { @@ -397,9 +398,15 @@ impl Renderer<'_> { let body = mb.move_(x, y); let body = self.base.scale_rect(body); let content = container.mono_content.get(); + self.stretch = if content.width() != mb.width() || content.height() != mb.height() { + Some(self.base.scale_point(mb.width(), mb.height())) + } else { + None + }; child .node .node_render(self, x + content.x1(), y + content.y1(), Some(&body)); + self.stretch = None; } else { let gap = self.state.theme.sizes.gap.get(); let (srgb_srgb, bw, border_color, focused_border_color, tpuh) = if gap != 0 { @@ -466,12 +473,18 @@ impl Renderer<'_> { self.base.fill_boxes2(&frame_rects, c, srgb, perceptual, x, y); } } + let content = child.content.get(); + self.stretch = if content.width() != body.width() || content.height() != body.height() { + Some(self.base.scale_point(body.width(), body.height())) + } else { + None + }; let body = body.move_(x, y); let body = self.base.scale_rect(body); - let content = child.content.get(); child .node .node_render(self, x + content.x1(), y + content.y1(), Some(&body)); + self.stretch = None; } } @@ -546,6 +559,7 @@ impl Renderer<'_> { self.render_surface_scaled(surface, x, y, None, bounds, false); } + pub fn render_surface_scaled( &mut self, surface: &WlSurface, @@ -555,6 +569,7 @@ impl Renderer<'_> { bounds: Option<&Rect>, is_subsurface: bool, ) { + let stretch = self.stretch.take(); let children = surface.children.borrow(); let buffer = match surface.buffer.get() { Some(b) => b, @@ -574,6 +589,16 @@ impl Renderer<'_> { } else { size = self.base.scale_point(size.0, size.1); } + let mut tpoints = *tpoints; + if let Some(s) = stretch { + if size.0 > 0 && size.1 > 0 { + let sx = s.0 as f32 / size.0 as f32; + let sy = s.1 as f32 / size.1 as f32; + tpoints.x2 *= sx; + tpoints.y2 *= sy; + } + size = s; + } if let Some(children) = children.deref() { macro_rules! render { ($children:expr) => { @@ -595,10 +620,10 @@ impl Renderer<'_> { }; } render!(&children.below); - self.render_buffer(surface, &buffer, x, y, *tpoints, size, bounds); + self.render_buffer(surface, &buffer, x, y, tpoints, size, bounds); render!(&children.above); } else { - self.render_buffer(surface, &buffer, x, y, *tpoints, size, bounds); + self.render_buffer(surface, &buffer, x, y, tpoints, size, bounds); } } diff --git a/src/state.rs b/src/state.rs index c39c717e..220242fe 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1297,6 +1297,7 @@ impl State { Rect::new_sized_saturating(0, 0, width, height) }, icons: None, + stretch: None, }; let mut sample_rect = SampleRect::identity(); sample_rect.buffer_transform = transform; diff --git a/src/tree/container.rs b/src/tree/container.rs index 6dea9989..153caf42 100644 --- a/src/tree/container.rs +++ b/src/tree/container.rs @@ -336,6 +336,7 @@ impl ContainerNode { node: new.clone(), active: Default::default(), body: Default::default(), + content: Default::default(), factor: Default::default(), title: Default::default(), @@ -489,9 +490,12 @@ impl ContainerNode { self.schedule_render_titles(); self.schedule_compute_render_positions(); self.layout_complete.trigger(); - if self.toplevel_data.visible.get() && self.all_children_match_body() { + if self.all_children_match_body() { + self.all_children_resized.trigger(); - self.damage(); + if self.toplevel_data.visible.get() { + self.damage(); + } } } @@ -1843,6 +1847,7 @@ impl Node for ContainerNode { self.update_child_size(node, width, height); } if self.all_children_match_body() { + self.all_children_resized.trigger(); if self.toplevel_data.visible.get() { self.damage(); @@ -2043,6 +2048,7 @@ impl ContainingNode for ContainerNode { node: new.clone(), active: Cell::new(false), body: Cell::new(node.body.get()), + content: Default::default(), factor: Cell::new(node.factor.get()), title: Default::default(),