Merge pull request #3809 from BDisp/v1_3752_windowsdriver-wt-preview-fix

Fixes #3752. Tracking Windows Terminal Preview Issue - App size is corrupted
This commit is contained in:
Tig
2024-11-07 16:25:17 -07:00
committed by GitHub

View File

@@ -18,7 +18,6 @@ namespace Terminal.Gui {
public const int STD_ERROR_HANDLE = -12; public const int STD_ERROR_HANDLE = -12;
internal IntPtr InputHandle, OutputHandle; internal IntPtr InputHandle, OutputHandle;
IntPtr ScreenBuffer;
readonly uint originalConsoleMode; readonly uint originalConsoleMode;
CursorVisibility? initialCursorVisibility = null; CursorVisibility? initialCursorVisibility = null;
CursorVisibility? currentCursorVisibility = null; CursorVisibility? currentCursorVisibility = null;
@@ -40,47 +39,47 @@ namespace Terminal.Gui {
public bool WriteToConsole (Size size, CharInfo [] charInfoBuffer, Coord coords, SmallRect window) public bool WriteToConsole (Size size, CharInfo [] charInfoBuffer, Coord coords, SmallRect window)
{ {
if (ScreenBuffer == IntPtr.Zero) { //if (OutputHandle == IntPtr.Zero) {
ReadFromConsoleOutput (size, coords, ref window); // 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) //public void ReadFromConsoleOutput (Size size, Coord coords, ref SmallRect window)
{ //{
ScreenBuffer = CreateConsoleScreenBuffer ( // OutputHandle = CreateConsoleScreenBuffer (
DesiredAccess.GenericRead | DesiredAccess.GenericWrite, // DesiredAccess.GenericRead | DesiredAccess.GenericWrite,
ShareMode.FileShareRead | ShareMode.FileShareWrite, // ShareMode.FileShareRead | ShareMode.FileShareWrite,
IntPtr.Zero, // IntPtr.Zero,
1, // 1,
IntPtr.Zero // IntPtr.Zero
); // );
if (ScreenBuffer == INVALID_HANDLE_VALUE) { // if (ScreenBuffer == INVALID_HANDLE_VALUE) {
var err = Marshal.GetLastWin32Error (); // var err = Marshal.GetLastWin32Error ();
if (err != 0) // if (err != 0)
throw new System.ComponentModel.Win32Exception (err); // throw new System.ComponentModel.Win32Exception (err);
} // }
if (!initialCursorVisibility.HasValue && GetCursorVisibility (out CursorVisibility visibility)) { // if (!initialCursorVisibility.HasValue && GetCursorVisibility (out CursorVisibility visibility)) {
initialCursorVisibility = visibility; // initialCursorVisibility = visibility;
} // }
if (!SetConsoleActiveScreenBuffer (ScreenBuffer)) { // if (!SetConsoleActiveScreenBuffer (ScreenBuffer)) {
throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); // 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)) { // if (!ReadConsoleOutput (ScreenBuffer, OriginalStdOutChars, coords, new Coord () { X = 0, Y = 0 }, ref window)) {
throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); // throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
} // }
} //}
public bool SetCursorPosition (Coord position) public bool SetCursorPosition (Coord position)
{ {
return SetConsoleCursorPosition (ScreenBuffer, position); return SetConsoleCursorPosition (OutputHandle, position);
} }
public void SetInitialCursorVisibility () public void SetInitialCursorVisibility ()
@@ -92,11 +91,11 @@ namespace Terminal.Gui {
public bool GetCursorVisibility (out CursorVisibility visibility) public bool GetCursorVisibility (out CursorVisibility visibility)
{ {
if (ScreenBuffer == IntPtr.Zero) { if (OutputHandle == IntPtr.Zero) {
visibility = CursorVisibility.Invisible; visibility = CursorVisibility.Invisible;
return false; return false;
} }
if (!GetConsoleCursorInfo (ScreenBuffer, out ConsoleCursorInfo info)) { if (!GetConsoleCursorInfo (OutputHandle, out ConsoleCursorInfo info)) {
var err = Marshal.GetLastWin32Error (); var err = Marshal.GetLastWin32Error ();
if (err != 0) { if (err != 0) {
throw new System.ComponentModel.Win32Exception (err); throw new System.ComponentModel.Win32Exception (err);
@@ -149,7 +148,7 @@ namespace Terminal.Gui {
bVisible = ((uint)visibility & 0xFF00) != 0 bVisible = ((uint)visibility & 0xFF00) != 0
}; };
if (!SetConsoleCursorInfo (ScreenBuffer, ref info)) if (!SetConsoleCursorInfo (OutputHandle, ref info))
return false; return false;
currentCursorVisibility = visibility; currentCursorVisibility = visibility;
@@ -165,28 +164,28 @@ namespace Terminal.Gui {
} }
ConsoleMode = originalConsoleMode; ConsoleMode = originalConsoleMode;
if (!SetConsoleActiveScreenBuffer (OutputHandle)) { //if (!SetConsoleActiveScreenBuffer (OutputHandle)) {
var err = Marshal.GetLastWin32Error (); // var err = Marshal.GetLastWin32Error ();
Console.WriteLine ("Error: {0}", err); // Console.WriteLine ("Error: {0}", err);
} //}
if (ScreenBuffer != IntPtr.Zero) { //if (ScreenBuffer != IntPtr.Zero) {
CloseHandle (ScreenBuffer); // CloseHandle (ScreenBuffer);
} //}
ScreenBuffer = IntPtr.Zero; //ScreenBuffer = IntPtr.Zero;
} }
internal Size GetConsoleBufferWindow (out Point position) internal Size GetConsoleBufferWindow (out Point position)
{ {
if (ScreenBuffer == IntPtr.Zero) { if (OutputHandle == IntPtr.Zero) {
position = Point.Empty; position = Point.Empty;
return Size.Empty; return Size.Empty;
} }
var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX (); var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
csbi.cbSize = (uint)Marshal.SizeOf (csbi); csbi.cbSize = (uint)Marshal.SizeOf (csbi);
if (!GetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) { if (!GetConsoleScreenBufferInfoEx (OutputHandle, ref csbi)) {
//throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); //throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
position = Point.Empty; position = Point.Empty;
return Size.Empty; return Size.Empty;
@@ -212,65 +211,65 @@ namespace Terminal.Gui {
return sz; return sz;
} }
internal Size SetConsoleWindow (short cols, short rows) //internal Size SetConsoleWindow (short cols, short rows)
{ //{
var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX (); // var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
csbi.cbSize = (uint)Marshal.SizeOf (csbi); // csbi.cbSize = (uint)Marshal.SizeOf (csbi);
if (!GetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) { // if (!GetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) {
throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); // throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
} // }
var maxWinSize = GetLargestConsoleWindowSize (ScreenBuffer); // var maxWinSize = GetLargestConsoleWindowSize (ScreenBuffer);
var newCols = Math.Min (cols, maxWinSize.X); // var newCols = Math.Min (cols, maxWinSize.X);
var newRows = Math.Min (rows, maxWinSize.Y); // var newRows = Math.Min (rows, maxWinSize.Y);
csbi.dwSize = new Coord (newCols, Math.Max (newRows, (short)1)); // csbi.dwSize = new Coord (newCols, Math.Max (newRows, (short)1));
csbi.srWindow = new SmallRect (0, 0, newCols, newRows); // csbi.srWindow = new SmallRect (0, 0, newCols, newRows);
csbi.dwMaximumWindowSize = new Coord (newCols, newRows); // csbi.dwMaximumWindowSize = new Coord (newCols, newRows);
if (!SetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) { // if (!SetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) {
throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); // throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
} // }
var winRect = new SmallRect (0, 0, (short)(newCols - 1), (short)Math.Max (newRows - 1, 0)); // var winRect = new SmallRect (0, 0, (short)(newCols - 1), (short)Math.Max (newRows - 1, 0));
if (!SetConsoleWindowInfo (OutputHandle, true, ref winRect)) { // if (!SetConsoleWindowInfo (OutputHandle, true, ref winRect)) {
//throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); // //throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
return new Size (cols, rows); // return new Size (cols, rows);
} // }
SetConsoleOutputWindow (csbi); // SetConsoleOutputWindow (csbi);
return new Size (winRect.Right + 1, newRows - 1 < 0 ? 0 : winRect.Bottom + 1); // return new Size (winRect.Right + 1, newRows - 1 < 0 ? 0 : winRect.Bottom + 1);
} //}
void SetConsoleOutputWindow (CONSOLE_SCREEN_BUFFER_INFOEX csbi) //void SetConsoleOutputWindow (CONSOLE_SCREEN_BUFFER_INFOEX csbi)
{ //{
if (ScreenBuffer != IntPtr.Zero && !SetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) { // if (ScreenBuffer != IntPtr.Zero && !SetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) {
throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); // throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
} // }
} //}
internal Size SetConsoleOutputWindow (out Point position) //internal Size SetConsoleOutputWindow (out Point position)
{ //{
if (ScreenBuffer == IntPtr.Zero) { // if (ScreenBuffer == IntPtr.Zero) {
position = Point.Empty; // position = Point.Empty;
return Size.Empty; // return Size.Empty;
} // }
var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX (); // var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
csbi.cbSize = (uint)Marshal.SizeOf (csbi); // csbi.cbSize = (uint)Marshal.SizeOf (csbi);
if (!GetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) { // if (!GetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) {
throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); // throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
} // }
var sz = new Size (csbi.srWindow.Right - csbi.srWindow.Left + 1, // var sz = new Size (csbi.srWindow.Right - csbi.srWindow.Left + 1,
Math.Max (csbi.srWindow.Bottom - csbi.srWindow.Top + 1, 0)); // Math.Max (csbi.srWindow.Bottom - csbi.srWindow.Top + 1, 0));
position = new Point (csbi.srWindow.Left, csbi.srWindow.Top); // position = new Point (csbi.srWindow.Left, csbi.srWindow.Top);
SetConsoleOutputWindow (csbi); // SetConsoleOutputWindow (csbi);
var winRect = new SmallRect (0, 0, (short)(sz.Width - 1), (short)Math.Max (sz.Height - 1, 0)); // var winRect = new SmallRect (0, 0, (short)(sz.Width - 1), (short)Math.Max (sz.Height - 1, 0));
if (!SetConsoleScreenBufferInfoEx (OutputHandle, ref csbi)) { // if (!SetConsoleScreenBufferInfoEx (OutputHandle, ref csbi)) {
throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); // throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
} // }
if (!SetConsoleWindowInfo (OutputHandle, true, ref winRect)) { // if (!SetConsoleWindowInfo (OutputHandle, true, ref winRect)) {
throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ()); // throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
} // }
return sz; // return sz;
} //}
//bool ContinueListeningForConsoleEvents = true; //bool ContinueListeningForConsoleEvents = true;
@@ -734,7 +733,7 @@ namespace Terminal.Gui {
WinConsole = new WindowsConsole (); WinConsole = new WindowsConsole ();
clipboard = new WindowsClipboard (); 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<KeyEvent> keyHandler, Action<KeyEvent> keyDownHandler, Action<KeyEvent> keyUpHandler, Action<MouseEvent> mouseHandler) public override void PrepareToRun (MainLoop mainLoop, Action<KeyEvent> keyHandler, Action<KeyEvent> keyDownHandler, Action<KeyEvent> keyUpHandler, Action<MouseEvent> mouseHandler)
@@ -748,28 +747,28 @@ namespace Terminal.Gui {
mLoop.ProcessInput = (e) => ProcessInput (e); mLoop.ProcessInput = (e) => ProcessInput (e);
mLoop.WinChanged = (e) => { //mLoop.WinChanged = (e) => {
ChangeWin (e); // ChangeWin (e);
}; //};
} }
private void ChangeWin (Size e) //private void ChangeWin (Size e)
{ //{
var w = e.Width; // var w = e.Width;
if (w == cols - 3 && e.Height < rows) { // if (w == cols - 3 && e.Height < rows) {
w += 3; // w += 3;
} // }
var newSize = WinConsole.SetConsoleWindow ( // var newSize = WinConsole.SetConsoleWindow (
(short)Math.Max (w, 16), (short)Math.Max (e.Height, 0)); // (short)Math.Max (w, 16), (short)Math.Max (e.Height, 0));
left = 0; // left = 0;
top = 0; // top = 0;
cols = newSize.Width; // cols = newSize.Width;
rows = newSize.Height; // rows = newSize.Height;
ResizeScreen (); // ResizeScreen ();
UpdateOffScreen (); // UpdateOffScreen ();
TerminalResized.Invoke (); // TerminalResized.Invoke ();
} //}
void ProcessInput (WindowsConsole.InputRecord inputEvent) void ProcessInput (WindowsConsole.InputRecord inputEvent)
{ {
@@ -893,6 +892,14 @@ namespace Terminal.Gui {
case WindowsConsole.EventType.Focus: case WindowsConsole.EventType.Focus:
keyModifiers = null; keyModifiers = null;
break; break;
case WindowsConsole.EventType.WindowBufferSize:
cols = inputEvent.WindowBufferSizeEvent.size.X;
rows = inputEvent.WindowBufferSizeEvent.size.Y;
ResizeScreen ();
TerminalResized.Invoke ();
break;
} }
} }