Преглед изворни кода

Fixes WindowsDriver HeightAsBuffer set to false. (#1466)

BDisp пре 3 година
родитељ
комит
ef9fb593e5
2 измењених фајлова са 238 додато и 145 уклоњено
  1. 237 143
      Terminal.Gui/ConsoleDrivers/WindowsDriver.cs
  2. 1 2
      Terminal.Gui/Core/Application.cs

+ 237 - 143
Terminal.Gui/ConsoleDrivers/WindowsDriver.cs

@@ -43,7 +43,7 @@ namespace Terminal.Gui {
 
 		internal IntPtr InputHandle, OutputHandle;
 		IntPtr ScreenBuffer;
-		uint originalConsoleMode;
+		readonly uint originalConsoleMode;
 		CursorVisibility? initialCursorVisibility = null;
 		CursorVisibility? currentCursorVisibility = null;
 		CursorVisibility? pendingCursorVisibility = null;
@@ -62,10 +62,10 @@ namespace Terminal.Gui {
 
 		public CharInfo [] OriginalStdOutChars;
 
-		public bool WriteToConsole (CharInfo [] charInfoBuffer, Coord coords, SmallRect window)
+		public bool WriteToConsole (Size size, CharInfo [] charInfoBuffer, Coord coords, SmallRect window)
 		{
 			if (ScreenBuffer == IntPtr.Zero) {
-				ReadFromConsoleOutput (new Size (Console.WindowWidth, Console.WindowHeight), coords, ref window);
+				ReadFromConsoleOutput (size, coords, ref window);
 			}
 
 			return WriteConsoleOutput (ScreenBuffer, charInfoBuffer, coords, new Coord () { X = window.Left, Y = window.Top }, ref window);
@@ -92,13 +92,14 @@ namespace Terminal.Gui {
 			}
 
 			if (!SetConsoleActiveScreenBuffer (ScreenBuffer)) {
-				var err = Marshal.GetLastWin32Error ();
-				throw new System.ComponentModel.Win32Exception (err);
+				throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
 			}
 
 			OriginalStdOutChars = new CharInfo [size.Height * size.Width];
 
-			ReadConsoleOutput (OutputHandle, OriginalStdOutChars, coords, new Coord () { X = 0, Y = 0 }, ref window);
+			if (!ReadConsoleOutput (ScreenBuffer, OriginalStdOutChars, coords, new Coord () { X = 0, Y = 0 }, ref window)) {
+				throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
+			}
 		}
 
 		public bool SetCursorPosition (Coord position)
@@ -183,6 +184,8 @@ namespace Terminal.Gui {
 				SetCursorVisibility (initialCursorVisibility.Value);
 			}
 
+			SetConsoleOutputWindow (out _);
+
 			ConsoleMode = originalConsoleMode;
 			//ContinueListeningForConsoleEvents = false;
 			if (!SetConsoleActiveScreenBuffer (OutputHandle)) {
@@ -196,22 +199,103 @@ namespace Terminal.Gui {
 			ScreenBuffer = IntPtr.Zero;
 		}
 
+		internal Size GetConsoleBufferWindow (out Point position)
+		{
+			if (ScreenBuffer == IntPtr.Zero) {
+				position = Point.Empty;
+				return Size.Empty;
+			}
+
+			var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
+			csbi.cbSize = (uint)Marshal.SizeOf (csbi);
+			if (!GetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) {
+				throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
+			}
+			var sz = new Size (csbi.srWindow.Right - csbi.srWindow.Left + 1,
+				csbi.srWindow.Bottom - csbi.srWindow.Top + 1);
+			position = new Point (csbi.srWindow.Left, csbi.srWindow.Top);
+
+			return sz;
+		}
+
+		internal Size GetConsoleOutputWindow (out Point position)
+		{
+			var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
+			csbi.cbSize = (uint)Marshal.SizeOf (csbi);
+			if (!GetConsoleScreenBufferInfoEx (OutputHandle, ref csbi)) {
+				throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
+			}
+			var sz = new Size (csbi.srWindow.Right - csbi.srWindow.Left + 1,
+				csbi.srWindow.Bottom - csbi.srWindow.Top + 1);
+			position = new Point (csbi.srWindow.Left, csbi.srWindow.Top);
+
+			return sz;
+		}
+
+		internal Size SetConsoleWindow (short cols, short rows)
+		{
+			var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
+			csbi.cbSize = (uint)Marshal.SizeOf (csbi);
+			if (!GetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) {
+				throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
+			}
+			csbi.dwSize = new Coord (cols, Math.Max (rows, (short)1));
+			csbi.srWindow = new SmallRect (0, 0, cols, rows);
+			csbi.dwMaximumWindowSize = new Coord (cols, rows);
+			if (!SetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) {
+				throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
+			}
+			var winRect = new SmallRect (0, 0, (short)(cols - 1), (short)Math.Max (rows - 1, 0));
+			if (!SetConsoleWindowInfo (ScreenBuffer, true, ref winRect)) {
+				throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
+			}
+			SetConsoleOutputWindow (csbi);
+			return new Size (winRect.Right + 1, rows - 1 < 0 ? 0 : winRect.Bottom + 1);
+		}
+
+		void SetConsoleOutputWindow (CONSOLE_SCREEN_BUFFER_INFOEX csbi)
+		{
+			if (ScreenBuffer != IntPtr.Zero && !SetConsoleScreenBufferInfoEx (OutputHandle, ref csbi)) {
+				throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
+			}
+		}
+
+		internal Size SetConsoleOutputWindow (out Point position)
+		{
+			if (ScreenBuffer == IntPtr.Zero) {
+				position = Point.Empty;
+				return Size.Empty;
+			}
+
+			var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
+			csbi.cbSize = (uint)Marshal.SizeOf (csbi);
+			if (!GetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) {
+				throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
+			}
+			var sz = new Size (csbi.srWindow.Right - csbi.srWindow.Left + 1,
+				Math.Max (csbi.srWindow.Bottom - csbi.srWindow.Top + 1, 0));
+			position = new Point (csbi.srWindow.Left, csbi.srWindow.Top);
+			SetConsoleOutputWindow (csbi);
+			var winRect = new SmallRect (0, 0, (short)(sz.Width - 1), (short)Math.Max (sz.Height - 1, 0));
+			if (!SetConsoleWindowInfo (OutputHandle, true, ref winRect)) {
+				throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
+			}
+
+			return sz;
+		}
+
 		//bool ContinueListeningForConsoleEvents = true;
 
 		public uint ConsoleMode {
 			get {
-				uint v;
-				GetConsoleMode (InputHandle, out v);
+				GetConsoleMode (InputHandle, out uint v);
 				return v;
 			}
-
 			set {
 				SetConsoleMode (InputHandle, value);
 			}
 		}
 
-		public bool HeightAsBuffer { get; set; }
-
 		[Flags]
 		public enum ConsoleModes : uint {
 			EnableProcessedInput = 1,
@@ -269,7 +353,7 @@ namespace Terminal.Gui {
 		[StructLayout (LayoutKind.Explicit)]
 		public struct MouseEventRecord {
 			[FieldOffset (0)]
-			public Coordinate MousePosition;
+			public Coord MousePosition;
 			[FieldOffset (4)]
 			public ButtonState ButtonState;
 			[FieldOffset (8)]
@@ -283,26 +367,12 @@ namespace Terminal.Gui {
 			}
 		}
 
-		[StructLayout (LayoutKind.Sequential)]
-		public struct Coordinate {
-			public short X;
-			public short Y;
-
-			public Coordinate (short X, short Y)
-			{
-				this.X = X;
-				this.Y = Y;
-			}
-
-			public override string ToString () => $"({X},{Y})";
-		};
-
 		public struct WindowBufferSizeRecord {
-			public Coordinate size;
+			public Coord size;
 
 			public WindowBufferSizeRecord (short x, short y)
 			{
-				this.size = new Coordinate (x, y);
+				this.size = new Coord (x, y);
 			}
 
 			public override string ToString () => $"[WindowBufferSize{size}";
@@ -413,6 +483,14 @@ namespace Terminal.Gui {
 			public short Right;
 			public short Bottom;
 
+			public SmallRect (short left, short top, short right, short bottom)
+			{
+				Left = left;
+				Top = top;
+				Right = right;
+				Bottom = bottom;
+			}
+
 			public static void MakeEmpty (ref SmallRect rect)
 			{
 				rect.Left = -1;
@@ -517,13 +595,12 @@ namespace Terminal.Gui {
 			DesiredAccess dwDesiredAccess,
 			ShareMode dwShareMode,
 			IntPtr secutiryAttributes,
-			UInt32 flags,
+			uint flags,
 			IntPtr screenBufferData
 		);
 
 		internal static IntPtr INVALID_HANDLE_VALUE = new IntPtr (-1);
 
-
 		[DllImport ("kernel32.dll", SetLastError = true)]
 		static extern bool SetConsoleActiveScreenBuffer (IntPtr Handle);
 
@@ -531,8 +608,7 @@ namespace Terminal.Gui {
 		static extern bool GetNumberOfConsoleInputEvents (IntPtr handle, out uint lpcNumberOfEvents);
 		public uint InputEventCount {
 			get {
-				uint v;
-				GetNumberOfConsoleInputEvents (InputHandle, out v);
+				GetNumberOfConsoleInputEvents (InputHandle, out uint v);
 				return v;
 			}
 		}
@@ -573,68 +649,80 @@ namespace Terminal.Gui {
 			ShowWindow (thisConsole, state);
 		}
 #endif
-#if false // See: https://github.com/migueldeicaza/gui.cs/issues/357
+		// See: https://github.com/migueldeicaza/gui.cs/issues/357
+
 		[StructLayout (LayoutKind.Sequential)]
-		public struct SMALL_RECT {
-			public short Left;
-			public short Top;
-			public short Right;
-			public short Bottom;
+		public struct CONSOLE_SCREEN_BUFFER_INFOEX {
+			public uint cbSize;
+			public Coord dwSize;
+			public Coord dwCursorPosition;
+			public ushort wAttributes;
+			public SmallRect srWindow;
+			public Coord dwMaximumWindowSize;
+			public ushort wPopupAttributes;
+			public bool bFullscreenSupported;
+
+			[MarshalAs (UnmanagedType.ByValArray, SizeConst = 16)]
+			public COLORREF [] ColorTable;
+		}
 
-			public SMALL_RECT (short Left, short Top, short Right, short Bottom)
+		[StructLayout (LayoutKind.Explicit, Size = 4)]
+		public struct COLORREF {
+			public COLORREF (byte r, byte g, byte b)
 			{
-				this.Left = Left;
-				this.Top = Top;
-				this.Right = Right;
-				this.Bottom = Bottom;
+				Value = 0;
+				R = r;
+				G = g;
+				B = b;
 			}
-		}
 
-		[StructLayout (LayoutKind.Sequential)]
-		public struct CONSOLE_SCREEN_BUFFER_INFO {
-			public int dwSize;
-			public int dwCursorPosition;
-			public short wAttributes;
-			public SMALL_RECT srWindow;
-			public int dwMaximumWindowSize;
+			public COLORREF (uint value)
+			{
+				R = 0;
+				G = 0;
+				B = 0;
+				Value = value & 0x00FFFFFF;
+			}
+
+			[FieldOffset (0)]
+			public byte R;
+			[FieldOffset (1)]
+			public byte G;
+			[FieldOffset (2)]
+			public byte B;
+
+			[FieldOffset (0)]
+			public uint Value;
 		}
 
 		[DllImport ("kernel32.dll", SetLastError = true)]
-		static extern bool GetConsoleScreenBufferInfo (IntPtr hConsoleOutput, out CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo);
+		static extern bool GetConsoleScreenBufferInfoEx (IntPtr hConsoleOutput, ref CONSOLE_SCREEN_BUFFER_INFOEX csbi);
 
-		// Theoretically GetConsoleScreenBuffer height should give the console Windoww size
-		// It does not work, however, and always returns the size the window was initially created at
-		internal Size GetWindowSize ()
-		{
-			var consoleScreenBufferInfo = new CONSOLE_SCREEN_BUFFER_INFO ();
-			//consoleScreenBufferInfo.dwSize = Marshal.SizeOf (typeof (CONSOLE_SCREEN_BUFFER_INFO));
-			GetConsoleScreenBufferInfo (OutputHandle, out consoleScreenBufferInfo);
-			return new Size (consoleScreenBufferInfo.srWindow.Right - consoleScreenBufferInfo.srWindow.Left,
-				consoleScreenBufferInfo.srWindow.Bottom - consoleScreenBufferInfo.srWindow.Top);
-		}
-#endif
+		[DllImport ("kernel32.dll", SetLastError = true)]
+		static extern bool SetConsoleScreenBufferInfoEx (IntPtr hConsoleOutput, ref CONSOLE_SCREEN_BUFFER_INFOEX ConsoleScreenBufferInfo);
+
+		[DllImport ("kernel32.dll", SetLastError = true)]
+		static extern bool SetConsoleWindowInfo (
+			IntPtr hConsoleOutput,
+			bool bAbsolute,
+			[In] ref SmallRect lpConsoleWindow);
 	}
 
 	internal class WindowsDriver : ConsoleDriver {
 		static bool sync = false;
 		WindowsConsole.CharInfo [] OutputBuffer;
-		int cols, rows, top;
-		WindowsConsole winConsole;
+		int cols, rows, left, top;
 		WindowsConsole.SmallRect damageRegion;
 		IClipboard clipboard;
 
 		public override int Cols => cols;
 		public override int Rows => rows;
-		public override int Left => 0;
+		public override int Left => left;
 		public override int Top => top;
 		public override bool HeightAsBuffer { get; set; }
-
 		public override IClipboard Clipboard => clipboard;
 
-		public WindowsConsole WinConsole {
-			get => winConsole;
-			private set => winConsole = value;
-		}
+		public WindowsConsole WinConsole { get; private set; }
 
 		Action<KeyEvent> keyHandler;
 		Action<KeyEvent> keyDownHandler;
@@ -643,7 +731,7 @@ namespace Terminal.Gui {
 
 		public WindowsDriver ()
 		{
-			winConsole = new WindowsConsole ();
+			WinConsole = new WindowsConsole ();
 			clipboard = new WindowsClipboard ();
 		}
 
@@ -669,16 +757,18 @@ namespace Terminal.Gui {
 		{
 			winChanging = true;
 			if (!HeightAsBuffer) {
+				var w = e.Width;
+				if (w == cols - 3 && e.Height < rows) {
+					w += 3;
+				}
+				var newSize = WinConsole.SetConsoleWindow (
+					(short)Math.Max (w, 16), (short)e.Height);
+				left = 0;
 				top = 0;
-				cols = e.Width;
-				rows = e.Height;
+				cols = newSize.Width;
+				rows = newSize.Height;
 				ResizeScreen ();
 				UpdateOffScreen ();
-				var bufferCoords = new WindowsConsole.Coord () {
-					X = (short)Clip.Width,
-					Y = (short)Clip.Height
-				};
-				winConsole.ReadFromConsoleOutput (e, bufferCoords, ref damageRegion);
 				if (!winChanging) {
 					TerminalResized.Invoke ();
 				}
@@ -783,11 +873,17 @@ namespace Terminal.Gui {
 				break;
 
 			case WindowsConsole.EventType.WindowBufferSize:
-				cols = inputEvent.WindowBufferSizeEvent.size.X;
-				rows = inputEvent.WindowBufferSizeEvent.size.Y;
-				ResizeScreen ();
-				UpdateOffScreen ();
-				TerminalResized?.Invoke ();
+				if (HeightAsBuffer) {
+					var winSize = WinConsole.GetConsoleBufferWindow (out Point pos);
+					left = pos.X;
+					top = pos.Y;
+					cols = inputEvent.WindowBufferSizeEvent.size.X;
+					rows = inputEvent.WindowBufferSizeEvent.size.Y;
+					//System.Diagnostics.Debug.WriteLine ($"{HeightAsBuffer},{cols},{rows}");
+					ResizeScreen ();
+					UpdateOffScreen ();
+					TerminalResized?.Invoke ();
+				}
 				break;
 
 			case WindowsConsole.EventType.Focus:
@@ -1276,11 +1372,10 @@ namespace Terminal.Gui {
 		{
 			TerminalResized = terminalResized;
 
-			cols = Console.WindowWidth;
-			rows = Console.WindowHeight;
-#if false
-			winConsole.ShowWindow (WindowsConsole.RESTORE);
-#endif
+			var winSize = WinConsole.GetConsoleOutputWindow (out Point pos);
+			cols = winSize.Width;
+			rows = winSize.Height;
+
 			WindowsConsole.SmallRect.MakeEmpty (ref damageRegion);
 
 			ResizeScreen ();
@@ -1333,7 +1428,7 @@ namespace Terminal.Gui {
 				Bottom = (short)Rows,
 				Right = (short)Cols
 			};
-			winConsole.ForceRefreshCursorVisibility ();
+			WinConsole.ForceRefreshCursorVisibility ();
 		}
 
 		void UpdateOffScreen ()
@@ -1415,7 +1510,7 @@ namespace Terminal.Gui {
 		{
 			UpdateScreen ();
 
-			winConsole.SetInitialCursorVisibility ();
+			WinConsole.SetInitialCursorVisibility ();
 #if false
 			var bufferCoords = new WindowsConsole.Coord (){
 				X = (short)Clip.Width,
@@ -1430,7 +1525,7 @@ namespace Terminal.Gui {
 			};
 
 			UpdateCursor();
-			winConsole.WriteToConsole (OutputBuffer, bufferCoords, window);
+			WinConsole.WriteToConsole (OutputBuffer, bufferCoords, window);
 #endif
 		}
 
@@ -1452,8 +1547,8 @@ namespace Terminal.Gui {
 			//};
 
 			UpdateCursor ();
-			winConsole.WriteToConsole (OutputBuffer, bufferCoords, damageRegion);
-			//			System.Diagnostics.Debugger.Log(0, "debug", $"Region={damageRegion.Right - damageRegion.Left},{damageRegion.Bottom - damageRegion.Top}\n");
+			WinConsole.WriteToConsole (new Size (Cols, Rows), OutputBuffer, bufferCoords, damageRegion);
+			// System.Diagnostics.Debugger.Log (0, "debug", $"Region={damageRegion.Right - damageRegion.Left},{damageRegion.Bottom - damageRegion.Top}\n");
 			WindowsConsole.SmallRect.MakeEmpty (ref damageRegion);
 		}
 
@@ -1463,12 +1558,13 @@ namespace Terminal.Gui {
 				X = (short)ccol,
 				Y = (short)crow
 			};
-			winConsole.SetCursorPosition (position);
+			WinConsole.SetCursorPosition (position);
 		}
 
 		public override void End ()
 		{
-			winConsole.Cleanup ();
+			WinConsole.Cleanup ();
+			WinConsole = null;
 		}
 
 		public override Attribute GetAttribute ()
@@ -1479,28 +1575,30 @@ namespace Terminal.Gui {
 		/// <inheritdoc/>
 		public override bool GetCursorVisibility (out CursorVisibility visibility)
 		{
-			return winConsole.GetCursorVisibility (out visibility);
+			return WinConsole.GetCursorVisibility (out visibility);
 		}
 
 		/// <inheritdoc/>
 		public override bool SetCursorVisibility (CursorVisibility visibility)
 		{
-			return winConsole.SetCursorVisibility (visibility);
+			return WinConsole.SetCursorVisibility (visibility);
 		}
 
 		/// <inheritdoc/>
 		public override bool EnsureCursorVisibility ()
 		{
-			return winConsole.EnsureCursorVisibility ();
+			return WinConsole.EnsureCursorVisibility ();
 		}
 
 		public override void SendKeys (char keyChar, ConsoleKey key, bool shift, bool alt, bool control)
 		{
-			WindowsConsole.InputRecord input = new WindowsConsole.InputRecord ();
-			input.EventType = WindowsConsole.EventType.Key;
+			WindowsConsole.InputRecord input = new WindowsConsole.InputRecord {
+				EventType = WindowsConsole.EventType.Key
+			};
 
-			WindowsConsole.KeyEventRecord keyEvent = new WindowsConsole.KeyEventRecord ();
-			keyEvent.bKeyDown = true;
+			WindowsConsole.KeyEventRecord keyEvent = new WindowsConsole.KeyEventRecord {
+				bKeyDown = true
+			};
 			WindowsConsole.ControlKeyState controlKey = new WindowsConsole.ControlKeyState ();
 			if (shift) {
 				controlKey |= WindowsConsole.ControlKeyState.ShiftPressed;
@@ -1607,12 +1705,12 @@ namespace Terminal.Gui {
 	internal class WindowsMainLoop : IMainLoopDriver {
 		ManualResetEventSlim eventReady = new ManualResetEventSlim (false);
 		ManualResetEventSlim waitForProbe = new ManualResetEventSlim (false);
-		//ManualResetEventSlim winChange = new ManualResetEventSlim (false);
+		ManualResetEventSlim winChange = new ManualResetEventSlim (false);
 		MainLoop mainLoop;
 		ConsoleDriver consoleDriver;
 		WindowsConsole winConsole;
-		//bool winChanged;
-		//Size windowSize;
+		bool winChanged;
+		Size windowSize;
 		CancellationTokenSource tokenSource = new CancellationTokenSource ();
 
 		// The records that we keep fetching
@@ -1630,10 +1728,7 @@ namespace Terminal.Gui {
 
 		public WindowsMainLoop (ConsoleDriver consoleDriver = null)
 		{
-			if (consoleDriver == null) {
-				throw new ArgumentNullException ("Console driver instance must be provided.");
-			}
-			this.consoleDriver = consoleDriver;
+			this.consoleDriver = consoleDriver ?? throw new ArgumentNullException ("Console driver instance must be provided.");
 			winConsole = ((WindowsDriver)consoleDriver).WinConsole;
 		}
 
@@ -1641,8 +1736,7 @@ namespace Terminal.Gui {
 		{
 			this.mainLoop = mainLoop;
 			Task.Run (WindowsInputHandler);
-			// Not working yet.
-			//Task.Run (CheckWinChange);
+			Task.Run (CheckWinChange);
 		}
 
 		void WindowsInputHandler ()
@@ -1657,29 +1751,31 @@ namespace Terminal.Gui {
 			}
 		}
 
-		//void CheckWinChange ()
-		//{
-		//	while (true) {
-		//		winChange.Wait ();
-		//		winChange.Reset ();
-		//		WaitWinChange ();
-		//		winChanged = true;
-		//		eventReady.Set ();
-		//	}
-		//}
-
-		//void WaitWinChange ()
-		//{
-		//	while (true) {
-		//		if (!consoleDriver.HeightAsBuffer) {
-		//			windowSize = new Size (Console.WindowWidth, Console.WindowHeight);
-		//			if (windowSize.Height < consoleDriver.Rows) {
-		//				// I still haven't been able to find a way to capture the shrinking in height.
-		//				//return;
-		//			}
-		//		}
-		//	}
-		//}
+		void CheckWinChange ()
+		{
+			while (true) {
+				winChange.Wait ();
+				winChange.Reset ();
+				WaitWinChange ();
+				winChanged = true;
+				eventReady.Set ();
+			}
+		}
+
+		void WaitWinChange ()
+		{
+			while (true) {
+				Thread.Sleep (100);
+				if (!consoleDriver.HeightAsBuffer) {
+					windowSize = winConsole.GetConsoleBufferWindow (out _);
+					//System.Diagnostics.Debug.WriteLine ($"{consoleDriver.HeightAsBuffer},{windowSize.Width},{windowSize.Height}");
+					if (windowSize != Size.Empty && windowSize.Width != consoleDriver.Cols
+						|| windowSize.Height != consoleDriver.Rows) {
+						return;
+					}
+				}
+			}
+		}
 
 		void IMainLoopDriver.Wakeup ()
 		{
@@ -1695,8 +1791,7 @@ namespace Terminal.Gui {
 
 			result = null;
 			waitForProbe.Set ();
-			// Nor working yet.
-			//winChange.Set ();
+			winChange.Set ();
 
 			try {
 				if (!tokenSource.IsCancellationRequested) {
@@ -1709,8 +1804,7 @@ namespace Terminal.Gui {
 			}
 
 			if (!tokenSource.IsCancellationRequested) {
-				//return result != null || CheckTimers (wait, out _) || winChanged;
-				return result != null || CheckTimers (wait, out _);
+				return result != null || CheckTimers (wait, out _) || winChanged;
 			}
 
 			tokenSource.Dispose ();
@@ -1748,10 +1842,10 @@ namespace Terminal.Gui {
 				result = null;
 				ProcessInput?.Invoke (inputEvent);
 			}
-			//if (winChanged) {
-			//	winChanged = false;
-			//	WinChanged?.Invoke (windowSize);
-			//}
+			if (winChanged) {
+				winChanged = false;
+				WinChanged?.Invoke (windowSize);
+			}
 		}
 	}
 

+ 1 - 2
Terminal.Gui/Core/Application.cs

@@ -118,11 +118,9 @@ namespace Terminal.Gui {
 				if (Driver == null) {
 					throw new ArgumentNullException ("The driver must be initialized first.");
 				}
-				if (Driver.HeightAsBuffer != value) {
 					Driver.HeightAsBuffer = value;
 				}
 			}
-		}
 
 		/// <summary>
 		/// Used only by <see cref="NetDriver"/> to forcing always moving the cursor position when writing to the screen.
@@ -545,6 +543,7 @@ namespace Terminal.Gui {
 				if (OutsideFrame (new Point (nme.X, nme.Y), mouseGrabView.Frame)) {
 					lastMouseOwnerView?.OnMouseLeave (me);
 				}
+				// System.Diagnostics.Debug.WriteLine ($"{nme.Flags};{nme.X};{nme.Y};{mouseGrabView}");
 				if (mouseGrabView != null) {
 					mouseGrabView.OnMouseEvent (nme);
 					return;