From 54679a9b683583321df5747673cdeae464c1405c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Mar 2026 22:56:24 +0000 Subject: [PATCH 1/3] Initial plan From e5bfe5987a92d3e65ef71e71909b79fecba072dc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Mar 2026 23:09:24 +0000 Subject: [PATCH 2/3] Add Draw trace category and instrument View.Drawing.cs and ApplicationImpl.LayoutAndDraw Co-authored-by: tig <585482+tig@users.noreply.github.com> --- Terminal.Gui/App/ApplicationImpl.Screen.cs | 6 +++ Terminal.Gui/App/Tracing/Trace.cs | 22 +++++++++++ Terminal.Gui/App/Tracing/TraceCategory.cs | 5 ++- Terminal.Gui/ViewBase/View.Drawing.cs | 11 ++++++ .../Tracing/TraceTests.cs | 37 +++++++++++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) diff --git a/Terminal.Gui/App/ApplicationImpl.Screen.cs b/Terminal.Gui/App/ApplicationImpl.Screen.cs index aa270eca8f..f9c12956fd 100644 --- a/Terminal.Gui/App/ApplicationImpl.Screen.cs +++ b/Terminal.Gui/App/ApplicationImpl.Screen.cs @@ -1,5 +1,7 @@ namespace Terminal.Gui.App; +using Trace = Terminal.Gui.Tracing.Trace; + internal partial class ApplicationImpl { /// @@ -48,6 +50,8 @@ private void RaiseScreenChangedEvent (Rectangle screen) /// public void LayoutAndDraw (bool forceRedraw = false) { + Trace.Draw ("ApplicationImpl", "Start", $"forceRedraw={forceRedraw}"); + if (ClearScreenNextIteration) { forceRedraw = true; @@ -94,5 +98,7 @@ public void LayoutAndDraw (bool forceRedraw = false) // Cause the driver to flush any pending updates to the terminal Driver?.Refresh (); } + + Trace.Draw ("ApplicationImpl", "End", $"neededLayout={neededLayout}, needsDraw={needsDraw}"); } } diff --git a/Terminal.Gui/App/Tracing/Trace.cs b/Terminal.Gui/App/Tracing/Trace.cs index f5ade35763..2855e6bdc4 100644 --- a/Terminal.Gui/App/Tracing/Trace.cs +++ b/Terminal.Gui/App/Tracing/Trace.cs @@ -286,6 +286,28 @@ public static void Configuration (string? id, string phase, string? message = nu #endregion + #region Draw Tracing + + /// + /// Traces a draw operation. + /// + /// An identifying string for the trace (e.g., ). + /// The phase of the draw operation (e.g., "Start", "End", "Adornments", "SubViews", "Text", "Content"). + /// Optional additional context. + /// Automatically captured caller method name. + [Conditional ("DEBUG")] + public static void Draw (string? id, string phase, string? message = null, [CallerMemberName] string method = "") + { + if (!EnabledCategories.HasFlag (TraceCategory.Draw)) + { + return; + } + + Backend.Log (new TraceEntry (TraceCategory.Draw, id ?? string.Empty, phase, method, message, DateTime.UtcNow, null)); + } + + #endregion + #region Keyboard Tracing /// diff --git a/Terminal.Gui/App/Tracing/TraceCategory.cs b/Terminal.Gui/App/Tracing/TraceCategory.cs index 889d9e551c..ef1bfab0c8 100644 --- a/Terminal.Gui/App/Tracing/TraceCategory.cs +++ b/Terminal.Gui/App/Tracing/TraceCategory.cs @@ -29,6 +29,9 @@ public enum TraceCategory /// Configuration management traces (property discovery, source loading, property assignment). Configuration = 32, + /// Draw operation traces (layout-and-draw, view draw phases, adornments, subviews). + Draw = 64, + /// All trace categories enabled. - All = Lifecycle | Command | Mouse | Keyboard | Navigation | Configuration + All = Lifecycle | Command | Mouse | Keyboard | Navigation | Configuration | Draw } diff --git a/Terminal.Gui/ViewBase/View.Drawing.cs b/Terminal.Gui/ViewBase/View.Drawing.cs index 4cab2ec8ea..585cb9d2b3 100644 --- a/Terminal.Gui/ViewBase/View.Drawing.cs +++ b/Terminal.Gui/ViewBase/View.Drawing.cs @@ -1,4 +1,5 @@ using System.ComponentModel; +using Terminal.Gui.Tracing; namespace Terminal.Gui.ViewBase; @@ -27,6 +28,7 @@ internal static void Draw (IEnumerable views, bool force) view.SetNeedsDraw (); } + Trace.Draw (view.ToIdentifyingString (), "Draw", $"force={force}"); view.Draw (context); } @@ -83,6 +85,8 @@ public void Draw (DrawContext? context = null) return; } + Trace.Draw (this.ToIdentifyingString (), "Start", $"NeedsDraw={NeedsDraw}, SubViewNeedsDraw={SubViewNeedsDraw}"); + Region? originalClip = GetClip (); // TODO: This can be further optimized by checking NeedsDraw below and only @@ -93,6 +97,7 @@ public void Draw (DrawContext? context = null) // Draw the Border and Padding Adornments. // Note: Margin with a Shadow is special-cased and drawn in a separate pass to support // transparent shadows. + Trace.Draw (this.ToIdentifyingString (), "Adornments"); DoDrawAdornments (originalClip); SetClip (originalClip); @@ -114,16 +119,19 @@ public void Draw (DrawContext? context = null) // Draw the SubViews first (order matters: SubViews, Text, Content) if (SubViewNeedsDraw) { + Trace.Draw (this.ToIdentifyingString (), "SubViews"); DoDrawSubViews (context); } // ------------------------------------ // Draw the text + Trace.Draw (this.ToIdentifyingString (), "Text"); SetAttributeForRole (Enabled ? VisualRole.Normal : VisualRole.Disabled); DoDrawText (context); // ------------------------------------ // Draw the content + Trace.Draw (this.ToIdentifyingString (), "Content"); DoDrawContent (context); // ------------------------------------ @@ -132,6 +140,7 @@ public void Draw (DrawContext? context = null) // because they may draw outside the viewport. SetClip (originalClip); originalClip = AddFrameToClip (); + Trace.Draw (this.ToIdentifyingString (), "LineCanvas"); DoRenderLineCanvas (context); // ------------------------------------ @@ -179,6 +188,8 @@ public void Draw (DrawContext? context = null) // But the context contains the region that was drawn by this view DoDrawComplete (context); + Trace.Draw (this.ToIdentifyingString (), "End"); + // When DoDrawComplete returns, Driver.Clip has been updated to exclude this view's area. // The next view drawn (earlier in Z-order, typically a peer view or the SuperView) will see // a clip with "holes" where this view (and any SubViews drawn before it) are located. diff --git a/Tests/UnitTestsParallelizable/Tracing/TraceTests.cs b/Tests/UnitTestsParallelizable/Tracing/TraceTests.cs index cbf5cffed0..d78ee532ad 100644 --- a/Tests/UnitTestsParallelizable/Tracing/TraceTests.cs +++ b/Tests/UnitTestsParallelizable/Tracing/TraceTests.cs @@ -476,6 +476,43 @@ public void LoggingBackend_FormatsConfigurationCorrectly () #endregion + #region Draw Category Tests + + // Copilot + [Fact] + public void TraceCategory_Draw_HasExpectedValue () + { + Assert.Equal (64, (int)TraceCategory.Draw); + } + + // Copilot + [Fact] + public void TraceCategory_All_IncludesDraw () + { + Assert.True (TraceCategory.All.HasFlag (TraceCategory.Draw)); + } + + // Copilot + [Fact] + public void Draw_Category_CanBeEnabled () + { + Trace.EnabledCategories = TraceCategory.None; + + try + { + Trace.EnabledCategories = TraceCategory.Draw; + + Assert.True (Trace.EnabledCategories.HasFlag (TraceCategory.Draw)); + } + finally + { + Trace.EnabledCategories = TraceCategory.None; + Trace.Backend = new NullBackend (); + } + } + + #endregion + #region Scenario Tests (merged from IssueScenarioTraceTests) /// From 478c5f835136433ee88d0c6c5e2e9d87a3dd01ee Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 12 Mar 2026 13:38:49 +0000 Subject: [PATCH 3/3] Add Configuration and Draw menu items to UICatalog Logging menu Co-authored-by: tig <585482+tig@users.noreply.github.com> --- Examples/UICatalog/UICatalogRunnable.cs | 42 +++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/Examples/UICatalog/UICatalogRunnable.cs b/Examples/UICatalog/UICatalogRunnable.cs index 3f3a3b3c0e..c7e3b4bb1b 100644 --- a/Examples/UICatalog/UICatalogRunnable.cs +++ b/Examples/UICatalog/UICatalogRunnable.cs @@ -398,6 +398,48 @@ View [] CreateLoggingMenuItems () Enabled = false, CommandView = navTraceCheckBox, HelpText = "Toggle Focus & TabBehavior tracing", Key = Key.K.WithCtrl }); + CheckBox configTraceCheckBox = new () + { + Text = "Con_figuration", + Value = Trace.EnabledCategories.HasFlag (TraceCategory.Configuration) ? CheckState.Checked : CheckState.UnChecked, + CanFocus = false + }; + + configTraceCheckBox.ValueChanging += (_, e) => + { + if (e.NewValue == CheckState.Checked) + { + Trace.EnabledCategories |= TraceCategory.Configuration; + } + else + { + Trace.EnabledCategories &= ~TraceCategory.Configuration; + } + }; + + menuItems.Add (new MenuItem { CommandView = configTraceCheckBox, HelpText = "Toggle Configuration management tracing" }); + + CheckBox drawTraceCheckBox = new () + { + Text = "_Draw", + Value = Trace.EnabledCategories.HasFlag (TraceCategory.Draw) ? CheckState.Checked : CheckState.UnChecked, + CanFocus = false + }; + + drawTraceCheckBox.ValueChanging += (_, e) => + { + if (e.NewValue == CheckState.Checked) + { + Trace.EnabledCategories |= TraceCategory.Draw; + } + else + { + Trace.EnabledCategories &= ~TraceCategory.Draw; + } + }; + + menuItems.Add (new MenuItem { CommandView = drawTraceCheckBox, HelpText = "Toggle Draw operation tracing" }); + // add a separator menuItems.Add (new Line ());