Sfoglia il codice sorgente

Fixes the CanFocus equal to false from setting HasFocus to true again. (#1612)

* Fixes the CanFocus equal to false from setting HasFocus to true again.

* Unit test also proving setting a toplevel CanFocus to false focus the next toplevel.

* Unit test proving that a view with CanFocus equal to true can be focused on the same toplevel.
BDisp 3 anni fa
parent
commit
56c28f6d37
2 ha cambiato i file con 107 aggiunte e 12 eliminazioni
  1. 9 12
      Terminal.Gui/Core/View.cs
  2. 98 0
      UnitTests/ViewTests.cs

+ 9 - 12
Terminal.Gui/Core/View.cs

@@ -356,18 +356,16 @@ namespace Terminal.Gui {
 					}
 					TabStop = value;
 
-					if (!value && Application.Top?.Focused == this) {
-						Application.Top.focused = null;
+					if (!value && SuperView?.Focused == this) {
+						SuperView.focused = null;
 					}
 					if (!value && HasFocus) {
 						SetHasFocus (false, this);
-						EnsureFocus ();
-						if (Focused == null) {
-							if (Application.Top.Focused == null) {
-								Application.Top.FocusNext ();
-							} else {
-								var v = Application.Top.GetMostFocused (Application.Top.Focused);
-								v.SetHasFocus (true, null, true);
+						SuperView?.EnsureFocus ();
+						if (SuperView != null && SuperView?.Focused == null) {
+							SuperView.FocusNext ();
+							if (SuperView.Focused == null) {
+								Application.Current.FocusNext ();
 							}
 							Application.EnsuresTopOnFront ();
 						}
@@ -1688,11 +1686,10 @@ namespace Terminal.Gui {
 		/// <param name="command"></param>
 		public void ClearKeybinding (Command command)
 		{
-			foreach(var kvp in KeyBindings.Where(kvp=>kvp.Value == command).ToArray())
-			{
+			foreach (var kvp in KeyBindings.Where (kvp => kvp.Value == command).ToArray ()) {
 				KeyBindings.Remove (kvp.Key);
 			}
-			
+
 		}
 
 		/// <summary>

+ 98 - 0
UnitTests/ViewTests.cs

@@ -1629,5 +1629,103 @@ namespace Terminal.Gui.Views {
 				return text;
 			}
 		}
+
+		[Fact]
+		[AutoInitShutdown]
+		public void CanFocus_Sets_To_False_Does_Not_Sets_HasFocus_To_True ()
+		{
+			var view = new View () { CanFocus = true };
+			var win = new Window () { Width = Dim.Fill (), Height = Dim.Fill () };
+			win.Add (view);
+			Application.Top.Add (win);
+			Application.Begin (Application.Top);
+
+			Assert.True (view.CanFocus);
+			Assert.True (view.HasFocus);
+
+			view.CanFocus = false;
+			Assert.False (view.CanFocus);
+			Assert.False (view.HasFocus);
+			Assert.Null (Application.Current.Focused);
+			Assert.Null (Application.Current.MostFocused);
+		}
+
+		[Fact]
+		[AutoInitShutdown]
+		public void CanFocus_Sets_To_False_On_Single_View_Focus_View_On_Another_Toplevel ()
+		{
+			var view1 = new View () { Width = 10, Height = 1, CanFocus = true };
+			var win1 = new Window () { Width = Dim.Percent (50), Height = Dim.Fill () };
+			win1.Add (view1);
+			var view2 = new View () { Width = 20, Height = 2, CanFocus = true };
+			var win2 = new Window () { X = Pos.Right (win1),  Width = Dim.Fill (), Height = Dim.Fill () };
+			win2.Add (view2);
+			Application.Top.Add (win1, win2);
+			Application.Begin (Application.Top);
+
+			Assert.True (view1.CanFocus);
+			Assert.True (view1.HasFocus);
+			Assert.True (view2.CanFocus);
+			Assert.True (view2.HasFocus);
+
+			view1.CanFocus = false;
+			Assert.False (view1.CanFocus);
+			Assert.False (view1.HasFocus);
+			Assert.Equal (win2, Application.Current.Focused);
+			Assert.Equal (view2, Application.Current.MostFocused);
+		}
+
+		[Fact]
+		[AutoInitShutdown]
+		public void CanFocus_Sets_To_False_With_Two_Views_Focus_Another_View_On_The_Same_Toplevel ()
+		{
+			var view1 = new View () { Width = 10, Height = 1, CanFocus = true };
+			var view12 = new View () { Y = 5, Width = 10, Height = 1, CanFocus = true };
+			var win1 = new Window () { Width = Dim.Percent (50), Height = Dim.Fill () };
+			win1.Add (view1, view12);
+			var view2 = new View () { Width = 20, Height = 2, CanFocus = true };
+			var win2 = new Window () { X = Pos.Right (win1), Width = Dim.Fill (), Height = Dim.Fill () };
+			win2.Add (view2);
+			Application.Top.Add (win1, win2);
+			Application.Begin (Application.Top);
+
+			Assert.True (view1.CanFocus);
+			Assert.True (view1.HasFocus);
+			Assert.True (view2.CanFocus);
+			Assert.True (view2.HasFocus);
+
+			view1.CanFocus = false;
+			Assert.False (view1.CanFocus);
+			Assert.False (view1.HasFocus);
+			Assert.Equal (win1, Application.Current.Focused);
+			Assert.Equal (view12, Application.Current.MostFocused);
+		}
+
+		[Fact]
+		[AutoInitShutdown]
+		public void CanFocus_Sets_To_False_On_Toplevel_Focus_View_On_Another_Toplevel ()
+		{
+			var view1 = new View () { Width = 10, Height = 1, CanFocus = true };
+			var win1 = new Window () { Width = Dim.Percent (50), Height = Dim.Fill () };
+			win1.Add (view1);
+			var view2 = new View () { Width = 20, Height = 2, CanFocus = true };
+			var win2 = new Window () { X = Pos.Right (win1), Width = Dim.Fill (), Height = Dim.Fill () };
+			win2.Add (view2);
+			Application.Top.Add (win1, win2);
+			Application.Begin (Application.Top);
+
+			Assert.True (view1.CanFocus);
+			Assert.True (view1.HasFocus);
+			Assert.True (view2.CanFocus);
+			Assert.True (view2.HasFocus);
+
+			win1.CanFocus = false;
+			Assert.False (view1.CanFocus);
+			Assert.False (view1.HasFocus);
+			Assert.False (win1.CanFocus);
+			Assert.False (win1.HasFocus);
+			Assert.Equal (win2, Application.Current.Focused);
+			Assert.Equal (view2, Application.Current.MostFocused);
+		}
 	}
 }