* Add comprehensive unit tests for WindowsKeyConverter - Implement 118 parallelizable unit tests for WindowsKeyConverter - Cover ToKey and ToKeyInfo methods with full bidirectional testing - Test basic characters, modifiers, special keys, function keys - Test VK_PACKET Unicode/IME input - Test OEM keys, NumPad keys, and lock states - Include round-trip conversion tests - All tests passing successfully Fixes #4389 * Add test documenting VK_PACKET surrogate pair limitation VK_PACKET sends surrogate pairs (e.g., emoji) as two separate events. Current WindowsKeyConverter processes each independently without combining. Test documents this limitation for future fix at InputProcessor level. * Mark WindowsKeyConverterTests as Windows-only Tests now skip on non-Windows platforms using SkipException in constructor. This prevents CI failures on macOS and Linux where Windows Console API is not available. * Properly mark WindowsKeyConverter tests as Windows-only Created custom xUnit attributes SkipOnNonWindowsFact and SkipOnNonWindowsTheory that automatically skip tests on non-Windows platforms. This prevents CI failures on macOS and Linux. * Refactor and enhance test coverage for input processors Refactored `ApplicationImpl.cs` to simplify its structure by removing the `_stopAfterFirstIteration` field. Reintroduced and modernized test files with improved structure and coverage: - `NetInputProcessorTests.cs`: Added tests for `ConsoleKeyInfo` to `Rune`/`Key` conversion and queue processing. - `WindowSizeMonitorTests.cs`: Added tests for size change event handling. - `WindowsInputProcessorTests.cs`: Added tests for keyboard and mouse input processing, including mouse flag mapping. - `WindowsKeyConverterTests.cs`: Added comprehensive tests for `InputRecord` to `Key` conversion, covering OEM keys, modifiers, Unicode, and round-trip integrity. Improved test coverage for edge cases, introduced parameterized tests, and documented known limitations for future improvements. * Use Trait-based platform filtering for WindowsKeyConverter tests Added [Trait('Platform', 'Windows')] and [Collection('Global Test Setup')] attributes. Tests will run on Windows but can be filtered in CI on other platforms using --filter 'Platform!=Windows' if needed. This approach doesn't interfere with GlobalTestSetup and works correctly with xUnit. * Filter Windows-specific tests on non-Windows CI platforms Added --filter 'Platform!=Windows' for Linux and macOS runners to exclude WindowsKeyConverterTests which require Windows Console APIs. Windows runner runs all tests normally. * Fix log path typo and remove Codecov upload step Corrected a typo in the log directory path from `logs/UnitTestsParallelable/` to `logs/UnitTestsParallelizable/`. Removed the "Upload Parallelizable UnitTests Coverage to Codecov" step, which was conditional on `matrix.os == 'ubuntu-latest'` and used the `codecov/codecov-action@v4` action. This change improves log handling and removes the Codecov integration. * Refactor application reset logic Replaced `Application.ResetState(true)` with a more explicit reset mechanism. Introduced `ApplicationImpl.SetInstance(null)` to clear the application instance and added `CM.Disable(true)` to disable specific components. This change improves control over the reset process and ensures a more granular approach to application state management. * Improve null safety with ?. and ! operators Enhanced null safety across the codebase by introducing the null-conditional operator (`?.`) and null-forgiving operator (`!`) where appropriate. - Updated `app` and `driver` method calls to use `?.` to prevent potential `NullReferenceException` errors. - Added `!` to assert non-nullability in cases like `e.Value!.ToString()` and `app.Driver?.Contents!`. - Modified `lv.SelectedItemChanged` event handler to ensure safe handling of nullable values. - Updated `app.Shutdown()`, `app.LayoutAndDraw()`, and mouse event handling to use `?.`. - Ensured `driver.SetScreenSize` is invoked only when `driver` is not null. - Improved string concatenation logic with null-forgiving operator for `Contents`. - General improvements to null safety to make the code more robust and resilient to null references. * Improve Unicode tests and clarify surrogate pair handling Updated `WindowsKeyConverterTests` to enhance readability, improve test data, and clarify comments. Key changes include: - Reformatted `[Collection]` and `[Trait]` attributes for consistency. - Replaced placeholder Unicode characters with meaningful examples: - Chinese: `中`, Japanese: `日`, Korean: `한`, Accented: `é`, Euro: `€`, Greek: `Ω`. - Updated comments to replace placeholder emojis (`??`) with `😀` (U+1F600) for clarity. - Adjusted surrogate pair test data to accurately reflect `😀`. - Improved documentation of current limitations and future fixes for surrogate pair handling. These changes ensure more accurate and meaningful test cases while improving code clarity. * Ensure platform-specific test execution on Windows Added `System.Runtime.InteropServices` and `Xunit.Sdk` namespaces to `WindowsKeyConverterTests.cs` to support platform checks and test setup. Marked the test class with `[Collection("Global Test Setup")]` to enable shared test setup. Updated the `ToKey_NumPadKeys_ReturnsExpectedKeyCode` method to include a platform check, ensuring the test only runs on Windows platforms. * Integrate TrueColor support into ColorPicker Merged TrueColors functionality into ColorPicker, enhancing the scenario with TrueColor demonstration and gradient features. Updated `ColorPicker.cs` to include driver information, TrueColor support indicators, and a toggle for `Force16Colors`. Removed `TrueColors.cs` as its functionality is now consolidated. Refined `ColorBar` to use dynamic height with `Dim.Auto` for better flexibility. Added documentation to `HueBar` to clarify its role in representing the Hue component in HSL color space. * Revert workflow change. * Reverted attribute that didn't actualy work.
Terminal.Gui UI Catalog
UI Catalog is a comprehensive sample library for Terminal.Gui. It attempts to satisfy the following goals:
- Be an easy-to-use showcase for Terminal.Gui concepts and features.
- Provide sample code that illustrates how to properly implement said concepts & features.
- Make it easy for contributors to add additional samples in a structured way.
Motivation
The original demo.cs sample app for Terminal.Gui is neither good to showcase, nor does it explain different concepts. In addition, because it is built on a single source file, it has proven to cause friction when multiple contributors are simultaneously working on different aspects of Terminal.Gui.
See Issue #368 for more background.
API Reference
How To Use
Build and run UI Catalog by typing dotnet run from the UI Catalog folder or by using the Terminal.Gui Visual Studio solution.
Program.cs is the main UI Catalog app and provides a UI for selecting and running Scenarios. Each *Scenario is implemented as a class derived from Scenario and Program.cs uses reflection to dynamically build the UI.
Scenarios are tagged with categories using the [ScenarioCategory] attribute. The left pane of the main screen lists the categories. Clicking on a category shows all the scenarios in that category.
Scenarios can be run either from the UICatalog.exe app UI or by being specified on the command line:
UICatalog.exe <Scenario Name>
e.g.
UICatalog.exe Buttons
Hitting ENTER on a selected Scenario or double-clicking on a Scenario runs that scenario as though it were a stand-alone Terminal.Gui app.
When a Scenario is run, it runs as though it were a standalone Terminal.Gui app. However, scaffolding is provided (in the Scenario base class) that (optionally) takes care of Terminal.Gui initialization.
Contributing by Adding Scenarios
To add a new Scenario simply:
- Create a new
.csfile in theScenariosdirectory that derives fromScenario. - Add a
[ScenarioMetaData]attribute to the class specifying the scenario's name and description. - Add one or more
[ScenarioCategory]attributes to the class specifying which categories the sceanrio belongs to. If you don't specify a category the sceanrio will show up in "All". - Implement the
Setupoverride which will be called when a user selects the scenario to run. - Optionally, implement the
Initand/orRunoverrides to provide a custom implementation.
The sample below is provided in the .\UICatalog\Scenarios directory as a generic sample that can be copied and re-named:
namespace UICatalog {
[ScenarioMetadata (Name: "Generic", Description: "Generic sample - A template for creating new Scenarios")]
[ScenarioCategory ("Controls")]
class MyScenario : Scenario {
public override void Setup ()
{
// Put your scenario code here, e.g.
Win.Add (new Button () {
Text = "Press me!",
X = Pos.Center (),
Y = Pos.Center (),
Clicked = () => MessageBox.Query (20, 7, "Hi", "Neat?", "Yes", "No")
});
}
}
}
Scenario provides Win, a Window object that provides a canvas for the Scenario to operate.
The default Window shows the Scenario name and supports exiting the Scenario through the Esc key.
To build a more advanced scenario, where control of the Toplevel and Window is needed (e.g. for scenarios using MenuBar or StatusBar), simply use Application.Top per normal Terminal.Gui programming, as seen in the Notepad scenario.
For complete control, the Init and Run overrides can be implemented. The base.Init creates Win. The base.Run simply calls Application.Run(Application.Top).
Contribution Guidelines
- Provide a terse, descriptive
NameforScenarios. Keep them short. - Provide a clear
Description. - Comment
Scenariocode to describe to others why it's a usefulScenario. - Annotate
Scenarioswith[ScenarioCategory]attributes. Minimize the number of new categories created. - Use the
Bug RepoCategory forScenariosthat reproduce bugs.- Include the Github Issue # in the Description.
- Once the bug has been fixed in
developsubmit another PR to remove theScenario(or modify it to provide a good regression test/sample).
- Tag bugs or suggestions for
UI CatalogasTerminal.GuiGithub Issues with "UICatalog: ".

