Browse Source

Merge pull request #2237 from tznind/null-ref-fix-set-focus

Fixes #2236 Avoid Null reference when OnLeave event handlers clears focus
Tig 2 years ago
parent
commit
def1a190aa
2 changed files with 36 additions and 2 deletions
  1. 3 2
      Terminal.Gui/Core/View.cs
  2. 33 0
      UnitTests/ViewTests.cs

+ 3 - 2
Terminal.Gui/Core/View.cs

@@ -1321,8 +1321,9 @@ namespace Terminal.Gui {
 
 			// Remove focus down the chain of subviews if focus is removed
 			if (!value && focused != null) {
-				focused.OnLeave (view);
-				focused.SetHasFocus (false, view);
+				var f = focused;
+				f.OnLeave (view);
+				f.SetHasFocus (false, view);
 				focused = null;
 			}
 		}

+ 33 - 0
UnitTests/ViewTests.cs

@@ -4062,5 +4062,38 @@ This is a tes
 			Assert.False (view.IsKeyPress);
 			Assert.True (view.IsKeyUp);
 		}
+
+		[Fact, AutoInitShutdown]
+		public void SetHasFocus_Do_Not_Throws_If_OnLeave_Remove_Focused_Changing_To_Null ()
+		{
+			var view1Leave = false;
+			var subView1Leave = false;
+			var subView1subView1Leave = false;
+			var top = Application.Top;
+			var view1 = new View { CanFocus = true };
+			var subView1 = new View { CanFocus = true };
+			var subView1subView1 = new View { CanFocus = true };
+			view1.Leave += (e) => {
+				view1Leave = true;
+			};
+			subView1.Leave += (e) => {
+				subView1.Remove (subView1subView1);
+				subView1Leave = true;
+			};
+			view1.Add (subView1);
+			subView1subView1.Leave += (e) => {
+				// This is never invoked
+				subView1subView1Leave = true;
+			};
+			subView1.Add (subView1subView1);
+			var view2 = new View { CanFocus = true };
+			top.Add (view1, view2);
+			Application.Begin (top);
+
+			view2.SetFocus ();
+			Assert.True (view1Leave);
+			Assert.True (subView1Leave);
+			Assert.False (subView1subView1Leave);
+		}
 	}
 }