From 4738e8535a4ad3815840652be47bfbecc97700bd Mon Sep 17 00:00:00 2001 From: Tig Date: Thu, 4 Dec 2025 16:32:24 -0700 Subject: [PATCH] Optimize screen handling and drawing logic Added a thread-safe lock mechanism (`_lockScreen`) to ensure safe updates to the `_screen` field, enabling future support for changing the `Driver` based on screen values. Improved the `ResetScreen` method documentation to clarify its purpose. Optimized the `LayoutAndDraw` method by: - Adding a layout step to adjust views based on screen size. - Reducing unnecessary redraws by selectively updating views that require it. - Ensuring the terminal driver flushes updates with `Driver?.Refresh()`. Removed redundant logging to streamline the code. --- Terminal.Gui/App/ApplicationImpl.Screen.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Terminal.Gui/App/ApplicationImpl.Screen.cs b/Terminal.Gui/App/ApplicationImpl.Screen.cs index ac69266ce..2605156dc 100644 --- a/Terminal.Gui/App/ApplicationImpl.Screen.cs +++ b/Terminal.Gui/App/ApplicationImpl.Screen.cs @@ -30,6 +30,8 @@ internal partial class ApplicationImpl throw new NotImplementedException ("Screen locations other than 0, 0 are not yet supported"); } + // TODO: Enable this to actually change the Driver. + lock (_lockScreen) { _screen = value; @@ -114,7 +116,7 @@ internal partial class ApplicationImpl } /// - /// INTERNAL: Resets the Screen field to null so it will be recalculated on next access. + /// INTERNAL: Resets the Screen rectangle to null so it will be recalculated on next access. /// private void ResetScreen () { @@ -169,20 +171,25 @@ internal partial class ApplicationImpl views.Insert (0, visiblePopover); } + // Layout bool neededLayout = View.Layout (views.ToArray ().Reverse ()!, Screen.Size); + // Draw bool needsDraw = forceRedraw || views.Any (v => v is { NeedsDraw: true } or { SubViewNeedsDraw: true }); if (Driver is { } && (neededLayout || needsDraw)) { Logging.Redraws.Add (1); - Logging.Trace ("LayoutAndDraw"); Driver.Clip = new (Screen); + // Only force a complete redraw if needed (needsLayout or forceRedraw). + // Otherwise, just redraw views that need it. View.Draw (views: views.ToArray ().Cast ()!, neededLayout || forceRedraw); Driver.Clip = new (Screen); + + // Cause the driver to flush any pending updates to the terminal Driver?.Refresh (); } }