Tig 1 рік тому
батько
коміт
f2eb9ce6e2

+ 7 - 2
Terminal.Gui/Application/Application.Navigation.cs

@@ -69,7 +69,12 @@ internal static class ApplicationNavigation
 
             if (!Application.Current.AdvanceFocus (NavigationDirection.Forward, true))
             {
-                Application.Current.AdvanceFocus (NavigationDirection.Forward, true);
+                Application.Current.AdvanceFocus (NavigationDirection.Forward, false);
+
+                if (Application.Current.Focused is null)
+                {
+                    Application.Current.RestoreFocus ();
+                }
             }
 
             if (top != Application.Current.Focused && top != Application.Current.Focused?.Focused)
@@ -133,7 +138,7 @@ internal static class ApplicationNavigation
 
             if (top.Focused is null)
             {
-                top.AdvanceFocus (NavigationDirection.Backward, true);
+                top.AdvanceFocus (NavigationDirection.Backward, false);
             }
 
             top.SetNeedsDisplay ();

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

@@ -179,7 +179,7 @@ public static partial class Application // Run (Begin, Run, End, Stop)
 
         toplevel.LayoutSubviews ();
         toplevel.PositionToplevels ();
-        toplevel.FocusFirst ();
+        toplevel.FocusFirst (null);
         ApplicationOverlapped.BringOverlappedTopToFront ();
 
         if (refreshDriver)

+ 3 - 0
Terminal.Gui/View/View.Hierarchy.cs

@@ -1,3 +1,5 @@
+using System.Diagnostics;
+
 namespace Terminal.Gui;
 
 public partial class View // SuperView/SubView hierarchy management (SuperView, SubViews, Add, Remove, etc.)
@@ -55,6 +57,7 @@ public partial class View // SuperView/SubView hierarchy management (SuperView,
             _tabIndexes = new ();
         }
 
+        Debug.Assert (!_subviews.Contains (view));
         _subviews.Add (view);
         _tabIndexes.Add (view);
         view._superView = this;

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

@@ -53,11 +53,11 @@ public partial class View // Focus and cross-view navigation management (TabStop
             switch (direction)
             {
                 case NavigationDirection.Forward:
-                    FocusFirst (groupOnly);
+                    FocusFirst (TabBehavior.TabGroup);
 
                     break;
                 case NavigationDirection.Backward:
-                    FocusLast (groupOnly);
+                    FocusLast (TabBehavior.TabGroup);
 
                     break;
                 default:
@@ -89,21 +89,33 @@ public partial class View // Focus and cross-view navigation management (TabStop
         }
         else
         {
-            // Wrap around
-            if (SuperView is {})
+            // focusedIndex is at end of list. If we are going backwards,...
+            if (groupOnly)
             {
-                if (direction == NavigationDirection.Forward)
-                {
-                    return false;
-                }
-                else
-                {
-                    return false;
+                // Go up the hierarchy
+                // Leave
+                Focused.SetHasFocus (false, this);
 
-                    //SuperView.FocusFirst (groupOnly);
-                }
-                return true;
+                // Signal that nothing is focused, and callers should try a peer-subview
+                Focused = null;
+
+                return false;
             }
+            // Wrap around
+            //if (SuperView is {})
+            //{
+            //    if (direction == NavigationDirection.Forward)
+            //    {
+            //        return false;
+            //    }
+            //    else
+            //    {
+            //        return false;
+
+            //        //SuperView.FocusFirst (groupOnly);
+            //    }
+            //    return true;
+            //}
             //next = index.Length - 1;
 
         }
@@ -120,11 +132,11 @@ public partial class View // Focus and cross-view navigation management (TabStop
             switch (direction)
             {
                 case NavigationDirection.Forward:
-                    view.FocusFirst (false);
+                    view.FocusFirst (TabBehavior.TabStop);
 
                     break;
                 case NavigationDirection.Backward:
-                    view.FocusLast (false);
+                    view.FocusLast (TabBehavior.TabStop);
 
                     break;
             }
@@ -213,7 +225,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
             if (!_canFocus && HasFocus)
             {
                 SetHasFocus (false, this);
-                SuperView?.FocusFirstOrLast ();
+                SuperView?.RestoreFocus ();
 
                 // If EnsureFocus () didn't set focus to a view, focus the next focusable view in the application
                 if (SuperView is { Focused: null })
@@ -290,12 +302,8 @@ public partial class View // Focus and cross-view navigation management (TabStop
     ///     Focuses the first focusable view in <see cref="View.TabIndexes"/> if one exists. If there are no views in
     ///     <see cref="View.TabIndexes"/> then the focus is set to the view itself.
     /// </summary>
-    /// <param name="groupOnly">
-    ///     If <see langword="true"/>, only subviews where <see cref="TabStop"/> is
-    ///     <see cref="TabBehavior.TabGroup"/> set
-    ///     will be considered.
-    /// </param>
-    public void FocusFirst (bool groupOnly = false)
+    /// <param name="behavior"></param>
+    public void FocusFirst (TabBehavior? behavior)
     {
         if (!CanBeVisible (this))
         {
@@ -309,7 +317,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
             return;
         }
 
-        var indicies = GetScopedTabIndexes (groupOnly ? TabBehavior.TabGroup : TabBehavior.TabStop, NavigationDirection.Forward);
+        var indicies = GetScopedTabIndexes (behavior, NavigationDirection.Forward);
         if (indicies.Length > 0)
         {
             SetFocus (indicies [0]);
@@ -320,12 +328,8 @@ public partial class View // Focus and cross-view navigation management (TabStop
     ///     Focuses the last focusable view in <see cref="View.TabIndexes"/> if one exists. If there are no views in
     ///     <see cref="View.TabIndexes"/> then the focus is set to the view itself.
     /// </summary>
-    /// <param name="groupOnly">
-    ///     If <see langword="true"/>, only subviews where <see cref="TabStop"/> is
-    ///     <see cref="TabBehavior.TabGroup"/> set
-    ///     will be considered.
-    /// </param>
-    public void FocusLast (bool groupOnly = false)
+    /// <param name="behavior"></param>
+    public void FocusLast (TabBehavior? behavior)
     {
         if (!CanBeVisible (this))
         {
@@ -339,7 +343,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
             return;
         }
 
-        var indicies = GetScopedTabIndexes (groupOnly ? TabBehavior.TabGroup : TabBehavior.TabStop, NavigationDirection.Forward);
+        var indicies = GetScopedTabIndexes (behavior, NavigationDirection.Forward);
         if (indicies.Length > 0)
         {
             SetFocus (indicies [^1]);
@@ -505,17 +509,17 @@ public partial class View // Focus and cross-view navigation management (TabStop
     ///     <see cref="FocusDirection"/>.
     ///     FocusDirection is not public. This API is thus non-deterministic from a public API perspective.
     /// </summary>
-    internal void FocusFirstOrLast ()
+    internal void RestoreFocus ()
     {
         if (Focused is null && _subviews?.Count > 0)
         {
             if (FocusDirection == NavigationDirection.Forward)
             {
-                FocusFirst ();
+                FocusFirst (null);
             }
             else
             {
-                FocusLast ();
+                FocusLast (null);
             }
         }
     }
@@ -582,7 +586,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
 
         // Ensure on either the first or last focusable subview of Focused
         // BUGBUG: With Groups, this means the previous focus is lost
-        Focused.FocusFirstOrLast ();
+        Focused.RestoreFocus ();
 
         // Recursively set focus upwards in the view hierarchy
         if (SuperView is { })
@@ -651,9 +655,24 @@ public partial class View // Focus and cross-view navigation management (TabStop
     /// <value>The tabIndexes.</value>
     public IList<View> TabIndexes => _tabIndexes?.AsReadOnly () ?? _empty;
 
-    private View [] GetScopedTabIndexes (TabBehavior behavior, NavigationDirection direction)
+    /// <summary>
+    /// Gets TabIndexes that are scoped to the specified behavior and direction. If behavior is null, all TabIndexes are returned.
+    /// </summary>
+    /// <param name="behavior"></param>
+    /// <param name="direction"></param>
+    /// <returns></returns>GetScopedTabIndexes
+    private View [] GetScopedTabIndexes (TabBehavior? behavior, NavigationDirection direction)
     {
-        var indicies = _tabIndexes.Where (v => v.TabStop == behavior && v is { CanFocus: true, Visible: true, Enabled: true });
+        IEnumerable<View> indicies;
+
+        if (behavior.HasValue)
+        {
+            indicies = _tabIndexes.Where (v => v.TabStop == behavior && v is { CanFocus: true, Visible: true, Enabled: true });
+        }
+        else
+        {
+            indicies = _tabIndexes.Where (v => v is { CanFocus: true, Visible: true, Enabled: true });
+        }
 
         if (direction == NavigationDirection.Backward)
         {

+ 3 - 2
Terminal.Gui/Views/ComboBox.cs

@@ -28,8 +28,9 @@ public class ComboBox : View, IDesignable
     /// <summary>Public constructor</summary>
     public ComboBox ()
     {
-        _search = new TextField ();
-        _listview = new ComboListView (this, HideDropdownListOnClick) { CanFocus = true };
+        _search = new TextField () { CanFocus = true, TabStop = TabBehavior.NoStop };
+
+        _listview = new ComboListView (this, HideDropdownListOnClick) { CanFocus = true, TabStop = TabBehavior.NoStop};
 
         _search.TextChanged += Search_Changed;
         _search.Accept += Search_Accept;

+ 1 - 0
Terminal.Gui/Views/DatePicker.cs

@@ -187,6 +187,7 @@ public class DatePicker : View
         BorderStyle = LineStyle.Single;
         Date = date;
         _dateLabel = new Label { X = 0, Y = 0, Text = "Date: " };
+        TabStop = TabBehavior.TabGroup;
 
         _calendar = new TableView
         {

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

@@ -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.FocusFirst ();
+        _tbPath.FocusFirst (null);
         _tbPath.SelectAll ();
 
         if (string.IsNullOrEmpty (Title))
@@ -1045,7 +1045,7 @@ public class FileDialog : Dialog
     {
         if (keyEvent.KeyCode == isKey)
         {
-            to.FocusFirst ();
+            to.FocusFirst (null);
 
             if (to == _tbPath)
             {
@@ -1434,7 +1434,7 @@ public class FileDialog : Dialog
     {
         if (_treeView.HasFocus && Separators.Contains ((char)keyEvent))
         {
-            _tbPath.FocusFirst ();
+            _tbPath.FocusFirst (null);
 
             // let that keystroke go through on the tbPath instead
             return true;

+ 2 - 0
Terminal.Gui/Views/FrameView.cs

@@ -13,6 +13,8 @@ public class FrameView : View
     /// </summary>
     public FrameView ()
     {
+        CanFocus = true;
+        TabStop = TabBehavior.TabGroup;
         Border.Thickness = new Thickness (1);
         Border.LineStyle = DefaultBorderStyle;
 

+ 1 - 0
Terminal.Gui/Views/ScrollView.cs

@@ -70,6 +70,7 @@ public class ScrollView : View
         _horizontal.OtherScrollBarView = _vertical;
         base.Add (_contentView);
         CanFocus = true;
+        TabStop = TabBehavior.TabGroup;
 
         MouseEnter += View_MouseEnter;
         MouseLeave += View_MouseLeave;

+ 1 - 0
Terminal.Gui/Views/Tab.cs

@@ -10,6 +10,7 @@ public class Tab : View
     {
         BorderStyle = LineStyle.Rounded;
         CanFocus = true;
+        //TabStop = TabBehavior.TabGroup;
     }
 
     /// <summary>The text to display in a <see cref="TabView"/>.</summary>

+ 4 - 2
Terminal.Gui/Views/TabView.cs

@@ -25,6 +25,7 @@ public class TabView : View
     public TabView ()
     {
         CanFocus = true;
+        TabStop = TabBehavior.TabGroup;
         _tabsBar = new TabRowView (this);
         _contentView = new View ();
 
@@ -564,6 +565,7 @@ public class TabView : View
             _host = host;
 
             CanFocus = true;
+            TabStop = TabBehavior.TabGroup;
             Height = 1; // BUGBUG: Views should avoid setting Height as doing so implies Frame.Size == GetContentSize ().
             Width = Dim.Fill ();
 
@@ -590,7 +592,7 @@ public class TabView : View
             Add (_rightScrollIndicator, _leftScrollIndicator);
         }
 
-        protected internal override bool OnMouseEvent  (MouseEvent me)
+        protected internal override bool OnMouseEvent (MouseEvent me)
         {
             Tab hit = me.View is Tab ? (Tab)me.View : null;
 
@@ -667,7 +669,7 @@ public class TabView : View
             RenderTabLine ();
 
             RenderUnderline ();
-            Driver.SetAttribute (GetNormalColor ());
+            Driver.SetAttribute (HasFocus ? GetFocusColor () : GetNormalColor ());
         }
 
         public override void OnDrawContentComplete (Rectangle viewport)

+ 2 - 1
Terminal.Gui/Views/Toplevel.cs

@@ -29,6 +29,7 @@ public partial class Toplevel : View
     public Toplevel ()
     {
         CanFocus = true;
+        TabStop = TabBehavior.TabGroup;
         Arrangement = ViewArrangement.Fixed;
         Width = Dim.Fill ();
         Height = Dim.Fill ();
@@ -430,7 +431,7 @@ public partial class Toplevel : View
         {
             if (Focused is null)
             {
-                FocusFirstOrLast ();
+                RestoreFocus ();
             }
 
             return null;

+ 1 - 0
Terminal.Gui/Views/Window.cs

@@ -28,6 +28,7 @@ public class Window : Toplevel
     public Window ()
     {
         CanFocus = true;
+        TabStop = TabBehavior.TabGroup;
         ColorScheme = Colors.ColorSchemes ["Base"]; // TODO: make this a theme property
         BorderStyle = DefaultBorderStyle;
         ShadowStyle = DefaultShadow;

+ 7 - 7
UICatalog/Scenarios/Editor.cs

@@ -238,7 +238,7 @@ public class Editor : Scenario
 
         _appWindow.Add (menu);
 
-        var siCursorPosition = new Shortcut(KeyCode.Null, "", null);
+        var siCursorPosition = new Shortcut (KeyCode.Null, "", null);
 
         var statusBar = new StatusBar (
                                        new []
@@ -722,7 +722,7 @@ public class Editor : Scenario
             }
             else
             {
-                FocusFirst();
+                FocusFirst (null);
             }
         }
 
@@ -737,9 +737,9 @@ public class Editor : Scenario
     {
         _findReplaceWindow.Visible = true;
         _findReplaceWindow.SuperView.BringSubviewToFront (_findReplaceWindow);
-        _tabView.SetFocus();
+        _tabView.SetFocus ();
         _tabView.SelectedTab = isFind ? _tabView.Tabs.ToArray () [0] : _tabView.Tabs.ToArray () [1];
-        _tabView.SelectedTab.View.FocusFirst ();
+        _tabView.SelectedTab.View.FocusFirst (null);
     }
 
     private void CreateFindReplace ()
@@ -753,10 +753,10 @@ public class Editor : Scenario
 
         _tabView.AddTab (new () { DisplayText = "Find", View = CreateFindTab () }, true);
         _tabView.AddTab (new () { DisplayText = "Replace", View = CreateReplaceTab () }, false);
-        _tabView.SelectedTabChanged += (s, e) => _tabView.SelectedTab.View.FocusFirst ();
+        _tabView.SelectedTabChanged += (s, e) => _tabView.SelectedTab.View.FocusFirst (null);
         _findReplaceWindow.Add (_tabView);
 
-        _tabView.SelectedTab.View.FocusLast (); // Hack to get the first tab to be focused
+        _tabView.SelectedTab.View.FocusLast (null); // Hack to get the first tab to be focused
         _findReplaceWindow.Visible = false;
         _appWindow.Add (_findReplaceWindow);
     }
@@ -828,7 +828,7 @@ public class Editor : Scenario
         }
     }
 
-    private void Find () { ShowFindReplace(true); }
+    private void Find () { ShowFindReplace (true); }
     private void FindNext () { ContinueFind (); }
     private void FindPrevious () { ContinueFind (false); }
 

+ 2 - 2
UICatalog/Scenarios/Notepad.cs

@@ -11,7 +11,7 @@ namespace UICatalog.Scenarios;
 public class Notepad : Scenario
 {
     private TabView _focusedTabView;
-    public Shortcut LenShortcut { get; private set; } 
+    public Shortcut LenShortcut { get; private set; }
     private int _numNewTabs = 1;
     private TabView _tabView;
 
@@ -309,7 +309,7 @@ public class Notepad : Scenario
         tab.CloneTo (newTabView);
         newTile.ContentView.Add (newTabView);
 
-        newTabView.FocusFirst ();
+        newTabView.FocusFirst (null);
         newTabView.AdvanceFocus (NavigationDirection.Forward);
     }
 

+ 1 - 1
UICatalog/Scenarios/Sliders.cs

@@ -609,7 +609,7 @@ public class Sliders : Scenario
                              };
         }
 
-        app.FocusFirst ();
+        app.FocusFirst (null);
 
         Application.Run (app);
         app.Dispose ();

+ 2 - 3
UICatalog/Scenarios/ViewExperiments.cs

@@ -15,7 +15,8 @@ public class ViewExperiments : Scenario
 
         Window app = new ()
         {
-            Title = GetQuitKeyAndName ()
+            Title = GetQuitKeyAndName (),
+            TabStop = TabBehavior.TabGroup
         };
 
 
@@ -82,8 +83,6 @@ public class ViewExperiments : Scenario
         };
         view2.Add (button);
 
-        view2.Add (button);
-
         var editor = new AdornmentsEditor
         {
             X = 0,

+ 13 - 13
UnitTests/Application/Application.NavigationTests.cs

@@ -21,7 +21,7 @@ public class ApplicationNavigationTests (ITestOutputHelper output)
     public void GetDeepestFocusedSubview_ShouldReturnSameView_WhenNoSubviewsHaveFocus ()
     {
         // Arrange
-        var view = new View () { Id = "view", CanFocus = true };;
+        var view = new View () { Id = "view", CanFocus = true }; ;
 
         // Act
         var result = ApplicationNavigation.GetDeepestFocusedSubview (view);
@@ -34,10 +34,10 @@ public class ApplicationNavigationTests (ITestOutputHelper output)
     public void GetDeepestFocusedSubview_ShouldReturnFocusedSubview ()
     {
         // Arrange
-        var parentView = new View () { Id = "parentView", CanFocus = true };;
-        var childView1 = new View () { Id = "childView1", CanFocus = true };;
-        var childView2 = new View () { Id = "childView2", CanFocus = true };;
-        var grandChildView = new View () { Id = "grandChildView", CanFocus = true };;
+        var parentView = new View () { Id = "parentView", CanFocus = true }; ;
+        var childView1 = new View () { Id = "childView1", CanFocus = true }; ;
+        var childView2 = new View () { Id = "childView2", CanFocus = true }; ;
+        var grandChildView = new View () { Id = "grandChildView", CanFocus = true }; ;
 
         parentView.Add (childView1, childView2);
         childView2.Add (grandChildView);
@@ -55,17 +55,17 @@ public class ApplicationNavigationTests (ITestOutputHelper output)
     public void GetDeepestFocusedSubview_ShouldReturnDeepestFocusedSubview ()
     {
         // Arrange
-        var parentView = new View () { Id = "parentView", CanFocus = true };;
-        var childView1 = new View () { Id = "childView1", CanFocus = true };;
-        var childView2 = new View () { Id = "childView2", CanFocus = true };;
-        var grandChildView = new View () { Id = "grandChildView", CanFocus = true };;
-        var greatGrandChildView = new View () { Id = "greatGrandChildView", CanFocus = true };;
+        var parentView = new View () { Id = "parentView", CanFocus = true }; ;
+        var childView1 = new View () { Id = "childView1", CanFocus = true }; ;
+        var childView2 = new View () { Id = "childView2", CanFocus = true }; ;
+        var grandChildView = new View () { Id = "grandChildView", CanFocus = true }; ;
+        var greatGrandChildView = new View () { Id = "greatGrandChildView", CanFocus = true }; ;
 
         parentView.Add (childView1, childView2);
         childView2.Add (grandChildView);
         grandChildView.Add (greatGrandChildView);
 
-        grandChildView.SetFocus();
+        grandChildView.SetFocus ();
 
         // Act
         var result = ApplicationNavigation.GetDeepestFocusedSubview (parentView);
@@ -152,8 +152,8 @@ public class ApplicationNavigationTests (ITestOutputHelper output)
     {
         // Arrange
         var top = new Toplevel ();
-        var view1 = new View () { Id = "view1", CanFocus = true };
-        var view2 = new View () { Id = "view2", CanFocus = true };
+        var view1 = new View () { Id = "view1", CanFocus = true, TabStop = TabBehavior.TabGroup };
+        var view2 = new View () { Id = "view2", CanFocus = true, TabStop = TabBehavior.TabGroup };
         top.Add (view1, view2);
         Application.Top = top;
         Application.Current = top;

+ 27 - 10
UnitTests/View/NavigationTests.cs

@@ -516,7 +516,7 @@ public class NavigationTests (ITestOutputHelper output) : TestsAllViews
                                      Assert.False (win.HasFocus);
 
                                      win.Enabled = true;
-                                     win.FocusFirst ();
+                                     win.FocusFirst (null);
                                      Assert.True (button.HasFocus);
                                      Assert.True (win.HasFocus);
 
@@ -1632,10 +1632,12 @@ public class NavigationTests (ITestOutputHelper output) : TestsAllViews
 
         View otherView = new ()
         {
+            Id = "otherView",
             X = 0, Y = 0,
             Height = 1,
             Width = 1,
             CanFocus = true,
+            TabStop = view.TabStop
         };
 
         view.X = Pos.Right (otherView);
@@ -1658,27 +1660,42 @@ public class NavigationTests (ITestOutputHelper output) : TestsAllViews
         Assert.Equal (1, nEnter);
         Assert.Equal (0, nLeave);
 
-        // Use keyboard to navigate to next view (otherView). 
+        // Use keyboard to navigate to next view (otherView).
         if (view is TextView)
         {
             Application.OnKeyDown (Key.Tab.WithCtrl);
         }
-        else if (view is DatePicker)
+        //else if (view is DatePicker)
+        //{
+        //    for (var i = 0; i < 4; i++)
+        //    {
+        //        Application.OnKeyDown (Key.Tab.WithCtrl);
+        //    }
+        //}
+        else
         {
-            for (var i = 0; i < 4; i++)
+            int tries = 0;
+            while (view.HasFocus)
             {
-                Application.OnKeyDown (Key.Tab.WithCtrl);
+                if (++tries > 10)
+                {
+                    Assert.Fail ($"{view} is not leaving.");
+                }
+                Application.OnKeyDown (view.TabStop == TabBehavior.TabStop ? Key.Tab : Key.Tab.WithCtrl);
             }
         }
-        else
-        {
-            Application.OnKeyDown (Key.Tab);
-        }
 
         Assert.Equal (1, nEnter);
         Assert.Equal (1, nLeave);
 
-        Application.OnKeyDown (Key.Tab);
+        Assert.False (view.HasFocus);
+        Assert.True (otherView.HasFocus);
+
+        // Now navigate back to our test view
+        Application.OnKeyDown (view.TabStop == TabBehavior.TabStop ? Key.Tab : Key.Tab.WithCtrl);
+
+        Assert.False (otherView.HasFocus);
+        Assert.True (view.HasFocus);
 
         Assert.Equal (2, nEnter);
         Assert.Equal (1, nLeave);

+ 1 - 1
UnitTests/View/ViewTests.cs

@@ -1091,7 +1091,7 @@ At 0,0
                                      Assert.True (RunesCount () == 0);
 
                                      win.Visible = true;
-                                     win.FocusFirst ();
+                                     win.FocusFirst (null);
                                      Assert.True (button.HasFocus);
                                      Assert.True (win.HasFocus);
                                      top.Draw ();

+ 4 - 4
UnitTests/Views/ComboBoxTests.cs

@@ -815,7 +815,7 @@ Three ",
         cb.SetSource (source);
         var top = new Toplevel ();
         top.Add (cb);
-        top.FocusFirst ();
+        top.FocusFirst (null);
         Assert.Equal (-1, cb.SelectedItem);
         Assert.Equal (string.Empty, cb.Text);
         var opened = false;
@@ -845,7 +845,7 @@ Three ",
         Assert.True (cb.NewKeyDownEvent (Key.CursorDown)); // losing focus
         Assert.False (cb.IsShow);
         Assert.False (cb.HasFocus);
-        top.FocusFirst (); // Gets focus again
+        top.FocusFirst (null); // Gets focus again
         Assert.False (cb.IsShow);
         Assert.True (cb.HasFocus);
         cb.Expand ();
@@ -954,7 +954,7 @@ Three
         Assert.False (cb.IsShow);
         Assert.Equal (-1, cb.SelectedItem);
         Assert.Equal ("One", cb.Text);
-        top.FocusFirst (); // Gets focus again
+        top.FocusFirst (null); // Gets focus again
         Assert.True (cb.HasFocus);
         Assert.False (cb.IsShow);
         Assert.Equal (-1, cb.SelectedItem);
@@ -974,7 +974,7 @@ Three
         var cb = new ComboBox ();
         var top = new Toplevel ();
         top.Add (cb);
-        top.FocusFirst ();
+        top.FocusFirst (null);
         Assert.Null (cb.Source);
         Assert.Equal (-1, cb.SelectedItem);
         ObservableCollection<string> source = [];

+ 2 - 2
UnitTests/Views/TableViewTests.cs

@@ -616,7 +616,7 @@ public class TableViewTests (ITestOutputHelper output)
         top.Add (tableView);
         Application.Begin (top);
 
-        top.FocusFirst ();
+        top.FocusFirst (null);
         Assert.True (tableView.HasFocus);
 
         Assert.Equal (0, tableView.RowOffset);
@@ -1606,7 +1606,7 @@ public class TableViewTests (ITestOutputHelper output)
         top.Add (tv);
         Application.Begin (top);
 
-        top.FocusFirst ();
+        top.FocusFirst (null);
         Assert.True (tv.HasFocus);
 
         // already on fish

+ 3 - 3
UnitTests/Views/TextFieldTests.cs

@@ -78,7 +78,7 @@ public class TextFieldTests (ITestOutputHelper output)
     public void Cancel_TextChanging_ThenBackspace ()
     {
         var tf = new TextField ();
-        tf.FocusFirstOrLast ();
+        tf.RestoreFocus ();
         tf.NewKeyDownEvent (Key.A.WithShift);
         Assert.Equal ("A", tf.Text);
 
@@ -929,7 +929,7 @@ public class TextFieldTests (ITestOutputHelper output)
     public void Backspace_From_End ()
     {
         var tf = new TextField { Text = "ABC" };
-        tf.FocusFirstOrLast ();
+        tf.RestoreFocus ();
         Assert.Equal ("ABC", tf.Text);
         tf.BeginInit ();
         tf.EndInit ();
@@ -956,7 +956,7 @@ public class TextFieldTests (ITestOutputHelper output)
     public void Backspace_From_Middle ()
     {
         var tf = new TextField { Text = "ABC" };
-        tf.FocusFirstOrLast ();
+        tf.RestoreFocus ();
         tf.CursorPosition = 2;
         Assert.Equal ("ABC", tf.Text);
 

+ 1 - 1
UnitTests/Views/TreeTableSourceTests.cs

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