diff --git a/frontends/rioterm/src/layout/compute_tests.rs b/frontends/rioterm/src/layout/compute_tests.rs index 266737bf..fae0f90f 100644 --- a/frontends/rioterm/src/layout/compute_tests.rs +++ b/frontends/rioterm/src/layout/compute_tests.rs @@ -261,6 +261,28 @@ fn test_compute_margin_exceeds_size() { assert_eq!(rows, MIN_LINES); } +#[test] +fn test_context_dimension_update_scale_refreshes_scaled_font_size() { + let dims = TextDimensions { + width: 8.0, + height: 16.0, + scale: 1.0, + }; + let cell = cell_for(dims); + let mut context = + ContextDimension::build(800.0, 600.0, dims, cell, 1.0, 14.0, Margin::all(10.0)); + + context.update_scale(2.0); + + assert_eq!(context.dimension.scale, 2.0); + assert_eq!(context.scaled_font_size, 28.0); + // Width/height-derived layout is recomputed separately after the new + // cell metrics are installed, so update_scale itself must not clobber + // the current row/column counts. + assert_eq!(context.columns, 97); + assert_eq!(context.lines, 36); +} + #[test] fn test_context_dimension_build() { let dims = TextDimensions { diff --git a/frontends/rioterm/src/layout/mod.rs b/frontends/rioterm/src/layout/mod.rs index 0e36e287..4edd878e 100644 --- a/frontends/rioterm/src/layout/mod.rs +++ b/frontends/rioterm/src/layout/mod.rs @@ -1673,6 +1673,15 @@ impl ContextDimension { // recomputed metrics do. } + /// Update only the stored scale factor. Caller must follow with + /// `compute_cell_metrics` + `update_dimensions` so width/height + /// and canonical cell stride are recomputed for the new DPI. + #[inline] + pub fn update_scale(&mut self, scale: f32) { + self.dimension.scale = scale; + self.scaled_font_size = self.font_size * scale; + } + /// Re-baseline the font size — both current and "original". /// Called from `update_config` so a config edit becomes the new /// reset target. Per-panel zoom (`change_font_size`) uses diff --git a/frontends/rioterm/src/screen/mod.rs b/frontends/rioterm/src/screen/mod.rs index 070bf03c..5ef264c6 100644 --- a/frontends/rioterm/src/screen/mod.rs +++ b/frontends/rioterm/src/screen/mod.rs @@ -601,16 +601,37 @@ impl Screen<'_> { ) -> &mut Self { self.sugarloaf.rescale(new_scale); self.sugarloaf.resize(new_size.width, new_size.height); - self.mark_dirty(); - self.resize_all_contexts(); - self.context_manager - .current_grid_mut() - .update_dimensions(&mut self.sugarloaf); + + for context_grid in self.context_manager.contexts_mut() { + let old_scale = context_grid.current().dimension.dimension.scale.max(1.0); + let scaled_margin = context_grid.scaled_margin; + let unscaled_margin = Margin::new( + scaled_margin.top / old_scale, + scaled_margin.right / old_scale, + scaled_margin.bottom / old_scale, + scaled_margin.left / old_scale, + ); + + context_grid.update_scaled_margin(Margin::new( + unscaled_margin.top * new_scale, + unscaled_margin.right * new_scale, + unscaled_margin.bottom * new_scale, + unscaled_margin.left * new_scale, + )); + + for context in context_grid.contexts_mut().values_mut() { + context.context_mut().dimension.update_scale(new_scale); + } + + context_grid.update_dimensions(&mut self.sugarloaf); + } + let width = new_size.width as f32; let height = new_size.height as f32; self.context_manager .resize_all_grids(width, height, &mut self.sugarloaf); + self.mark_dirty(); self }