From 5c0dc43c9c83f6baead5c96d08e84a4089056e36 Mon Sep 17 00:00:00 2001 From: BDisp Date: Wed, 6 Nov 2024 16:16:17 +0000 Subject: [PATCH] Fixes #3752. Tracking Windows Terminal Preview Issue - App size is corrupted --- Terminal.Gui/ConsoleDrivers/WindowsDriver.cs | 243 ++++++++++--------- 1 file changed, 125 insertions(+), 118 deletions(-) diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index 01d13b80d..0abcc6024 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -18,7 +18,6 @@ namespace Terminal.Gui { public const int STD_ERROR_HANDLE = -12; internal IntPtr InputHandle, OutputHandle; - IntPtr ScreenBuffer; readonly uint originalConsoleMode; CursorVisibility? initialCursorVisibility = null; CursorVisibility? currentCursorVisibility = null; @@ -40,47 +39,47 @@ namespace Terminal.Gui { public bool WriteToConsole (Size size, CharInfo [] charInfoBuffer, Coord coords, SmallRect window) { - if (ScreenBuffer == IntPtr.Zero) { - ReadFromConsoleOutput (size, coords, ref window); - } + //if (OutputHandle == IntPtr.Zero) { + // ReadFromConsoleOutput (size, coords, ref window); + //} - return WriteConsoleOutput (ScreenBuffer, charInfoBuffer, coords, new Coord () { X = window.Left, Y = window.Top }, ref window); + return WriteConsoleOutput (OutputHandle, charInfoBuffer, coords, new Coord () { X = window.Left, Y = window.Top }, ref window); } - public void ReadFromConsoleOutput (Size size, Coord coords, ref SmallRect window) - { - ScreenBuffer = CreateConsoleScreenBuffer ( - DesiredAccess.GenericRead | DesiredAccess.GenericWrite, - ShareMode.FileShareRead | ShareMode.FileShareWrite, - IntPtr.Zero, - 1, - IntPtr.Zero - ); - if (ScreenBuffer == INVALID_HANDLE_VALUE) { - var err = Marshal.GetLastWin32Error (); + //public void ReadFromConsoleOutput (Size size, Coord coords, ref SmallRect window) + //{ + // OutputHandle = CreateConsoleScreenBuffer ( + // DesiredAccess.GenericRead | DesiredAccess.GenericWrite, + // ShareMode.FileShareRead | ShareMode.FileShareWrite, + // IntPtr.Zero, + // 1, + // IntPtr.Zero + // ); + // if (ScreenBuffer == INVALID_HANDLE_VALUE) { + // var err = Marshal.GetLastWin32Error (); - if (err != 0) - throw new System.ComponentModel.Win32Exception (err); - } + // if (err != 0) + // throw new System.ComponentModel.Win32Exception (err); + // } - if (!initialCursorVisibility.HasValue && GetCursorVisibility (out CursorVisibility visibility)) { - initialCursorVisibility = visibility; - } + // if (!initialCursorVisibility.HasValue && GetCursorVisibility (out CursorVisibility visibility)) { + // initialCursorVisibility = visibility; + // } - if (!SetConsoleActiveScreenBuffer (ScreenBuffer)) { - throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); - } + // if (!SetConsoleActiveScreenBuffer (ScreenBuffer)) { + // throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); + // } - OriginalStdOutChars = new CharInfo [size.Height * size.Width]; + // OriginalStdOutChars = new CharInfo [size.Height * size.Width]; - if (!ReadConsoleOutput (ScreenBuffer, OriginalStdOutChars, coords, new Coord () { X = 0, Y = 0 }, ref window)) { - throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); - } - } + // 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) { - return SetConsoleCursorPosition (ScreenBuffer, position); + return SetConsoleCursorPosition (OutputHandle, position); } public void SetInitialCursorVisibility () @@ -92,11 +91,11 @@ namespace Terminal.Gui { public bool GetCursorVisibility (out CursorVisibility visibility) { - if (ScreenBuffer == IntPtr.Zero) { + if (OutputHandle == IntPtr.Zero) { visibility = CursorVisibility.Invisible; return false; } - if (!GetConsoleCursorInfo (ScreenBuffer, out ConsoleCursorInfo info)) { + if (!GetConsoleCursorInfo (OutputHandle, out ConsoleCursorInfo info)) { var err = Marshal.GetLastWin32Error (); if (err != 0) { throw new System.ComponentModel.Win32Exception (err); @@ -149,7 +148,7 @@ namespace Terminal.Gui { bVisible = ((uint)visibility & 0xFF00) != 0 }; - if (!SetConsoleCursorInfo (ScreenBuffer, ref info)) + if (!SetConsoleCursorInfo (OutputHandle, ref info)) return false; currentCursorVisibility = visibility; @@ -165,28 +164,28 @@ namespace Terminal.Gui { } ConsoleMode = originalConsoleMode; - if (!SetConsoleActiveScreenBuffer (OutputHandle)) { - var err = Marshal.GetLastWin32Error (); - Console.WriteLine ("Error: {0}", err); - } + //if (!SetConsoleActiveScreenBuffer (OutputHandle)) { + // var err = Marshal.GetLastWin32Error (); + // Console.WriteLine ("Error: {0}", err); + //} - if (ScreenBuffer != IntPtr.Zero) { - CloseHandle (ScreenBuffer); - } + //if (ScreenBuffer != IntPtr.Zero) { + // CloseHandle (ScreenBuffer); + //} - ScreenBuffer = IntPtr.Zero; + //ScreenBuffer = IntPtr.Zero; } internal Size GetConsoleBufferWindow (out Point position) { - if (ScreenBuffer == IntPtr.Zero) { + if (OutputHandle == 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)) { + if (!GetConsoleScreenBufferInfoEx (OutputHandle, ref csbi)) { //throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); position = Point.Empty; return Size.Empty; @@ -212,65 +211,65 @@ namespace Terminal.Gui { return sz; } - internal Size SetConsoleWindow (short cols, short rows) - { - var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX (); - csbi.cbSize = (uint)Marshal.SizeOf (csbi); + //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 ()); - } - var maxWinSize = GetLargestConsoleWindowSize (ScreenBuffer); - var newCols = Math.Min (cols, maxWinSize.X); - var newRows = Math.Min (rows, maxWinSize.Y); - csbi.dwSize = new Coord (newCols, Math.Max (newRows, (short)1)); - csbi.srWindow = new SmallRect (0, 0, newCols, newRows); - csbi.dwMaximumWindowSize = new Coord (newCols, newRows); - if (!SetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) { - throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); - } - var winRect = new SmallRect (0, 0, (short)(newCols - 1), (short)Math.Max (newRows - 1, 0)); - if (!SetConsoleWindowInfo (OutputHandle, true, ref winRect)) { - //throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); - return new Size (cols, rows); - } - SetConsoleOutputWindow (csbi); - return new Size (winRect.Right + 1, newRows - 1 < 0 ? 0 : winRect.Bottom + 1); - } + // if (!GetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) { + // throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); + // } + // var maxWinSize = GetLargestConsoleWindowSize (ScreenBuffer); + // var newCols = Math.Min (cols, maxWinSize.X); + // var newRows = Math.Min (rows, maxWinSize.Y); + // csbi.dwSize = new Coord (newCols, Math.Max (newRows, (short)1)); + // csbi.srWindow = new SmallRect (0, 0, newCols, newRows); + // csbi.dwMaximumWindowSize = new Coord (newCols, newRows); + // if (!SetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) { + // throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); + // } + // var winRect = new SmallRect (0, 0, (short)(newCols - 1), (short)Math.Max (newRows - 1, 0)); + // if (!SetConsoleWindowInfo (OutputHandle, true, ref winRect)) { + // //throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); + // return new Size (cols, rows); + // } + // SetConsoleOutputWindow (csbi); + // return new Size (winRect.Right + 1, newRows - 1 < 0 ? 0 : winRect.Bottom + 1); + //} - void SetConsoleOutputWindow (CONSOLE_SCREEN_BUFFER_INFOEX csbi) - { - if (ScreenBuffer != IntPtr.Zero && !SetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) { - throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); - } - } + //void SetConsoleOutputWindow (CONSOLE_SCREEN_BUFFER_INFOEX csbi) + //{ + // if (ScreenBuffer != IntPtr.Zero && !SetConsoleScreenBufferInfoEx (ScreenBuffer, 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; - } + //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 (!SetConsoleScreenBufferInfoEx (OutputHandle, ref csbi)) { - throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); - } - if (!SetConsoleWindowInfo (OutputHandle, true, ref winRect)) { - throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); - } + // 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 (!SetConsoleScreenBufferInfoEx (OutputHandle, ref csbi)) { + // throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); + // } + // if (!SetConsoleWindowInfo (OutputHandle, true, ref winRect)) { + // throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); + // } - return sz; - } + // return sz; + //} //bool ContinueListeningForConsoleEvents = true; @@ -734,7 +733,7 @@ namespace Terminal.Gui { WinConsole = new WindowsConsole (); clipboard = new WindowsClipboard (); - isWindowsTerminal = Environment.GetEnvironmentVariable ("WT_SESSION") != null; + isWindowsTerminal = Environment.GetEnvironmentVariable ("WT_SESSION") != null || Environment.GetEnvironmentVariable ("VSAPPIDNAME") != null; } public override void PrepareToRun (MainLoop mainLoop, Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler) @@ -748,28 +747,28 @@ namespace Terminal.Gui { mLoop.ProcessInput = (e) => ProcessInput (e); - mLoop.WinChanged = (e) => { - ChangeWin (e); - }; + //mLoop.WinChanged = (e) => { + // ChangeWin (e); + //}; } - private void ChangeWin (Size e) - { - var w = e.Width; - if (w == cols - 3 && e.Height < rows) { - w += 3; - } - var newSize = WinConsole.SetConsoleWindow ( - (short)Math.Max (w, 16), (short)Math.Max (e.Height, 0)); + //private void ChangeWin (Size e) + //{ + // var w = e.Width; + // if (w == cols - 3 && e.Height < rows) { + // w += 3; + // } + // var newSize = WinConsole.SetConsoleWindow ( + // (short)Math.Max (w, 16), (short)Math.Max (e.Height, 0)); - left = 0; - top = 0; - cols = newSize.Width; - rows = newSize.Height; - ResizeScreen (); - UpdateOffScreen (); - TerminalResized.Invoke (); - } + // left = 0; + // top = 0; + // cols = newSize.Width; + // rows = newSize.Height; + // ResizeScreen (); + // UpdateOffScreen (); + // TerminalResized.Invoke (); + //} void ProcessInput (WindowsConsole.InputRecord inputEvent) { @@ -893,6 +892,14 @@ namespace Terminal.Gui { case WindowsConsole.EventType.Focus: keyModifiers = null; break; + + case WindowsConsole.EventType.WindowBufferSize: + cols = inputEvent.WindowBufferSizeEvent.size.X; + rows = inputEvent.WindowBufferSizeEvent.size.Y; + + ResizeScreen (); + TerminalResized.Invoke (); + break; } }