Sfoglia il codice sorgente

Merge pull request #1066 from BDisp/heightasbuffer-as-true

A provisional solution to the #1065 issue. Setting HeightAsBuffer as true by default.
Charlie Kindel 4 anni fa
parent
commit
ca333ceb70

+ 97 - 258
Terminal.Gui/ConsoleDrivers/WindowsDriver.cs

@@ -62,13 +62,13 @@ namespace Terminal.Gui {
 		public bool WriteToConsole (CharInfo [] charInfoBuffer, Coord coords, SmallRect window)
 		{
 			if (ScreenBuffer == IntPtr.Zero) {
-				window = ReadFromConsoleOutput (new Size (Console.WindowWidth, Console.WindowHeight), coords, window);
+				ReadFromConsoleOutput (new Size (Console.WindowWidth, Console.WindowHeight), coords, ref window);
 			}
 
 			return WriteConsoleOutput (ScreenBuffer, charInfoBuffer, coords, new Coord () { X = window.Left, Y = window.Top }, ref window);
 		}
 
-		public SmallRect ReadFromConsoleOutput (Size size, Coord coords, SmallRect window)
+		public void ReadFromConsoleOutput (Size size, Coord coords, ref SmallRect window)
 		{
 			ScreenBuffer = CreateConsoleScreenBuffer (
 				DesiredAccess.GenericRead | DesiredAccess.GenericWrite,
@@ -80,9 +80,8 @@ namespace Terminal.Gui {
 			if (ScreenBuffer == INVALID_HANDLE_VALUE) {
 				var err = Marshal.GetLastWin32Error ();
 
-				if (err != 0 && HeightAsBuffer) {
+				if (err != 0)
 					throw new System.ComponentModel.Win32Exception (err);
-				}
 			}
 
 			if (!initialCursorVisibility.HasValue && GetCursorVisibility (out CursorVisibility visibility)) {
@@ -91,15 +90,12 @@ namespace Terminal.Gui {
 
 			if (!SetConsoleActiveScreenBuffer (ScreenBuffer)) {
 				var err = Marshal.GetLastWin32Error ();
-				if (HeightAsBuffer) {
-					throw new System.ComponentModel.Win32Exception (err);
-				}
+				throw new System.ComponentModel.Win32Exception (err);
 			}
 
 			OriginalStdOutChars = new CharInfo [size.Height * size.Width];
-			ReadConsoleOutput (OutputHandle, OriginalStdOutChars, coords, new Coord () { X = 0, Y = 0 }, ref window);
 
-			return window;
+			ReadConsoleOutput (OutputHandle, OriginalStdOutChars, coords, new Coord () { X = 0, Y = 0 }, ref window);
 		}
 
 		public bool SetCursorPosition (Coord position)
@@ -558,120 +554,62 @@ namespace Terminal.Gui {
 			}
 		}
 
-		// Not needed on the constructor. Perhaps could be used on resizing. To study.
+#if false      // Not needed on the constructor. Perhaps could be used on resizing. To study.
 		[DllImport ("kernel32.dll", ExactSpelling = true)]
 		static extern IntPtr GetConsoleWindow ();
 
-		internal IntPtr GetConsole ()
-		{
-			return GetConsoleWindow ();
-		}
-
-		[DllImport ("user32.dll")]
-		[return: MarshalAs (UnmanagedType.Bool)]
-		static extern bool GetWindowPlacement (IntPtr hWnd, ref WindowPlacement lpwndpl);
-
-		[DllImport ("user32.dll", SetLastError = true)]
-		[return: MarshalAs (UnmanagedType.Bool)]
-		static extern bool SetWindowPlacement (IntPtr hWnd, [In] ref WindowPlacement lpwndpl);
-
-		internal struct WindowPlacement {
-			public int length;
-			public int flags;
-			public int showCmd;
-			public System.Drawing.Point ptMinPosition;
-			public System.Drawing.Point ptMaxPosition;
-			public System.Drawing.Rectangle rcNormalPosition;
-#if _MAC
-			public System.Drawing.Rectangle rcDevice;
-#endif
-		}
+		[DllImport ("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+		static extern bool ShowWindow (IntPtr hWnd, int nCmdShow);
 
-		// flags
-		public const int WPF_SET_MIN_POSITION = 1;
-		public const int WPF_RESTORE_TO_MAXIMIZED = 2;
-		public const int WPF_ASYNC_WINDOWPLACEMENT = 4;
-
-		// showCmd
 		public const int HIDE = 0;
-		public const int SHOW_NORMAL = 1;
-		public const int SHOW_MINIMIZED = 2;
-		public const int SHOW_MAXIMIZED = 3;
-		public const int SHOW_NOACTIVATE = 4;
-		public const int SHOW = 5;
+		public const int MAXIMIZE = 3;
 		public const int MINIMIZE = 6;
-		public const int SHOW_MIN_NOACTIVE = 7;
-		public const int SHOW_NA = 8;
 		public const int RESTORE = 9;
-		public const int SHOW_DEFAULT = 10;
-		public const int FORCE_MINIMIZE = 11;
 
-		internal bool GetWindow (IntPtr handle, ref WindowPlacement placement)
+		internal void ShowWindow (int state)
 		{
-			placement = new WindowPlacement {
-				length = Marshal.SizeOf (typeof (WindowPlacement))
-			};
-			return GetWindowPlacement (handle, ref placement);
-		}
-
-		internal bool SetWindow (IntPtr handle, ref WindowPlacement placement)
-		{
-			return SetWindowPlacement (handle, ref placement);
-		}
-
-		[DllImport ("user32.dll", SetLastError = true)]
-		static extern bool GetWindowRect (IntPtr hwnd, out System.Drawing.Rectangle lpRect);
-
-		internal bool GetRect (IntPtr handle, out System.Drawing.Rectangle lpRect)
-		{
-			return GetWindowRect (handle, out lpRect);
-		}
-
-#if false
-		// size of a device name string
-		private const int CCHDEVICENAME = 32;
-
-		[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Auto)]
-		internal struct MonitorInfoEx {
-			public uint cbSize;
-			public System.Drawing.Rectangle rcMonitor;
-			public System.Drawing.Rectangle rcWork;
-			public int dwFlags;
-			[MarshalAs (UnmanagedType.ByValTStr, SizeConst = CCHDEVICENAME)]
-			public string szDevice;
+			IntPtr thisConsole = GetConsoleWindow ();
+			ShowWindow (thisConsole, state);
 		}
+#endif
+#if false // 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;
 
-		[DllImport ("user32.dll", CharSet = CharSet.Auto)]
-		static extern bool GetMonitorInfo (IntPtr hMonitor, ref MonitorInfoEx lpmi);
-
-		internal bool GetMonitor(IntPtr hMonitor, ref MonitorInfoEx minfo)
-		{
-			minfo.cbSize = (uint)Marshal.SizeOf (minfo);
-			return GetMonitorInfo (hMonitor, ref minfo);
+			public SMALL_RECT (short Left, short Top, short Right, short Bottom)
+			{
+				this.Left = Left;
+				this.Top = Top;
+				this.Right = Right;
+				this.Bottom = Bottom;
+			}
 		}
 
-		[DllImport ("user32.dll")]
-		static extern IntPtr MonitorFromWindow (IntPtr hwnd, uint dwFlags);
-
-		public const int MONITOR_DEFAULTTONULL = 0;
-		public const int MONITOR_DEFAULTTOPRIMARY = 1;
-		public const int MONITOR_DEFAULTTONEAREST = 2;
-
-		internal IntPtr GetMonitorWindow (IntPtr hwnd, uint dwFlag)
-		{
-			return MonitorFromWindow (hwnd, dwFlag);
+		[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;
 		}
 
 		[DllImport ("kernel32.dll", SetLastError = true)]
-		static extern bool GetConsoleScreenBufferInfo (IntPtr hConsoleOutput, out ConsoleScreenBufferInfo ConsoleScreenBufferInfo);
+		static extern bool GetConsoleScreenBufferInfo (IntPtr hConsoleOutput, out CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo);
 
-		// Theoretically GetConsoleScreenBuffer height should give the console Window size, but the Top is always 0.
+		// 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 (IntPtr handle)
+		internal Size GetWindowSize ()
 		{
-			GetConsoleScreenBufferInfo (handle, out ConsoleScreenBufferInfo consoleScreenBufferInfo);
-			return new Size (consoleScreenBufferInfo.srWindow.Right - consoleScreenBufferInfo.srWindow.Left + 1,
-				consoleScreenBufferInfo.srWindow.Bottom - consoleScreenBufferInfo.srWindow.Top + 1);
+			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
 	}
@@ -700,12 +638,10 @@ namespace Terminal.Gui {
 
 		public WindowsDriver ()
 		{
-			winConsole = new WindowsConsole () {
-				HeightAsBuffer = this.HeightAsBuffer
-			};
+			winConsole = new WindowsConsole ();
 		}
 
-		MainLoop mainLoop;
+		bool winChanging;
 
 		public override void PrepareToRun (MainLoop mainLoop, Action<KeyEvent> keyHandler, Action<KeyEvent> keyDownHandler, Action<KeyEvent> keyUpHandler, Action<MouseEvent> mouseHandler)
 		{
@@ -713,41 +649,36 @@ namespace Terminal.Gui {
 			this.keyDownHandler = keyDownHandler;
 			this.keyUpHandler = keyUpHandler;
 			this.mouseHandler = mouseHandler;
-			this.mainLoop = mainLoop;
 
 			var mLoop = mainLoop.Driver as WindowsMainLoop;
 
 			mLoop.ProcessInput = (e) => ProcessInput (e);
 
-			mLoop.WinChanged = (e) => ChangeWin (e);
+			mLoop.WinChanged = (e) => {
+				ChangeWin (e);
+			};
 		}
 
-		bool winChanging;
-		bool wasChangeWin;
-
-		void ChangeWin (Size size)
+		private void ChangeWin (Size e)
 		{
+			winChanging = true;
 			if (!HeightAsBuffer) {
-				winChanging = true;
 				top = 0;
-				cols = size.Width;
-				rows = size.Height;
+				cols = e.Width;
+				rows = e.Height;
 				ResizeScreen ();
 				UpdateOffScreen ();
 				var bufferCoords = new WindowsConsole.Coord () {
-					X = (short)cols,
-					Y = (short)rows
+					X = (short)Clip.Width,
+					Y = (short)Clip.Height
 				};
-				winConsole.ReadFromConsoleOutput (size, bufferCoords, damageRegion);
+				winConsole.ReadFromConsoleOutput (e, bufferCoords, ref damageRegion);
 				if (!winChanging) {
 					TerminalResized.Invoke ();
 				}
-				wasChangeWin = true;
 			}
 		}
 
-		bool isFromRestore;
-
 		void ProcessInput (WindowsConsole.InputRecord inputEvent)
 		{
 			switch (inputEvent.EventType) {
@@ -839,25 +770,11 @@ namespace Terminal.Gui {
 				break;
 
 			case WindowsConsole.EventType.WindowBufferSize:
-				if (HeightAsBuffer) {
-					cols = inputEvent.WindowBufferSizeEvent.size.X;
-					rows = inputEvent.WindowBufferSizeEvent.size.Y;
-					ResizeScreen ();
-					UpdateOffScreen ();
-					TerminalResized?.Invoke ();
-				} else if (!HeightAsBuffer && !wasChangeWin && !(mainLoop.Driver as WindowsMainLoop).Maximized
-					&& !isFromRestore) {
-					ChangeWin (new Size (inputEvent.WindowBufferSizeEvent.size.X,
-						inputEvent.WindowBufferSizeEvent.size.Y));
-				} else if (!HeightAsBuffer && wasChangeWin && (mainLoop.Driver as WindowsMainLoop).Restored) {
-					(mainLoop.Driver as WindowsMainLoop).Restored = false;
-					isFromRestore = true;
-				} else if (!HeightAsBuffer && wasChangeWin && !(mainLoop.Driver as WindowsMainLoop).Maximized
-					&& !(mainLoop.Driver as WindowsMainLoop).Restored && !isFromRestore) {
-					wasChangeWin = false;
-				} else if (isFromRestore) {
-					isFromRestore = false;
-				}
+				cols = inputEvent.WindowBufferSizeEvent.size.X;
+				rows = inputEvent.WindowBufferSizeEvent.size.Y;
+				ResizeScreen ();
+				UpdateOffScreen ();
+				TerminalResized?.Invoke ();
 				break;
 
 			case WindowsConsole.EventType.Focus:
@@ -1433,7 +1350,7 @@ 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");
+			//			System.Diagnostics.Debugger.Log(0, "debug", $"Region={damageRegion.Right - damageRegion.Left},{damageRegion.Bottom - damageRegion.Top}\n");
 			WindowsConsole.SmallRect.MakeEmpty (ref damageRegion);
 		}
 
@@ -1515,12 +1432,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
@@ -1536,9 +1453,6 @@ namespace Terminal.Gui {
 		/// </summary>
 		public Action<Size> WinChanged;
 
-		public bool Maximized;
-		public bool Restored;
-
 		public WindowsMainLoop (ConsoleDriver consoleDriver = null)
 		{
 			if (consoleDriver == null) {
@@ -1552,7 +1466,8 @@ namespace Terminal.Gui {
 		{
 			this.mainLoop = mainLoop;
 			Task.Run (WindowsInputHandler);
-			Task.Run (CheckWinChange);
+			// Nor working yet.
+			//Task.Run (CheckWinChange);
 		}
 
 		void WindowsInputHandler ()
@@ -1567,105 +1482,29 @@ namespace Terminal.Gui {
 			}
 		}
 
-		void CheckWinChange ()
-		{
-			while (true) {
-				winChange.Wait ();
-				winChange.Reset ();
-				WaitWinChange ();
-				winChanged = true;
-				eventReady.Set ();
-			}
-		}
-
-		const int Width_Divider = 8;
-		const int Height_Divider = 18;
-		bool docked;
-
-		void WaitWinChange ()
-		{
-			var handle = winConsole.GetConsole ();
-
-			while (!consoleDriver.HeightAsBuffer) {
-				WindowsConsole.WindowPlacement windowPlacement = new WindowsConsole.WindowPlacement ();
-				winConsole.GetWindow (handle, ref windowPlacement);
-
-				if (windowPlacement.rcNormalPosition.Size.Height > -1) {
-					windowSize = SetWindowSize (windowPlacement.rcNormalPosition);
-
-					if (windowPlacement.showCmd != WindowsConsole.SHOW_MAXIMIZED && !Maximized && !Restored && !docked
-						&& (windowSize.Width != consoleDriver.Cols || windowSize.Height != consoleDriver.Rows)) {
-						docked = false;
-						return;
-					} else if (windowPlacement.showCmd == WindowsConsole.SHOW_MAXIMIZED && !Maximized
-						&& (Console.LargestWindowWidth != consoleDriver.Cols || Console.LargestWindowHeight != consoleDriver.Rows)) {
-						windowSize = new Size (Console.LargestWindowWidth, Console.LargestWindowHeight);
-						Maximized = true;
-						docked = false;
-						return;
-					} else if (windowPlacement.showCmd != WindowsConsole.SHOW_MAXIMIZED && Maximized) {
-						windowPlacement = new WindowsConsole.WindowPlacement () {
-							showCmd = WindowsConsole.RESTORE
-						};
-						winConsole.SetWindow (handle, ref windowPlacement);
-						Restored = true;
-						Maximized = false;
-						docked = false;
-						return;
-					} else if (!Maximized && IsDockedToMonitor (handle, windowPlacement)) {
-						return;
-					}
-				}
-			}
-
-			Size SetWindowSize (System.Drawing.Rectangle rect)
-			{
-				return new Size (Math.Max (((rect.Width - rect.X) / Width_Divider) - 2, 0),
-					Math.Max (((rect.Height - rect.Y) / Height_Divider) - 2, 0));
-			}
-
-			bool IsDockedToMonitor (IntPtr hWnd, WindowsConsole.WindowPlacement placement)
-			{
-				System.Drawing.Rectangle rc;
-				winConsole.GetRect (hWnd, out rc);
-
-				var changed = placement.showCmd == WindowsConsole.SHOW_NORMAL
-				    && (rc.Left != placement.rcNormalPosition.Left ||
-					rc.Top != placement.rcNormalPosition.Top ||
-					rc.Right != placement.rcNormalPosition.Right ||
-					rc.Bottom != placement.rcNormalPosition.Bottom);
-
-				if (changed) {
-					var pSize = new Size (placement.rcNormalPosition.Size.Width - placement.rcNormalPosition.X,
-						placement.rcNormalPosition.Size.Height - placement.rcNormalPosition.Y);
-					var rSize = new Size (rc.Width - rc.X,
-						rc.Height - rc.Y);
-					windowSize = SetWindowSize (rc);
-
-					if ((rc.X < 0) || (rc.Y == 0) || (rc.Y == 0 && rc.X < 0)
-						|| (rc.Y == 0 && rc.Right / Width_Divider >= Console.LargestWindowWidth)
-						|| (rc.X < 0 && rc.Bottom / Height_Divider >= Console.LargestWindowHeight)
-						|| (rc.X / Width_Divider >= Console.LargestWindowWidth / 2 - 1 && rc.Bottom / Height_Divider >= Console.LargestWindowHeight)) {
-						if (!docked || consoleDriver.Cols != windowSize.Width
-							|| consoleDriver.Rows != windowSize.Height) {
-							docked = true;
-						} else {
-							changed = false;
-						}
-					} else {
-						if (!docked && (pSize == rSize || rSize.Width / Width_Divider >= Console.LargestWindowWidth
-							|| rSize.Height / Height_Divider >= Console.LargestWindowHeight)) {
-							changed = false;
-						}
-						docked = false;
-					}
-				} else {
-					docked = false;
-				}
-
-				return changed;
-			}
-		}
+		//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 IMainLoopDriver.Wakeup ()
 		{
@@ -1679,11 +1518,10 @@ namespace Terminal.Gui {
 				return true;
 			}
 
-			//result = null;
+			result = null;
 			waitForProbe.Set ();
-			if (!consoleDriver.HeightAsBuffer) {
-				winChange.Set ();
-			}
+			// Nor working yet.
+			//winChange.Set ();
 
 			try {
 				if (!tokenSource.IsCancellationRequested) {
@@ -1696,7 +1534,8 @@ namespace Terminal.Gui {
 			}
 
 			if (!tokenSource.IsCancellationRequested) {
-				return result != null || CheckTimers (wait, out _) || winChanged;
+				//return result != null || CheckTimers (wait, out _) || winChanged;
+				return result != null || CheckTimers (wait, out _);
 			}
 
 			tokenSource.Dispose ();
@@ -1734,10 +1573,10 @@ namespace Terminal.Gui {
 				result = null;
 				ProcessInput?.Invoke (inputEvent);
 			}
-			if (winChanged) {
-				winChanged = false;
-				WinChanged?.Invoke (windowSize);
-			}
+			//if (winChanged) {
+			//	winChanged = false;
+			//	WinChanged?.Invoke (windowSize);
+			//}
 		}
 	}
 }

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

@@ -88,7 +88,6 @@ namespace Terminal.Gui {
 				}
 				if (Driver.HeightAsBuffer != value) {
 					Driver.HeightAsBuffer = value;
-					Driver.Refresh ();
 				}
 			}
 		}

+ 1 - 1
UICatalog/UICatalog.cs

@@ -63,7 +63,7 @@ namespace UICatalog {
 		private static Scenario _runningScenario = null;
 		private static bool _useSystemConsole = false;
 		private static ConsoleDriver.DiagnosticFlags _diagnosticFlags;
-		private static bool _heightAsBuffer;
+		private static bool _heightAsBuffer = false;
 		private static bool _alwaysSetPosition;
 
 		static void Main (string [] args)