Skip to content

Commit c61e07f

Browse files
committed
Document Unix direct ANSI approach and credit Terminal.Gui v2
Add detailed class remarks to NetConsoleDriver explaining the raw libc I/O architecture on Unix, why .NET Console APIs cause echo leaks, and credit Terminal.Gui v2 for the approach (stdin fd 0, tcflush, alternate screen buffer).
1 parent 42318fe commit c61e07f

1 file changed

Lines changed: 21 additions & 7 deletions

File tree

SharpConsoleUI/Drivers/NetConsoleDriver.cs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,34 @@ public enum RenderMode
4747
}
4848

4949
/// <summary>
50-
/// Provides a cross-platform console driver implementation using .NET Console APIs.
50+
/// Provides a cross-platform console driver implementation.
5151
/// </summary>
5252
/// <remarks>
5353
/// <para>
54-
/// This driver supports both Windows and Unix-like platforms, handling platform-specific
55-
/// console mode configuration for mouse input, virtual terminal processing, and other features.
54+
/// <b>Windows:</b> Uses .NET Console APIs with Win32 console mode configuration for
55+
/// virtual terminal input/output and mouse reporting.
5656
/// </para>
5757
/// <para>
58-
/// On Windows, the driver configures console modes using Win32 API calls to enable
59-
/// virtual terminal input/output and mouse reporting.
58+
/// <b>Unix (UseDirectAnsi=true):</b> Bypasses .NET's Console infrastructure entirely,
59+
/// using raw libc I/O for both input (read from stdin fd 0) and output (write to stdout fd 1).
60+
/// Terminal is put into raw mode via tcgetattr/tcsetattr (cfmakeraw equivalent), and an
61+
/// alternate screen buffer is used for clean display. Console.Out is redirected to /dev/null
62+
/// to prevent .NET runtime code from touching stdout. Window size is queried via ioctl
63+
/// TIOCGWINSZ instead of Console.WindowWidth/Height. SIGINT/SIGTSTP are suppressed via
64+
/// signal() instead of Console.TreatControlCAsInput.
65+
/// </para>
66+
/// <para>
67+
/// <b>Why:</b> .NET's ConsolePal.Unix calls tcsetattr on every Console.ReadKey, Console.SetCursorPosition,
68+
/// Console.CursorVisible, and even Console.OutputEncoding access. Each tcsetattr briefly toggles
69+
/// the ECHO flag, creating windows where raw mouse/keyboard ANSI sequences leak to the screen.
70+
/// The only reliable fix is to never touch any Console.* property on the hot path.
6071
/// </para>
6172
/// <para>
62-
/// Mouse events are parsed from ANSI escape sequences in both X10 and SGR formats,
63-
/// supporting button presses, releases, clicks, double-clicks, triple-clicks, and wheel events.
73+
/// <b>Approach inspired by Terminal.Gui v2</b> (https://github.com/gui-cs/Terminal.Gui),
74+
/// which solved the same problem in their Unix NetDriver by using raw file descriptor I/O
75+
/// and avoiding all .NET Console APIs on Unix. Key techniques adopted: reading from stdin fd 0
76+
/// directly (not /dev/tty, to avoid byte competition with .NET's internal fd 0 reader),
77+
/// tcflush to clear pending input, and alternate screen buffer usage.
6478
/// </para>
6579
/// </remarks>
6680
public class NetConsoleDriver : IConsoleDriver

0 commit comments

Comments
 (0)