From db5fdebfa9ad48bb80e1528dc7f262cea9676511 Mon Sep 17 00:00:00 2001 From: Tig Date: Sat, 25 Oct 2025 06:58:20 -0600 Subject: [PATCH] Fixes #4320 - `Dialog` focus (#4321) * Fixes #4320 - Dialog and MessageBox rendering of Text should ignore HasFocus Refactor and enhance text drawing logic Refactored `DoDrawText` in `View.Drawing.cs` to improve efficiency by adding early exits for unnecessary operations and introducing extensibility points (`OnDrawingText`, `OnDrewText`, and `DrewText` event). Simplified `DrawText` by delegating logic to `DoDrawText`. Added `OnDrewText` and `DrewText` event to allow custom post-draw handling. Updated `Dialog` class to ensure consistent text rendering using the `Normal` attribute and cleaned up event handling logic. * Update Terminal.Gui/ViewBase/View.Drawing.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Refactor Dialog text rendering logic Refactored the `Dialog` class to improve text rendering behavior: - Introduced `_drawingText` flag to track text drawing state. - Updated `OnDrawingText` to set `_drawingText` to `true`. - Updated `OnDrewText` to reset `_drawingText` to `false`. - Replaced `GettingAttributeForRoleHandler` with `OnGettingAttributeForRole`. - Ensures `VisualRole.Focus` uses the normal scheme attribute when drawing text. - Removed unused event handler `GettingAttributeForRoleHandler`. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Terminal.Gui/ViewBase/View.Drawing.cs | 31 ++++++++++++++++++--------- Terminal.Gui/Views/Dialog.cs | 30 ++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/Terminal.Gui/ViewBase/View.Drawing.cs b/Terminal.Gui/ViewBase/View.Drawing.cs index ff90c2731..6919b8e34 100644 --- a/Terminal.Gui/ViewBase/View.Drawing.cs +++ b/Terminal.Gui/ViewBase/View.Drawing.cs @@ -377,6 +377,16 @@ public partial class View // Drawing APIs private void DoDrawText (DrawContext? context = null) { + if (!NeedsDraw) + { + return; + } + + if (!string.IsNullOrEmpty (TextFormatter.Text)) + { + TextFormatter.NeedsFormat = true; + } + if (OnDrawingText (context)) { return; @@ -397,6 +407,9 @@ public partial class View // Drawing APIs } DrawText (context); + + OnDrewText(); + DrewText?.Invoke(this, EventArgs.Empty); } /// @@ -425,11 +438,6 @@ public partial class View // Drawing APIs /// The draw context to report drawn areas to. public void DrawText (DrawContext? context = null) { - if (!string.IsNullOrEmpty (TextFormatter.Text)) - { - TextFormatter.NeedsFormat = true; - } - var drawRect = new Rectangle (ContentToScreen (Point.Empty), GetContentSize ()); // Use GetDrawRegion to get precise drawn areas @@ -438,11 +446,6 @@ public partial class View // Drawing APIs // Report the drawn area to the context context?.AddDrawnRegion (textRegion); - if (!NeedsDraw) - { - return; - } - TextFormatter?.Draw ( drawRect, HasFocus ? GetAttributeForRole (VisualRole.Focus) : GetAttributeForRole (VisualRole.Normal), @@ -454,6 +457,14 @@ public partial class View // Drawing APIs SetSubViewNeedsDraw (); } + /// + /// Called when the of the View has been drawn. + /// + protected virtual void OnDrewText () { } + + /// Raised when the of the View has been drawn. + public event EventHandler? DrewText; + #endregion DrawText #region DrawContent diff --git a/Terminal.Gui/Views/Dialog.cs b/Terminal.Gui/Views/Dialog.cs index b6fc4af5e..bf5379f36 100644 --- a/Terminal.Gui/Views/Dialog.cs +++ b/Terminal.Gui/Views/Dialog.cs @@ -138,4 +138,34 @@ public class Dialog : Window /// [ConfigurationProperty (Scope = typeof (ThemeScope))] public new static ShadowStyle DefaultShadow { get; set; } = ShadowStyle.Transparent; + + + // Dialogs are Modal and Focus is indicated by their Border. The following code ensures the + // Text of the dialog (e.g. for a MessageBox) is always drawn using the Normal Attribute. + private bool _drawingText; + + /// + protected override bool OnDrawingText () + { + _drawingText = true; + return false; + } + + /// + protected override void OnDrewText () + { + _drawingText = false; + } + + /// + protected override bool OnGettingAttributeForRole (in VisualRole role, ref Attribute currentAttribute) + { + if (_drawingText && role is VisualRole.Focus && Border?.Thickness != Thickness.Empty) + { + currentAttribute = GetScheme ().Normal; + return true; + } + + return false; + } }