diff --git a/Terminal.Gui/Application/Application.Initialization.cs b/Terminal.Gui/Application/Application.Initialization.cs
index a971850e3..16b7b83d4 100644
--- a/Terminal.Gui/Application/Application.Initialization.cs
+++ b/Terminal.Gui/Application/Application.Initialization.cs
@@ -40,7 +40,6 @@ public static partial class Application // Initialization (Init/Shutdown)
internal static bool _initialized;
internal static int _mainThreadId = -1;
-
// INTERNAL function for initializing an app with a Toplevel factory object, driver, and mainloop.
//
// Called from:
diff --git a/Terminal.Gui/Application/Application.Keyboard.cs b/Terminal.Gui/Application/Application.Keyboard.cs
index e8d698286..703a84982 100644
--- a/Terminal.Gui/Application/Application.Keyboard.cs
+++ b/Terminal.Gui/Application/Application.Keyboard.cs
@@ -25,6 +25,7 @@ public static partial class Application // Keyboard handling
private static void OnAlternateForwardKeyChanged (KeyChangedEventArgs e)
{
+ // TODO: The fact Top has it's own AlternateForwardKey and events is needlessly complex. Remove it.
foreach (Toplevel top in _topLevels.ToArray ())
{
top.OnAlternateForwardKeyChanged (e);
@@ -52,6 +53,7 @@ public static partial class Application // Keyboard handling
private static void OnAlternateBackwardKeyChanged (KeyChangedEventArgs oldKey)
{
+ // TODO: The fact Top has it's own AlternateBackwardKey and events is needlessly complex. Remove it.
foreach (Toplevel top in _topLevels.ToArray ())
{
top.OnAlternateBackwardKeyChanged (oldKey);
@@ -79,6 +81,7 @@ public static partial class Application // Keyboard handling
private static void OnQuitKeyChanged (KeyChangedEventArgs e)
{
+ // TODO: The fact Top has it's own QuitKey and events is needlessly complex. Remove it.
// Duplicate the list so if it changes during enumeration we're safe
foreach (Toplevel top in _topLevels.ToArray ())
{
diff --git a/Terminal.Gui/Application/Application.cs b/Terminal.Gui/Application/Application.cs
index 202b66044..3b4c9d9f7 100644
--- a/Terminal.Gui/Application/Application.cs
+++ b/Terminal.Gui/Application/Application.cs
@@ -137,232 +137,14 @@ public static partial class Application
SynchronizationContext.SetSynchronizationContext (null);
}
- // When `End ()` is called, it is possible `RunState.Toplevel` is a different object than `Top`.
- // This field is set in `End` in this case so that `Begin` correctly sets `Top`.
-
- // TODO: Determine if this is really needed. The only code that calls WakeUp I can find
- // is ProgressBarStyles, and it's not clear it needs to.
-
- #region Toplevel handling
-
- /// Holds the stack of TopLevel views.
-
- // BUGBUG: Technically, this is not the full lst of TopLevels. There be dragons here, e.g. see how Toplevel.Id is used. What
- // about TopLevels that are just a SubView of another View?
- internal static readonly Stack _topLevels = new ();
-
- /// The object used for the application on startup ()
- /// The top.
- public static Toplevel? Top { get; private set; }
-
- ///
- /// The current object. This is updated in enters and leaves to
- /// point to the current
- /// .
- ///
- ///
- /// Only relevant in scenarios where is .
- ///
- /// The current.
- public static Toplevel? Current { get; private set; }
-
- private static void EnsureModalOrVisibleAlwaysOnTop (Toplevel topLevel)
- {
- if (!topLevel.Running
- || (topLevel == Current && topLevel.Visible)
- || OverlappedTop == null
- || _topLevels.Peek ().Modal)
- {
- return;
- }
-
- foreach (Toplevel? top in _topLevels.Reverse ())
- {
- if (top.Modal && top != Current)
- {
- MoveCurrent (top);
-
- return;
- }
- }
-
- if (!topLevel.Visible && topLevel == Current)
- {
- OverlappedMoveNext ();
- }
- }
-
#nullable enable
- private static Toplevel? FindDeepestTop (Toplevel start, in Point location)
- {
- if (!start.Frame.Contains (location))
- {
- return null;
- }
-
- if (_topLevels is { Count: > 0 })
- {
- int rx = location.X - start.Frame.X;
- int ry = location.Y - start.Frame.Y;
-
- foreach (Toplevel? t in _topLevels)
- {
- if (t != Current)
- {
- if (t != start && t.Visible && t.Frame.Contains (rx, ry))
- {
- start = t;
-
- break;
- }
- }
- }
- }
-
- return start;
- }
#nullable restore
- private static View FindTopFromView (View view)
- {
- View top = view?.SuperView is { } && view?.SuperView != Top
- ? view.SuperView
- : view;
-
- while (top?.SuperView is { } && top?.SuperView != Top)
- {
- top = top.SuperView;
- }
-
- return top;
- }
-
#nullable enable
// Only return true if the Current has changed.
- private static bool MoveCurrent (Toplevel top)
- {
- // The Current is modal and the top is not modal Toplevel then
- // the Current must be moved above the first not modal Toplevel.
- if (OverlappedTop is { }
- && top != OverlappedTop
- && top != Current
- && Current?.Modal == true
- && !_topLevels.Peek ().Modal)
- {
- lock (_topLevels)
- {
- _topLevels.MoveTo (Current, 0, new ToplevelEqualityComparer ());
- }
-
- var index = 0;
- Toplevel? [] savedToplevels = _topLevels.ToArray ();
-
- foreach (Toplevel? t in savedToplevels)
- {
- if (!t!.Modal && t != Current && t != top && t != savedToplevels [index])
- {
- lock (_topLevels)
- {
- _topLevels.MoveTo (top, index, new ToplevelEqualityComparer ());
- }
- }
-
- index++;
- }
-
- return false;
- }
-
- // The Current and the top are both not running Toplevel then
- // the top must be moved above the first not running Toplevel.
- if (OverlappedTop is { }
- && top != OverlappedTop
- && top != Current
- && Current?.Running == false
- && top?.Running == false)
- {
- lock (_topLevels)
- {
- _topLevels.MoveTo (Current, 0, new ToplevelEqualityComparer ());
- }
-
- var index = 0;
-
- foreach (Toplevel? t in _topLevels.ToArray ())
- {
- if (!t.Running && t != Current && index > 0)
- {
- lock (_topLevels)
- {
- _topLevels.MoveTo (top, index - 1, new ToplevelEqualityComparer ());
- }
- }
-
- index++;
- }
-
- return false;
- }
-
- if ((OverlappedTop is { } && top?.Modal == true && _topLevels.Peek () != top)
- || (OverlappedTop is { } && Current != OverlappedTop && Current?.Modal == false && top == OverlappedTop)
- || (OverlappedTop is { } && Current?.Modal == false && top != Current)
- || (OverlappedTop is { } && Current?.Modal == true && top == OverlappedTop))
- {
- lock (_topLevels)
- {
- _topLevels.MoveTo (top, 0, new ToplevelEqualityComparer ());
- Current = top;
- }
- }
-
- return true;
- }
#nullable restore
- /// Invoked when the terminal's size changed. The new size of the terminal is provided.
- ///
- /// Event handlers can set to to prevent
- /// from changing it's size to match the new terminal size.
- ///
- public static event EventHandler SizeChanging;
-
- ///
- /// Called when the application's size changes. Sets the size of all s and fires the
- /// event.
- ///
- /// The new size.
- /// if the size was changed.
- public static bool OnSizeChanging (SizeChangedEventArgs args)
- {
- SizeChanging?.Invoke (null, args);
-
- if (args.Cancel || args.Size is null)
- {
- return false;
- }
-
- foreach (Toplevel t in _topLevels)
- {
- t.SetRelativeLayout (args.Size.Value);
- t.LayoutSubviews ();
- t.PositionToplevels ();
- t.OnSizeChanging (new (args.Size));
-
- if (PositionCursor (t))
- {
- Driver.UpdateCursor ();
- }
- }
-
- Refresh ();
-
- return true;
- }
-
- #endregion Toplevel handling
-
///
/// Gets a string representation of the Application as rendered by .
///
diff --git a/Terminal.Gui/Views/Toplevel.cs b/Terminal.Gui/Views/Toplevel.cs
index 617dfa7fc..32d8f8a89 100644
--- a/Terminal.Gui/Views/Toplevel.cs
+++ b/Terminal.Gui/Views/Toplevel.cs
@@ -6,7 +6,7 @@ namespace Terminal.Gui;
///
///
///
-/// Toplevels can run as modal (popup) views, started by calling
+/// Toplevel views can run as modal (popup) views, started by calling
/// . They return control to the caller when
/// has been called (which sets the
/// property to false).
@@ -14,7 +14,7 @@ namespace Terminal.Gui;
///
/// A Toplevel is created when an application initializes Terminal.Gui by calling .
/// The application Toplevel can be accessed via . Additional Toplevels can be created
-/// and run (e.g. s. To run a Toplevel, create the and call
+/// and run (e.g. s). To run a Toplevel, create the and call
/// .
///
///
@@ -259,32 +259,30 @@ public partial class Toplevel : View
return;
}
- if (NeedsDisplay || SubViewNeedsDisplay || LayoutNeeded)
+ if (NeedsDisplay || SubViewNeedsDisplay /*|| LayoutNeeded*/)
{
- //Driver.SetAttribute (GetNormalColor ());
- // TODO: It's bad practice for views to always clear. Defeats the purpose of clipping etc...
Clear ();
- LayoutSubviews ();
- PositionToplevels ();
+ //LayoutSubviews ();
+ //PositionToplevels ();
- if (this == Application.OverlappedTop)
- {
- foreach (Toplevel top in Application.OverlappedChildren.AsEnumerable ().Reverse ())
- {
- if (top.Frame.IntersectsWith (Viewport))
- {
- if (top != this && !top.IsCurrentTop && !OutsideTopFrame (top) && top.Visible)
- {
- top.SetNeedsLayout ();
- top.SetNeedsDisplay (top.Viewport);
- top.Draw ();
- top.OnRenderLineCanvas ();
- }
- }
- }
- }
+ //if (this == Application.OverlappedTop)
+ //{
+ // foreach (Toplevel top in Application.OverlappedChildren.AsEnumerable ().Reverse ())
+ // {
+ // if (top.Frame.IntersectsWith (Viewport))
+ // {
+ // if (top != this && !top.IsCurrentTop && !OutsideTopFrame (top) && top.Visible)
+ // {
+ // top.SetNeedsLayout ();
+ // top.SetNeedsDisplay (top.Viewport);
+ // top.Draw ();
+ // top.OnRenderLineCanvas ();
+ // }
+ // }
+ // }
+ //}
- // This should not be here, but in base
+ // BUGBUG: This appears to be a hack to get ScrollBarViews to render correctly.
foreach (View view in Subviews)
{
if (view.Frame.IntersectsWith (Viewport) && !OutsideTopFrame (this))
@@ -296,12 +294,6 @@ public partial class Toplevel : View
}
base.OnDrawContent (viewport);
-
- // This is causing the menus drawn incorrectly if UseSubMenusSingleFrame is true
- //if (this.MenuBar is { } && this.MenuBar.IsMenuOpen && this.MenuBar.openMenu is { }) {
- // // TODO: Hack until we can get compositing working right.
- // this.MenuBar.openMenu.Redraw (this.MenuBar.openMenu.Viewport);
- //}
}
}
@@ -315,6 +307,9 @@ public partial class Toplevel : View
/// Called from before the redraws for the first
/// time.
///
+ ///
+ /// Overrides must call base.OnLoaded() to ensure any Toplevel subviews are initialized properly and the event is raised.
+ ///
public virtual void OnLoaded ()
{
IsLoaded = true;