Преглед на файлове

OnEnter/Leave -> OnHasFocusChanging/OnHasFocusChanged

Tig преди 11 месеца
родител
ревизия
ef7f88d3b4
променени са 39 файла, в които са добавени 590 реда и са изтрити 658 реда
  1. 1 1
      README.md
  2. 1 1
      Terminal.Gui/Application/Application.Run.cs
  3. 1 1
      Terminal.Gui/Application/ApplicationOverlapped.cs
  4. 2 2
      Terminal.Gui/View/View.Hierarchy.cs
  5. 56 59
      Terminal.Gui/View/View.Navigation.cs
  6. 4 4
      Terminal.Gui/Views/ComboBox.cs
  7. 4 4
      Terminal.Gui/Views/FileDialog.cs
  8. 1 1
      Terminal.Gui/Views/ListView.cs
  9. 1 1
      Terminal.Gui/Views/Menu/Menu.cs
  10. 1 1
      Terminal.Gui/Views/Menu/MenuBar.cs
  11. 2 2
      Terminal.Gui/Views/Shortcut.cs
  12. 1 1
      Terminal.Gui/Views/TextField.cs
  13. 1 1
      Terminal.Gui/Views/TextView.cs
  14. 1 1
      Terminal.Gui/Views/TreeView/TreeView.cs
  15. 1 1
      UICatalog/KeyBindingsDialog.cs
  16. 2 2
      UICatalog/Scenarios/ASCIICustomButton.cs
  17. 3 3
      UICatalog/Scenarios/ConfigurationEditor.cs
  18. 2 2
      UICatalog/Scenarios/DynamicMenuBar.cs
  19. 1 1
      UICatalog/Scenarios/DynamicStatusBar.cs
  20. 2 2
      UICatalog/Scenarios/Editor.cs
  21. 5 5
      UICatalog/Scenarios/KeyBindings.cs
  22. 1 1
      UICatalog/Scenarios/MenuBarScenario.cs
  23. 3 3
      UICatalog/Scenarios/Notepad.cs
  24. 12 12
      UnitTests/FileServices/FileDialogTests.cs
  25. 3 3
      UnitTests/View/Navigation/AddRemoveTests.cs
  26. 0 451
      UnitTests/View/Navigation/EnterLeaveTests.cs
  27. 378 0
      UnitTests/View/Navigation/HasFocusEventTests.cs
  28. 16 16
      UnitTests/View/Navigation/NavigationTests.cs
  29. 5 5
      UnitTests/View/ViewTests.cs
  30. 28 28
      UnitTests/Views/OverlappedTests.cs
  31. 2 2
      UnitTests/Views/ScrollViewTests.cs
  32. 16 16
      UnitTests/Views/TabViewTests.cs
  33. 17 17
      UnitTests/Views/ToplevelTests.cs
  34. 1 1
      UnitTests/Views/TreeTableSourceTests.cs
  35. 3 3
      UnitTests/Views/WindowTests.cs
  36. 1 1
      docfx/docs/View.md
  37. 2 0
      docfx/docs/index.md
  38. 7 1
      docfx/docs/migratingfromv1.md
  39. 2 2
      docfx/docs/navigation.md

+ 1 - 1
README.md

@@ -35,7 +35,7 @@ dotnet run
 * [API Documentation](https://gui-cs.github.io/Terminal.GuiV2Docs/api/Terminal.Gui.html)
 * [Documentation Home](https://gui-cs.github.io/Terminal.GuiV2Docs)
 
-_The Documentation matches the most recent Nuget release from the `v2_develop` branch. The documentation for v1 is here: ([![Version](https://img.shields.io/nuget/v/Terminal.Gui.svg)](https://www.nuget.org/packages/Terminal.Gui))_
+The above documentation matches the most recent Nuget release from the `v2_develop` branch. Get the [v1 documentation here]( (This is the v2 API documentation. For v1 go here: https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui.html)
 
 See the [`Terminal.Gui/` README](https://github.com/gui-cs/Terminal.Gui/tree/master/Terminal.Gui) for an overview of how the library is structured. 
 

+ 1 - 1
Terminal.Gui/Application/Application.Run.cs

@@ -222,7 +222,7 @@ public static partial class Application // Run (Begin, Run, End, Stop)
     internal static bool PositionCursor (View view)
     {
         // Find the most focused view and position the cursor there.
-        View? mostFocused = view?.GetMostFocused ();
+        View? mostFocused = view?.MostFocused;
 
         if (mostFocused is null)
         {

+ 1 - 1
Terminal.Gui/Application/ApplicationOverlapped.cs

@@ -75,7 +75,7 @@ public static class ApplicationOverlapped
             return;
         }
 
-        View? top = FindTopFromView (Application.Top?.GetMostFocused ());
+        View? top = FindTopFromView (Application.Top?.MostFocused);
 
         if (top is Toplevel && Application.Top?.Subviews.Count > 1 && Application.Top.Subviews [^1] != top)
         {

+ 2 - 2
Terminal.Gui/View/View.Hierarchy.cs

@@ -196,7 +196,7 @@ public partial class View // SuperView/SubView hierarchy management (SuperView,
         // If a view being removed is focused, it should lose focus.
         if (view.HasFocus)
         {
-            view.LeaveFocus(this, true);
+            view.FocusChanged(this, true);
         }
 
         Rectangle touched = view.Frame;
@@ -217,7 +217,7 @@ public partial class View // SuperView/SubView hierarchy management (SuperView,
 
         if (HasFocus)
         {
-            FocusDeepest (TabStop, NavigationDirection.Forward);
+            FocusDeepest (NavigationDirection.Forward, TabStop);
         }
 
         OnRemoved (new (this, view));

+ 56 - 59
Terminal.Gui/View/View.Navigation.cs

@@ -21,8 +21,8 @@ public partial class View // Focus and cross-view navigation management (TabStop
     ///         these conditions are not met when this property is set to <see langword="true"/> <see cref="HasFocus"/> will not change.
     ///     </para>
     ///     <para>
-    ///         Setting this property causes the <see cref="OnEnter"/> and <see cref="OnLeave"/> virtual methods (and <see cref="Enter"/> and
-    ///         <see cref="Leave"/> events to be raised). If the event is cancelled, <see cref="HasFocus"/> will not be changed.
+    ///         Setting this property causes the <see cref="OnHasFocusChanging"/> and <see cref="OnHasFocusChanged"/> virtual methods (and <see cref="HasFocusChanging"/> and
+    ///         <see cref="HasFocusChanged"/> events to be raised). If the event is cancelled, <see cref="HasFocus"/> will not be changed.
     ///     </para>
     ///     <para>
     ///         Setting this property to <see langword="true"/> will recursively set <see cref="HasFocus"/> to
@@ -45,7 +45,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
             {
                 if (value)
                 {
-                    if (EnterFocus (Application.Navigation!.GetFocused ()))
+                    if (FocusChanging (Application.Navigation!.GetFocused ()))
                     {
                         // The change happened
                         // HasFocus is now true
@@ -53,7 +53,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
                 }
                 else
                 {
-                    LeaveFocus (null);
+                    FocusChanged (null);
                 }
             }
         }
@@ -66,18 +66,18 @@ public partial class View // Focus and cross-view navigation management (TabStop
     /// </summary>
     public bool SetFocus ()
     {
-        return EnterFocus (Application.Navigation?.GetFocused ());
+        return FocusChanging (Application.Navigation?.GetFocused ());
     }
 
     /// <summary>
-    ///     Called when view is entering focus. This method is called by <see cref="SetHasFocus"/> and other methods that
+    ///     INTERNAL: Called when focus is going to change to this view. This method is called by <see cref="SetFocus"/> and other methods that
     ///     set or remove focus from a view.
     /// </summary>
-    /// <param name="leavingView">The previously focused view. If <see langword="null"/> there is no previously focused view.</param>
+    /// <param name="previousFocusedView">The previously focused view. If <see langword="null"/> there is no previously focused view.</param>
     /// <param name="traversingUp"></param>
     /// <returns><see langword="true"/> if <see cref="HasFocus"/> was changed to <see langword="true"/>.</returns>
     /// <exception cref="InvalidOperationException"></exception>
-    private bool EnterFocus ([CanBeNull] View leavingView, bool traversingUp = false)
+    private bool FocusChanging ([CanBeNull] View previousFocusedView, bool traversingUp = false)
     {
         Debug.Assert (ApplicationNavigation.IsInHierarchy (SuperView, this));
 
@@ -89,7 +89,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
 
         if (CanFocus && SuperView is { CanFocus: false })
         {
-            Debug.WriteLine($@"WARNING: Attempt to EnterFocus where SuperView.CanFocus == false. {this}");
+            Debug.WriteLine($@"WARNING: Attempt to FocusChanging where SuperView.CanFocus == false. {this}");
             return false;
         }
 
@@ -107,7 +107,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
 
         if (!traversingUp)
         {
-            if (CancelEnterFocus (leavingView))
+            if (NotifyFocusChanging (previousFocusedView))
             {
                 return false;
             }
@@ -134,14 +134,14 @@ public partial class View // Focus and cross-view navigation management (TabStop
         // If we previously had a subview with focus (`Focused = subview`), we need to make sure that all subviews down the `subview`-hierarchy LeaveFocus.
         // LeaveFocus will recurse down the subview hierarchy and will also set PreviouslyMostFocused
         View focused = Focused;
-        focused?.LeaveFocus (this, true);
+        focused?.FocusChanged (this, true);
 
         // We need to ensure all superviews up the superview hierarchy have focus.
         // Any of them may cancel gaining focus. In which case we need to back out.
         if (SuperView is { HasFocus: false } sv)
         {
             // Tell EnterFocus that we're traversing up the superview hierarchy
-            if (!sv.EnterFocus (leavingView, true))
+            if (!sv.FocusChanging (previousFocusedView, true))
             {
                 // The change was cancelled
                 return false;
@@ -160,7 +160,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
         _hasFocus = true;
 
         // Ensure that the peer loses focus
-        focusedPeer?.LeaveFocus (this, true);
+        focusedPeer?.FocusChanged (this, true);
 
         // We're the most focused view in the application, we need to set the focused view to this view.
         Application.Navigation?.SetFocused (this);
@@ -170,24 +170,24 @@ public partial class View // Focus and cross-view navigation management (TabStop
         // Post-conditions - prove correctness
         if (HasFocus == previousValue)
         {
-            throw new InvalidOperationException ($"EnterFocus was not cancelled and the HasFocus value did not change.");
+            throw new InvalidOperationException ($"FocusChanging was not cancelled and the HasFocus value did not change.");
         }
 
         return true;
     }
 
 
-    private bool CancelEnterFocus (View leavingView)
+    private bool NotifyFocusChanging (View leavingView)
     {
         // Call the virtual method
-        if (OnEnter (leavingView))
+        if (OnHasFocusChanging (leavingView))
         {
             // The event was cancelled
             return true;
         }
 
         var args = new FocusEventArgs (leavingView, this);
-        Enter?.Invoke (this, args);
+        HasFocusChanging?.Invoke (this, args);
 
         if (args.Cancel)
         {
@@ -198,48 +198,44 @@ public partial class View // Focus and cross-view navigation management (TabStop
         return false;
     }
 
-    /// <summary>Virtual method invoked when this view is gaining focus (entering).</summary>
-    /// <param name="leavingView">The view that is leaving focus.</param>
+    /// <summary>Virtual method invoked when the focus is changing to this View.</summary>
+    /// <param name="currentlyFocusedView">The view that is currently Focused. May be <see langword="null"/>.</param>
     /// <returns> <see langword="true"/>, if the event is to be cancelled, <see langword="false"/> otherwise.</returns>
-    protected virtual bool OnEnter ([CanBeNull] View leavingView)
+    protected virtual bool OnHasFocusChanging ([CanBeNull] View currentlyFocusedView)
     {
         return false;
     }
 
     /// <summary>Raised when the view is gaining (entering) focus. Can be cancelled.</summary>
-    /// <remarks>
-    ///     Raised by <see cref="EnterFocus"/>.
-    /// </remarks>
-    public event EventHandler<FocusEventArgs> Enter;
+    public event EventHandler<FocusEventArgs> HasFocusChanging;
 
     /// <summary>
-    ///     Called when view is losing focus.
+    ///     Called when focus has changed to another view.
     /// </summary>
-    /// <param name="enteringView">The previously focused view. If <see langword="null"/> there is no previously focused view.</param>
-    /// <returns><see langword="true"/> if <see cref="HasFocus"/> was changed.</returns>
+    /// <param name="focusedVew">The view that now has focus. If <see langword="null"/> there is no view that has focus.</param>
     /// <exception cref="InvalidOperationException"></exception>
-    private void LeaveFocus ([CanBeNull] View enteringView, bool traversingDown = false)
+    private void FocusChanged ([CanBeNull] View focusedVew, bool traversingDown = false)
     {
         // Pre-conditions
         if (!_hasFocus)
         {
-            throw new InvalidOperationException ($"LeaveFocus should not be called if the view does not have focus.");
+            throw new InvalidOperationException ($"FocusChanged should not be called if the view does not have focus.");
         }
 
         // If enteringView is null, we need to find the view that should get focus, and SetFocus on it.
-        if (!traversingDown && enteringView is null)
+        if (!traversingDown && focusedVew is null)
         {
             if (SuperView?._previouslyMostFocused is { } && SuperView?._previouslyMostFocused != this)
             {
                 SuperView?._previouslyMostFocused?.SetFocus ();
 
-                // The above will cause LeaveFocus, so we can return
+                // The above will cause FocusChanged, so we can return
                 return;
             }
 
             if (SuperView is {} && SuperView.AdvanceFocus (NavigationDirection.Forward, TabStop))
             {
-                // The above will cause LeaveFocus, so we can return
+                // The above will cause FocusChanged, so we can return
                 return;
             }
 
@@ -259,8 +255,8 @@ public partial class View // Focus and cross-view navigation management (TabStop
         }
 
         // Before we can leave focus, we need to make sure that all views down the subview-hierarchy have left focus.
-        View mostFocused = GetMostFocused ();
-        if (mostFocused is { } && (enteringView is null || mostFocused != enteringView))
+        View mostFocused = MostFocused;
+        if (mostFocused is { } && (focusedVew is null || mostFocused != focusedVew))
         {
             // Start at the bottom and work our way up to us
             View bottom = mostFocused;
@@ -269,7 +265,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
             {
                 if (bottom.HasFocus)
                 {
-                    bottom.LeaveFocus (enteringView, true);
+                    bottom.FocusChanged (focusedVew, true);
                 }
                 bottom = bottom.SuperView;
             }
@@ -279,10 +275,10 @@ public partial class View // Focus and cross-view navigation management (TabStop
         bool previousValue = HasFocus;
 
         // Call the virtual method - NOTE: Leave cannot be cancelled
-        OnLeave (enteringView);
+        OnHasFocusChanged (focusedVew);
 
-        var args = new FocusEventArgs (enteringView, this);
-        Leave?.Invoke (this, args);
+        var args = new FocusEventArgs (focusedVew, this);
+        HasFocusChanged?.Invoke (this, args);
 
         // Get whatever peer has focus, if any
         View focusedPeer = SuperView?.Focused;
@@ -293,7 +289,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
             // Now ensure all views up the superview-hierarchy are unfocused
             if (SuperView is { HasFocus: true } && focusedPeer == this)
             {
-                SuperView.LeaveFocus (enteringView);
+                SuperView.FocusChanged (focusedVew);
             }
         }
 
@@ -312,18 +308,15 @@ public partial class View // Focus and cross-view navigation management (TabStop
     [CanBeNull]
     private View _previouslyMostFocused;
 
-    /// <summary>Virtual method invoked when this view is losing focus (leaving).</summary>
-    /// <param name="enteringView">The view that is gaining focus.</param>
-    protected virtual void OnLeave ([CanBeNull] View enteringView)
+    /// <summary>Virtual method invoked after another view gets focus. May be <see langword="null"/>.</summary>
+    /// <param name="focusedVew">The view is now focused.</param>
+    protected virtual void OnHasFocusChanged ([CanBeNull] View focusedVew)
     {
         return;
     }
 
-    /// <summary>Raised when the view is gaining (entering) focus. Can NOT be cancelled.</summary>
-    /// <remarks>
-    ///     Raised by <see cref="LeaveFocus"/>.
-    /// </remarks>
-    public event EventHandler<FocusEventArgs> Leave;
+    /// <summary>Raised when the view is gaining (entering) focus. Can not be cancelled.</summary>
+    public event EventHandler<FocusEventArgs> HasFocusChanged;
 
     #endregion HasFocus
 
@@ -399,7 +392,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
         }
 
         // The subview does not have focus, but at least one other that can. Can this one be focused?
-        return view.EnterFocus (Focused);
+        return view.FocusChanging (Focused);
     }
 
 
@@ -426,22 +419,26 @@ public partial class View // Focus and cross-view navigation management (TabStop
     /// <summary>
     ///     Returns the most focused Subview down the subview-hierarchy.
     /// </summary>
-    /// <returns>The most focused Subview, or <see langword="null"/> if no Subview is focused.</returns>
-    public View GetMostFocused ()
+    /// <value>The most focused Subview, or <see langword="null"/> if no Subview is focused.</value>
+    public View MostFocused
     {
-        if (Focused is null)
+        get
         {
-            return null;
-        }
+            // TODO: Remove this API. It's duplicative of Application.Navigation.GetFocused.
+            if (Focused is null)
+            {
+                return null;
+            }
 
-        View most = Focused!.GetMostFocused ();
+            View most = Focused!.MostFocused;
 
-        if (most is { })
-        {
-            return most;
-        }
+            if (most is { })
+            {
+                return most;
+            }
 
-        return Focused;
+            return Focused;
+        }
     }
 
     ///// <summary>

+ 4 - 4
Terminal.Gui/Views/ComboBox.cs

@@ -299,7 +299,7 @@ public class ComboBox : View, IDesignable
     }
 
     /// <inheritdoc/>
-    protected override bool OnEnter (View view)
+    protected override bool OnHasFocusChanging (View view)
     {
         if (!_search.HasFocus && !_listview.HasFocus)
         {
@@ -315,7 +315,7 @@ public class ComboBox : View, IDesignable
     public virtual void OnExpanded () { Expanded?.Invoke (this, EventArgs.Empty); }
 
     /// <inheritdoc/>
-    protected override void OnLeave (View view)
+    protected override void OnHasFocusChanged (View view)
     {
         if (_source?.Count > 0
             && _selectedItem > -1
@@ -940,7 +940,7 @@ public class ComboBox : View, IDesignable
             }
         }
 
-        protected override bool OnEnter (View view)
+        protected override bool OnHasFocusChanging (View view)
         {
             if (_hideDropdownListOnClick)
             {
@@ -952,7 +952,7 @@ public class ComboBox : View, IDesignable
             return false; // Don't cancel the focus switch
         }
 
-        protected override void OnLeave (View view)
+        protected override void OnHasFocusChanged (View view)
         {
             if (_hideDropdownListOnClick)
             {

+ 4 - 4
Terminal.Gui/Views/FileDialog.cs

@@ -518,7 +518,7 @@ public class FileDialog : Dialog
             };
             AllowedTypeMenuClicked (0);
 
-            _allowedTypeMenuBar.Enter += (s, e) => { _allowedTypeMenuBar.OpenMenu (0); };
+            _allowedTypeMenuBar.HasFocusChanging += (s, e) => { _allowedTypeMenuBar.OpenMenu (0); };
 
             _allowedTypeMenuBar.DrawContentComplete += (s, e) =>
                                                        {
@@ -538,7 +538,7 @@ public class FileDialog : Dialog
         // to streamline user experience and allow direct typing of paths
         // with zero navigation we start with focus in the text box and any
         // default/current path fully selected and ready to be overwritten
-        _tbPath.FocusDeepest (null, NavigationDirection.Forward);
+        _tbPath.FocusDeepest (NavigationDirection.Forward, null);
         _tbPath.SelectAll ();
 
         if (string.IsNullOrEmpty (Title))
@@ -1050,7 +1050,7 @@ public class FileDialog : Dialog
     {
         if (keyEvent.KeyCode == isKey)
         {
-            to.FocusDeepest (null, NavigationDirection.Forward);
+            to.FocusDeepest (NavigationDirection.Forward, null);
 
             if (to == _tbPath)
             {
@@ -1439,7 +1439,7 @@ public class FileDialog : Dialog
     {
         if (_treeView.HasFocus && Separators.Contains ((char)keyEvent))
         {
-            _tbPath.FocusDeepest (null, NavigationDirection.Forward);
+            _tbPath.FocusDeepest (NavigationDirection.Forward, null);
 
             // let that keystroke go through on the tbPath instead
             return true;

+ 1 - 1
Terminal.Gui/Views/ListView.cs

@@ -739,7 +739,7 @@ public class ListView : View, IDesignable
     }
 
     /// <inheritdoc/>
-    protected override bool OnEnter (View view)
+    protected override bool OnHasFocusChanging (View view)
     {
         if (_lastSelectedItem != _selected)
         {

+ 1 - 1
Terminal.Gui/Views/Menu/Menu.cs

@@ -587,7 +587,7 @@ internal sealed class Menu : View
         _host.Run (action);
     }
 
-    protected override void OnLeave (View view)
+    protected override void OnHasFocusChanged (View view)
     {
         _host.LostFocus (view);
 

+ 1 - 1
Terminal.Gui/Views/Menu/MenuBar.cs

@@ -755,7 +755,7 @@ public class MenuBar : View, IDesignable
         {
             case null:
                 // Open a submenu below a MenuBar
-                _lastFocused ??= SuperView is null ? Application.Current?.GetMostFocused () : SuperView.GetMostFocused ();
+                _lastFocused ??= SuperView is null ? Application.Current?.MostFocused : SuperView.MostFocused;
 
                 if (_openSubMenu is { } && !CloseMenu (false, true))
                 {

+ 2 - 2
Terminal.Gui/Views/Shortcut.cs

@@ -837,7 +837,7 @@ public class Shortcut : View, IOrientation, IDesignable
     private View _lastFocusedView;
 
     /// <inheritdoc/>
-    protected override bool OnEnter (View view)
+    protected override bool OnHasFocusChanging (View view)
     {
         SetColors ();
         _lastFocusedView = view;
@@ -846,7 +846,7 @@ public class Shortcut : View, IOrientation, IDesignable
     }
 
     /// <inheritdoc/>
-    protected override void OnLeave (View view)
+    protected override void OnHasFocusChanged (View view)
     {
         SetColors ();
         _lastFocusedView = this;

+ 1 - 1
Terminal.Gui/Views/TextField.cs

@@ -1033,7 +1033,7 @@ public class TextField : View
     }
 
     /// <inheritdoc/>
-    protected override void OnLeave (View view)
+    protected override void OnHasFocusChanged (View view)
     {
         if (Application.MouseGrabView is { } && Application.MouseGrabView == this)
         {

+ 1 - 1
Terminal.Gui/Views/TextView.cs

@@ -3650,7 +3650,7 @@ public class TextView : View
     }
 
     /// <inheritdoc/>
-    protected override void OnLeave (View view)
+    protected override void OnHasFocusChanged (View view)
     {
         if (Application.MouseGrabView is { } && Application.MouseGrabView == this)
         {

+ 1 - 1
Terminal.Gui/Views/TreeView/TreeView.cs

@@ -1155,7 +1155,7 @@ public class TreeView<T> : View, ITreeView where T : class
     }
 
     ///<inheritdoc/>
-    protected override bool OnEnter (View view)
+    protected override bool OnHasFocusChanging (View view)
     {
         if (SelectedObject is null && Objects.Any ())
         {

+ 1 - 1
UICatalog/KeyBindingsDialog.cs

@@ -60,7 +60,7 @@ internal class KeyBindingsDialog : Dialog
         AddButton (cancel);
 
         // Register event handler as the last thing in constructor to prevent early calls
-        // before it is even shown (e.g. OnEnter)
+        // before it is even shown (e.g. OnHasFocusChanging)
         _commandsListView.SelectedItemChanged += CommandsListView_SelectedItemChanged;
 
         // Setup to show first ListView entry

+ 2 - 2
UICatalog/Scenarios/ASCIICustomButton.cs

@@ -110,7 +110,7 @@ public class ASCIICustomButtonTest : Scenario
             Add (_border, _fill, title);
         }
 
-        protected override bool OnEnter (View view)
+        protected override bool OnHasFocusChanging (View view)
         {
             _border.Visible = false;
             _fill.Visible = true;
@@ -119,7 +119,7 @@ public class ASCIICustomButtonTest : Scenario
             return false; // don't cancel
         }
 
-        protected override void OnLeave (View view)
+        protected override void OnHasFocusChanged (View view)
         {
             _border.Visible = true;
             _fill.Visible = false;

+ 3 - 3
UICatalog/Scenarios/ConfigurationEditor.cs

@@ -101,7 +101,7 @@ public class ConfigurationEditor : Scenario
     }
     public void Save ()
     {
-        if (_tileView.GetMostFocused () is ConfigTextView editor)
+        if (_tileView.MostFocused is ConfigTextView editor)
         {
             editor.Save ();
         }
@@ -133,7 +133,7 @@ public class ConfigurationEditor : Scenario
 
             textView.Read ();
 
-            textView.Enter += (s, e) => { _lenShortcut.Title = $"Len:{textView.Text.Length}"; };
+            textView.HasFocusChanging += (s, e) => { _lenShortcut.Title = $"Len:{textView.Text.Length}"; };
         }
 
         Application.Top.LayoutSubviews ();
@@ -172,7 +172,7 @@ public class ConfigurationEditor : Scenario
 
     private void Reload ()
     {
-        if (_tileView.GetMostFocused () is ConfigTextView editor)
+        if (_tileView.MostFocused is ConfigTextView editor)
         {
             editor.Read ();
         }

+ 2 - 2
UICatalog/Scenarios/DynamicMenuBar.cs

@@ -938,7 +938,7 @@ public class DynamicMenuBar : Scenario
                                               SetFrameDetails (menuBarItem);
                                           };
 
-            _lstMenus.Enter += (s, e) =>
+            _lstMenus.HasFocusChanging += (s, e) =>
                                {
                                    MenuItem menuBarItem = _lstMenus.SelectedItem > -1 && DataContext.Menus.Count > 0
                                                               ? DataContext.Menus [_lstMenus.SelectedItem].MenuItem
@@ -966,7 +966,7 @@ public class DynamicMenuBar : Scenario
                                        SelectCurrentMenuBarItem ();
                                    };
 
-            lblMenuBar.Enter += (s, e) =>
+            lblMenuBar.HasFocusChanging += (s, e) =>
                                  {
                                      if (_menuBar?.Menus != null)
                                      {

+ 1 - 1
UICatalog/Scenarios/DynamicStatusBar.cs

@@ -440,7 +440,7 @@ public class DynamicStatusBar : Scenario
                                       }
                                   };
 
-            _lstItems.Enter += (s, e) =>
+            _lstItems.HasFocusChanging += (s, e) =>
                                {
                                    Shortcut statusItem = DataContext.Items.Count > 0
                                                                ? DataContext.Items [_lstItems.SelectedItem].Shortcut

+ 2 - 2
UICatalog/Scenarios/Editor.cs

@@ -860,7 +860,7 @@ public class Editor : Scenario
             Width = Dim.Fill (1),
             Text = _textToFind
         };
-        txtToFind.Enter += (s, e) => txtToFind.Text = _textToFind;
+        txtToFind.HasFocusChanging += (s, e) => txtToFind.Text = _textToFind;
         d.Add (txtToFind);
 
         var btnFindNext = new Button
@@ -1088,7 +1088,7 @@ public class Editor : Scenario
             Width = Dim.Fill (1),
             Text = _textToFind
         };
-        txtToFind.Enter += (s, e) => txtToFind.Text = _textToFind;
+        txtToFind.HasFocusChanging += (s, e) => txtToFind.Text = _textToFind;
         d.Add (txtToFind);
 
         var btnFindNext = new Button

+ 5 - 5
UICatalog/Scenarios/KeyBindings.cs

@@ -125,8 +125,8 @@ public sealed class KeyBindings : Scenario
         };
         appWindow.Add (_focusedBindingsListView);
 
-        appWindow.Leave += AppWindow_Leave;
-        appWindow.Enter += AppWindow_Leave;
+        appWindow.HasFocusChanged += AppWindow_Leave;
+        appWindow.HasFocusChanging += AppWindow_Leave;
         appWindow.DrawContent += AppWindow_DrawContent;
 
         // Run - Start the application.
@@ -139,10 +139,10 @@ public sealed class KeyBindings : Scenario
 
     private void AppWindow_DrawContent (object sender, DrawEventArgs e)
     {
-        _focusedBindingsListView.Title = $"_Focused ({Application.Top.GetMostFocused ().GetType ().Name}) Bindings";
+        _focusedBindingsListView.Title = $"_Focused ({Application.Top.MostFocused.GetType ().Name}) Bindings";
 
         _focusedBindings.Clear ();
-        foreach (var binding in Application.Top.GetMostFocused ().KeyBindings.Bindings.Where (b => b.Value.Scope == KeyBindingScope.Focused))
+        foreach (var binding in Application.Top.MostFocused.KeyBindings.Bindings.Where (b => b.Value.Scope == KeyBindingScope.Focused))
         {
             _focusedBindings.Add ($"{binding.Key} -> {binding.Value.Commands [0]}");
         }
@@ -150,7 +150,7 @@ public sealed class KeyBindings : Scenario
 
     private void AppWindow_Leave (object sender, FocusEventArgs e)
     {
-        foreach (var binding in Application.Top.GetMostFocused ().KeyBindings.Bindings.Where (b => b.Value.Scope == KeyBindingScope.Focused))
+        foreach (var binding in Application.Top.MostFocused.KeyBindings.Bindings.Where (b => b.Value.Scope == KeyBindingScope.Focused))
         {
             _focusedBindings.Add ($"{binding.Key} -> {binding.Value.Commands [0]}");
         }

+ 1 - 1
UICatalog/Scenarios/MenuBarScenario.cs

@@ -107,7 +107,7 @@ public class MenuBarScenario : Scenario
                                };
 
         // There's no focus change event, so this is a bit of a hack.
-        menuBar.LayoutComplete += (s, e) => { _focusedView.Text = appWindow.GetMostFocused ()?.ToString () ?? "None"; };
+        menuBar.LayoutComplete += (s, e) => { _focusedView.Text = appWindow.MostFocused?.ToString () ?? "None"; };
 
         var openBtn = new Button { X = Pos.Center (), Y = 4, Text = "_Open Menu", IsDefault = true };
         openBtn.Accept += (s, e) => { menuBar.OpenMenu (); };

+ 3 - 3
UICatalog/Scenarios/Notepad.cs

@@ -84,7 +84,7 @@ public class Notepad : Scenario
 
         _focusedTabView = _tabView;
         _tabView.SelectedTabChanged += TabView_SelectedTabChanged;
-        _tabView.Enter += (s, e) => _focusedTabView = _tabView;
+        _tabView.HasFocusChanging += (s, e) => _focusedTabView = _tabView;
 
         top.Ready += (s, e) =>
                      {
@@ -241,7 +241,7 @@ public class Notepad : Scenario
 
         tv.TabClicked += TabView_TabClicked;
         tv.SelectedTabChanged += TabView_SelectedTabChanged;
-        tv.Enter += (s, e) => _focusedTabView = tv;
+        tv.HasFocusChanging += (s, e) => _focusedTabView = tv;
 
         return tv;
     }
@@ -309,7 +309,7 @@ public class Notepad : Scenario
         tab.CloneTo (newTabView);
         newTile.ContentView.Add (newTabView);
 
-        newTabView.FocusDeepest (null, NavigationDirection.Forward);
+        newTabView.FocusDeepest (NavigationDirection.Forward, null);
         newTabView.AdvanceFocus (NavigationDirection.Forward, null);
     }
 

+ 12 - 12
UnitTests/FileServices/FileDialogTests.cs

@@ -107,8 +107,8 @@ public class FileDialogTests (ITestOutputHelper output)
         Application.OnKeyDown (Key.Tab);
 #endif
 
-        Assert.IsType<TextField> (dlg.GetMostFocused ());
-        var tf = (TextField)dlg.GetMostFocused ();
+        Assert.IsType<TextField> (dlg.MostFocused);
+        var tf = (TextField)dlg.MostFocused;
         Assert.Equal ("Enter Search", tf.Caption);
 
         // Dialog has not yet been confirmed with a choice
@@ -142,9 +142,9 @@ public class FileDialogTests (ITestOutputHelper output)
 
         AssertIsTheStartingDirectory (dlg.Path);
 
-        Assert.IsType<TextField> (dlg.GetMostFocused ());
+        Assert.IsType<TextField> (dlg.MostFocused);
         Send ('v', ConsoleKey.DownArrow);
-        Assert.IsType<TableView> (dlg.GetMostFocused ());
+        Assert.IsType<TableView> (dlg.MostFocused);
 
         // ".." should be the first thing selected
         // ".." should not mess with the displayed path
@@ -181,9 +181,9 @@ public class FileDialogTests (ITestOutputHelper output)
         IReadOnlyCollection<string> eventMultiSelected = null;
         dlg.FilesSelected += (s, e) => { eventMultiSelected = e.Dialog.MultiSelected; };
 
-        Assert.IsType<TextField> (dlg.GetMostFocused ());
+        Assert.IsType<TextField> (dlg.MostFocused);
         Send ('v', ConsoleKey.DownArrow);
-        Assert.IsType<TableView> (dlg.GetMostFocused ());
+        Assert.IsType<TableView> (dlg.MostFocused);
 
         // Try to toggle '..'
         Send (' ', ConsoleKey.Spacebar);
@@ -236,9 +236,9 @@ public class FileDialogTests (ITestOutputHelper output)
         IReadOnlyCollection<string> eventMultiSelected = null;
         dlg.FilesSelected += (s, e) => { eventMultiSelected = e.Dialog.MultiSelected; };
 
-        Assert.IsType<TextField> (dlg.GetMostFocused ());
+        Assert.IsType<TextField> (dlg.MostFocused);
         Send ('v', ConsoleKey.DownArrow);
-        Assert.IsType<TableView> (dlg.GetMostFocused ());
+        Assert.IsType<TableView> (dlg.MostFocused);
 
         // Move selection to subfolder
         Send ('v', ConsoleKey.DownArrow);
@@ -288,9 +288,9 @@ public class FileDialogTests (ITestOutputHelper output)
         IReadOnlyCollection<string> eventMultiSelected = null;
         dlg.FilesSelected += (s, e) => { eventMultiSelected = e.Dialog.MultiSelected; };
 
-        Assert.IsType<TextField> (dlg.GetMostFocused ());
+        Assert.IsType<TextField> (dlg.MostFocused);
         Send ('v', ConsoleKey.DownArrow);
-        Assert.IsType<TableView> (dlg.GetMostFocused ());
+        Assert.IsType<TableView> (dlg.MostFocused);
 
         // Move selection to subfolder
         Send ('v', ConsoleKey.DownArrow);
@@ -331,9 +331,9 @@ public class FileDialogTests (ITestOutputHelper output)
         dlg.OpenMode = openModeMixed ? OpenMode.Mixed : OpenMode.Directory;
         dlg.AllowsMultipleSelection = multiple;
 
-        Assert.IsType<TextField> (dlg.GetMostFocused ());
+        Assert.IsType<TextField> (dlg.MostFocused);
         Send ('v', ConsoleKey.DownArrow);
-        Assert.IsType<TableView> (dlg.GetMostFocused ());
+        Assert.IsType<TableView> (dlg.MostFocused);
 
         // Should be selecting ..
         Send ('v', ConsoleKey.DownArrow);

+ 3 - 3
UnitTests/View/Navigation/AddRemoveTests.cs

@@ -22,7 +22,7 @@ public class AddRemoveNavigationTests (ITestOutputHelper _output) : TestsAllView
             Id = "subView",
             CanFocus = true
         };
-        subView.Enter += (s, e) => nEnter++;
+        subView.HasFocusChanging += (s, e) => nEnter++;
 
         top.Add (subView);
 
@@ -82,7 +82,7 @@ public class AddRemoveNavigationTests (ITestOutputHelper _output) : TestsAllView
             Id = "subView",
             CanFocus = true
         };
-        subView.Leave += (s, e) => nLeave++;
+        subView.HasFocusChanged += (s, e) => nLeave++;
 
         top.Add (subView);
 
@@ -114,7 +114,7 @@ public class AddRemoveNavigationTests (ITestOutputHelper _output) : TestsAllView
             Id = "subView1",
             CanFocus = true
         };
-        subView1.Leave += (s, e) => nLeave1++;
+        subView1.HasFocusChanged += (s, e) => nLeave1++;
 
         View subView2 = new View ()
         {

+ 0 - 451
UnitTests/View/Navigation/EnterLeaveTests.cs

@@ -1,451 +0,0 @@
-using Xunit.Abstractions;
-
-namespace Terminal.Gui.ViewTests;
-
-public class EnterLeaveTests (ITestOutputHelper _output) : TestsAllViews
-{
-    [Fact]
-    public void SetFocus_FiresEnter ()
-    {
-        int nEnter = 0;
-        int nLeave = 0;
-        var view = new View ()
-        {
-            Id = "view",
-            CanFocus = true
-        };
-        view.Enter += (s, e) => nEnter++;
-        view.Leave += (s, e) => nLeave++;
-
-        Assert.True (view.CanFocus);
-        Assert.False (view.HasFocus);
-
-        view.SetFocus ();
-        Assert.True (view.HasFocus);
-        Assert.Equal (1, nEnter);
-        Assert.Equal (0, nLeave);
-    }
-
-    [Fact]
-    public void RemoveFocus_FiresLeave ()
-    {
-        int nEnter = 0;
-        int nLeave = 0;
-        var view = new View ()
-        {
-            Id = "view",
-            CanFocus = true
-        };
-        view.Enter += (s, e) => nEnter++;
-        view.Leave += (s, e) => nLeave++;
-
-        Assert.True (view.CanFocus);
-        Assert.False (view.HasFocus);
-
-        view.SetFocus ();
-        Assert.True (view.HasFocus);
-        Assert.Equal (1, nEnter);
-        Assert.Equal (0, nLeave);
-
-        view.HasFocus = false;
-        Assert.Equal (1, nEnter);
-        Assert.Equal (1, nLeave);
-    }
-    
-    [Fact]
-    public void SetFocus_SubView_SetFocus_FiresEnter ()
-    {
-        int viewEnterCount = 0;
-        int viewLeaveCount = 0;
-        var view = new View ()
-        {
-            Id = "view",
-            CanFocus = true
-        };
-        view.Enter += (s, e) => viewEnterCount++;
-        view.Leave += (s, e) => viewLeaveCount++;
-
-        int subviewEnterCount = 0;
-        int subviewLeaveCount = 0;
-        var subview = new View ()
-        {
-            Id = "subview",
-            CanFocus = true
-        };
-        subview.Enter += (s, e) => subviewEnterCount++;
-        subview.Leave += (s, e) => subviewLeaveCount++;
-
-        view.Add (subview);
-
-        view.SetFocus ();
-
-        Assert.Equal (1, viewEnterCount);
-        Assert.Equal (0, viewLeaveCount);
-
-        Assert.Equal (1, subviewEnterCount);
-        Assert.Equal (0, subviewLeaveCount);
-    }
-
-    [Fact]
-    public void RemoveFocus_SubView_FiresLeave ()
-    {
-        int viewEnterCount = 0;
-        int viewLeaveCount = 0;
-        var view = new View ()
-        {
-            Id = "view",
-            CanFocus = true
-        };
-        view.Enter += (s, e) => viewEnterCount++;
-        view.Leave += (s, e) => viewLeaveCount++;
-
-        int subviewEnterCount = 0;
-        int subviewLeaveCount = 0;
-        var subview = new View ()
-        {
-            Id = "subview",
-            CanFocus = true
-        };
-        subview.Enter += (s, e) => subviewEnterCount++;
-        subview.Leave += (s, e) => subviewLeaveCount++;
-
-        view.Add (subview);
-
-        view.SetFocus ();
-
-        view.HasFocus = false;
-
-        Assert.Equal (1, viewEnterCount);
-        Assert.Equal (1, viewLeaveCount);
-
-        Assert.Equal (1, subviewEnterCount);
-        Assert.Equal (1, subviewLeaveCount);
-
-        view.SetFocus ();
-
-        Assert.Equal (2, viewEnterCount);
-        Assert.Equal (1, viewLeaveCount);
-
-        Assert.Equal (2, subviewEnterCount);
-        Assert.Equal (1, subviewLeaveCount);
-
-        subview.HasFocus = false;
-
-        Assert.Equal (2, viewEnterCount);
-        Assert.Equal (2, viewLeaveCount);
-
-        Assert.Equal (2, subviewEnterCount);
-        Assert.Equal (2, subviewLeaveCount);
-    }
-    
-    [Fact]
-    public void SetFocus_CompoundSubView_FiresEnter ()
-    {
-        int viewEnterCount = 0;
-        int viewLeaveCount = 0;
-        var view = new View ()
-        {
-            Id = "view",
-            CanFocus = true
-        };
-        view.Enter += (s, e) => viewEnterCount++;
-        view.Leave += (s, e) => viewLeaveCount++;
-
-        int subViewEnterCount = 0;
-        int subViewLeaveCount = 0;
-        var subView = new View ()
-        {
-            Id = "subView",
-            CanFocus = true
-        };
-        subView.Enter += (s, e) => subViewEnterCount++;
-        subView.Leave += (s, e) => subViewLeaveCount++;
-
-        int subviewSubView1EnterCount = 0;
-        int subviewSubView1LeaveCount = 0;
-        var subViewSubView1 = new View ()
-        {
-            Id = "subViewSubView1",
-            CanFocus = false
-        };
-        subViewSubView1.Enter += (s, e) => subviewSubView1EnterCount++;
-        subViewSubView1.Leave += (s, e) => subviewSubView1LeaveCount++;
-
-        int subviewSubView2EnterCount = 0;
-        int subviewSubView2LeaveCount = 0;
-        var subViewSubView2 = new View ()
-        {
-            Id = "subViewSubView2",
-            CanFocus = true
-        };
-        subViewSubView2.Enter += (s, e) => subviewSubView2EnterCount++;
-        subViewSubView2.Leave += (s, e) => subviewSubView2LeaveCount++;
-
-        int subviewSubView3EnterCount = 0;
-        int subviewSubView3LeaveCount = 0;
-        var subViewSubView3 = new View ()
-        {
-            Id = "subViewSubView3",
-            CanFocus = false
-        };
-        subViewSubView3.Enter += (s, e) => subviewSubView3EnterCount++;
-        subViewSubView3.Leave += (s, e) => subviewSubView3LeaveCount++;
-
-        subView.Add (subViewSubView1, subViewSubView2, subViewSubView3);
-
-        view.Add (subView);
-
-        view.SetFocus ();
-        Assert.True(view.HasFocus);
-        Assert.True (subView.HasFocus);
-        Assert.False (subViewSubView1.HasFocus);
-        Assert.True (subViewSubView2.HasFocus);
-        Assert.False (subViewSubView3.HasFocus);
-
-        Assert.Equal (1, viewEnterCount);
-        Assert.Equal (0, viewLeaveCount);
-
-        Assert.Equal (1, subViewEnterCount);
-        Assert.Equal (0, subViewLeaveCount);
-
-        Assert.Equal (0, subviewSubView1EnterCount);
-        Assert.Equal (0, subviewSubView1LeaveCount);
-
-        Assert.Equal (1, subviewSubView2EnterCount);
-        Assert.Equal (0, subviewSubView2LeaveCount);
-
-        Assert.Equal (0, subviewSubView3EnterCount);
-        Assert.Equal (0, subviewSubView3LeaveCount);
-    }
-
-
-    [Fact]
-    public void RemoveFocus_CompoundSubView_FiresLeave ()
-    {
-        int viewEnterCount = 0;
-        int viewLeaveCount = 0;
-        var view = new View ()
-        {
-            Id = "view",
-            CanFocus = true
-        };
-        view.Enter += (s, e) => viewEnterCount++;
-        view.Leave += (s, e) => viewLeaveCount++;
-
-        int subViewEnterCount = 0;
-        int subViewLeaveCount = 0;
-        var subView = new View ()
-        {
-            Id = "subView",
-            CanFocus = true
-        };
-        subView.Enter += (s, e) => subViewEnterCount++;
-        subView.Leave += (s, e) => subViewLeaveCount++;
-
-        int subviewSubView1EnterCount = 0;
-        int subviewSubView1LeaveCount = 0;
-        var subViewSubView1 = new View ()
-        {
-            Id = "subViewSubView1",
-            CanFocus = false
-        };
-        subViewSubView1.Enter += (s, e) => subviewSubView1EnterCount++;
-        subViewSubView1.Leave += (s, e) => subviewSubView1LeaveCount++;
-
-        int subviewSubView2EnterCount = 0;
-        int subviewSubView2LeaveCount = 0;
-        var subViewSubView2 = new View ()
-        {
-            Id = "subViewSubView2",
-            CanFocus = true
-        };
-        subViewSubView2.Enter += (s, e) => subviewSubView2EnterCount++;
-        subViewSubView2.Leave += (s, e) => subviewSubView2LeaveCount++;
-
-        int subviewSubView3EnterCount = 0;
-        int subviewSubView3LeaveCount = 0;
-        var subViewSubView3 = new View ()
-        {
-            Id = "subViewSubView3",
-            CanFocus = false
-        };
-        subViewSubView3.Enter += (s, e) => subviewSubView3EnterCount++;
-        subViewSubView3.Leave += (s, e) => subviewSubView3LeaveCount++;
-
-        subView.Add (subViewSubView1, subViewSubView2, subViewSubView3);
-
-        view.Add (subView);
-
-        view.SetFocus ();
-        Assert.True (view.HasFocus);
-        Assert.True (subView.HasFocus);
-        Assert.False (subViewSubView1.HasFocus);
-        Assert.True (subViewSubView2.HasFocus);
-        Assert.False (subViewSubView3.HasFocus);
-
-        view.HasFocus = false;
-        Assert.False (view.HasFocus);
-        Assert.False (subView.HasFocus);
-        Assert.False (subViewSubView1.HasFocus);
-        Assert.False (subViewSubView2.HasFocus);
-        Assert.False (subViewSubView3.HasFocus);
-
-        Assert.Equal (1, viewEnterCount);
-        Assert.Equal (1, viewLeaveCount);
-
-        Assert.Equal (1, subViewEnterCount);
-        Assert.Equal (1, subViewLeaveCount);
-
-        Assert.Equal (0, subviewSubView1EnterCount);
-        Assert.Equal (0, subviewSubView1LeaveCount);
-
-        Assert.Equal (1, subviewSubView2EnterCount);
-        Assert.Equal (1, subviewSubView2LeaveCount);
-
-        Assert.Equal (0, subviewSubView3EnterCount);
-        Assert.Equal (0, subviewSubView3LeaveCount);
-    }
-
-
-    [Fact]
-    public void SetFocus_Peer_LeavesOther ()
-    {
-        var view = new View ()
-        {
-            Id = "view",
-            CanFocus = true
-        };
-
-        var subview1 = new View ()
-        {
-            Id = "subview1",
-            CanFocus = true
-        };
-
-        var subview2 = new View ()
-        {
-            Id = "subview2",
-            CanFocus = true
-        };
-        view.Add (subview1, subview2);
-
-        view.SetFocus ();
-        Assert.Equal (subview1, view.Focused);
-        Assert.True (subview1.HasFocus);
-        Assert.False (subview2.HasFocus);
-
-        subview2.SetFocus ();
-        Assert.Equal (subview2, view.Focused);
-        Assert.True (subview2.HasFocus);
-        Assert.False (subview1.HasFocus);
-    }
-
-    [Fact]
-    public void SetFocus_Peer_LeavesOthers_Subviews ()
-    {
-        var top = new View
-        {
-            Id = "top",
-            CanFocus = true
-        };
-        var view1 = new View
-        {
-            Id = "view1",
-            CanFocus = true
-        };
-
-        var subView1 = new View
-        {
-            Id = "subView1",
-            CanFocus = true
-        };
-
-        view1.Add (subView1);
-
-        var subView1SubView1 = new View
-        {
-            Id = "subView1subView1",
-            CanFocus = true
-        };
-
-        subView1.Add (subView1SubView1);
-
-        var view2 = new View
-        {
-            Id = "view2",
-            CanFocus = true
-        };
-
-        top.Add (view1, view2);
-        Assert.False (view1.HasFocus);
-        Assert.False (view2.HasFocus);
-
-        view1.SetFocus ();
-        Assert.True (view1.HasFocus);
-        Assert.True (subView1.HasFocus);
-        Assert.True (subView1SubView1.HasFocus);
-        Assert.Equal (subView1, view1.Focused);
-        Assert.Equal (subView1SubView1, subView1.Focused);
-
-        view2.SetFocus ();
-        Assert.False (view1.HasFocus);
-        Assert.True (view2.HasFocus);
-    }
-
-
-    [Fact]
-    public void HasFocus_False_Leave_Invoked ()
-    {
-        var view = new View ()
-        {
-            Id = "view",
-            CanFocus = true
-        };
-        Assert.True (view.CanFocus);
-        Assert.False (view.HasFocus);
-
-        int leaveInvoked = 0;
-
-        view.Leave += (s, e) => leaveInvoked++;
-
-        view.SetFocus ();
-        Assert.True (view.HasFocus);
-        Assert.Equal (0, leaveInvoked);
-
-        view.HasFocus = false;
-        Assert.False (view.HasFocus);
-        Assert.Equal (1, leaveInvoked);
-    }
-
-    [Fact]
-    public void HasFocus_False_Leave_Invoked_ForAllSubViews ()
-    {
-        var view = new View ()
-        {
-            Id = "view",
-            CanFocus = true
-        };
-
-        var subview = new View ()
-        {
-            Id = "subview",
-            CanFocus = true
-        };
-        view.Add (subview);
-
-        int leaveInvoked = 0;
-
-        view.Leave += (s, e) => leaveInvoked++;
-        subview.Leave += (s, e) => leaveInvoked++;
-
-        view.SetFocus ();
-        Assert.True (view.HasFocus);
-        Assert.Equal (0, leaveInvoked);
-
-        view.HasFocus = false;
-        Assert.False (view.HasFocus);
-        Assert.False (subview.HasFocus);
-        Assert.Equal (2, leaveInvoked);
-    }
-
-}

+ 378 - 0
UnitTests/View/Navigation/HasFocusEventTests.cs

@@ -0,0 +1,378 @@
+using Xunit.Abstractions;
+
+namespace Terminal.Gui.ViewTests;
+
+public class HasFocusEventTests (ITestOutputHelper _output) : TestsAllViews
+{
+    [Fact]
+    public void SetFocus_Raises_HasFocusChanging ()
+    {
+        var nEnter = 0;
+        var nLeave = 0;
+
+        var view = new View
+        {
+            Id = "view",
+            CanFocus = true
+        };
+        view.HasFocusChanging += (s, e) => nEnter++;
+        view.HasFocusChanged += (s, e) => nLeave++;
+
+        Assert.True (view.CanFocus);
+        Assert.False (view.HasFocus);
+
+        view.SetFocus ();
+        Assert.True (view.HasFocus);
+        Assert.Equal (1, nEnter);
+        Assert.Equal (0, nLeave);
+    }
+
+    [Fact]
+    public void RemoveFocus_Raises_HasFocusChanged ()
+    {
+        var nEnter = 0;
+        var nLeave = 0;
+
+        var view = new View
+        {
+            Id = "view",
+            CanFocus = true
+        };
+        view.HasFocusChanging += (s, e) => nEnter++;
+        view.HasFocusChanged += (s, e) => nLeave++;
+
+        Assert.True (view.CanFocus);
+        Assert.False (view.HasFocus);
+
+        view.SetFocus ();
+        Assert.True (view.HasFocus);
+        Assert.Equal (1, nEnter);
+        Assert.Equal (0, nLeave);
+
+        view.HasFocus = false;
+        Assert.Equal (1, nEnter);
+        Assert.Equal (1, nLeave);
+    }
+
+    [Fact]
+    public void SetFocus_SubView_SetFocus_Raises_HasFocusChanging ()
+    {
+        var viewEnterCount = 0;
+        var viewLeaveCount = 0;
+
+        var view = new View
+        {
+            Id = "view",
+            CanFocus = true
+        };
+        view.HasFocusChanging += (s, e) => viewEnterCount++;
+        view.HasFocusChanged += (s, e) => viewLeaveCount++;
+
+        var subviewEnterCount = 0;
+        var subviewLeaveCount = 0;
+
+        var subview = new View
+        {
+            Id = "subview",
+            CanFocus = true
+        };
+        subview.HasFocusChanging += (s, e) => subviewEnterCount++;
+        subview.HasFocusChanged += (s, e) => subviewLeaveCount++;
+
+        view.Add (subview);
+
+        view.SetFocus ();
+
+        Assert.Equal (1, viewEnterCount);
+        Assert.Equal (0, viewLeaveCount);
+
+        Assert.Equal (1, subviewEnterCount);
+        Assert.Equal (0, subviewLeaveCount);
+    }
+
+    [Fact]
+    public void RemoveFocus_SubView_Raises_HasFocusChanged ()
+    {
+        var viewEnterCount = 0;
+        var viewLeaveCount = 0;
+
+        var view = new View
+        {
+            Id = "view",
+            CanFocus = true
+        };
+        view.HasFocusChanging += (s, e) => viewEnterCount++;
+        view.HasFocusChanged += (s, e) => viewLeaveCount++;
+
+        var subviewEnterCount = 0;
+        var subviewLeaveCount = 0;
+
+        var subview = new View
+        {
+            Id = "subview",
+            CanFocus = true
+        };
+        subview.HasFocusChanging += (s, e) => subviewEnterCount++;
+        subview.HasFocusChanged += (s, e) => subviewLeaveCount++;
+
+        view.Add (subview);
+
+        view.SetFocus ();
+
+        view.HasFocus = false;
+
+        Assert.Equal (1, viewEnterCount);
+        Assert.Equal (1, viewLeaveCount);
+
+        Assert.Equal (1, subviewEnterCount);
+        Assert.Equal (1, subviewLeaveCount);
+
+        view.SetFocus ();
+
+        Assert.Equal (2, viewEnterCount);
+        Assert.Equal (1, viewLeaveCount);
+
+        Assert.Equal (2, subviewEnterCount);
+        Assert.Equal (1, subviewLeaveCount);
+
+        subview.HasFocus = false;
+
+        Assert.Equal (2, viewEnterCount);
+        Assert.Equal (2, viewLeaveCount);
+
+        Assert.Equal (2, subviewEnterCount);
+        Assert.Equal (2, subviewLeaveCount);
+    }
+
+    [Fact]
+    public void SetFocus_CompoundSubView_Raises_HasFocusChanging ()
+    {
+        var viewEnterCount = 0;
+        var viewLeaveCount = 0;
+
+        var view = new View
+        {
+            Id = "view",
+            CanFocus = true
+        };
+        view.HasFocusChanging += (s, e) => viewEnterCount++;
+        view.HasFocusChanged += (s, e) => viewLeaveCount++;
+
+        var subViewEnterCount = 0;
+        var subViewLeaveCount = 0;
+
+        var subView = new View
+        {
+            Id = "subView",
+            CanFocus = true
+        };
+        subView.HasFocusChanging += (s, e) => subViewEnterCount++;
+        subView.HasFocusChanged += (s, e) => subViewLeaveCount++;
+
+        var subviewSubView1EnterCount = 0;
+        var subviewSubView1LeaveCount = 0;
+
+        var subViewSubView1 = new View
+        {
+            Id = "subViewSubView1",
+            CanFocus = false
+        };
+        subViewSubView1.HasFocusChanging += (s, e) => subviewSubView1EnterCount++;
+        subViewSubView1.HasFocusChanged += (s, e) => subviewSubView1LeaveCount++;
+
+        var subviewSubView2EnterCount = 0;
+        var subviewSubView2LeaveCount = 0;
+
+        var subViewSubView2 = new View
+        {
+            Id = "subViewSubView2",
+            CanFocus = true
+        };
+        subViewSubView2.HasFocusChanging += (s, e) => subviewSubView2EnterCount++;
+        subViewSubView2.HasFocusChanged += (s, e) => subviewSubView2LeaveCount++;
+
+        var subviewSubView3EnterCount = 0;
+        var subviewSubView3LeaveCount = 0;
+
+        var subViewSubView3 = new View
+        {
+            Id = "subViewSubView3",
+            CanFocus = false
+        };
+        subViewSubView3.HasFocusChanging += (s, e) => subviewSubView3EnterCount++;
+        subViewSubView3.HasFocusChanged += (s, e) => subviewSubView3LeaveCount++;
+
+        subView.Add (subViewSubView1, subViewSubView2, subViewSubView3);
+
+        view.Add (subView);
+
+        view.SetFocus ();
+        Assert.True (view.HasFocus);
+        Assert.True (subView.HasFocus);
+        Assert.False (subViewSubView1.HasFocus);
+        Assert.True (subViewSubView2.HasFocus);
+        Assert.False (subViewSubView3.HasFocus);
+
+        Assert.Equal (1, viewEnterCount);
+        Assert.Equal (0, viewLeaveCount);
+
+        Assert.Equal (1, subViewEnterCount);
+        Assert.Equal (0, subViewLeaveCount);
+
+        Assert.Equal (0, subviewSubView1EnterCount);
+        Assert.Equal (0, subviewSubView1LeaveCount);
+
+        Assert.Equal (1, subviewSubView2EnterCount);
+        Assert.Equal (0, subviewSubView2LeaveCount);
+
+        Assert.Equal (0, subviewSubView3EnterCount);
+        Assert.Equal (0, subviewSubView3LeaveCount);
+    }
+
+    [Fact]
+    public void RemoveFocus_CompoundSubView_Raises_HasFocusChanged ()
+    {
+        var viewEnterCount = 0;
+        var viewLeaveCount = 0;
+
+        var view = new View
+        {
+            Id = "view",
+            CanFocus = true
+        };
+        view.HasFocusChanging += (s, e) => viewEnterCount++;
+        view.HasFocusChanged += (s, e) => viewLeaveCount++;
+
+        var subViewEnterCount = 0;
+        var subViewLeaveCount = 0;
+
+        var subView = new View
+        {
+            Id = "subView",
+            CanFocus = true
+        };
+        subView.HasFocusChanging += (s, e) => subViewEnterCount++;
+        subView.HasFocusChanged += (s, e) => subViewLeaveCount++;
+
+        var subviewSubView1EnterCount = 0;
+        var subviewSubView1LeaveCount = 0;
+
+        var subViewSubView1 = new View
+        {
+            Id = "subViewSubView1",
+            CanFocus = false
+        };
+        subViewSubView1.HasFocusChanging += (s, e) => subviewSubView1EnterCount++;
+        subViewSubView1.HasFocusChanged += (s, e) => subviewSubView1LeaveCount++;
+
+        var subviewSubView2EnterCount = 0;
+        var subviewSubView2LeaveCount = 0;
+
+        var subViewSubView2 = new View
+        {
+            Id = "subViewSubView2",
+            CanFocus = true
+        };
+        subViewSubView2.HasFocusChanging += (s, e) => subviewSubView2EnterCount++;
+        subViewSubView2.HasFocusChanged += (s, e) => subviewSubView2LeaveCount++;
+
+        var subviewSubView3EnterCount = 0;
+        var subviewSubView3LeaveCount = 0;
+
+        var subViewSubView3 = new View
+        {
+            Id = "subViewSubView3",
+            CanFocus = false
+        };
+        subViewSubView3.HasFocusChanging += (s, e) => subviewSubView3EnterCount++;
+        subViewSubView3.HasFocusChanged += (s, e) => subviewSubView3LeaveCount++;
+
+        subView.Add (subViewSubView1, subViewSubView2, subViewSubView3);
+
+        view.Add (subView);
+
+        view.SetFocus ();
+        Assert.True (view.HasFocus);
+        Assert.True (subView.HasFocus);
+        Assert.False (subViewSubView1.HasFocus);
+        Assert.True (subViewSubView2.HasFocus);
+        Assert.False (subViewSubView3.HasFocus);
+
+        view.HasFocus = false;
+        Assert.False (view.HasFocus);
+        Assert.False (subView.HasFocus);
+        Assert.False (subViewSubView1.HasFocus);
+        Assert.False (subViewSubView2.HasFocus);
+        Assert.False (subViewSubView3.HasFocus);
+
+        Assert.Equal (1, viewEnterCount);
+        Assert.Equal (1, viewLeaveCount);
+
+        Assert.Equal (1, subViewEnterCount);
+        Assert.Equal (1, subViewLeaveCount);
+
+        Assert.Equal (0, subviewSubView1EnterCount);
+        Assert.Equal (0, subviewSubView1LeaveCount);
+
+        Assert.Equal (1, subviewSubView2EnterCount);
+        Assert.Equal (1, subviewSubView2LeaveCount);
+
+        Assert.Equal (0, subviewSubView3EnterCount);
+        Assert.Equal (0, subviewSubView3LeaveCount);
+    }
+
+    [Fact]
+    public void HasFocus_False_Leave_Raised ()
+    {
+        var view = new View
+        {
+            Id = "view",
+            CanFocus = true
+        };
+        Assert.True (view.CanFocus);
+        Assert.False (view.HasFocus);
+
+        var leaveInvoked = 0;
+
+        view.HasFocusChanged += (s, e) => leaveInvoked++;
+
+        view.SetFocus ();
+        Assert.True (view.HasFocus);
+        Assert.Equal (0, leaveInvoked);
+
+        view.HasFocus = false;
+        Assert.False (view.HasFocus);
+        Assert.Equal (1, leaveInvoked);
+    }
+
+    [Fact]
+    public void HasFocus_False_Leave_Raised_ForAllSubViews ()
+    {
+        var view = new View
+        {
+            Id = "view",
+            CanFocus = true
+        };
+
+        var subview = new View
+        {
+            Id = "subview",
+            CanFocus = true
+        };
+        view.Add (subview);
+
+        var leaveInvoked = 0;
+
+        view.HasFocusChanged += (s, e) => leaveInvoked++;
+        subview.HasFocusChanged += (s, e) => leaveInvoked++;
+
+        view.SetFocus ();
+        Assert.True (view.HasFocus);
+        Assert.Equal (0, leaveInvoked);
+
+        view.HasFocus = false;
+        Assert.False (view.HasFocus);
+        Assert.False (subview.HasFocus);
+        Assert.Equal (2, leaveInvoked);
+    }
+}

+ 16 - 16
UnitTests/View/Navigation/NavigationTests.cs

@@ -138,8 +138,8 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews
         var nEnter = 0;
         var nLeave = 0;
 
-        view.Enter += (s, e) => nEnter++;
-        view.Leave += (s, e) => nLeave++;
+        view.HasFocusChanging += (s, e) => nEnter++;
+        view.HasFocusChanged += (s, e) => nLeave++;
 
         top.Add (view, otherView);
         Assert.False (view.HasFocus);
@@ -294,8 +294,8 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews
         var nEnter = 0;
         var nLeave = 0;
 
-        view.Enter += (s, e) => nEnter++;
-        view.Leave += (s, e) => nLeave++;
+        view.HasFocusChanging += (s, e) => nEnter++;
+        view.HasFocusChanged += (s, e) => nLeave++;
 
         top.Add (view, otherView);
         Application.Begin (top);
@@ -409,25 +409,25 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews
         Application.Current.Add (frm);
         Application.Current.SetFocus ();
 
-        Assert.Equal (winSubview, Application.Current.GetMostFocused ());
+        Assert.Equal (winSubview, Application.Current.MostFocused);
 
         Application.OnKeyDown (Key.Tab); // Move to the next TabStop. There is none. So we should stay.
-        Assert.Equal (winSubview, Application.Current.GetMostFocused ());
+        Assert.Equal (winSubview, Application.Current.MostFocused);
 
         Application.OnKeyDown (Key.F6);
-        Assert.Equal (frmSubview, Application.Current.GetMostFocused ());
+        Assert.Equal (frmSubview, Application.Current.MostFocused);
 
         Application.OnKeyDown (Key.Tab);
-        Assert.Equal (frmSubview, Application.Current.GetMostFocused ());
+        Assert.Equal (frmSubview, Application.Current.MostFocused);
 
         Application.OnKeyDown (Key.F6);
-        Assert.Equal (winSubview, Application.Current.GetMostFocused ());
+        Assert.Equal (winSubview, Application.Current.MostFocused);
 
         Application.OnKeyDown (Key.F6.WithShift);
-        Assert.Equal (frmSubview, Application.Current.GetMostFocused ());
+        Assert.Equal (frmSubview, Application.Current.MostFocused);
 
         Application.OnKeyDown (Key.F6.WithShift);
-        Assert.Equal (winSubview, Application.Current.GetMostFocused ());
+        Assert.Equal (winSubview, Application.Current.MostFocused);
 
         Application.Current.Dispose ();
     }
@@ -451,7 +451,7 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews
         View view3 = null;
         var removed = false;
 
-        view2.Enter += (s, e) =>
+        view2.HasFocusChanging += (s, e) =>
                        {
                            if (!removed)
                            {
@@ -463,7 +463,7 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews
                            }
                        };
 
-        view2.Leave += (s, e) =>
+        view2.HasFocusChanged += (s, e) =>
                        {
                            Application.Current.Remove (view3);
                            view3.Dispose ();
@@ -503,7 +503,7 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews
         Assert.False (view.HasFocus);
         view.SetFocus ();
         Assert.True (view.HasFocus);
-        Assert.Null (view.GetMostFocused ());
+        Assert.Null (view.MostFocused);
     }
 
     [Fact]
@@ -526,7 +526,7 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews
         view.SetFocus ();
         Assert.True (view.HasFocus);
         Assert.True (subview.HasFocus);
-        Assert.Equal (subview, view.GetMostFocused ());
+        Assert.Equal (subview, view.MostFocused);
 
         var subview2 = new View ()
         {
@@ -535,7 +535,7 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews
         };
 
         view.Add (subview2);
-        Assert.Equal (subview2, view.GetMostFocused ());
+        Assert.Equal (subview2, view.MostFocused);
     }
 
     //    [Fact]

+ 5 - 5
UnitTests/View/ViewTests.cs

@@ -777,7 +777,7 @@ At 0,0
         Assert.False (r.WantContinuousButtonPressed);
         Assert.False (r.WantMousePositionReports);
         Assert.Null (r.SuperView);
-        Assert.Null (r.GetMostFocused ());
+        Assert.Null (r.MostFocused);
         Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
         r.Dispose ();
 
@@ -801,7 +801,7 @@ At 0,0
         Assert.False (r.WantContinuousButtonPressed);
         Assert.False (r.WantMousePositionReports);
         Assert.Null (r.SuperView);
-        Assert.Null (r.GetMostFocused ());
+        Assert.Null (r.MostFocused);
         Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
         r.Dispose ();
 
@@ -825,7 +825,7 @@ At 0,0
         Assert.False (r.WantContinuousButtonPressed);
         Assert.False (r.WantMousePositionReports);
         Assert.Null (r.SuperView);
-        Assert.Null (r.GetMostFocused ());
+        Assert.Null (r.MostFocused);
         Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
         r.Dispose ();
 
@@ -858,7 +858,7 @@ At 0,0
         Assert.False (r.WantContinuousButtonPressed);
         Assert.False (r.WantMousePositionReports);
         Assert.Null (r.SuperView);
-        Assert.Null (r.GetMostFocused ());
+        Assert.Null (r.MostFocused);
         Assert.Equal (TextDirection.TopBottom_LeftRight, r.TextDirection);
         r.Dispose ();
     }
@@ -1083,7 +1083,7 @@ At 0,0
                                      Assert.True (RunesCount () == 0);
 
                                      win.Visible = true;
-                                     win.FocusDeepest (null, NavigationDirection.Forward);
+                                     win.FocusDeepest (NavigationDirection.Forward, null);
                                      Assert.True (button.HasFocus);
                                      Assert.True (win.HasFocus);
                                      top.Draw ();

+ 28 - 28
UnitTests/Views/OverlappedTests.cs

@@ -1072,8 +1072,8 @@ public class OverlappedTests
         Assert.True (win1.IsCurrentTop);
         Assert.True (ApplicationOverlapped.IsOverlapped(win1));
         Assert.Null (top.Focused);
-        Assert.Null (top.GetMostFocused ());
-        Assert.Equal (tf1W1, win1.GetMostFocused ());
+        Assert.Null (top.MostFocused);
+        Assert.Equal (tf1W1, win1.MostFocused);
         Assert.True (ApplicationOverlapped.IsOverlapped(win1));
         Assert.Single (ApplicationOverlapped.OverlappedChildren!);
 
@@ -1086,8 +1086,8 @@ public class OverlappedTests
         Assert.True (win2.IsCurrentTop);
         Assert.True (ApplicationOverlapped.IsOverlapped(win2));
         Assert.Null (top.Focused);
-        Assert.Null (top.GetMostFocused ());
-        Assert.Equal (tf1W2, win2.GetMostFocused ());
+        Assert.Null (top.MostFocused);
+        Assert.Equal (tf1W2, win2.MostFocused);
         Assert.Equal (2, ApplicationOverlapped.OverlappedChildren!.Count);
 
         ApplicationOverlapped.MoveToOverlappedChild (win1);
@@ -1109,7 +1109,7 @@ public class OverlappedTests
         Assert.True (Application.OnKeyDown (Key.F5)); // refresh
 
         Assert.True (win1.IsCurrentTop);
-        Assert.Equal (tvW1, win1.GetMostFocused ());
+        Assert.Equal (tvW1, win1.MostFocused);
         Assert.True (Application.OnKeyDown (Key.Tab));
         Assert.Equal ($"\tFirst line Win1{Environment.NewLine}Second line Win1", tvW1.Text);
 
@@ -1122,22 +1122,22 @@ public class OverlappedTests
         Assert.True (Application.OnKeyDown (Key.F6.WithShift));    // move back to win1
         Assert.Equal (win1, ApplicationOverlapped.OverlappedChildren [0]);
 
-        Assert.Equal (tvW1, win1.GetMostFocused ());
+        Assert.Equal (tvW1, win1.MostFocused);
         Assert.True (Application.OnKeyDown (Key.Tab));    // text view eats tab
         Assert.Equal (win1, ApplicationOverlapped.OverlappedChildren [0]);
-        Assert.Equal (tvW1, win1.GetMostFocused ());
+        Assert.Equal (tvW1, win1.MostFocused);
 
         tvW1.AllowsTab = false;
         Assert.True (Application.OnKeyDown (Key.Tab));    // text view eats tab
         Assert.Equal (win1, ApplicationOverlapped.OverlappedChildren [0]);
-        Assert.Equal (tf2W1, win1.GetMostFocused ());
+        Assert.Equal (tf2W1, win1.MostFocused);
 
         Assert.True (Application.OnKeyDown (Key.CursorRight));
         Assert.Equal (win1, ApplicationOverlapped.OverlappedChildren [0]);
-        Assert.Equal (tf2W1, win1.GetMostFocused ());
+        Assert.Equal (tf2W1, win1.MostFocused);
         Assert.True (Application.OnKeyDown (Key.CursorDown));
         Assert.Equal (win1, ApplicationOverlapped.OverlappedChildren [0]);
-        Assert.Equal (tf1W1, win1.GetMostFocused ());
+        Assert.Equal (tf1W1, win1.MostFocused);
 #if UNIX_KEY_BINDINGS
         Assert.True (ApplicationOverlapped.OverlappedChildren [0].ProcessKeyDown (new (Key.I.WithCtrl)));
         Assert.Equal (win1, ApplicationOverlapped.OverlappedChildren [0]);
@@ -1145,50 +1145,50 @@ public class OverlappedTests
 #endif
         Assert.True (Application.OnKeyDown (Key.Tab));
         Assert.Equal (win1, ApplicationOverlapped.OverlappedChildren [0]);
-        Assert.Equal (tvW1, win1.GetMostFocused ());
+        Assert.Equal (tvW1, win1.MostFocused);
         Assert.True (Application.OnKeyDown (Key.CursorLeft));  // The view to the left of tvW1 is tf2W1, but tvW1 is still focused and eats cursor keys
         Assert.Equal (win1, ApplicationOverlapped.OverlappedChildren [0]);
-        Assert.Equal (tvW1, win1.GetMostFocused ());
+        Assert.Equal (tvW1, win1.MostFocused);
         Assert.True (Application.OnKeyDown (Key.CursorUp));
         Assert.Equal (win1, ApplicationOverlapped.OverlappedChildren [0]);
-        Assert.Equal (tvW1, win1.GetMostFocused ());
+        Assert.Equal (tvW1, win1.MostFocused);
         Assert.True (Application.OnKeyDown (Key.Tab));
         Assert.Equal (win1, ApplicationOverlapped.OverlappedChildren [0]);
-        Assert.Equal (tf2W1, win1.GetMostFocused ());
+        Assert.Equal (tf2W1, win1.MostFocused);
 
         Assert.True (Application.OnKeyDown (Key.F6)); // Move to win2
         Assert.Equal (win2, ApplicationOverlapped.OverlappedChildren [0]);
-        Assert.Equal (tf1W2, win2.GetMostFocused ());
+        Assert.Equal (tf1W2, win2.MostFocused);
         tf2W2.SetFocus ();
         Assert.True (tf2W2.HasFocus);
 
         Assert.True (Application.OnKeyDown (Key.F6.WithShift));
         Assert.Equal (win1, ApplicationOverlapped.OverlappedChildren [0]);
-        Assert.Equal (tf2W1, win1.GetMostFocused ());
+        Assert.Equal (tf2W1, win1.MostFocused);
         Assert.True (Application.OnKeyDown (Application.NextTabGroupKey));
         Assert.Equal (win2, ApplicationOverlapped.OverlappedChildren [0]);
-        Assert.Equal (tf2W2, win2.GetMostFocused ());
+        Assert.Equal (tf2W2, win2.MostFocused);
         Assert.True (Application.OnKeyDown (Application.PrevTabGroupKey));
         Assert.Equal (win1, ApplicationOverlapped.OverlappedChildren [0]);
-        Assert.Equal (tf2W1, win1.GetMostFocused ());
+        Assert.Equal (tf2W1, win1.MostFocused);
         Assert.True (Application.OnKeyDown (Key.CursorDown));
         Assert.Equal (win1, ApplicationOverlapped.OverlappedChildren [0]);
-        Assert.Equal (tf1W1, win1.GetMostFocused ());
+        Assert.Equal (tf1W1, win1.MostFocused);
 #if UNIX_KEY_BINDINGS
         Assert.True (Application.OnKeyDown (new (Key.B.WithCtrl)));
 #else
         Assert.True (Application.OnKeyDown (Key.CursorLeft));
 #endif
         Assert.Equal (win1, ApplicationOverlapped.OverlappedChildren [0]);
-        Assert.Equal (tf1W1, win1.GetMostFocused ());
+        Assert.Equal (tf1W1, win1.MostFocused);
         Assert.True (Application.OnKeyDown (Key.CursorDown));
         Assert.Equal (win1, ApplicationOverlapped.OverlappedChildren [0]);
-        Assert.Equal (tvW1, win1.GetMostFocused ());
+        Assert.Equal (tvW1, win1.MostFocused);
         Assert.Equal (Point.Empty, tvW1.CursorPosition);
 
         Assert.True (Application.OnKeyDown (Key.End.WithCtrl));
         Assert.Equal (win1, ApplicationOverlapped.OverlappedChildren [0]);
-        Assert.Equal (tvW1, win1.GetMostFocused ());
+        Assert.Equal (tvW1, win1.MostFocused);
         Assert.Equal (new (16, 1), tvW1.CursorPosition); // Last position of the text
 #if UNIX_KEY_BINDINGS
         Assert.True (Application.OnKeyDown (new (Key.F.WithCtrl)));
@@ -1196,7 +1196,7 @@ public class OverlappedTests
         Assert.True (Application.OnKeyDown (Key.CursorRight)); // should move to next view w/ in Group (tf2W1)
 #endif
         Assert.Equal (win1, ApplicationOverlapped.OverlappedChildren [0]);
-        Assert.Equal (tf2W1, win1.GetMostFocused ());
+        Assert.Equal (tf2W1, win1.MostFocused);
 
 #if UNIX_KEY_BINDINGS
         Assert.True (ApplicationOverlapped.OverlappedChildren [0].ProcessKeyDown (new (Key.L.WithCtrl)));
@@ -1228,7 +1228,7 @@ public class OverlappedTests
         Application.Current = current;
         Assert.True (current.HasFocus);
         Assert.Equal (superView.Focused, current);
-        Assert.Equal (superView.GetMostFocused (), current);
+        Assert.Equal (superView.MostFocused, current);
 
         // Act
         ApplicationOverlapped.SetFocusToNextViewWithWrap (Application.Current.SuperView.TabIndexes, NavigationDirection.Forward);
@@ -1277,14 +1277,14 @@ public class OverlappedTests
     {
         public bool IsFocused { get; private set; }
 
-        protected override bool OnEnter (View view)
+        protected override bool OnHasFocusChanging (View view)
         {
             IsFocused = true;
 
             return false;
         }
 
-        protected override void OnLeave (View view) { IsFocused = false; }
+        protected override void OnHasFocusChanged (View view) { IsFocused = false; }
     }
 
     private class TestView : View
@@ -1295,14 +1295,14 @@ public class OverlappedTests
         }
         public bool IsFocused { get; private set; }
 
-        protected override bool OnEnter (View view)
+        protected override bool OnHasFocusChanging (View view)
         {
             IsFocused = true;
 
             return false; // don't cancel
         }
 
-        protected override void OnLeave (View view)
+        protected override void OnHasFocusChanged (View view)
         {
             IsFocused = false;
         }

+ 2 - 2
UnitTests/Views/ScrollViewTests.cs

@@ -1119,7 +1119,7 @@ public class ScrollViewTests (ITestOutputHelper output)
             CanFocus = true;
         }
 
-        protected override bool OnEnter (View view)
+        protected override bool OnHasFocusChanging (View view)
         {
             Border.LineStyle = LineStyle.None;
             Border.Thickness = new (0);
@@ -1129,7 +1129,7 @@ public class ScrollViewTests (ITestOutputHelper output)
             return false; // don't cancel
         }
 
-        protected override void OnLeave (View view)
+        protected override void OnHasFocusChanged (View view)
         {
             Border.LineStyle = LineStyle.Single;
             Border.Thickness = new (1);

+ 16 - 16
UnitTests/Views/TabViewTests.cs

@@ -394,8 +394,8 @@ public class TabViewTests (ITestOutputHelper output)
         // Is the selected tab view hosting focused
         Assert.Equal (tab1, tv.SelectedTab);
         Assert.Equal (tv, top.Focused);
-        Assert.Equal (tv.GetMostFocused (), top.Focused.GetMostFocused ());
-        Assert.Equal (tv.SelectedTab.View, top.Focused.GetMostFocused ());
+        Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
+        Assert.Equal (tv.SelectedTab.View, top.Focused.MostFocused);
 
         // Press the cursor up key to focus the selected tab
         Application.OnKeyDown (Key.CursorUp);
@@ -404,7 +404,7 @@ public class TabViewTests (ITestOutputHelper output)
         // Is the selected tab focused
         Assert.Equal (tab1, tv.SelectedTab);
         Assert.Equal (tv, top.Focused);
-        Assert.Equal (tv.GetMostFocused (), top.Focused.GetMostFocused ());
+        Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
 
         Tab oldChanged = null;
         Tab newChanged = null;
@@ -422,12 +422,12 @@ public class TabViewTests (ITestOutputHelper output)
         Assert.Equal (tab2, newChanged);
         Assert.Equal (tab2, tv.SelectedTab);
         Assert.Equal (tv, top.Focused);
-        Assert.Equal (tv.GetMostFocused (), top.Focused.GetMostFocused ());
+        Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
 
         // Press the cursor down key. Since the selected tab has no focusable views, the focus should move to the next view in the toplevel
         Application.OnKeyDown (Key.CursorDown);
         Assert.Equal (tab2, tv.SelectedTab);
-        Assert.Equal (btn, top.GetMostFocused ());
+        Assert.Equal (btn, top.MostFocused);
 
         // Add a focusable subview to Selected Tab
         var btnSubView = new View ()
@@ -441,26 +441,26 @@ public class TabViewTests (ITestOutputHelper output)
         // Press cursor up. Should focus the subview in the selected tab.
         Application.OnKeyDown (Key.CursorUp);
         Assert.Equal (tab2, tv.SelectedTab);
-        Assert.Equal (btnSubView, top.GetMostFocused ());
+        Assert.Equal (btnSubView, top.MostFocused);
 
         Application.OnKeyDown (Key.CursorUp);
-        Assert.Equal (tab2, top.GetMostFocused ());
+        Assert.Equal (tab2, top.MostFocused);
 
         // Press the cursor down key twice.
         Application.OnKeyDown (Key.CursorDown);
         Application.OnKeyDown (Key.CursorDown);
-        Assert.Equal (btn, top.GetMostFocused ());
+        Assert.Equal (btn, top.MostFocused);
 
         // Press the cursor down key again will focus next view in the toplevel, whic is the TabView
         Application.OnKeyDown (Key.CursorDown);
         Assert.Equal (tab2, tv.SelectedTab);
         Assert.Equal (tv, top.Focused);
-        Assert.Equal (tab1, tv.GetMostFocused ());
+        Assert.Equal (tab1, tv.MostFocused);
 
         // Press the cursor down key to focus the selected tab view hosting again
         Application.OnKeyDown (Key.CursorDown);
         Assert.Equal (tab2, tv.SelectedTab);
-        Assert.Equal (btnSubView, top.GetMostFocused ());
+        Assert.Equal (btnSubView, top.MostFocused);
 
         // Press the cursor up key to focus the selected tab
         Application.OnKeyDown (Key.CursorUp);
@@ -469,7 +469,7 @@ public class TabViewTests (ITestOutputHelper output)
         // Is the selected tab focused
         Assert.Equal (tab2, tv.SelectedTab);
         Assert.Equal (tv, top.Focused);
-        Assert.Equal (tv.GetMostFocused (), top.Focused.GetMostFocused ());
+        Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
 
         // Press the cursor left key to select the previous tab
         Application.OnKeyDown (Key.CursorLeft);
@@ -478,7 +478,7 @@ public class TabViewTests (ITestOutputHelper output)
         Assert.Equal (tab1, newChanged);
         Assert.Equal (tab1, tv.SelectedTab);
         Assert.Equal (tv, top.Focused);
-        Assert.Equal (tv.GetMostFocused (), top.Focused.GetMostFocused ());
+        Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
 
         // Press the end key to select the last tab
         Application.OnKeyDown (Key.End);
@@ -487,7 +487,7 @@ public class TabViewTests (ITestOutputHelper output)
         Assert.Equal (tab2, newChanged);
         Assert.Equal (tab2, tv.SelectedTab);
         Assert.Equal (tv, top.Focused);
-        Assert.Equal (tv.GetMostFocused (), top.Focused.GetMostFocused ());
+        Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
 
         // Press the home key to select the first tab
         Application.OnKeyDown (Key.Home);
@@ -496,7 +496,7 @@ public class TabViewTests (ITestOutputHelper output)
         Assert.Equal (tab1, newChanged);
         Assert.Equal (tab1, tv.SelectedTab);
         Assert.Equal (tv, top.Focused);
-        Assert.Equal (tv.GetMostFocused (), top.Focused.GetMostFocused ());
+        Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
 
         // Press the page down key to select the next set of tabs
         Application.OnKeyDown (Key.PageDown);
@@ -505,7 +505,7 @@ public class TabViewTests (ITestOutputHelper output)
         Assert.Equal (tab2, newChanged);
         Assert.Equal (tab2, tv.SelectedTab);
         Assert.Equal (tv, top.Focused);
-        Assert.Equal (tv.GetMostFocused (), top.Focused.GetMostFocused ());
+        Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
 
         // Press the page up key to select the previous set of tabs
         Application.OnKeyDown (Key.PageUp);
@@ -514,7 +514,7 @@ public class TabViewTests (ITestOutputHelper output)
         Assert.Equal (tab1, newChanged);
         Assert.Equal (tab1, tv.SelectedTab);
         Assert.Equal (tv, top.Focused);
-        Assert.Equal (tv.GetMostFocused (), top.Focused.GetMostFocused ());
+        Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
         top.Dispose ();
     }
 

+ 17 - 17
UnitTests/Views/ToplevelTests.cs

@@ -467,7 +467,7 @@ public partial class ToplevelTests (ITestOutputHelper output)
         Assert.Equal (new (0, 0, 40, 25), win1.Frame);
         Assert.Equal (new (41, 0, 40, 25), win2.Frame);
         Assert.Equal (win1, top.Focused);
-        Assert.Equal (tf1W1, top.GetMostFocused ());
+        Assert.Equal (tf1W1, top.MostFocused);
 
         Assert.True (isRunning);
         Assert.True (Application.OnKeyDown (Application.QuitKey));
@@ -478,35 +478,35 @@ public partial class ToplevelTests (ITestOutputHelper output)
 
         Assert.True (Application.OnKeyDown (Key.Tab));
         Assert.Equal (win1, top.Focused);
-        Assert.Equal (tvW1, top.GetMostFocused ());
+        Assert.Equal (tvW1, top.MostFocused);
         Assert.True (Application.OnKeyDown (Key.Tab));
         Assert.Equal ($"\tFirst line Win1{Environment.NewLine}Second line Win1", tvW1.Text);
         Assert.True (Application.OnKeyDown (Key.Tab.WithShift));
         Assert.Equal ($"First line Win1{Environment.NewLine}Second line Win1", tvW1.Text);
 
-        var prevMostFocusedSubview = top.GetMostFocused ();
+        var prevMostFocusedSubview = top.MostFocused;
 
         Assert.True (Application.OnKeyDown (Key.F6)); // move to next TabGroup (win2)
         Assert.Equal (win2, top.Focused);
 
         Assert.True (Application.OnKeyDown (Key.F6.WithShift)); // move to prev TabGroup (win1)
         Assert.Equal (win1, top.Focused);
-        Assert.Equal (tf2W1, top.GetMostFocused ());  // BUGBUG: Should be prevMostFocusedSubview - We need to cache the last focused view in the TabGroup somehow
+        Assert.Equal (tf2W1, top.MostFocused);  // BUGBUG: Should be prevMostFocusedSubview - We need to cache the last focused view in the TabGroup somehow
 
         prevMostFocusedSubview.SetFocus ();
 
-        Assert.Equal (tvW1, top.GetMostFocused ());
+        Assert.Equal (tvW1, top.MostFocused);
 
         tf2W1.SetFocus ();
         Assert.True (Application.OnKeyDown (Key.Tab)); // tf2W1 is last subview in win1 - tabbing should take us to first subview of win1
         Assert.Equal (win1, top.Focused);
-        Assert.Equal (tf1W1, top.GetMostFocused ());
+        Assert.Equal (tf1W1, top.MostFocused);
         Assert.True (Application.OnKeyDown (Key.CursorRight)); // move char to right in tf1W1. We're at last char so nav to next view
         Assert.Equal (win1, top.Focused);
-        Assert.Equal (tvW1, top.GetMostFocused ());
+        Assert.Equal (tvW1, top.MostFocused);
         Assert.True (Application.OnKeyDown (Key.CursorDown)); // move down to next view (tvW1)
         Assert.Equal (win1, top.Focused);
-        Assert.Equal (tvW1, top.GetMostFocused ());
+        Assert.Equal (tvW1, top.MostFocused);
 #if UNIX_KEY_BINDINGS
         Assert.True (Application.OnKeyDown (new (Key.I.WithCtrl)));
         Assert.Equal (win1, top.GetFocused ());
@@ -514,34 +514,34 @@ public partial class ToplevelTests (ITestOutputHelper output)
 #endif
         Assert.True (Application.OnKeyDown (Key.Tab.WithShift)); // Ignored. TextView eats shift-tab by default
         Assert.Equal (win1, top.Focused);
-        Assert.Equal (tvW1, top.GetMostFocused ());
+        Assert.Equal (tvW1, top.MostFocused);
         tvW1.AllowsTab = false;
         Assert.True (Application.OnKeyDown (Key.Tab.WithShift));
         Assert.Equal (win1, top.Focused);
-        Assert.Equal (tf1W1, top.GetMostFocused ());
+        Assert.Equal (tf1W1, top.MostFocused);
         Assert.True (Application.OnKeyDown (Key.CursorLeft));
         Assert.Equal (win1, top.Focused);
-        Assert.Equal (tf2W1, top.GetMostFocused ());
+        Assert.Equal (tf2W1, top.MostFocused);
         Assert.True (Application.OnKeyDown (Key.CursorUp));
         Assert.Equal (win1, top.Focused);
-        Assert.Equal (tvW1, top.GetMostFocused ());
+        Assert.Equal (tvW1, top.MostFocused);
 
         // nav to win2
         Assert.True (Application.OnKeyDown (Key.F6));
         Assert.Equal (win2, top.Focused);
-        Assert.Equal (tf1W2, top.GetMostFocused ());
+        Assert.Equal (tf1W2, top.MostFocused);
         Assert.True (Application.OnKeyDown (Key.F6.WithShift));
         Assert.Equal (win1, top.Focused);
-        Assert.Equal (tf2W1, top.GetMostFocused ());
+        Assert.Equal (tf2W1, top.MostFocused);
         Assert.True (Application.OnKeyDown (Application.NextTabGroupKey));
         Assert.Equal (win2, top.Focused);
-        Assert.Equal (tf1W2, top.GetMostFocused ());
+        Assert.Equal (tf1W2, top.MostFocused);
         Assert.True (Application.OnKeyDown (Application.PrevTabGroupKey));
         Assert.Equal (win1, top.Focused);
-        Assert.Equal (tf2W1, top.GetMostFocused ());
+        Assert.Equal (tf2W1, top.MostFocused);
         Assert.True (Application.OnKeyDown (Key.CursorUp));
         Assert.Equal (win1, top.Focused);
-        Assert.Equal (tvW1, top.GetMostFocused ());
+        Assert.Equal (tvW1, top.MostFocused);
 
         top.Dispose ();
     }

+ 1 - 1
UnitTests/Views/TreeTableSourceTests.cs

@@ -290,7 +290,7 @@ public class TreeTableSourceTests : IDisposable
         var top = new Toplevel ();
         top.Add (tableView);
         top.RestoreFocus (null);
-        Assert.Equal (tableView, top.GetMostFocused ());
+        Assert.Equal (tableView, top.MostFocused);
 
         return tableView;
     }

+ 3 - 3
UnitTests/Views/WindowTests.cs

@@ -143,7 +143,7 @@ public class WindowTests
         Assert.False (defaultWindow.WantContinuousButtonPressed);
         Assert.False (defaultWindow.WantMousePositionReports);
         Assert.Null (defaultWindow.SuperView);
-        Assert.Null (defaultWindow.GetMostFocused ());
+        Assert.Null (defaultWindow.MostFocused);
         Assert.Equal (TextDirection.LeftRight_TopBottom, defaultWindow.TextDirection);
 
         // Empty Rect
@@ -167,7 +167,7 @@ public class WindowTests
         Assert.False (windowWithFrameRectEmpty.WantContinuousButtonPressed);
         Assert.False (windowWithFrameRectEmpty.WantMousePositionReports);
         Assert.Null (windowWithFrameRectEmpty.SuperView);
-        Assert.Null (windowWithFrameRectEmpty.GetMostFocused ());
+        Assert.Null (windowWithFrameRectEmpty.MostFocused);
         Assert.Equal (TextDirection.LeftRight_TopBottom, windowWithFrameRectEmpty.TextDirection);
 
         // Rect with values
@@ -198,7 +198,7 @@ public class WindowTests
         Assert.False (windowWithFrame1234.WantContinuousButtonPressed);
         Assert.False (windowWithFrame1234.WantMousePositionReports);
         Assert.Null (windowWithFrame1234.SuperView);
-        Assert.Null (windowWithFrame1234.GetMostFocused ());
+        Assert.Null (windowWithFrame1234.MostFocused);
         Assert.Equal (TextDirection.LeftRight_TopBottom, windowWithFrame1234.TextDirection);
     }
 

+ 1 - 1
docfx/docs/View.md

@@ -132,7 +132,7 @@ This covers my thinking on how we will refactor `View` and the classes in the `V
 ## Design
 
 * `Responder`("Responder base class implemented by objects that want to participate on keyboard and mouse input.") remains mostly unchanged, with minor changes:
-   * Methods that take `View` parameters (e.g. `OnEnter`) change to take `Responder` (bad OO design).
+   * Methods that take `View` parameters change to take `Responder` (bad OO design).
    * Nuke `IsOverriden` (bad OO design)
    * Move `View.Data` to `Responder` (primitive)
    * Move `Command` and `KeyBinding` stuff from `View`.

+ 2 - 0
docfx/docs/index.md

@@ -2,6 +2,8 @@
 
  A toolkit for building rich Terminal User Interface (TUI) apps with .NET that run on Windows, the Mac, and Linux/Unix.
 
+ (This is the v2 API documentation. For v1 go here: https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui.html)
+
 ## Features
 
 * **[Cross Platform](drivers.md)** - Windows, Mac, and Linux. Terminal drivers for Curses, Windows, and the .NET Console mean apps will work well on both color and monochrome terminals. Apps also work over SSH.

+ 7 - 1
docfx/docs/migratingfromv1.md

@@ -225,12 +225,18 @@ In v2, the API is (NOT YET IMPLEMENTED) simplified. A view simply reports the st
 See [navigation.md](navigation.md) for more details.
 See also [Keyboard](keyboard.md) where HotKey is covered more deeply...
 
+* In v1 it was not possible to remove focus from a view. `HasFocus` as a get-only property. In v2, `view.HasFocus` can be set as well. Setting to `true` is equivalent to calling `view.SetFocus`. Setting to `false` is equivalent to calling `view.SuperView.AdvanceFocus` (which might not actually cause `view` to stop having focus). 
 * In v1, calling `super.Add (view)` where `view.CanFocus == true` caused all views up the hierarchy (all SuperViews) to get `CanFocus` set to `true` as well. In v2, developers need to explicitly set `CanFocus` for any view in the view-hierarchy where focus is desired. This simplifies the implementation and removes confusing automatic behavior. 
 * In v1, if `view.CanFocus == true`, `Add` would automatically set `TabStop`. In v2, the automatic setting of `TabStop` in `Add` is retained because it is not overly complex to do so and is a nice convenience for developers to not have to set both `Tabstop` and `CanFocus`. Note v2 does NOT automatically change `CanFocus` if `TabStop` is changed.
 * `view.TabStop` now describes the behavior of a view in the focus-chain. the `TabBehavior` enum includes `NoStop` (the view may be focusable, but not via next/prev keyboard nav), `TabStop` (the view may be focusable, and `NextTabStop`/`PrevTabStop` keyboard nav will stop), `TabGroup` (the view may be focusable, and `NextTabGroup`/`PrevTabGroup` keyboard nav will stop). 
 * In v1, the `View.Focused` property was a cache of which view in `SubViews/TabIndexes` had `HasFocus == true`. There was a lot of logic for keeping this property in sync. In v2, `View.Focused` is a get-only, computed property. 
-* In v1, the `View.OnEnter/Enter` and `View.OnLeave/Leave` virtual methods/events could be used to notify that a view had gained or lost focus, but had confusing semantics around what it mean to override (requiring calling `base`) and bug-ridden behavior on what the return values signified. The "Enter" and "Leave" terminology was confusing. In v2, the terminology is "Focus" and "Blur", matching modern web frameworks and the `View.OnFocus/Focus` and `View.OnBlur/Blur` virtual methods/events follow standard dotnet event patterns. The `OnFocus/Focus` event supports being cancelled.
+* In v1, the `View.MostFocused` property recursed down the subview-hierarchy on each get. In addition, because only one View in an application can be the "most focused", it doesn't make sense for this property to be on every View. In v2, this API is removed. Use `Application.Navigation.GetFocused()` instead.
+* The v1 APIs `View.EnsureFocus`/`FocusNext`/`FocusPrev`/`FocusFirst`/`FocusLast` are replaced in v2 with these APIs that accomplish the same thing, more simply.
+  - `public bool AdvanceFocus (NavigationDirection direction, TabBehavior? behavior)`  
+  - `public bool FocusDeepest (NavigationDirection direction, TabBehavior? behavior)` 
+* In v1, the `View.OnEnter/Enter` and `View.OnLeave/Leave` virtual methods/events could be used to notify that a view had gained or lost focus, but had confusing semantics around what it mean to override (requiring calling `base`) and bug-ridden behavior on what the return values signified. The "Enter" and "Leave" terminology was confusing. In v2, `View.OnHasFocusChanging/HasFocusChanging` and `View.OnHasFocusChanged/HasFocusChanged` replace `View.OnEnter/Enter` and `View.OnLeave/Leave`. These virtual methods/events follow standard Terminal.Gui event patterns. The `View.OnHasFocusChanging/HasFocusChanging` event supports being cancelled.
 * In v1, the concept of `Mdi` views included a large amount of complex code (in `Toplevel` and `Application`) for dealing with navigation across overlapped Views. This has all been radically simplified in v2. Any View can work in an "overlapped" or "tiled" way. See [navigation.md](navigation.md) for more details.
+* The `View.TabIndex` and `View.TabIndexes` have been removed. Change the order of the views in `View.Subviews` to change the navigation order. 
 
 ### How to Fix (Focus API)
 

+ 2 - 2
docfx/docs/navigation.md

@@ -18,8 +18,8 @@
 - **Tab** - Describes the `Tab` key found on all keyboards, a break in text that is wider than a space, or a UI element that is a stop-point for keyboard navigation. The use of the word "Tab" for this comes from the typewriter, and is re-enforced by the existence of a `Tab` key on all keyboards.
 - **TabStop** - A `View` that is an ultimate stop-point for keyboard navigation. In this usage, ultimate means the `View` has no focusable subviews. The `Application.NextTabStopKey` and `Application.PrevTabStopKey` are `Key.Tab` and `Key.Tab.WithShift` respectively. These keys navigate only between peer-views. 
 - **TabGroup** - A `View` that is a container for other focusable views. The `Application.NextTabGroupKey` and `Application.PrevTabGroupKey` are `Key.PageDown.WithCtrl` and `Key.PageUp.WithCtrl` respectively. These keys enable the user to use the keyboard to navigate up and down the view-hierarchy. 
-- **Enter** / **Gain** - Means a View that previously was not focused is now becoming focused. "The View is entering focus" is the same as "The View is gaining focus".
-- **Leave** / **Lose** - Means a View that previously was focused is now becoming un-focused. "The View is leaving focus" is the same as "The View is losing focus".
+- **Enter** / **Gain** - Means a View that previously was not focused is now becoming focused. "The View is entering focus" is the same as "The View is gaining focus". These terms are legacy terms from v1.
+- **Leave** / **Lose** - Means a View that previously was focused is now becoming un-focused. "The View is leaving focus" is the same as "The View is losing focus". These terms are legacy terms from v1.
 
 ## Tenets for Terminal.Gui UI Navigation (Unless you know better ones...)