Browse Source

Fixes #2326. Invisible cursor after modal dialog.

BDisp 2 years ago
parent
commit
057bbcaea8

+ 4 - 0
Terminal.Gui/ConsoleDrivers/WindowsDriver.cs

@@ -116,6 +116,10 @@ namespace Terminal.Gui {
 
 
 		public bool GetCursorVisibility (out CursorVisibility visibility)
 		public bool GetCursorVisibility (out CursorVisibility visibility)
 		{
 		{
+			if (ScreenBuffer == IntPtr.Zero) {
+				visibility = CursorVisibility.Invisible;
+				return false;
+			}
 			if (!GetConsoleCursorInfo (ScreenBuffer, out ConsoleCursorInfo info)) {
 			if (!GetConsoleCursorInfo (ScreenBuffer, out ConsoleCursorInfo info)) {
 				var err = Marshal.GetLastWin32Error ();
 				var err = Marshal.GetLastWin32Error ();
 				if (err != 0) {
 				if (err != 0) {

+ 3 - 0
Terminal.Gui/Core/Application.cs

@@ -933,6 +933,8 @@ namespace Terminal.Gui {
 				if (Top != null && toplevel != Top && !toplevels.Contains (Top)) {
 				if (Top != null && toplevel != Top && !toplevels.Contains (Top)) {
 					Top.Dispose ();
 					Top.Dispose ();
 					Top = null;
 					Top = null;
+				} else if (Top != null && toplevel != Top && toplevels.Contains (Top)) {
+					Top.OnLeave (toplevel);
 				}
 				}
 				if (string.IsNullOrEmpty (toplevel.Id.ToString ())) {
 				if (string.IsNullOrEmpty (toplevel.Id.ToString ())) {
 					var count = 1;
 					var count = 1;
@@ -1043,6 +1045,7 @@ namespace Terminal.Gui {
 					MdiTop.OnAllChildClosed ();
 					MdiTop.OnAllChildClosed ();
 				} else {
 				} else {
 					SetCurrentAsTop ();
 					SetCurrentAsTop ();
+					Current.OnEnter (Current);
 				}
 				}
 				Refresh ();
 				Refresh ();
 			}
 			}

+ 12 - 0
Terminal.Gui/Core/Toplevel.cs

@@ -960,6 +960,18 @@ namespace Terminal.Gui {
 			}
 			}
 			return false;
 			return false;
 		}
 		}
+
+		///<inheritdoc/>
+		public override bool OnEnter (View view)
+		{
+			return MostFocused?.OnEnter (view) ?? base.OnEnter (view);
+		}
+
+		///<inheritdoc/>
+		public override bool OnLeave (View view)
+		{
+			return MostFocused?.OnLeave (view) ?? base.OnLeave (view);
+		}
 	}
 	}
 
 
 	/// <summary>
 	/// <summary>

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

@@ -2035,6 +2035,16 @@ namespace Terminal.Gui {
 			return base.OnEnter (view);
 			return base.OnEnter (view);
 		}
 		}
 
 
+		///<inheritdoc/>
+		public override bool OnLeave (View view)
+		{
+			if (Application.MouseGrabView != null && Application.MouseGrabView == this) {
+				Application.UngrabMouse ();
+			}
+
+			return base.OnLeave (view);
+		}
+
 		// Returns an encoded region start..end (top 32 bits are the row, low32 the column)
 		// Returns an encoded region start..end (top 32 bits are the row, low32 the column)
 		void GetEncodedRegionBounds (out long start, out long end,
 		void GetEncodedRegionBounds (out long start, out long end,
 			int? startRow = null, int? startCol = null, int? cRow = null, int? cCol = null)
 			int? startRow = null, int? startCol = null, int? cRow = null, int? cCol = null)
@@ -4447,16 +4457,6 @@ namespace Terminal.Gui {
 			line = r;
 			line = r;
 		}
 		}
 
 
-		///<inheritdoc/>
-		public override bool OnLeave (View view)
-		{
-			if (Application.MouseGrabView != null && Application.MouseGrabView == this) {
-				Application.UngrabMouse ();
-			}
-
-			return base.OnLeave (view);
-		}
-
 		/// <summary>
 		/// <summary>
 		/// Allows clearing the <see cref="HistoryText.HistoryTextItem"/> items updating the original text.
 		/// Allows clearing the <see cref="HistoryText.HistoryTextItem"/> items updating the original text.
 		/// </summary>
 		/// </summary>

+ 42 - 5
UnitTests/TopLevels/ToplevelTests.cs

@@ -696,7 +696,7 @@ namespace Terminal.Gui.TopLevelTests {
 					((FakeDriver)Application.Driver).SetBufferSize (40, 15);
 					((FakeDriver)Application.Driver).SetBufferSize (40, 15);
 					MessageBox.Query ("About", "Hello Word", "Ok");
 					MessageBox.Query ("About", "Hello Word", "Ok");
 
 
-				} else if (iterations == 1) 					TestHelpers.AssertDriverContentsWithFrameAre (@"
+				} else if (iterations == 1) TestHelpers.AssertDriverContentsWithFrameAre (@"
  File                                   
  File                                   
 ┌ Window ──────────────────────────────┐
 ┌ Window ──────────────────────────────┐
 │                                      │
 │                                      │
@@ -712,7 +712,7 @@ namespace Terminal.Gui.TopLevelTests {
 │                                      │
 │                                      │
 └──────────────────────────────────────┘
 └──────────────────────────────────────┘
  CTRL-N New                             ", output);
  CTRL-N New                             ", output);
-else if (iterations == 2) {
+				else if (iterations == 2) {
 					Assert.Null (Application.MouseGrabView);
 					Assert.Null (Application.MouseGrabView);
 					// Grab the mouse
 					// Grab the mouse
 					ReflectionTools.InvokePrivate (
 					ReflectionTools.InvokePrivate (
@@ -815,8 +815,8 @@ else if (iterations == 2) {
 
 
 					Assert.Null (Application.MouseGrabView);
 					Assert.Null (Application.MouseGrabView);
 
 
-				} else if (iterations == 8) 					Application.RequestStop ();
-else if (iterations == 9) 					Application.RequestStop ();
+				} else if (iterations == 8) Application.RequestStop ();
+				else if (iterations == 9) Application.RequestStop ();
 			};
 			};
 
 
 			Application.Run ();
 			Application.Run ();
@@ -956,7 +956,7 @@ else if (iterations == 9) 					Application.RequestStop ();
 
 
 					Assert.Null (Application.MouseGrabView);
 					Assert.Null (Application.MouseGrabView);
 
 
-				} else if (iterations == 8) 					Application.RequestStop ();
+				} else if (iterations == 8) Application.RequestStop ();
 			};
 			};
 
 
 			Application.Run ();
 			Application.Run ();
@@ -974,5 +974,42 @@ else if (iterations == 9) 					Application.RequestStop ();
 			exception = Record.Exception (() => ((FakeDriver)Application.Driver).SetBufferSize (10, 0));
 			exception = Record.Exception (() => ((FakeDriver)Application.Driver).SetBufferSize (10, 0));
 			Assert.Null (exception);
 			Assert.Null (exception);
 		}
 		}
+
+		[Fact, AutoInitShutdown]
+		public void OnEnter_OnLeave_Triggered_On_Application_Begin_End ()
+		{
+			var isEnter = false;
+			var isLeave = false;
+			var v = new View ();
+			v.Enter += (_) => isEnter = true;
+			v.Leave += (_) => isLeave = true;
+			var top = Application.Top;
+			top.Add (v);
+
+			Assert.False (v.CanFocus);
+			var exception = Record.Exception (() => top.OnEnter (top));
+			Assert.Null (exception);
+			exception = Record.Exception (() => top.OnLeave (top));
+			Assert.Null (exception);
+
+			v.CanFocus = true;
+			Application.Begin (top);
+
+			Assert.True (isEnter);
+			Assert.False (isLeave);
+
+			isEnter = false;
+			var d = new Dialog ();
+			var rs = Application.Begin (d);
+
+			Assert.False (isEnter);
+			Assert.True (isLeave);
+
+			isLeave = false;
+			Application.End (rs);
+
+			Assert.True (isEnter);
+			Assert.False (isLeave);
+		}
 	}
 	}
 }
 }