From ed05e17913cb4d04f8672575ba005516813c8788 Mon Sep 17 00:00:00 2001 From: Tig Date: Fri, 25 Oct 2024 08:08:16 -0600 Subject: [PATCH] Fixed issue with enter/leave --- Terminal.Gui/Application/Application.Mouse.cs | 9 +++++ Terminal.Gui/Application/Application.Run.cs | 37 ++++++++++++------- Terminal.Gui/Views/FileDialog.cs | 1 + 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/Terminal.Gui/Application/Application.Mouse.cs b/Terminal.Gui/Application/Application.Mouse.cs index a944c4c37..b440c65b9 100644 --- a/Terminal.Gui/Application/Application.Mouse.cs +++ b/Terminal.Gui/Application/Application.Mouse.cs @@ -249,6 +249,15 @@ public static partial class Application // Mouse handling View = deepestViewUnderMouse }; } + + // TODO: There should be a clearner way to to this + // Add a timeout to ensure at least one application iteration happens after each + // mouse event, enabling Refresh to be called. + Application.AddTimeout(new (0,0,0,0, 200), + () => + { + return false; + }); } diff --git a/Terminal.Gui/Application/Application.Run.cs b/Terminal.Gui/Application/Application.Run.cs index eb1e6c263..500a20fc0 100644 --- a/Terminal.Gui/Application/Application.Run.cs +++ b/Terminal.Gui/Application/Application.Run.cs @@ -169,11 +169,17 @@ public static partial class Application // Run (Begin, Run, End, Stop) Top.HasFocus = false; } + // Force leave events for any entered views in the old Top + if (GetLastMousePosition () is { }) + { + RaiseMouseEnterLeaveEvents (GetLastMousePosition ()!.Value, new List ()); + } + Top?.OnDeactivate (toplevel); - Toplevel previousCurrent = Top!; + Toplevel previousTop = Top!; Top = toplevel; - Top.OnActivate (previousCurrent); + Top.OnActivate (previousTop); } } @@ -182,10 +188,6 @@ public static partial class Application // Run (Begin, Run, End, Stop) { toplevel.BeginInit (); toplevel.EndInit (); // Calls Layout - - //// Force a layout - normally this is done each iteration of the main loop but we prime it here. - //toplevel.SetLayoutNeeded (); - //toplevel.Layout (Screen.Size); } // Try to set initial focus to any TabStop @@ -194,11 +196,6 @@ public static partial class Application // Run (Begin, Run, End, Stop) toplevel.SetFocus (); } - // DEBATE: Should Begin call Refresh (or Draw) here? It previously did. - // FOR: the screen has something on it after Begin is called. - // AGAINST: the screen is cleared and then redrawn in RunLoop. We don't want to draw twice. - //Refresh (); - toplevel.OnLoaded (); if (PositionCursor ()) @@ -513,14 +510,26 @@ public static partial class Application // Run (Begin, Run, End, Stop) //Driver?.ClearContents (); } - foreach (Toplevel tl in TopLevels.Reverse ()) + Stack redrawStack = new (TopLevels); + + while (redrawStack.Count > 0) { + Toplevel? tlToDraw = redrawStack.Pop (); + if (clear || forceRedraw) { - tl.SetNeedsDisplay (); + tlToDraw.SetNeedsDisplay (); } - tl.Draw (); + if (!(!View.CanBeVisible (tlToDraw) || tlToDraw is { NeedsDisplay: false, SubViewNeedsDisplay: false })) + { + tlToDraw.Draw (); + + if (redrawStack.TryPeek (out var nexToplevel)) + { + nexToplevel.SetNeedsDisplay(); + } + } } Driver?.Refresh (); diff --git a/Terminal.Gui/Views/FileDialog.cs b/Terminal.Gui/Views/FileDialog.cs index 133e04866..7b12b992d 100644 --- a/Terminal.Gui/Views/FileDialog.cs +++ b/Terminal.Gui/Views/FileDialog.cs @@ -494,6 +494,7 @@ public class FileDialog : Dialog MoveSubviewTowardsStart (_btnCancel); } + SetNeedsDisplay(); SetNeedsLayout(); }