From 4ce1310371b83e205644b398b139964ec2abe218 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 2 Feb 2026 11:20:37 -0800 Subject: [PATCH] renderer: reset overlay anytime sizing changes Fixes #10522 This also fixes possible runtime safety crashes. Whenever the underlying size information doesn't match what our renderer or grid see, then we should deinit and reinit. --- src/renderer/generic.zig | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/renderer/generic.zig b/src/renderer/generic.zig index c8acebd0f..a56d117bb 100644 --- a/src/renderer/generic.zig +++ b/src/renderer/generic.zig @@ -2206,10 +2206,35 @@ pub fn Renderer(comptime GraphicsAPI: type) type { } // If we had a previous overlay, clear it. Otherwise, init. - const overlay: *Overlay = if (self.overlay) |*v| overlay: { - v.reset(); - break :overlay v; - } else overlay: { + const overlay: *Overlay = overlay: { + if (self.overlay) |*v| existing: { + // Verify that our overlay size matches our screen + // size as we know it now. If not, deinit and reinit. + // Note: these intCasts are always safe because z2d + // stores as i32 but we always init with a u32. + const width: u32 = @intCast(v.surface.getWidth()); + const height: u32 = @intCast(v.surface.getHeight()); + const term_size = self.size.terminal(); + if (width != term_size.width or + height != term_size.height) break :existing; + + // We also depend on cell size. + if (v.cell_size.width != self.size.cell.width or + v.cell_size.height != self.size.cell.height) break :existing; + + // Everything matches, so we can just reset the surface + // and redraw. + v.reset(); + break :overlay v; + } + + // If we reached this point we want to reset our overlay. + if (self.overlay) |*v| { + v.deinit(alloc); + self.overlay = null; + } + + assert(self.overlay == null); const new: Overlay = try .init(alloc, self.size); self.overlay = new; break :overlay &self.overlay.?;