From 2ec08d5939d8b966ae73247db7a170478b74ed08 Mon Sep 17 00:00:00 2001 From: BDisp Date: Tue, 22 Jul 2025 20:57:38 +0100 Subject: [PATCH 1/3] Fixes #4198. Application.Invoke isn't wakeup the driver if idle (#4199) --- Terminal.Gui/App/ApplicationImpl.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Terminal.Gui/App/ApplicationImpl.cs b/Terminal.Gui/App/ApplicationImpl.cs index 4eadc2ad6..01465e6d1 100644 --- a/Terminal.Gui/App/ApplicationImpl.cs +++ b/Terminal.Gui/App/ApplicationImpl.cs @@ -293,6 +293,10 @@ public class ApplicationImpl : IApplication return false; } ); + + // Ensure the action is executed in the main loop + // Wakeup mainloop if it's waiting for events + Application.MainLoop.Wakeup (); } /// From 3b13d5a83ce6526d889e31cb4effa4dd376d5276 Mon Sep 17 00:00:00 2001 From: BDisp Date: Tue, 22 Jul 2025 20:58:10 +0100 Subject: [PATCH 2/3] Fixes #4196. Application.Begin doesn't refresh the screen at start (#4197) * Fixes #4196. Application.Begin doesn't refresh the screen at start * Reformatting to run CI again * Revert "Reformatting to run CI again" This reverts commit ef639c1e6489022a3df840147f2261239f9c2a5d. * Trying fix an issue where sometimes subview variable is null running unit tests * Add comment and decrease the delay time --- Terminal.Gui/App/Application.Run.cs | 12 ++++++++++-- Terminal.Gui/ViewBase/View.Drawing.cs | 2 +- Tests/UnitTests/Views/SpinnerViewTests.cs | 2 ++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Terminal.Gui/App/Application.Run.cs b/Terminal.Gui/App/Application.Run.cs index 30c1384a3..443e97ade 100644 --- a/Terminal.Gui/App/Application.Run.cs +++ b/Terminal.Gui/App/Application.Run.cs @@ -212,8 +212,16 @@ public static partial class Application // Run (Begin, Run, End, Stop) NotifyNewRunState?.Invoke (toplevel, new (rs)); - // Force an Idle event so that an Iteration (and Refresh) happen. - Invoke (() => { }); + if (!ConsoleDriver.RunningUnitTests) + { + // Force an Idle event to be added to timeout outside the Application.MainThreadId, + // so that an Iteration (and Refresh) happen in the Application.MainThreadId + Task.Run (() => + { + Invoke (() => { }); + Task.Delay (1).Wait (); + }); + } return rs; } diff --git a/Terminal.Gui/ViewBase/View.Drawing.cs b/Terminal.Gui/ViewBase/View.Drawing.cs index 912133e78..a8d2d4bf8 100644 --- a/Terminal.Gui/ViewBase/View.Drawing.cs +++ b/Terminal.Gui/ViewBase/View.Drawing.cs @@ -807,7 +807,7 @@ public partial class View // Drawing APIs } // There was multiple enumeration error here, so calling ToArray - probably a stop gap - foreach (View subview in SubViews.ToArray ()) + foreach (View subview in InternalSubViews) { if (subview.Frame.IntersectsWith (viewPortRelativeRegion)) { diff --git a/Tests/UnitTests/Views/SpinnerViewTests.cs b/Tests/UnitTests/Views/SpinnerViewTests.cs index 6382f8297..a77fa9488 100644 --- a/Tests/UnitTests/Views/SpinnerViewTests.cs +++ b/Tests/UnitTests/Views/SpinnerViewTests.cs @@ -11,6 +11,8 @@ public class SpinnerViewTests (ITestOutputHelper output) [InlineData (false)] public void TestSpinnerView_AutoSpin (bool callStop) { + ConsoleDriver.RunningUnitTests = true; + SpinnerView view = GetSpinnerView (); Assert.Empty (Application.MainLoop.TimedEvents.Timeouts); From add2877e09a2145c75c2e316c445c5c9fc0e7e89 Mon Sep 17 00:00:00 2001 From: BDisp Date: Thu, 24 Jul 2025 13:26:51 +0100 Subject: [PATCH 3/3] Fixes #4206. There is no need to use a Task.Run to force Invoke in the MainThreadId (#4207) --- Terminal.Gui/App/Application.Run.cs | 12 ++---------- Terminal.Gui/App/ApplicationImpl.cs | 13 ++++++++++--- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Terminal.Gui/App/Application.Run.cs b/Terminal.Gui/App/Application.Run.cs index 443e97ade..30c1384a3 100644 --- a/Terminal.Gui/App/Application.Run.cs +++ b/Terminal.Gui/App/Application.Run.cs @@ -212,16 +212,8 @@ public static partial class Application // Run (Begin, Run, End, Stop) NotifyNewRunState?.Invoke (toplevel, new (rs)); - if (!ConsoleDriver.RunningUnitTests) - { - // Force an Idle event to be added to timeout outside the Application.MainThreadId, - // so that an Iteration (and Refresh) happen in the Application.MainThreadId - Task.Run (() => - { - Invoke (() => { }); - Task.Delay (1).Wait (); - }); - } + // Force an Idle event so that an Iteration (and Refresh) happen. + Invoke (() => { }); return rs; } diff --git a/Terminal.Gui/App/ApplicationImpl.cs b/Terminal.Gui/App/ApplicationImpl.cs index 01465e6d1..d3b7fed57 100644 --- a/Terminal.Gui/App/ApplicationImpl.cs +++ b/Terminal.Gui/App/ApplicationImpl.cs @@ -275,6 +275,8 @@ public class ApplicationImpl : IApplication if (Application.MainThreadId == Thread.CurrentThread.ManagedThreadId) { action (); + WakeupMainLoop (); + return; } @@ -294,9 +296,14 @@ public class ApplicationImpl : IApplication } ); - // Ensure the action is executed in the main loop - // Wakeup mainloop if it's waiting for events - Application.MainLoop.Wakeup (); + WakeupMainLoop (); + + void WakeupMainLoop () + { + // Ensure the action is executed in the main loop + // Wakeup mainloop if it's waiting for events + Application.MainLoop?.Wakeup (); + } } ///