From 0872c9149b93e0c905dfcf689e97bb1aa78638a4 Mon Sep 17 00:00:00 2001 From: "Pedro M. de Echanove Pasquin" Date: Wed, 4 Nov 2026 13:13:47 +0100 Subject: [PATCH] =?UTF-8?q?Make=20a=20scroll=20or=20fading=20viewport's=20?= =?UTF-8?q?sub-canvas=20again=20when=20the=20window's=20scale=20changes,?= =?UTF-8?q?=20rather=20than=20keep=20drawing=20it=20at=20the=20old=20one?= =?UTF-8?q?=20Prompt=20opened=20on=20a=20screen=20at=20scale=202=20and=20m?= =?UTF-8?q?oved=20to=20one=20at=20scale=201=20drew=20its=20tab=20labels=20?= =?UTF-8?q?and=20icons=20at=20twice=20their=20size,=20with=20only=20a=20co?= =?UTF-8?q?uple=20of=20letters=20fitting=20in=20each=20tab,=20while=20the?= =?UTF-8?q?=20star,=20the=20+=20and=20the=20menu=20beside=20the=20tab=20ro?= =?UTF-8?q?w,=20and=20the=20terminal,=20came=20out=20right.=20Opened=20on?= =?UTF-8?q?=20the=20second=20screen=20directly,=20the=20tabs=20were=20righ?= =?UTF-8?q?t=20too.=20The=20sub-canvases=20of=20scrolls=20(`scroll=5Fcanva?= =?UTF-8?q?ses`)=20and=20fading=20viewports=20(`viewport=5Fcanvases`)=20ar?= =?UTF-8?q?e=20kept=20from=20one=20frame=20to=20the=20next=20and=20reused,?= =?UTF-8?q?=20resized=20when=20their=20size=20changes.=20`Canvas::sub=5Fca?= =?UTF-8?q?nvas`=20copies=20the=20parent's=20`dpi=5Fscale`=20and=20layout?= =?UTF-8?q?=20viewport=20when=20it=20makes=20one,=20so=20a=20sub-canvas=20?= =?UTF-8?q?kept=20across=20a=20change=20of=20scale=20went=20on=20with=20th?= =?UTF-8?q?e=20old=20one.=20Prompt's=20tab=20strip=20sits=20in=20a=20horiz?= =?UTF-8?q?ontal=20scroll,=20so=20its=20labels=20were=20drawn=20at=20px(13?= =?UTF-8?q?)=20=C3=97=202=20on=20a=20canvas=20at=20scale=201.=20`reuse=5Fs?= =?UTF-8?q?ub=5Fcanvas`=20takes=20the=20pooled=20sub-canvas=20only=20while?= =?UTF-8?q?=20its=20`dpi=5Fscale`=20matches=20the=20parent's,=20resizing?= =?UTF-8?q?=20it=20as=20before,=20and=20otherwise=20makes=20a=20new=20one?= =?UTF-8?q?=20with=20`parent.sub=5Fcanvas`,=20which=20takes=20the=20curren?= =?UTF-8?q?t=20scale,=20density=20and=20viewport.=20Both=20the=20scroll=20?= =?UTF-8?q?and=20the=20fading=20viewport=20go=20through=20it.=20Not=20veri?= =?UTF-8?q?fied:=20the=20move=20of=20Prompt=20between=20the=20two=20screen?= =?UTF-8?q?s=20has=20not=20been=20tried=20with=20this=20change.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/draw/layout.rs | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/draw/layout.rs b/src/draw/layout.rs index ac21777..61ea6a1 100644 --- a/src/draw/layout.rs +++ b/src/draw/layout.rs @@ -17,6 +17,20 @@ use crate::widget::{ Element, LaidOutWidget, WidgetHandlers }; use super::DrawCtx; use super::damage::clamp_rect_to; +/// The previous frame's sub-canvas resized to `width × height`, or a new one when the parent's scale changed since, as a sub-canvas keeps the scale it was made with. +fn reuse_sub_canvas( pooled: Option, parent: &Canvas, width: u32, height: u32 ) -> Canvas +{ + match pooled + { + Some( mut sub ) if sub.dpi_scale() == parent.dpi_scale() => + { + if sub.size() != ( width, height ) { sub.resize( width, height ); } + sub + } + _ => parent.sub_canvas( width, height ), + } +} + pub( crate ) fn layout_and_draw( element: &Element, canvas: &mut Canvas, @@ -295,13 +309,9 @@ pub( crate ) fn layout_and_draw( ctx.scroll_offsets.insert( my_idx, ( ox, oy ) ); } - // Reuse the sub-canvas from the previous frame if its size matches; - // only reallocate when the viewport is resized. let sw = (rect.width.ceil() as u32).max( 1 ); let sh = (rect.height.ceil() as u32).max( 1 ); - let mut sub = ctx.scroll_canvases.remove( &my_idx ) - .map( |mut c| { if c.size() != ( sw, sh ) { c.resize( sw, sh ); } c } ) - .unwrap_or_else( || canvas.sub_canvas( sw, sh ) ); + let mut sub = reuse_sub_canvas( ctx.scroll_canvases.remove( &my_idx ), canvas, sw, sh ); sub.clear(); // Child content fills at least the full viewport on each @@ -462,9 +472,7 @@ pub( crate ) fn layout_and_draw( let vh = ( rect.height.ceil() as u32 ).max( 1 ); let seq = ctx.viewport_seq; ctx.viewport_seq += 1; - let mut sub = ctx.viewport_canvases.remove( &seq ) - .map( |mut c| { if c.size() != ( vw, vh ) { c.resize( vw, vh ); } c } ) - .unwrap_or_else( || canvas.sub_canvas( vw, vh ) ); + let mut sub = reuse_sub_canvas( ctx.viewport_canvases.remove( &seq ), canvas, vw, vh ); if v.local_viewport { sub.set_local_layout_viewport(); } sub.clear();