Browse Source

Merge branch 'v2_develop' into copilot/fix-3ee850b1-eb6b-46b0-964b-3b98d2c0c14e

Tig 1 month ago
parent
commit
5aecf4bf84
41 changed files with 690 additions and 988 deletions
  1. 2 45
      .cursorrules
  2. 123 24
      .github/ISSUE_TEMPLATE/bug_report.md
  3. 3 325
      .github/copilot-instructions.md
  4. 10 175
      AGENTS.md
  5. 344 159
      CONTRIBUTING.md
  6. 1 1
      README.md
  7. 4 56
      Terminal.Gui/App/Application.Run.cs
  8. 34 68
      Terminal.Gui/README.md
  9. 10 10
      Terminal.Gui/ViewBase/Adornment/ShadowView.cs
  10. 1 1
      Terminal.Gui/ViewBase/View.Drawing.cs
  11. 3 0
      Terminal.Gui/ViewBase/View.cs
  12. 1 1
      Terminal.Gui/Views/Color/ColorBar.cs
  13. 4 4
      Terminal.Gui/Views/FileDialogs/FileDialog.cs
  14. 1 1
      Terminal.Gui/Views/GraphView/GraphView.cs
  15. 1 1
      Terminal.Gui/Views/GraphView/IAnnotation.cs
  16. 2 2
      Terminal.Gui/Views/GraphView/TextAnnotation.cs
  17. 3 3
      Terminal.Gui/Views/ListView.cs
  18. 18 20
      Terminal.Gui/Views/Menuv1/Menu.cs
  19. 1 1
      Terminal.Gui/Views/Menuv1/MenuBar.cs
  20. 4 4
      Terminal.Gui/Views/ProgressBar.cs
  21. 1 1
      Terminal.Gui/Views/RadioGroup.cs
  22. 2 2
      Terminal.Gui/Views/Slider/Slider.cs
  23. 1 1
      Terminal.Gui/Views/SpinnerView/SpinnerView.cs
  24. 19 20
      Terminal.Gui/Views/TableView/TableView.cs
  25. 1 1
      Terminal.Gui/Views/TableView/TreeTableSource.cs
  26. 3 3
      Terminal.Gui/Views/TextInput/TextField.cs
  27. 4 4
      Terminal.Gui/Views/TextInput/TextValidateField.cs
  28. 1 1
      Terminal.Gui/Views/TreeView/Branch.cs
  29. 3 3
      Terminal.Gui/Views/TreeView/TreeView.cs
  30. 3 2
      Terminal.sln
  31. 1 1
      Tests/UnitTests/Application/ApplicationTests.cs
  32. 9 13
      Tests/UnitTests/Dialogs/WizardTests.cs
  33. 2 2
      Tests/UnitTests/View/Adornment/BorderTests.cs
  34. 3 3
      Tests/UnitTests/View/Draw/ClearViewportTests.cs
  35. 6 6
      Tests/UnitTests/Views/LabelTests.cs
  36. 8 9
      Tests/UnitTests/Views/Menuv1/MenuBarv1Tests.cs
  37. 2 2
      Tests/UnitTests/Views/TextViewTests.cs
  38. 2 0
      docfx/docs/View.md
  39. 23 7
      docfx/docs/drivers.md
  40. 22 2
      docfx/docs/migratingfromv1.md
  41. 4 4
      docfx/docs/multitasking.md

+ 2 - 45
.cursorrules

@@ -1,48 +1,5 @@
 # Terminal.Gui - Cursor AI Rules
 # Terminal.Gui - Cursor AI Rules
 
 
-This project uses comprehensive AI agent instructions. See:
-- `.github/copilot-instructions.md` - Complete onboarding guide (primary reference)
-- `AGENTS.md` - General AI agent guidelines
+> **📘 Source of Truth: [CONTRIBUTING.md](CONTRIBUTING.md)**
 
 
-## Quick Reference
-
-### Project Type
-- .NET 8.0 cross-platform console UI toolkit
-- 496 source files in core library
-- GitFlow branching (v2_develop = default)
-
-### Essential Commands
-
-```bash
-# Always run from repo root in this order:
-dotnet restore                                              # First! (~15-20s)
-dotnet build --configuration Debug --no-restore            # ~50s, expect ~326 warnings
-dotnet test Tests/UnitTestsParallelizable --no-build       # Preferred test suite
-dotnet run --project Examples/UICatalog/UICatalog.csproj   # Demo app
-```
-
-### Code Style (Enforced)
-- **DO**: Use explicit types (avoid `var`), target-typed `new()`, 4-space indent
-- **DO**: Format only files you modify (ReSharper/Rider `Ctrl-E-C` or `Ctrl-K-D`)
-- **DO**: Follow `.editorconfig` and `Terminal.sln.DotSettings`
-- **DON'T**: Add new linters, modify unrelated code, decrease test coverage
-
-### Testing Rules
-- Add new tests to `Tests/UnitTestsParallelizable/` (preferred)
-- Avoid `Application.Init` and static dependencies in tests
-- Don't use `[AutoInitShutdown]` attribute (legacy)
-- Maintain 70%+ code coverage on new code
-
-### API Documentation (Required)
-- All public APIs need XML docs (`<summary>`, `<remarks>`, `<example>`)
-- Use `<see cref=""/>` for cross-references
-- Complex topics → `docfx/docs/*.md`
-
-### Common Issues
-- ~326 build warnings are normal (nullable refs, etc.)
-- Tests can take 5-10 minutes
-- Run `dotnet restore` before any build
-- Read `.github/copilot-instructions.md` for full troubleshooting
-
----
-**See `.github/copilot-instructions.md` for complete instructions**
+This project uses [CONTRIBUTING.md](CONTRIBUTING.md) as the single source of truth for contribution guidelines. AI agents, including CoPilot and Cursor **MUST** follow the guidelines in [CONTRIBUTING.md](CONTRIBUTING.md)/

+ 123 - 24
.github/ISSUE_TEMPLATE/bug_report.md

@@ -1,41 +1,140 @@
 ---
 ---
 name: Bug report
 name: Bug report
-about: Create a report to help us improve
+about: Create a report to help us improve Terminal.Gui
 title: ''
 title: ''
 labels: bug
 labels: bug
 assignees: ''
 assignees: ''
 
 
 ---
 ---
 
 
-**Describe the bug**
+## Describe the bug
+
 A clear and concise description of what the bug is.
 A clear and concise description of what the bug is.
 
 
-**To Reproduce**
+## To Reproduce
+
 Steps to reproduce the behavior:
 Steps to reproduce the behavior:
-1. Go to '...'
-2. Click on '....'
-3. Scroll down to '....'
-4. See error
 
 
-**Expected behavior**
-A clear and concise description of what you expected to happen.
+1. Run the following code:
+   ```csharp
+   // Paste your minimal reproduction code here
+   ```
+
+2. Expected behavior: (describe what should happen)
+
+3. Actual behavior: (describe what actually happens)
+
+## Environment
+
+Please run the following commands in your terminal and paste the output:
+
+### OS Information
+
+**Windows (PowerShell):**
+```powershell
+"OS: $(Get-CimInstance Win32_OperatingSystem | Select-Object -ExpandProperty Caption) $(Get-CimInstance Win32_OperatingSystem | Select-Object -ExpandProperty Version)"
+```
+
+**macOS/Linux:**
+```bash
+echo "OS: $(uname -s) $(uname -r)"
+```
+
+**Output:**
+```
+(paste output here)
+```
+
+### Terminal Information
+
+**Windows Terminal:**
+```powershell
+"Terminal: Windows Terminal $(Get-AppxPackage -Name Microsoft.WindowsTerminal | Select-Object -ExpandProperty Version)"
+```
+
+**Other terminals:**
+```bash
+echo $TERM
+```
+
+**Output:**
+```
+(paste output here)
+```
+
+### PowerShell Version
+
+```powershell
+$PSVersionTable.PSVersion
+```
+
+**Output:**
+```
+(paste output here)
+```
+
+### .NET Information
+
+```bash
+dotnet --version
+dotnet --info
+```
+
+**Output:**
+```
+(paste output here)
+```
+
+### Terminal.Gui Version
+
+**Option 1 - Run UICatalog (easiest):**
+
+UICatalog displays the Terminal.Gui version in its About box and status bar.
+
+```bash
+dotnet run --project Examples/UICatalog/UICatalog.csproj
+```
+
+**Option 2 - NuGet Package Version:**
+```
+(e.g., 2.0.0-alpha.1, 2.0.0-develop.123, etc.)
+```
+
+**Option 3 - Building from source:**
+```bash
+git rev-parse HEAD
+git describe --tags --always --dirty
+```
+
+**Version:**
+```
+(paste version here)
+```
+
+## Screenshots, GIFs, or Terminal Output
+
+If applicable, add screenshots, animated GIFs, or copy/paste terminal output to help explain your problem.
+
+**Animated GIFs are especially helpful for showing behavior!**
+
+- **Windows**: [ShareX](https://getsharex.com/) (free, captures screen to GIF)
+- **macOS**: [Kap](https://getkap.co/) (free, open source)
+- **Linux**: [Peek](https://github.com/phw/peek) (free)
+
+**For terminal output, use code blocks:**
 
 
-**Screenshots**
-If applicable, add screenshots to help explain your problem.
+```
+(paste terminal output here)
+```
 
 
-**Desktop (please complete the following information):**
- - OS: [e.g. iOS]
- - Browser [e.g. chrome, safari]
- - Version [e.g. 22]
+## Additional context
 
 
-**Smartphone (please complete the following information):**
- - Device: [e.g. iPhone6]
- - OS: [e.g. iOS8.1]
- - Browser [e.g. stock browser, safari]
- - Version [e.g. 22]
+Add any other context about the problem here, such as:
+- Does this happen consistently or intermittently?
+- Did this work in a previous version?
+- Are there any error messages in the console?
+- Terminal configuration or settings that might be relevant?
 
 
-**Additional context**
-Add any other context about the problem here.
+## For Maintainers
 
 
-**Set Project & Milestone**
-If you have access, please don't forget to set the right Project and Milestone.
+**Set Project & Milestone:** If you have access, please don't forget to set the right Project and Milestone.

+ 3 - 325
.github/copilot-instructions.md

@@ -1,327 +1,5 @@
-# Terminal.Gui - Copilot Coding Agent Instructions
+# Terminal.Gui - CoPilot AI Rules
 
 
-This file provides onboarding instructions for GitHub Copilot and other AI coding agents working with Terminal.Gui.
+> **📘 Source of Truth: [CONTRIBUTING.md](CONTRIBUTING.md)**
 
 
-## Project Overview
-
-**Terminal.Gui** is a cross-platform UI toolkit for creating console-based graphical user interfaces in .NET. It's a large codebase (~1,050 C# files, 333MB) providing a comprehensive framework for building interactive console applications with support for keyboard and mouse input, customizable views, and a robust event system.
-
-**Key characteristics:**
-- **Language**: C# (net8.0)
-- **Size**: ~496 source files in core library, ~1,050 total C# files
-- **Platform**: Cross-platform (Windows, macOS, Linux)
-- **Architecture**: Console UI toolkit with driver-based architecture
-- **Version**: v2 (Alpha), v1 (maintenance mode)
-- **Branching**: GitFlow model (v2_develop is default/active development)
-
-## Building and Testing
-
-### Required Tools
-- **.NET SDK**: 8.0.0 (see `global.json`)
-- **Runtime**: .NET 8.x (latest GA)
-- **Optional**: ReSharper/Rider for code formatting
-
-### Build Commands (In Order)
-
-**ALWAYS run these commands from the repository root:**
-
-1. **Restore packages** (required first, ~15-20 seconds):
-   ```bash
-   dotnet restore
-   ```
-
-2. **Build solution** (Debug, ~50 seconds):
-   ```bash
-   dotnet build --configuration Debug --no-restore
-   ```
-   - Expect ~326 warnings (nullable reference warnings, unused variables, etc.) - these are normal
-   - 0 errors expected
-
-3. **Build Release** (for packaging):
-   ```bash
-   dotnet build --configuration Release --no-restore
-   ```
-
-### Test Commands
-
-**Two test projects exist:**
-
-1. **Non-parallel tests** (depend on static state, ~10 min timeout):
-   ```bash
-   dotnet test Tests/UnitTests --no-build --verbosity normal
-   ```
-   - Uses `Application.Init` and static state
-   - Cannot run in parallel
-   - Includes `--blame` flags for crash diagnostics
-
-2. **Parallel tests** (can run concurrently, ~10 min timeout):
-   ```bash
-   dotnet test Tests/UnitTestsParallelizable --no-build --verbosity normal
-   ```
-   - No dependencies on static state
-   - Preferred for new tests
-
-3. **Integration tests**:
-   ```bash
-   dotnet test Tests/IntegrationTests --no-build --verbosity normal
-   ```
-
-**Important**: Tests may take significant time. CI uses blame flags for crash detection:
-```bash
---diag:logs/UnitTests/logs.txt --blame --blame-crash --blame-hang --blame-hang-timeout 60s --blame-crash-collect-always
-```
-
-### Running Examples
-
-**UICatalog** (comprehensive demo app):
-```bash
-dotnet run --project Examples/UICatalog/UICatalog.csproj
-```
-
-## Repository Structure
-
-### Root Directory Files
-- `Terminal.sln` - Main solution file
-- `Terminal.sln.DotSettings` - ReSharper code style settings
-- `.editorconfig` - Code formatting rules (111KB, extensive)
-- `global.json` - .NET SDK version pinning
-- `Directory.Build.props` - Common MSBuild properties
-- `Directory.Packages.props` - Central package version management
-- `GitVersion.yml` - Version numbering configuration
-- `AGENTS.md` - General AI agent instructions (also useful reference)
-- `CONTRIBUTING.md` - Contribution guidelines
-- `README.md` - Project documentation
-
-### Main Directories
-
-**`/Terminal.Gui/`** - Core library (496 C# files):
-- `App/` - Application lifecycle (`Application.cs` static class, `RunState`, `MainLoop`)
-- `Configuration/` - `ConfigurationManager` for settings
-- `Drivers/` - Console driver implementations (`IConsoleDriver`, `NetDriver`, `UnixDriver`, `WindowsDriver`)
-- `Drawing/` - Rendering system (attributes, colors, glyphs)
-- `Input/` - Keyboard and mouse input handling
-- `ViewBase/` - Core `View` class hierarchy and layout
-- `Views/` - Specific View subclasses (Window, Dialog, Button, ListView, etc.)
-- `Text/` - Text manipulation and formatting
-
-**`/Tests/`**:
-- `UnitTests/` - Non-parallel tests (use `Application.Init`, static state)
-- `UnitTestsParallelizable/` - Parallel tests (no static dependencies)
-- `IntegrationTests/` - Integration tests
-- `StressTests/` - Long-running stress tests (scheduled daily)
-- `coverlet.runsettings` - Code coverage configuration
-
-**`/Examples/`**:
-- `UICatalog/` - Comprehensive demo app for manual testing
-- `Example/` - Basic example
-- `NativeAot/`, `SelfContained/` - Deployment examples
-- `ReactiveExample/`, `CommunityToolkitExample/` - Integration examples
-
-**`/docfx/`** - Documentation source:
-- `docs/` - Conceptual documentation (deep dives)
-- `api/` - Generated API docs (gitignored)
-- `docfx.json` - DocFX configuration
-
-**`/Scripts/`** - PowerShell build utilities (requires PowerShell 7.4+)
-
-**`/.github/workflows/`** - CI/CD pipelines:
-- `unit-tests.yml` - Main test workflow (Ubuntu, Windows, macOS)
-- `build-release.yml` - Release build verification
-- `integration-tests.yml` - Integration test workflow
-- `publish.yml` - NuGet package publishing
-- `api-docs.yml` - Documentation building and deployment
-- `codeql-analysis.yml` - Security scanning
-
-## Code Style and Quality
-
-### Formatting
-- **Do NOT add formatting tools** - Use existing `.editorconfig` and `Terminal.sln.DotSettings`
-- Format code with:
-  1. ReSharper/Rider (`Ctrl-E-C`)
-  2. JetBrains CleanupCode CLI tool (free)
-  3. Visual Studio (`Ctrl-K-D`) as fallback
-- **Only format files you modify**
-
-### Code Style Tenets
-1. **Six-Year-Old Reading Level** - Readability over terseness
-2. **Consistency, Consistency, Consistency** - Follow existing patterns ruthlessly
-3. **Don't be Weird** - Follow Microsoft/.NET conventions
-4. **Set and Forget** - Rely on automated tooling
-5. **Documentation is the Spec** - API docs are source of truth
-
-### Coding Conventions
-
-**⚠️ CRITICAL - These rules MUST be followed in ALL new code:**
-
-#### Type Declarations and Object Creation
-- **ALWAYS use explicit types** - Never use `var` except for basic types (`int`, `string`, `bool`, `double`, `float`, `decimal`, `char`, `byte`)
-  ```csharp
-  // ✅ CORRECT - Explicit types
-  View view = new () { Width = 10 };
-  MouseEventArgs args = new () { Position = new Point(5, 5) };
-  List<View?> views = new ();
-  var count = 0;  // OK - int is a basic type
-  var name = "test";  // OK - string is a basic type
-  
-  // ❌ WRONG - Using var for non-basic types
-  var view = new View { Width = 10 };
-  var args = new MouseEventArgs { Position = new Point(5, 5) };
-  var views = new List<View?>();
-  ```
-
-- **ALWAYS use target-typed `new()`** - Use `new ()` instead of `new TypeName()` when the type is already declared
-  ```csharp
-  // ✅ CORRECT - Target-typed new
-  View view = new () { Width = 10 };
-  MouseEventArgs args = new ();
-  
-  // ❌ WRONG - Redundant type name
-  View view = new View() { Width = 10 };
-  MouseEventArgs args = new MouseEventArgs();
-  ```
-
-#### Other Conventions
-- Follow `.editorconfig` settings (e.g., braces on new lines, spaces after keywords)
-- 4-space indentation
-- No trailing whitespace
-- See `CONTRIBUTING.md` for full guidelines
-
-**These conventions apply to ALL code - production code, test code, examples, and samples.**
-
-## Testing Requirements
-
-### Code Coverage
-- **Never decrease code coverage** - PRs must maintain or increase coverage
-- Target: 70%+ coverage for new code
-- CI monitors coverage on each PR
-
-### Test Patterns
-- **Parallelizable tests preferred** - Add new tests to `UnitTestsParallelizable` when possible
-- **Avoid static dependencies** - Don't use `Application.Init`, `ConfigurationManager` in tests
-- **Don't use `[AutoInitShutdown]`** - Legacy pattern, being phased out
-- **Make tests granular** - Each test should cover smallest area possible
-- Follow existing test patterns in respective test projects
-
-### Test Configuration
-- `xunit.runner.json` - xUnit configuration
-- `coverlet.runsettings` - Coverage settings (OpenCover format)
-
-## API Documentation Requirements
-
-**All public APIs MUST have XML documentation:**
-- Clear, concise `<summary>` tags
-- Use `<see cref=""/>` for cross-references
-- Add `<remarks>` for context
-- Include `<example>` for non-obvious usage
-- Complex topics → `docfx/docs/*.md` files
-- Proper English and grammar
-
-## Common Build Issues
-
-### Issue: Build Warnings
-- **Expected**: ~326 warnings (nullable refs, unused vars, xUnit suggestions)
-- **Action**: Don't add new warnings; fix warnings in code you modify
-
-### Issue: Test Timeouts
-- **Expected**: Tests can take 5-10 minutes
-- **Action**: Use appropriate timeout values (60-120 seconds for test commands)
-
-### Issue: Restore Failures
-- **Solution**: Ensure `dotnet restore` completes before building
-- **Note**: Takes 15-20 seconds on first run
-
-### Issue: NativeAot/SelfContained Build
-- **Solution**: Restore these projects explicitly:
-  ```bash
-  dotnet restore ./Examples/NativeAot/NativeAot.csproj -f
-  dotnet restore ./Examples/SelfContained/SelfContained.csproj -f
-  ```
-
-## CI/CD Validation
-
-The following checks run on PRs:
-
-1. **Unit Tests** (`unit-tests.yml`):
-   - Runs on Ubuntu, Windows, macOS
-   - Both parallel and non-parallel test suites
-   - Code coverage collection
-   - 10-minute timeout per job
-
-2. **Build Release** (`build-release.yml`):
-   - Verifies Release configuration builds
-   - Tests NativeAot and SelfContained builds
-   - Packs NuGet package
-
-3. **Integration Tests** (`integration-tests.yml`):
-   - Cross-platform integration testing
-   - 10-minute timeout
-
-4. **CodeQL Analysis** (`codeql-analysis.yml`):
-   - Security vulnerability scanning
-
-To replicate CI locally:
-```bash
-# Full CI sequence:
-dotnet restore
-dotnet build --configuration Debug --no-restore
-dotnet test Tests/UnitTests --no-build --verbosity normal
-dotnet test Tests/UnitTestsParallelizable --no-build --verbosity normal
-dotnet build --configuration Release --no-restore
-```
-
-## Branching and PRs
-
-### GitFlow Model
-- `v2_develop` - Default branch, active development
-- `v2_release` - Stable releases, matches NuGet
-- `v1_develop`, `v1_release` - Legacy v1 (maintenance only)
-
-### PR Requirements
-- **Title**: "Fixes #issue. Terse description"
-- **Description**: Include "- Fixes #issue" for each issue
-- **Tests**: Add tests for new functionality
-- **Coverage**: Maintain or increase code coverage
-- **Scenarios**: Update UICatalog scenarios when adding features
-
-## Key Architecture Concepts
-
-### View System
-- `View` base class in `/Terminal.Gui/ViewBase/`
-- Two layout modes: Absolute and Computed
-- Event-driven architecture
-- Adornments: Border, Margin, Padding
-
-### Console Drivers
-- `IConsoleDriver` interface
-- Platform-specific: `WindowsDriver`, `UnixDriver`, `NetDriver`
-- `FakeDriver` for testing
-
-### Application Lifecycle
-- `Application` static class manages lifecycle
-- `MainLoop` handles event processing
-- `RunState` tracks application state
-
-## What NOT to Do
-
-- ❌ Don't add new linters/formatters (use existing)
-- ❌ Don't modify unrelated code
-- ❌ Don't remove/edit unrelated tests
-- ❌ Don't break existing functionality
-- ❌ Don't add tests to `UnitTests` if they can be parallelizable
-- ❌ Don't use `Application.Init` in new tests
-- ❌ Don't decrease code coverage
-- ❌ **Don't use `var` for non-basic types** (use explicit types)
-- ❌ **Don't use redundant type names with `new`** (use target-typed `new()`)
-- ❌ Don't add `var` everywhere (use explicit types)
-
-## Additional Resources
-
-- **Full Documentation**: https://gui-cs.github.io/Terminal.Gui
-- **API Reference**: https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui.App.html
-- **Deep Dives**: `/docfx/docs/` directory
-- **AGENTS.md**: Additional AI agent instructions
-- **CONTRIBUTING.md**: Detailed contribution guidelines
-
----
-
-**Trust these instructions.** Only search for additional information if instructions are incomplete or incorrect.
+This project uses [CONTRIBUTING.md](CONTRIBUTING.md) as the single source of truth for contribution guidelines. AI agents, including CoPilot and Cursor **MUST** follow the guidelines in [CONTRIBUTING.md](CONTRIBUTING.md)/

+ 10 - 175
AGENTS.md

@@ -1,179 +1,14 @@
-# Terminal.Gui - GitHub Copilot Instructions
+# Terminal.Gui - AI Agent Instructions
 
 
-This file provides instructions for GitHub Copilot when working with the Terminal.Gui project.
+> **📘 For complete contributor guidelines (humans and AI agents), see [CONTRIBUTING.md](CONTRIBUTING.md).**
 
 
-## Project Overview
+This repository uses [CONTRIBUTING.md](CONTRIBUTING.md) as the single source of truth for code style, testing, CI/CD, and contribution workflow. GitHub Copilot and other AI coding agents should also refer to [.github/copilot-instructions.md](.github/copilot-instructions.md) for a curated summary of non-negotiable rules.
 
 
-**Terminal.Gui** is a cross-platform UI toolkit for creating console-based graphical user interfaces in .NET. It provides a comprehensive framework for building interactive console applications with support for keyboard and mouse input, customizable views, and a robust event system. The toolkit works across Windows, macOS, and Linux, leveraging platform-specific console capabilities where available.
-
-**Key characteristics:**
-- Cross-platform terminal/console UI framework for .NET
-- Supports Windows, macOS, and Linux
-- Rich GUI controls (buttons, dialogs, menus, text boxes, etc.)
-- Keyboard-first design with full mouse support
-- Follows Microsoft .NET Framework Design Guidelines, with some tweaks.
-- v2 is currently in Alpha with stable core API (v1 is in maintenance mode)
-
-## Documentation
-
-- Full documentation: [gui-cs.github.io/Terminal.Gui](https://gui-cs.github.io/Terminal.Gui)
-- API Reference: [API Documentation](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui.App.html)
-- Getting Started: [Getting Started Guide](https://gui-cs.github.io/Terminal.Gui/docs/getting-started)
-
-## Repository Structure
-
-- `/Terminal.Gui/` - Core library source code
-  - `App/` - Core application logic, `Application.cs` (static class managing `RunState` and `MainLoop`)
-  - `Configuration/` - `ConfigurationManager` for application settings
-  - `Drivers/` - Console driver implementations (`IConsoleDriver.cs`, `NetDriver`, `UnixDriver`, `WindowsDriver`)
-  - `Drawing/` - Rendering graphical elements in the console
-  - `Input/` - Keyboard and mouse input handling
-  - `View/` - Core `View` class hierarchy
-  - `Views/` - Specific sub-classes of `View` (Toplevel, Window, Dialog, etc.)
-- `/Examples/` - Sample applications and demos
-- `/Examples/UICatalog/` - Comprehensive demo app for manual testing
-- `/Tests/` - Unit and integration tests
-- `/docfx/` - Documentation source files (Deep Dive Articles and API docs)
-- `/Scripts/` - Build and utility scripts
-
-## Branching Model
-
-**Terminal.Gui uses GitFlow:**
-- `v2_develop` - Default branch for v2 development (active development)
-- `v2_release` - Stable release branches matching NuGet packages
-
-## Code Style and Standards
-
-### Code Style Tenets
-
-1. **Six-Year-Old Reading Level** - Prioritize readability over terseness. Use clear variable names and comments.
-2. **Consistency, Consistency, Consistency** - Follow established patterns ruthlessly.
-3. **Don't be Weird** - Follow Microsoft and .NET community conventions.
-4. **Set and Forget** - Use ReSharper/Rider for automated formatting.
-5. **Documentation is the Spec** - API documentation is the source of truth.
-
-### Coding Conventions
-
-- Based on [Microsoft C# Coding Conventions](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions)
-- Project settings defined and enforced via `./Terminal.sln.DotSettings` and `./.editorconfig`
-- Use `var` only for the most basic dotnet types - prefer explicit types for clarity
-- Use target-typed new
-
-## API Design Guidelines
-
-### Public API Tenets
-
-1. **Stand on the shoulders of giants** - Follow [Microsoft .NET Framework Design Guidelines](https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/)
-2. **Don't Break Existing Stuff** - Avoid breaking changes; find compatible ways to add features
-3. **Fail-fast** - Prefer early failure to expose bugs sooner
-4. **Standards Reduce Complexity** - Use standard .NET idioms, tweaked to match Terminal.Gui. 
-
-### API Documentation Requirements
-
-**All public APIs must have XML documentation:**
-- Clear, concise, and complete `<summary>` tags
-- Use `<see cref=""/>` liberally for cross-references
-- Add `<remarks>` for context and detailed explanations
-- Document complex topics in `docfx/articles/*.md` files
-- Use proper English and correct grammar
-- Provide sample code via `<example>` in cases where a sample is needed (not for very obvious things)
-
-### Events
-
-- Follow the [Events Deep Dive](https://gui-cs.github.io/Terminal.Gui/docs/events.html) documentation
-- Use the Cancellable Work Pattern for user-initiated actions
-- Use the CWPHelpers if possible
-- Name event handlers consistently (e.g., `On[EventName]`), following dotnet guidelines.
-
-## User Experience Tenets
-
-1. **Honor What's Come Before** - Follow established Mac/Windows GUI idioms (e.g., `Ctrl-C` for copy)
-2. **Consistency Matters** - Common UI patterns should be consistent (e.g., `Ctrl-Q` quits modals)
-3. **Honor the OS, but Work Everywhere** - Take advantage of platform capabilities while maintaining cross-platform support
-4. **Keyboard first, Mouse also** - Optimize for keyboard, but ensure everything also works with mouse
-
-## Testing
-
-### Unit Test Requirements
-
-- **Never decrease code coverage** - Aim for 70%+ coverage on new code
-- Write unit tests for all new functionality
-- Follow existing test patterns in `/Tests/`
-- Many existing unit tests are obtuse and not really unit tests. Anytime new tests are added or updated, strive to refactor the tests into more granular tests where each test covers the smallest area possible. 
-- Many existing unit tests in the `./Tests/UnitTests` project incorrectly require `Application.Init` and use `[AutoInitShutdown]`. Anytime new tests are added or updated, strive to remove these dependencies and make the tests parallelizable. This means not taking any dependency on static objects like `Application` and `ConfigurationManager`. 
-
-## Pull Request Guidelines
-
-- Titles should be of the form "Fixes #issue. Terse description." 
-- If the PR addresses multiple issues, use "Fixes #issue1, #issue2. Terse description."
-- First comment should include "- Fixes #issue" for each issue addressed. If an issue is only partially addressed, use "Partially addresses #issue".
-- First comment should include a thorough description of the change and any impact. 
-- Put temporary .md files in `/docfx/docs/drafts/` and remove before merging.
-
-## Building and Running
-
-### Build the Solution
-```powershell
-dotnet build
-```
-
-### Run Tests
-```powershell
-dotnet test
-```
-
-## Key Concepts
-
-`./docfx/docs` contains a set of architectural and key-concept deep-dives. 
-
-## Additional Guidelines
-1. Maintain existing code structure and organization unless explicitly told
-2. View sub-classes must not use private APIs
-3. Suggest changes to the `./docfx/docs/` folder when appropriate
-
-## Working with Pull Request Branches
-
-When creating PRs, include instructions at the end of each PR description for how to pull the branch down locally. Use the following template, adapted for the typical remote setup where `origin` points to the user's fork and `upstream` points to `gui-cs/Terminal.Gui`:
-
-```markdown
-## How to Pull This PR Branch Locally
-
-If you want to test or modify this PR locally, use one of these approaches based on your remote setup:
-
-### Method 1: Fetch from upstream (if branch exists there)
-```bash
-# Fetch the branch from upstream
-git fetch upstream <branch-name>
-
-# Switch to the branch
-git checkout <branch-name>
-
-# Make your changes, then commit them
-git add .
-git commit -m "Your commit message"
-
-# Push to your fork (origin)
-git push origin <branch-name>
-```
-
-### Method 2: Fetch by PR number
-```bash
-# Fetch the PR branch from upstream by PR number
-git fetch upstream pull/<PR_NUMBER>/head:<branch-name>
-
-# Switch to the branch
-git checkout <branch-name>
-
-# Make your changes, then commit them
-git add .
-git commit -m "Your commit message"
-
-# Push to your fork (origin)
-git push origin <branch-name>
-```
-
-The PR will automatically update when you push to the branch in your fork.
-```
-
-**Note:** Adjust the remote names if your setup differs (e.g., if `origin` points to `gui-cs/Terminal.Gui` and you have a separate remote for your fork).
+**Key highlights for AI agents:**
+- Always use explicit types (no `var` except for built-in simple types)
+- Always use target-typed `new()` syntax
+- Add new tests to `Tests/UnitTestsParallelizable/` when possible
+- Never decrease code coverage
+- Follow `.editorconfig` and `Terminal.sln.DotSettings` for formatting
 
 
+See [CONTRIBUTING.md](CONTRIBUTING.md) for complete details.

+ 344 - 159
CONTRIBUTING.md

@@ -1,234 +1,419 @@
 # Contributing to Terminal.Gui
 # Contributing to Terminal.Gui
 
 
-We welcome contributions from the community. See [Issues](https://github.com/gui-cs/Terminal.Gui/issues) for a list of open [bugs](https://github.com/gui-cs/Terminal.Gui/issues?q=is%3Aopen+is%3Aissue+label%3Abug) and [enhancements](https://github.com/gui-cs/Terminal.Gui/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement). Contributors looking for something fun to work on should look at issues tagged as:
+> **📘 This document is the single source of truth for all contributors (humans and AI agents) to Terminal.Gui.**
 
 
-- [good first issue](https://github.com/gui-cs/Terminal.Gui/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
-- [up for grabs](https://github.com/gui-cs/Terminal.Gui/issues?q=is%3Aopen+is%3Aissue+label%3Aup-for-grabs)
-- [help wanted](https://github.com/gui-cs/Terminal.Gui/issues?q=is%3Aopen+is%3Aissue+label%3Aup-for-grabs)
+Welcome! This guide provides everything you need to know to contribute effectively to Terminal.Gui, including project structure, build instructions, coding conventions, testing requirements, and CI/CD workflows.
 
 
-## Forking and Submitting Changes
+## Table of Contents
 
 
-Terminal.Gui uses the [GitFlow](https://nvie.com/posts/a-successful-git-branching-model/) branching model. 
+- [Project Overview](#project-overview)
+- [Building and Testing](#building-and-testing)
+- [Coding Conventions](#coding-conventions)
+- [Testing Requirements](#testing-requirements)
+- [API Documentation Requirements](#api-documentation-requirements)
+- [Pull Request Guidelines](#pull-request-guidelines)
+- [CI/CD Workflows](#cicd-workflows)
+- [Repository Structure](#repository-structure)
+- [Branching Model](#branching-model)
+- [Key Architecture Concepts](#key-architecture-concepts)
+- [What NOT to Do](#what-not-to-do)
+- [Additional Resources](#additional-resources)
 
 
-* The `v1_release` and `v2_release` branches are always stable, and always match the most recently released Nuget package.
-* The `v1_develop` and `v2_develop` branches are where new development and bug-fixes happen. `v2_develop` is the default Github branch.
+---
 
 
-### Forking Terminal.Gui
+## Project Overview
 
 
-1. Use GitHub to fork the `Terminal.Gui` repo to your account (https://github.com/gui-cs/Terminal.Gui/fork).
+**Terminal.Gui** is a cross-platform UI toolkit for creating console-based graphical user interfaces in .NET. It's a large codebase (~1,050 C# files, 333MB) providing a comprehensive framework for building interactive console applications with support for keyboard and mouse input, customizable views, and a robust event system.
 
 
-2. Clone your fork to your local machine
+**Key characteristics:**
+- **Language**: C# (net8.0)
+- **Size**: ~496 source files in core library, ~1,050 total C# files
+- **Platform**: Cross-platform (Windows, macOS, Linux)
+- **Architecture**: Console UI toolkit with driver-based architecture
+- **Version**: v2 (Alpha), v1 (maintenance mode)
+- **Branching**: GitFlow model (v2_develop is default/active development)
 
 
-```
-git clone https://github.com/<yourID>/Terminal.Gui
-```
+---
 
 
-Now, your local repo will have an `origin` remote pointing to `https://github.com/<yourID>/Terminal.Gui`.
+## Building and Testing
 
 
-3. Add a remote for `upstream`: 
-```
-git remote add upstream https://github.com/gui-cs/Terminal.Gui
-```
-You now have your own fork and a local repo that references it as `origin`. Your local repo also now references the orignal Terminal.Gui repo as `upstream`. 
+### Required Tools
 
 
-### Starting to Make a Change
+- **.NET SDK**: 8.0.0 (see `global.json`)
+- **Runtime**: .NET 8.x (latest GA)
+- **Optional**: ReSharper/Rider for code formatting (honor `.editorconfig` and `Terminal.sln.DotSettings`)
 
 
-Ensure your local `v1_develop` (for v1) or `v2_develop` (for v2) branch is up-to-date with `upstream` (`github.com/gui-cs/Terminal.Gui`):
-```powershell
-cd ./Terminal.Gui
-git checkout v2_develop
-git pull upstream v2_develop
-```
+### Build Commands (In Order)
 
 
-Create a new local branch:
-```powershell
-git checkout -b my_new_branch
-```
+**ALWAYS run these commands from the repository root:**
+
+1. **Restore packages** (required first, ~15-20 seconds):
+   ```bash
+   dotnet restore
+   ```
 
 
-### Making Changes
-Follow all the guidelines below.
+2. **Build solution** (Debug, ~50 seconds):
+   ```bash
+   dotnet build --configuration Debug --no-restore
+   ```
+   - Expect ~326 warnings (nullable reference warnings, unused variables, etc.) - these are normal
+   - 0 errors expected
 
 
-* [Coding Style](#TerminalGui-Coding-Style)
-* [Unit Tests](#Unit-Tests)
-* [Sample Code](#Sample-Code)
-* API Documentation
-* etc...
+3. **Build Release** (for packaging):
+   ```bash
+   dotnet build --configuration Release --no-restore
+   ```
 
 
-When you're ready, commit your changes:
+### Test Commands
 
 
-```powershell
-git add .
-git commit -m "Fixes #1234. Some bug"
-```
+**Two test projects exist:**
 
 
-### Submitting a Pull Request
+1. **Non-parallel tests** (depend on static state, ~10 min timeout):
+   ```bash
+   dotnet test Tests/UnitTests --no-build --verbosity normal
+   ```
+   - Uses `Application.Init` and static state
+   - Cannot run in parallel
+   - Includes `--blame` flags for crash diagnostics
+
+2. **Parallel tests** (can run concurrently, ~10 min timeout):
+   ```bash
+   dotnet test Tests/UnitTestsParallelizable --no-build --verbosity normal
+   ```
+   - No dependencies on static state
+   - **Preferred for new tests**
 
 
-1. Push your local branch to your fork (`origin`):
+3. **Integration tests**:
+   ```bash
+   dotnet test Tests/IntegrationTests --no-build --verbosity normal
+   ```
 
 
-```powershell
-git push --set-upstream origin my_new_branch
+**Important**: Tests may take significant time. CI uses blame flags for crash detection:
+```bash
+--diag:logs/UnitTests/logs.txt --blame --blame-crash --blame-hang --blame-hang-timeout 60s --blame-crash-collect-always
 ```
 ```
 
 
-2. Create the Pull Request:
+### Common Build Issues
+
+#### Issue: Build Warnings
+- **Expected**: ~326 warnings (nullable refs, unused vars, xUnit suggestions)
+- **Action**: Don't add new warnings; fix warnings in code you modify
+
+#### Issue: Test Timeouts
+- **Expected**: Tests can take 5-10 minutes
+- **Action**: Use appropriate timeout values (60-120 seconds for test commands)
+
+#### Issue: Restore Failures
+- **Solution**: Ensure `dotnet restore` completes before building
+- **Note**: Takes 15-20 seconds on first run
 
 
-In the output of the `git push` command you'll see instructions with a link to the Pull Request:
+#### Issue: NativeAot/SelfContained Build
+- **Solution**: Restore these projects explicitly:
+  ```bash
+  dotnet restore ./Examples/NativeAot/NativeAot.csproj -f
+  dotnet restore ./Examples/SelfContained/SelfContained.csproj -f
+  ```
 
 
-```powershell
- $ git push --set-upstream origin my_new_branch
-Enumerating objects: 8, done.
-...
-remote:
-remote: Create a pull request for 'my_new_branch' on GitHub by visiting:
-remote:      https://github.com/<yourID>/Terminal.Gui/pull/new/more_doc_fixes
-remote:
-...
+### Running Examples
+
+**UICatalog** (comprehensive demo app):
+```bash
+dotnet run --project Examples/UICatalog/UICatalog.csproj
 ```
 ```
 
 
-3. Go to that URL and create the Pull Request:
+---
 
 
-(in Windows Terminal, just CTRL-Click on the URL)
+## Coding Conventions
 
 
-Follow the template instructions found on Github.
+### Code Style Tenets
 
 
-## Tenets for [gui-cs](www.github.com/gui-cs) Code Style (Unless you have better ones)
+1. **Six-Year-Old Reading Level** - Readability over terseness
+2. **Consistency, Consistency, Consistency** - Follow existing patterns ruthlessly
+3. **Don't be Weird** - Follow Microsoft/.NET conventions
+4. **Set and Forget** - Rely on automated tooling
+5. **Documentation is the Spec** - API docs are source of truth
 
 
-* **Six-Year-Old Reading Level** - Our code style is biased towards code readability and away from terseness. This is *Systems Software* and needs to stand the test of time. Code should be structured and use variable names that make it readable by a 6-year-old, and comments in code are encouraged. 
-* **Consistency, Consistency, Consistency** - We adopt and document our standards for code style and then enforce them ruthlessly. For example, we require code reviews to pay attention to code style, not just functionality. 
-* **Don't be Weird** - Like all developers we have opinions, but our opinions on code style are tempered by existing standards. We are biased towards code style that used by Microsoft and other leading dotnet developers. For example, we choose 4 spaces for indentation instead of 8.
-* **Set and Forget** - We embrace and encourage the use of technology that makes it easy for contributors to apply best-practice code-style, such as ReSharper. As we do so we are mindful that tools can cause hidden issues and merge hell.
-* **Documentation is the Spec** - We care deeply about providing delightful developer documentation and are sticklers for grammar and clarity. If the code and the docs conflict, we are biased to believe what we wrote in the API documentation. This drives a virtuous cycle of clear thinking.
+### Code Formatting
 
 
-**Terminal.Gui** uses a derivative of the [Microsoft C# Coding Conventions](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions), with any deviations from those (somewhat older) conventions codified in the .editorconfig for the solution, as well as even more specific definitions in team-shared dotsettings files, used by ReSharper and Rider.\
+- **Do NOT add formatting tools** - Use existing `.editorconfig` and `Terminal.sln.DotSettings`
+- Format code with:
+  1. ReSharper/Rider (`Ctrl-E-C`)
+  2. JetBrains CleanupCode CLI tool (free)
+  3. Visual Studio (`Ctrl-K-D`) as fallback
+- **Only format files you modify**
 
 
-### Critical Coding Standards
+### Critical Coding Rules
 
 
-**⚠️ These rules MUST be followed in ALL new code (production, tests, examples, samples):**
+**⚠️ CRITICAL - These rules MUST be followed in ALL new or modified code:**
 
 
 #### Type Declarations and Object Creation
 #### Type Declarations and Object Creation
 
 
-1. **ALWAYS use explicit types** - Never use `var` except for basic types (`int`, `string`, `bool`, `double`, `float`, `decimal`, `char`, `byte`)
-
-   ```csharp
-   // ✅ CORRECT - Explicit types
-   View view = new () { Width = 10 };
-   MouseEventArgs args = new () { Position = new Point(5, 5) };
-   List<View?> views = new ();
-   var count = 0;  // OK - int is a basic type
-   var name = "test";  // OK - string is a basic type
-   
-   // ❌ WRONG - Using var for non-basic types
-   var view = new View { Width = 10 };
-   var args = new MouseEventArgs { Position = new Point(5, 5) };
-   var views = new List<View?>();
-   ```
-
-2. **ALWAYS use target-typed `new()`** - Use `new ()` instead of `new TypeName()` when the type is already declared
+- **ALWAYS use explicit types** - Never use `var` except for built-in simple types (`int`, `string`, `bool`, `double`, `float`, `decimal`, `char`, `byte`)
+  ```csharp
+  // ✅ CORRECT - Explicit types
+  View view = new () { Width = 10 };
+  MouseEventArgs args = new () { Position = new Point(5, 5) };
+  List<View?> views = new ();
+  var count = 0;  // OK - int is a built-in type
+  var name = "test";  // OK - string is a built-in type
+  
+  // ❌ WRONG - Using var for non-built-in types
+  var view = new View { Width = 10 };
+  var args = new MouseEventArgs { Position = new Point(5, 5) };
+  var views = new List<View?>();
+  ```
+
+- **ALWAYS use target-typed `new()`** - Use `new ()` instead of `new TypeName()` when the type is already declared
+  ```csharp
+  // ✅ CORRECT - Target-typed new
+  View view = new () { Width = 10 };
+  MouseEventArgs args = new ();
+  
+  // ❌ WRONG - Redundant type name
+  View view = new View() { Width = 10 };
+  MouseEventArgs args = new MouseEventArgs();
+  ```
+
+#### Other Conventions
+
+- Follow `.editorconfig` settings (e.g., braces on new lines, spaces after keywords)
+- 4-space indentation
+- No trailing whitespace
+- File-scoped namespaces
+
+**⚠️ CRITICAL - These conventions apply to ALL code - production code, test code, examples, and samples.**
+
+---
+
+## Testing Requirements
+
+### Code Coverage
+
+- **Never decrease code coverage** - PRs must maintain or increase coverage
+- Target: 70%+ coverage for new code
+- CI monitors coverage on each PR
+
+### Test Patterns
+
+- **Parallelizable tests preferred** - Add new tests to `UnitTestsParallelizable` when possible
+- **Avoid static dependencies** - Don't use `Application.Init`, `ConfigurationManager` in tests
+- **Don't use `[AutoInitShutdown]`** - Legacy pattern, being phased out
+- **Make tests granular** - Each test should cover smallest area possible
+- Follow existing test patterns in respective test projects
+
+### Test Configuration
+
+- `xunit.runner.json` - xUnit configuration
+- `coverlet.runsettings` - Coverage settings (OpenCover format)
+
+---
+
+## API Documentation Requirements
+
+**All public APIs MUST have XML documentation:**
+
+- Clear, concise `<summary>` tags
+- Use `<see cref=""/>` for cross-references
+- Add `<remarks>` for context
+- Include `<example>` for non-obvious usage
+- Complex topics → `docfx/docs/*.md` files
+- Proper English and grammar - Clear, concise, complete. Use imperative mood.
+
+---
+
+## Pull Request Guidelines
+
+### PR Requirements
+
+- **Title**: "Fixes #issue. Terse description". If multiple issues, list all, separated by commas (e.g. "Fixes #123, #456. Terse description")
+- **Description**: 
+  - Include "- Fixes #issue" for each issue near the top
+  - **ALWAYS** include instructions for pulling down locally at end of Description
+  - Suggest user setup a remote named `copilot` pointing to your fork
+  - Example:
+    ```markdown
+    # To pull down this PR locally:
+    git remote add copilot <your-fork-url>
+    git fetch copilot <branch-name>
+    git checkout copilot/<branch-name>
+    ```
+- **Coding Style**: Follow all coding conventions in this document for new and modified code
+- **Tests**: Add tests for new functionality (see [Testing Requirements](#testing-requirements))
+- **Coverage**: Maintain or increase code coverage
+- **Scenarios**: Update UICatalog scenarios when adding features
+- **Warnings**: **CRITICAL - PRs must not introduce any new warnings**
+  - Any file modified in a PR that currently generates warnings **MUST** be fixed to remove those warnings
+  - Exception: Warnings caused by `[Obsolete]` attributes can remain
+  - Expected baseline: ~326 warnings (mostly nullable reference warnings, unused variables, xUnit suggestions)
+  - Action: Before submitting a PR, verify your changes don't add new warnings and fix any warnings in files you modify
+
+---
+
+## CI/CD Workflows
+
+The repository uses multiple GitHub Actions workflows. What runs and when:
+
+### 1) Build Solution (`.github/workflows/build.yml`)
+
+- **Triggers**: push and pull_request to `v2_release`, `v2_develop` (ignores `**.md`); supports `workflow_call`
+- **Runner/timeout**: `ubuntu-latest`, 10 minutes
+- **Steps**:
+  - Checkout and setup .NET 8.x GA
+  - `dotnet restore`
+  - Build Debug: `dotnet build --configuration Debug --no-restore -property:NoWarn=0618%3B0612`
+  - Build Release (library): `dotnet build Terminal.Gui/Terminal.Gui.csproj --configuration Release --no-incremental --force -property:NoWarn=0618%3B0612`
+  - Pack Release: `dotnet pack Terminal.Gui/Terminal.Gui.csproj --configuration Release --output ./local_packages -property:NoWarn=0618%3B0612`
+  - Restore NativeAot/SelfContained examples, then restore solution again
+  - Build Release for `Examples/NativeAot` and `Examples/SelfContained`
+  - Build Release solution
+  - Upload artifacts named `build-artifacts`, retention 1 day
 
 
-   ```csharp
-   // ✅ CORRECT - Target-typed new
-   View view = new () { Width = 10 };
-   MouseEventArgs args = new ();
-   
-   // ❌ WRONG - Redundant type name
-   View view = new View() { Width = 10 };
-   MouseEventArgs args = new MouseEventArgs();
-   ```
+### 2) Build & Run Unit Tests (`.github/workflows/unit-tests.yml`)
 
 
-**Why these rules matter:**
-- Explicit types improve code readability and make the type system more apparent
-- Target-typed `new()` reduces redundancy while maintaining clarity
-- Consistency across the codebase makes it easier for all contributors to read and maintain code
-- These conventions align with modern C# best practices (C# 9.0+)
+- **Triggers**: push and pull_request to `v2_release`, `v2_develop` (ignores `**.md`)
+- **Process**: Calls build workflow, then runs:
+  - Non-parallel UnitTests on Ubuntu/Windows/macOS matrix with coverage and blame/diag flags; `xunit.stopOnFail=false`
+  - Parallel UnitTestsParallelizable similarly with coverage; `xunit.stopOnFail=false`
+  - Uploads logs per-OS
 
 
-### Code Formatting
+### 3) Build & Run Integration Tests (`.github/workflows/integration-tests.yml`)
 
 
-Before you commit code, please run the formatting rules on **only the code file(s) you have modified**, in one of the following ways, in order of most preferred to least preferred:
+- **Triggers**: push and pull_request to `v2_release`, `v2_develop` (ignores `**.md`)
+- **Process**: Calls build workflow, then runs IntegrationTests on matrix with blame/diag; `xunit.stopOnFail=true`
+- Uploads logs per-OS
 
 
- 1. `Ctrl-E-C` if using ReSharper or Rider
- 2. Running the free [CleanupCode](https://www.jetbrains.com/help/resharper/CleanupCode.html) tool from JetBrains (this applies the same formatting rules as if you had used ReSharper or Rider, but is free for all users, if you don't have a license for those products)
-     - Run at the command line, from the solution root directory, as: `cleanupcode.exe relative/path/to/your/file.cs`
- 3. If you are unable to use either of those options, the last resort is to use `Ctrl-K-D` in Visual Studio (with default C# developer key bindings), to apply the subset of the formatting rules that Visual Studio can apply.
+### 4) Publish to NuGet (`.github/workflows/publish.yml`)
 
 
-## User Experience Tenets
+- **Triggers**: push to `v2_release`, `v2_develop`, and tags `v*` (ignores `**.md`)
+- Uses GitVersion to compute SemVer, builds Release, packs with symbols, and pushes to NuGet.org using `NUGET_API_KEY`
 
 
-**Terminal.Gui**, as a UI framework, heavily influences how console graphical user interfaces (GUIs) work. We use the following [tenets](https://ceklog.kindel.com/2020/02/10/tenets/) to guide us:
+### 5) Build and publish API docs (`.github/workflows/api-docs.yml`)
 
 
-*NOTE: Like all tenets, these are up for debate. If you disagree, have questions, or suggestions about these tenets and guidelines submit an Issue using the [design](https://github.com/gui-cs/Terminal.Gui/issues?q=is%3Aopen+is%3Aissue+label%3Adesign) tag.*
+- **Triggers**: push to `v1_release` and `v2_develop`
+- Builds DocFX site on Windows and deploys to GitHub Pages when `ref_name` is `v2_release` or `v2_develop`
 
 
-1. **Honor What's Come Before**. The Mac and Windows OS's have well-established GUI idioms that are mostly consistent. We adhere to these versus inventing new ways for users to do things. For example, **Terminal.Gui** adopts the `ctrl/command-c`, `ctrl/command-v`, and `ctrl/command-x` keyboard shortcuts for cut, copy, and paste versus defining new shortcuts.
-2. **Consistency Matters**. Common UI idioms should be consistent across the GUI framework. For example, `ctrl/command-q` quits/exits all modal views. See [Issue #456](https://github.com/gui-cs/Terminal.Gui/issues/456) as a counter-example that should be fixed.
-3. **Honor the OS, but Work Everywhere**. **Terminal.Gui** is cross-platform, but we support taking advantage of a platform's unique advantages. For example, the Windows Console API is richer than the Unix API in terms of keyboard handling. Thus, in Windows pressing the `alt` key in a **Terminal.Gui** app will activate the `MenuBar`, but in Unix, the user has to press the full hotkey (e.g. `alt-f`) or `F9`. 
-4. **Keyboard first, Mouse also**. Users use consoles primarily with the keyboard; **Terminal.Gui** is optimized for getting stuff done without using the Mouse. However, as a GUI framework, the Mouse is essential thus we strive to ensure that everything also works via the Mouse.
+### Replicating CI Locally
+
+```bash
+# Full CI sequence:
+dotnet restore
+dotnet build --configuration Debug --no-restore
+dotnet test Tests/UnitTests --no-build --verbosity normal
+dotnet test Tests/UnitTestsParallelizable --no-build --verbosity normal
+dotnet build --configuration Release --no-restore
+```
 
 
-## Public API Tenets & Guidelines
+---
 
 
-**Terminal.Gui** provides an API that is used by many. As the project evolves, contributors should follow these [tenets](https://ceklog.kindel.com/2020/02/10/tenets/) to ensure Consistency and backward compatibility.
+## Repository Structure
 
 
-*NOTE: Like all tenets, these are up for debate. If you disagree, have questions, or suggestions about these tenets and guidelines submit an Issue using the [design](https://github.com/gui-cs/Terminal.Gui/issues?q=is%3Aopen+is%3Aissue+label%3Adesign) tag.*
+### Root Directory Files
 
 
-1. **Stand on the shoulders of giants.** Follow the [Microsoft .NET Framework Design Guidelines](https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/) where appropriate. 
-2. **Don't Break Existing Stuff.** Avoid breaking changes to user behavior or the public API; instead, figure out how to implement new functionality in a similar way. If a breaking change can't be avoided, follow the guidelines below.
-3. **Fail-fast.** Fail-fast makes bugs and failures appear sooner, leading to a higher-quality framework and API.
-4. **Standards Reduce Complexity**. We strive to adopt standard API idoms because doing so reduces complexity for users of the API. For example, see Tenet #1 above. A counterexample is [Issue #447](https://github.com/gui-cs/Terminal.Gui/issues/447).
+- `Terminal.sln` - Main solution file
+- `Terminal.sln.DotSettings` - ReSharper code style settings
+- `.editorconfig` - Code formatting rules (111KB, extensive)
+- `global.json` - .NET SDK version pinning
+- `Directory.Build.props` - Common MSBuild properties
+- `Directory.Packages.props` - Central package version management
+- `GitVersion.yml` - Version numbering configuration
+- `CONTRIBUTING.md` - This file - contribution guidelines (source of truth)
+- `AGENTS.md` - Pointer to this file for AI agents
+- `README.md` - Project documentation
 
 
-### Include API Documentation
+### Main Directories
 
 
-Great care has been provided thus far in ensuring **Terminal.Gui** has great [API Documentation](https://gui-cs.github.io/Terminal.Gui). Contributors have the responsibility of continuously improving the API Documentation.
+**`/Terminal.Gui/`** - Core library (496 C# files):
+- `App/` - Application lifecycle (`Application.cs` static class, `RunState`, `MainLoop`)
+- `Configuration/` - `ConfigurationManager` for settings
+- `Drivers/` - Console driver implementations (`IConsoleDriver`, `NetDriver`, `UnixDriver`, `WindowsDriver`)
+- `Drawing/` - Rendering system (attributes, colors, glyphs)
+- `Input/` - Keyboard and mouse input handling
+- `ViewBase/` - Core `View` class hierarchy and layout
+- `Views/` - Specific View subclasses (Window, Dialog, Button, ListView, etc.)
+- `Text/` - Text manipulation and formatting
+- `FileServices/` - File operations and services
 
 
-- All public APIs must have clear, concise, and complete documentation in the form of [XML Documentation](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/xmldoc/).
-- Keep the `<summary></summary>` terse.
-- Use `<see cref=""/>` liberally to cross-link topics.
-- Use `<remarks></remarks>` to add more context and explanation.
-- For complex topics, provide conceptual documentation in the `docfx/articles` folder as a `.md` file. It will automatically get picked up and be added to [Conceptual Documentation](https://gui-cs.github.io/Terminal.Gui/docs/index.html).
-- Use proper English and good grammar.
+**`/Tests/`**:
+- `UnitTests/` - Non-parallel tests (use `Application.Init`, static state)
+- `UnitTestsParallelizable/` - Parallel tests (no static dependencies) - **Preferred**
+- `IntegrationTests/` - Integration tests
+- `StressTests/` - Long-running stress tests (scheduled daily)
+- `coverlet.runsettings` - Code coverage configuration
 
 
-### Defining Events
+**`/Examples/`**:
+- `UICatalog/` - Comprehensive demo app for manual testing
+- `Example/` - Basic example
+- `NativeAot/`, `SelfContained/` - Deployment examples
+- `ReactiveExample/`, `CommunityToolkitExample/` - Integration examples
 
 
-See https://gui-cs.github.io/Terminal.Gui/docs/events.html
+**`/docfx/`** - Documentation source:
+- `docs/` - Conceptual documentation (deep dives)
+- `api/` - Generated API docs (gitignored)
+- `docfx.json` - DocFX configuration
 
 
+**`/Scripts/`** - PowerShell build utilities (requires PowerShell 7.4+)
 
 
-### Defining new `View` classes
+**`/.github/workflows/`** - CI/CD pipelines (see [CI/CD Workflows](#cicd-workflows))
 
 
-- Support parameterless constructors (see [Issue 102](Parameterless constructors #102)). Do not require callers to use a parameterized constructor except when forcing `Absolute Layout`).
-- Avoid doing initialization via constructors. Instead use a property so consumers can use object initialization (e.g. `var foo = new Foo() { a = b };`).
-- Ensure the `UICatalog` demo for the new class illustrates both `Absolutle Layout` and `Computed Layout`.
+---
 
 
-## Breaking Changes to User Behavior or the Public API
+## Branching Model
 
 
-- Tag all pull requests that cause breaking changes to user behavior or the public API with the [breaking-change](https://github.com/gui-cs/Terminal.Gui/issues?q=is%3Aopen+is%3Aissue+label%3Abreaking-change) tag. This will help project maintainers track and document these.
-- Add a `<remark></remark>` to the XML Documentation to the code describing the breaking change. These will get picked up in the [API Documentation](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui.html).
+### GitFlow Model
 
 
-## Unit Tests
+- `v2_develop` - Default branch, active development
+- `v2_release` - Stable releases, matches NuGet
+- `v1_develop`, `v1_release` - Legacy v1 (maintenance only)
 
 
-PRs should never cause code coverage to go down. Ideally, every PR will get the project closer to 100%. PRs that include new functionality (e.g. a new control) should have at least 70% code coverage for the new functionality. 
+---
 
 
-**Terminal.Gui** has an automated unit or regression test suite. See the [Testing wiki](https://github.com/gui-cs/Terminal.Gui/wiki/Testing).
+## Key Architecture Concepts
 
 
-We analyze unit tests and code coverage on each PR push. 
+**⚠️ CRITICAL - Contributors should understand these concepts before starting work.**
 
 
-The code coverage of the latest released build (on NuGet) is shown as a badge at the top of `README.md`. Here as well:
+See `/docfx/docs/` for deep dives on:
 
 
-![Code Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/migueldeicaza/90ef67a684cb71db1817921a970f8d27/raw/code-coverage.json)
+- **Application Lifecycle** - How `Application.Init`, `Application.Run`, and `Application.Shutdown` work
+- **View Hierarchy** - Understanding `View`, `Toplevel`, `Window`, and view containment
+- **Layout System** - Pos, Dim, and automatic layout
+- **Event System** - How keyboard, mouse, and application events flow
+- **Driver Architecture** - How console drivers abstract platform differences
+- **Drawing Model** - How rendering works with Attributes, Colors, and Glyphs
 
 
-The project uses Fine Code Coverage to allow easy access to code coverage info on a per-component basis.
+Key documentation:
+- [View Documentation](https://gui-cs.github.io/Terminal.Gui/docs/View.html)
+- [Events Deep Dive](https://gui-cs.github.io/Terminal.Gui/docs/events.html)
+- [Layout System](https://gui-cs.github.io/Terminal.Gui/docs/layout.html)
+- [Keyboard Handling](https://gui-cs.github.io/Terminal.Gui/docs/keyboard.html)
+- [Mouse Support](https://gui-cs.github.io/Terminal.Gui/docs/mouse.html)
+- [Drivers](https://gui-cs.github.io/Terminal.Gui/docs/drivers.html)
 
 
-Use the following command to generate the same CC info that the Publish Github Action uses to publish the results to the badge:
+---
 
 
-```
-dotnet test --no-restore --verbosity normal --collect:"XPlat Code Coverage"  --settings UnitTests/coverlet.runsettings
-```
+## What NOT to Do
 
 
-Then open up the resulting `coverage.opencover.xml` file and you'll see the `sequenceCoverage` value:
+- ❌ Don't add new linters/formatters (use existing)
+- ❌ Don't modify unrelated code
+- ❌ Don't remove/edit unrelated tests
+- ❌ Don't break existing functionality
+- ❌ Don't add tests to `UnitTests` if they can be parallelizable
+- ❌ Don't use `Application.Init` in new tests
+- ❌ Don't decrease code coverage
+- ❌ **Don't use `var` for anything but built-in simple types** (use explicit types)
+- ❌ **Don't use redundant type names with `new`** (**ALWAYS PREFER** target-typed `new ()`)
+- ❌ **Don't introduce new warnings** (fix warnings in files you modify; exception: `[Obsolete]` warnings)
 
 
-```xml
-<?xml version="1.0" encoding="utf-8"?>
-<CoverageSession>
-  <Summary numSequencePoints="15817" visitedSequencePoints="7249" numBranchPoints="9379" visitedBranchPoints="3640" sequenceCoverage="45.83" branchCoverage="38.81" maxCyclomaticComplexity="10276" minCyclomaticComplexity="10276" visitedClasses="105" numClasses="141" visitedMethods="965" numMethods="1751" />
- 
-```
+---
 
 
-## Sample Code
+## Additional Resources
 
 
-[UI Catalog](https://github.com/gui-cs/Terminal.Gui/tree/master/UICatalog) is a great sample app for manual testing.
+- **Full Documentation**: https://gui-cs.github.io/Terminal.Gui
+- **API Reference**: https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui.App.html
+- **Deep Dives**: `/docfx/docs/` directory
+- **Getting Started**: https://gui-cs.github.io/Terminal.Gui/docs/getting-started.html
+- **Migrating from v1 to v2**: https://gui-cs.github.io/Terminal.Gui/docs/migratingfromv1.html
+- **Showcase**: https://gui-cs.github.io/Terminal.Gui/docs/showcase.html
+
+---
 
 
-When adding new functionality, fixing bugs, or changing things, please either add a new `Scenario` to **UICatalog** or update an existing `Scenario` to fully illustrate your work and provide a test-case.
+**Thank you for contributing to Terminal.Gui!** 🎉

+ 1 - 1
README.md

@@ -86,7 +86,7 @@ Or, you can use the [Terminal.Gui.Templates](https://github.com/gui-cs/Terminal.
 
 
 # Contributing
 # Contributing
 
 
-See [CONTRIBUTING.md](./CONTRIBUTING.md).
+See [CONTRIBUTING.md](CONTRIBUTING.md) for complete contribution guidelines.
 
 
 Debates on architecture and design can be found in Issues tagged with [design](https://github.com/gui-cs/Terminal.Gui/issues?q=is%3Aopen+is%3Aissue+label%3Av2+label%3Adesign).
 Debates on architecture and design can be found in Issues tagged with [design](https://github.com/gui-cs/Terminal.Gui/issues?q=is%3Aopen+is%3Aissue+label%3Av2+label%3Adesign).
 
 

+ 4 - 56
Terminal.Gui/App/Application.Run.cs

@@ -61,15 +61,6 @@ public static partial class Application // Run (Begin -> Run -> Layout/Draw -> E
     {
     {
         ArgumentNullException.ThrowIfNull (toplevel);
         ArgumentNullException.ThrowIfNull (toplevel);
 
 
-        //#if DEBUG_IDISPOSABLE
-        //        Debug.Assert (!toplevel.WasDisposed);
-
-        //        if (_cachedRunStateToplevel is { } && _cachedRunStateToplevel != toplevel)
-        //        {
-        //            Debug.Assert (_cachedRunStateToplevel.WasDisposed);
-        //        }
-        //#endif
-
         // Ensure the mouse is ungrabbed.
         // Ensure the mouse is ungrabbed.
         if (Mouse.MouseGrabView is { })
         if (Mouse.MouseGrabView is { })
         {
         {
@@ -130,11 +121,6 @@ public static partial class Application // Run (Begin -> Run -> Layout/Draw -> E
                     TopLevels.Push (toplevel);
                     TopLevels.Push (toplevel);
                 }
                 }
             }
             }
-
-            //if (TopLevels.FindDuplicates (new ToplevelEqualityComparer ()).Count > 0)
-            //{
-            //    throw new ArgumentException ("There are duplicates Toplevel IDs");
-            //}
         }
         }
 
 
         if (Top is null)
         if (Top is null)
@@ -174,11 +160,6 @@ public static partial class Application // Run (Begin -> Run -> Layout/Draw -> E
             toplevel.EndInit (); // Calls Layout
             toplevel.EndInit (); // Calls Layout
         }
         }
 
 
-        // Call ConfigurationManager Apply here to ensure all subscribers to ConfigurationManager.Applied
-        // can update their state appropriately.
-        // BUGBUG: DO NOT DO THIS. Leave this commented out until we can figure out how to do this right
-        //Apply ();
-
         // Try to set initial focus to any TabStop
         // Try to set initial focus to any TabStop
         if (!toplevel.HasFocus)
         if (!toplevel.HasFocus)
         {
         {
@@ -402,7 +383,7 @@ public static partial class Application // Run (Begin -> Run -> Layout/Draw -> E
     ///     need to be laid out (see <see cref="View.NeedsLayout"/>) will be laid out.
     ///     need to be laid out (see <see cref="View.NeedsLayout"/>) will be laid out.
     ///     Only Views that need to be drawn (see <see cref="View.NeedsDraw"/>) will be drawn.
     ///     Only Views that need to be drawn (see <see cref="View.NeedsDraw"/>) will be drawn.
     /// </summary>
     /// </summary>
-    /// <param name="forceDraw">
+    /// <param name="forceRedraw">
     ///     If <see langword="true"/> the entire View hierarchy will be redrawn. The default is <see langword="false"/> and
     ///     If <see langword="true"/> the entire View hierarchy will be redrawn. The default is <see langword="false"/> and
     ///     should only be overriden for testing.
     ///     should only be overriden for testing.
     /// </param>
     /// </param>
@@ -467,35 +448,10 @@ public static partial class Application // Run (Begin -> Run -> Layout/Draw -> E
     /// <returns><see langword="false"/> if at least one iteration happened.</returns>
     /// <returns><see langword="false"/> if at least one iteration happened.</returns>
     public static bool RunIteration (ref RunState state, bool firstIteration = false)
     public static bool RunIteration (ref RunState state, bool firstIteration = false)
     {
     {
-        // If the driver has events pending do an iteration of the driver MainLoop
-        if (MainLoop is { Running: true } && MainLoop.EventsPending ())
-        {
-            // Notify Toplevel it's ready
-            if (firstIteration)
-            {
-                state.Toplevel.OnReady ();
-            }
+        ApplicationImpl appImpl = (ApplicationImpl)ApplicationImpl.Instance;
+        appImpl.Coordinator?.RunIteration ();
 
 
-            MainLoop.RunIteration ();
-
-            Iteration?.Invoke (null, new ());
-        }
-
-        firstIteration = false;
-
-        if (Top is null)
-        {
-            return firstIteration;
-        }
-
-        LayoutAndDraw (TopLevels.Any (v => v.NeedsLayout || v.NeedsDraw));
-
-        if (PositionCursor ())
-        {
-            Driver?.UpdateCursor ();
-        }
-
-        return firstIteration;
+        return false;
     }
     }
 
 
     /// <summary>Stops the provided <see cref="Toplevel"/>, causing or the <paramref name="top"/> if provided.</summary>
     /// <summary>Stops the provided <see cref="Toplevel"/>, causing or the <paramref name="top"/> if provided.</summary>
@@ -510,14 +466,6 @@ public static partial class Application // Run (Begin -> Run -> Layout/Draw -> E
     /// </remarks>
     /// </remarks>
     public static void RequestStop (Toplevel? top = null) { ApplicationImpl.Instance.RequestStop (top); }
     public static void RequestStop (Toplevel? top = null) { ApplicationImpl.Instance.RequestStop (top); }
 
 
-    internal static void OnNotifyStopRunState (Toplevel top)
-    {
-        if (EndAfterFirstIteration)
-        {
-            NotifyStopRunState?.Invoke (top, new (top));
-        }
-    }
-
     /// <summary>
     /// <summary>
     ///     Building block API: completes the execution of a <see cref="Toplevel"/> that was started with
     ///     Building block API: completes the execution of a <see cref="Toplevel"/> that was started with
     ///     <see cref="Begin(Toplevel)"/> .
     ///     <see cref="Begin(Toplevel)"/> .

+ 34 - 68
Terminal.Gui/README.md

@@ -8,43 +8,7 @@
 
 
 ## Project Folder Structure
 ## Project Folder Structure
 
 
-- `\` - The root folder contains the core solution and project files for the library.
-	- `Terminal.Gui.sln` - The Visual Studio solution file for the project.
-	- `Terminal.Gui.csproj` - The project file defining build configurations and dependencies.
-	- `App\` - Contains the core `Application` logic, including `Application.cs`, a `static` class that serves as the base 'application engine', managing `RunState` and `MainLoop`.
-
-- `Configuration\` - Classes related to the `ConfigurationManager` for handling application settings.
-
-- `Drivers\` - Contains the console driver implementations:
-	- `IConsoleDriver.cs` - Defines the Console Driver API.
-	- Driver implementations for .NET (`DotNetDriver`), Unix & macOS (`UnixDriver`), and Windows (`WindowsDriver`).
-
-- `Drawing\` - Classes related to rendering graphical elements in the console.
-
-- `FileServices\` - Utility classes for file operations and services.
-
-- `Input\` - Classes handling keyboard and mouse input:
-	- `Events.cs` - Defines structs and classes for keyboard and mouse events.
-
-- `Resources\` - Assets and resources used by the library.
-
-- `Text\` - Classes for text processing and formatting.
-
-- `View\` - Core `View` class hierarchy (excluding specific sub-classes):
-	- `View.cs` - The base class for non-modal visual elements such as controls.
-	- Related subdirectories for layout and positioning logic.
-
-- `ViewBase\` - Base classes and utilities for views.
-
-- `Views\` - Specific sub-classes of `View`:
-	- `Toplevel` - Base class for modal visual elements like top-level windows and dialogs, supporting `MenuBar` and `StatusBar`.
-	- `Window` - Implements framed top-level views with titles.
-	- `Dialog` - Specialized windows for user interaction.
-	- Other specialized view classes.
-
-## Showcase
-
-See the [Showcase](docs/showcase.md) to find independent applications and examples built with Terminal.Gui.
+This directory contains the core **Terminal.Gui** library source code. For a detailed repository structure, see [CONTRIBUTING.md - Repository Structure](../CONTRIBUTING.md#repository-structure).
 
 
 ## Getting Started
 ## Getting Started
 
 
@@ -52,14 +16,9 @@ For instructions on how to start using **Terminal.Gui**, refer to the [Getting S
 
 
 ## Documentation
 ## Documentation
 
 
-Comprehensive documentation for **Terminal.Gui** is available at [gui-cs.github.io/Terminal.Gui](https://gui-cs.github.io/Terminal.Gui). Key resources include:
-- [Events Deep Dive](https://gui-cs.github.io/Terminal.Gui/docs/events.html) - Detailed guide on event handling and the Cancellable Work Pattern.
-- [View Documentation](https://gui-cs.github.io/Terminal.Gui/docs/View.html) - Information on creating and customizing views.
-- [Keyboard Handling](https://gui-cs.github.io/Terminal.Gui/docs/keyboard.html) - Guide to managing keyboard input.
-- [Mouse Support](https://gui-cs.github.io/Terminal.Gui/docs/mouse.html) - Details on implementing mouse interactions.
-- [Showcase](https://gui-cs.github.io/Terminal.Gui/docs/showcase.html) - A collection of applications and examples built with Terminal.Gui.
+Comprehensive documentation is available at [gui-cs.github.io/Terminal.Gui](https://gui-cs.github.io/Terminal.Gui).
 
 
-For information on generating and updating the API documentation locally, refer to the [DocFX README](../docfx/README.md) in the `docfx` folder.
+For information on generating and updating the API documentation locally, refer to the [DocFX README](../docfx/README.md).
 
 
 ## Versioning
 ## Versioning
 
 
@@ -75,7 +34,7 @@ The project version (used in the NuGet package and `Terminal.Gui.dll`) is determ
 To define a new version, tag a commit using `git tag`:
 To define a new version, tag a commit using `git tag`:
 
 
 ```powershell
 ```powershell
-git tag v1.3.4-beta.5 -a -m "Release v1.3.4 Beta 5"
+git tag v2.1.0-beta.1 -a -m "Release v2.1.0 Beta 1"
 dotnet-gitversion /updateprojectfiles
 dotnet-gitversion /updateprojectfiles
 dotnet build -c Release
 dotnet build -c Release
 ```
 ```
@@ -92,15 +51,15 @@ To release a new version, follow these steps based on [Semantic Versioning](http
 
 
 ### Steps for Release:
 ### Steps for Release:
 
 
-1. **Verify the `develop` branch is ready for release**:
-	- Ensure all changes are committed and pushed to the `develop` branch.
-	- Ensure your local `develop` branch is up-to-date with `upstream/develop`.
+1. **Verify the `v2_develop` branch is ready for release**:
+	- Ensure all changes are committed and pushed to the `v2_develop` branch.
+	- Ensure your local `v2_develop` branch is up-to-date with `upstream/v2_develop`.
 
 
-2. **Create a pull request for the release in the `develop` branch**:
+2. **Create a pull request for the release in the `v2_develop` branch**:
 	- Title the PR as "Release vX.Y.Z".
 	- Title the PR as "Release vX.Y.Z".
 	```powershell
 	```powershell
-	git checkout develop
-	git pull upstream develop
+	git checkout v2_develop
+	git pull upstream v2_develop
 	git checkout -b vX_Y_Z
 	git checkout -b vX_Y_Z
 	git add .
 	git add .
 	git commit -m "Release vX.Y.Z"
 	git commit -m "Release vX.Y.Z"
@@ -110,28 +69,28 @@ To release a new version, follow these steps based on [Semantic Versioning](http
 
 
 3. **On github.com, verify the build action worked on your fork, then merge the PR**.
 3. **On github.com, verify the build action worked on your fork, then merge the PR**.
 
 
-4. **Pull the merged `develop` from `upstream`**:
+4. **Pull the merged `v2_develop` from `upstream`**:
 	```powershell
 	```powershell
-	git checkout develop
-	git pull upstream develop
+	git checkout v2_develop
+	git pull upstream v2_develop
 	```
 	```
 
 
-5. **Merge `develop` into `main`**:
+5. **Merge `v2_develop` into `v2_release`**:
 	```powershell
 	```powershell
-	git checkout main
-	git pull upstream main
-	git merge develop
+	git checkout v2_release
+	git pull upstream v2_release
+	git merge v2_develop
 	```
 	```
 	- Fix any merge errors.
 	- Fix any merge errors.
 
 
-6. **Create a new annotated tag for the release on `main`**:
+6. **Create a new annotated tag for the release on `v2_release`**:
 	```powershell
 	```powershell
 	git tag vX.Y.Z -a -m "Release vX.Y.Z"
 	git tag vX.Y.Z -a -m "Release vX.Y.Z"
 	```
 	```
 
 
-7. **Push the new tag to `main` on `upstream`**:
+7. **Push the new tag to `v2_release` on `upstream`**:
 	```powershell
 	```powershell
-	git push --atomic upstream main vX.Y.Z
+	git push --atomic upstream v2_release vX.Y.Z
 	```
 	```
 
 
 8. **Monitor Github Actions to ensure the NuGet publishing worked**:
 8. **Monitor Github Actions to ensure the NuGet publishing worked**:
@@ -143,18 +102,25 @@ To release a new version, follow these steps based on [Semantic Versioning](http
 10. **Add a new Release in Github**:
 10. **Add a new Release in Github**:
 	- Go to [GitHub Releases](https://github.com/gui-cs/Terminal.Gui/releases) and generate release notes with the list of PRs since the last release.
 	- Go to [GitHub Releases](https://github.com/gui-cs/Terminal.Gui/releases) and generate release notes with the list of PRs since the last release.
 
 
-11. **Update the `develop` branch with the new version**:
+11. **Update the `v2_develop` branch with the new version**:
 	```powershell
 	```powershell
-	git checkout develop
-	git pull upstream develop
-	git merge main
-	git push upstream develop
+	git checkout v2_develop
+	git pull upstream v2_develop
+	git merge v2_release
+	git push upstream v2_develop
 	```
 	```
 
 
 ## NuGet
 ## NuGet
 
 
-The official NuGet package for Terminal.Gui is available at [https://www.nuget.org/packages/Terminal.Gui](https://www.nuget.org/packages/Terminal.Gui). When a new version tag is defined and merged into `main`, a NuGet package is automatically generated by a GitHub Action. Pre-release versions (e.g., `1.3.4-beta.5`) are tagged as pre-release on NuGet.
+The official NuGet package for Terminal.Gui is available at [https://www.nuget.org/packages/Terminal.Gui](https://www.nuget.org/packages/Terminal.Gui). When a new version tag is defined and merged into `v2_release`, a NuGet package is automatically generated by a GitHub Action. Pre-release versions (e.g., `2.0.0-beta.5`) are tagged as pre-release on NuGet.
 
 
 ## Contributing
 ## Contributing
 
 
-We welcome contributions from the community. For detailed guidelines on how to contribute, including coding style, unit tests, and pull request processes, please refer to [CONTRIBUTING.md](https://github.com/gui-cs/Terminal.Gui/blob/master/CONTRIBUTING.md).
+We welcome contributions from the community. For complete contribution guidelines, including:
+- Build and test instructions
+- Coding conventions and style rules
+- Testing requirements and patterns
+- Pull request guidelines
+- CI/CD workflows
+
+Please refer to [CONTRIBUTING.md](../CONTRIBUTING.md) in the repository root.

+ 10 - 10
Terminal.Gui/ViewBase/Adornment/ShadowView.cs

@@ -95,12 +95,12 @@ internal class ShadowView : View
         {
         {
             for (int c = Math.Max (0, screen.X + 1); c < screen.X + screen.Width; c++)
             for (int c = Math.Max (0, screen.X + 1); c < screen.X + screen.Width; c++)
             {
             {
-                Driver?.Move (c, r);
+                Driver.Move (c, r);
                 SetAttribute (GetAttributeUnderLocation (new (c, r)));
                 SetAttribute (GetAttributeUnderLocation (new (c, r)));
 
 
-                if (c < Driver?.Contents!.GetLength (1) && r < Driver?.Contents?.GetLength (0))
+                if (c < ScreenContents?.GetLength (1) && r < ScreenContents?.GetLength (0))
                 {
                 {
-                    Driver.AddRune (Driver.Contents [r, c].Rune);
+                    AddRune (ScreenContents [r, c].Rune);
                 }
                 }
             }
             }
         }
         }
@@ -129,12 +129,12 @@ internal class ShadowView : View
         {
         {
             for (int r = Math.Max (0, screen.Y); r < screen.Y + viewport.Height; r++)
             for (int r = Math.Max (0, screen.Y); r < screen.Y + viewport.Height; r++)
             {
             {
-                Driver?.Move (c, r);
+                Driver.Move (c, r);
                 SetAttribute (GetAttributeUnderLocation (new (c, r)));
                 SetAttribute (GetAttributeUnderLocation (new (c, r)));
 
 
-                if (Driver?.Contents is { } && screen.X < Driver.Contents.GetLength (1) && r < Driver.Contents.GetLength (0))
+                if (ScreenContents is { } && screen.X < ScreenContents.GetLength (1) && r < ScreenContents.GetLength (0))
                 {
                 {
-                    Driver.AddRune (Driver.Contents [r, c].Rune);
+                    AddRune (ScreenContents [r, c].Rune);
                 }
                 }
             }
             }
         }
         }
@@ -151,14 +151,14 @@ internal class ShadowView : View
             return Attribute.Default;
             return Attribute.Default;
         }
         }
 
 
-        if (Driver?.Contents == null ||
-            location.Y < 0 || location.Y >= Driver.Contents.GetLength (0) ||
-            location.X < 0 || location.X >= Driver.Contents.GetLength (1))
+        if (ScreenContents == null ||
+            location.Y < 0 || location.Y >= ScreenContents.GetLength (0) ||
+            location.X < 0 || location.X >= ScreenContents.GetLength (1))
         {
         {
             return Attribute.Default;
             return Attribute.Default;
         }
         }
 
 
-        Attribute attr = Driver!.Contents! [location.Y, location.X].Attribute!.Value;
+        Attribute attr = ScreenContents [location.Y, location.X].Attribute!.Value;
 
 
         var newAttribute =
         var newAttribute =
             new Attribute (
             new Attribute (

+ 1 - 1
Terminal.Gui/ViewBase/View.Drawing.cs

@@ -658,7 +658,7 @@ public partial class View // Drawing APIs
                     Driver.Move (p.Key.X, p.Key.Y);
                     Driver.Move (p.Key.X, p.Key.Y);
 
 
                     // TODO: #2616 - Support combining sequences that don't normalize
                     // TODO: #2616 - Support combining sequences that don't normalize
-                    Driver.AddRune (p.Value.Value.Rune);
+                    AddRune (p.Value.Value.Rune);
                 }
                 }
             }
             }
 
 

+ 3 - 0
Terminal.Gui/ViewBase/View.cs

@@ -130,6 +130,9 @@ public partial class View : IDisposable, ISupportInitializeNotification
         set => _driver = value;
         set => _driver = value;
     }
     }
 
 
+    /// <summary>Gets the screen buffer contents. This is a convenience property for Views that need direct access to the screen buffer.</summary>
+    protected Cell [,]? ScreenContents => Driver?.Contents;
+
     /// <summary>Initializes a new instance of <see cref="View"/>.</summary>
     /// <summary>Initializes a new instance of <see cref="View"/>.</summary>
     /// <remarks>
     /// <remarks>
     ///     <para>
     ///     <para>

+ 1 - 1
Terminal.Gui/Views/Color/ColorBar.cs

@@ -92,7 +92,7 @@ internal abstract class ColorBar : View, IColorBar
         {
         {
             Move (0, 0);
             Move (0, 0);
             SetAttribute (HasFocus ? GetAttributeForRole (VisualRole.Focus) : GetAttributeForRole (VisualRole.Normal));
             SetAttribute (HasFocus ? GetAttributeForRole (VisualRole.Focus) : GetAttributeForRole (VisualRole.Normal));
-            Driver?.AddStr (Text);
+            AddStr (Text);
 
 
             // TODO: is there a better method than this? this is what it is in TableView
             // TODO: is there a better method than this? this is what it is in TableView
             xOffset = Text.EnumerateRunes ().Sum (c => c.GetColumns ());
             xOffset = Text.EnumerateRunes ().Sum (c => c.GetColumns ());

+ 4 - 4
Terminal.Gui/Views/FileDialogs/FileDialog.cs

@@ -427,9 +427,9 @@ public class FileDialog : Dialog, IDesignable
             Move (0, Viewport.Height / 2);
             Move (0, Viewport.Height / 2);
 
 
             SetAttribute (new (Color.Red, GetAttributeForRole (VisualRole.Normal).Background));
             SetAttribute (new (Color.Red, GetAttributeForRole (VisualRole.Normal).Background));
-            Driver!.AddStr (new (' ', feedbackPadLeft));
-            Driver.AddStr (_feedback);
-            Driver.AddStr (new (' ', feedbackPadRight));
+            AddStr (new (' ', feedbackPadLeft));
+            AddStr (_feedback);
+            AddStr (new (' ', feedbackPadRight));
         }
         }
 
 
         return true;
         return true;
@@ -507,7 +507,7 @@ public class FileDialog : Dialog, IDesignable
             _allowedTypeMenuBar.DrawingContent += (s, e) =>
             _allowedTypeMenuBar.DrawingContent += (s, e) =>
                                                   {
                                                   {
                                                       _allowedTypeMenuBar.Move (e.NewViewport.Width - 1, 0);
                                                       _allowedTypeMenuBar.Move (e.NewViewport.Width - 1, 0);
-                                                      Driver!.AddRune (Glyphs.DownArrow);
+                                                      AddRune (Glyphs.DownArrow);
                                                   };
                                                   };
 
 
             Add (_allowedTypeMenuBar);
             Add (_allowedTypeMenuBar);

+ 1 - 1
Terminal.Gui/Views/GraphView/GraphView.cs

@@ -213,7 +213,7 @@ public class GraphView : View, IDesignable
         for (var i = 0; i < Viewport.Height; i++)
         for (var i = 0; i < Viewport.Height; i++)
         {
         {
             Move (0, i);
             Move (0, i);
-            Driver?.AddStr (new (' ', Viewport.Width));
+            AddStr (new (' ', Viewport.Width));
         }
         }
 
 
         // If there is no data do not display a graph
         // If there is no data do not display a graph

+ 1 - 1
Terminal.Gui/Views/GraphView/IAnnotation.cs

@@ -18,7 +18,7 @@ public interface IAnnotation
 
 
     /// <summary>
     /// <summary>
     ///     Called once after series have been rendered (or before if <see cref="BeforeSeries"/> is true). Use
     ///     Called once after series have been rendered (or before if <see cref="BeforeSeries"/> is true). Use
-    ///     <see cref="View.Driver"/> to draw and <see cref="View.Viewport"/> to avoid drawing outside of graph
+    ///     methods like <see cref="View.AddStr(string)"/> and <see cref="View.AddRune(Rune)"/> to draw. Use <see cref="View.Viewport"/> to avoid drawing outside of graph.
     /// </summary>
     /// </summary>
     /// <param name="graph"></param>
     /// <param name="graph"></param>
     void Render (GraphView graph);
     void Render (GraphView graph);

+ 2 - 2
Terminal.Gui/Views/GraphView/TextAnnotation.cs

@@ -68,11 +68,11 @@ public class TextAnnotation : IAnnotation
 
 
         if (Text.Length < availableWidth)
         if (Text.Length < availableWidth)
         {
         {
-            graph.Driver?.AddStr (Text);
+            graph.AddStr (Text);
         }
         }
         else
         else
         {
         {
-            graph.Driver?.AddStr (Text.Substring (0, availableWidth));
+            graph.AddStr (Text.Substring (0, availableWidth));
         }
         }
     }
     }
 }
 }

+ 3 - 3
Terminal.Gui/Views/ListView.cs

@@ -750,7 +750,7 @@ public class ListView : View, IDesignable
             {
             {
                 for (var c = 0; c < f.Width; c++)
                 for (var c = 0; c < f.Width; c++)
                 {
                 {
-                    Driver?.AddRune ((Rune)' ');
+                    AddRune ((Rune)' ');
                 }
                 }
             }
             }
             else
             else
@@ -766,11 +766,11 @@ public class ListView : View, IDesignable
 
 
                 if (_allowsMarking)
                 if (_allowsMarking)
                 {
                 {
-                    Driver?.AddRune (
+                    AddRune (
                                     _source.IsMarked (item) ? AllowsMultipleSelection ? Glyphs.CheckStateChecked : Glyphs.Selected :
                                     _source.IsMarked (item) ? AllowsMultipleSelection ? Glyphs.CheckStateChecked : Glyphs.Selected :
                                     AllowsMultipleSelection ? Glyphs.CheckStateUnChecked : Glyphs.UnSelected
                                     AllowsMultipleSelection ? Glyphs.CheckStateUnChecked : Glyphs.UnSelected
                                    );
                                    );
-                    Driver?.AddRune ((Rune)' ');
+                    AddRune ((Rune)' ');
                 }
                 }
 
 
                 Source.Render (this, isSelected, item, col, row, f.Width - col, start);
                 Source.Render (this, isSelected, item, col, row, f.Width - col, start);

+ 18 - 20
Terminal.Gui/Views/Menuv1/Menu.cs

@@ -847,7 +847,7 @@ internal sealed class Menu : View
                 continue;
                 continue;
             }
             }
 
 
-            if (ViewportToScreen (Viewport).Y + i >= Driver.Rows)
+            if (ViewportToScreen (Viewport).Y + i >= Application.Screen.Height)
             {
             {
                 break;
                 break;
             }
             }
@@ -863,11 +863,10 @@ internal sealed class Menu : View
 
 
             if (item is null && BorderStyle != LineStyle.None)
             if (item is null && BorderStyle != LineStyle.None)
             {
             {
-                Point s = ViewportToScreen (new Point (-1, i));
-                Driver.Move (s.X, s.Y);
-                Driver.AddRune (Glyphs.LeftTee);
+                Move (-1, i);
+                AddRune (Glyphs.LeftTee);
             }
             }
-            else if (Frame.X < Driver.Cols)
+            else if (Frame.X < Application.Screen.Width)
             {
             {
                 Move (0, i);
                 Move (0, i);
             }
             }
@@ -882,28 +881,28 @@ internal sealed class Menu : View
                     continue;
                     continue;
                 }
                 }
 
 
-                if (ViewportToScreen (Viewport).X + p >= Driver.Cols)
+                if (ViewportToScreen (Viewport).X + p >= Application.Screen.Width)
                 {
                 {
                     break;
                     break;
                 }
                 }
 
 
                 if (item is null)
                 if (item is null)
                 {
                 {
-                    Driver.AddRune (Glyphs.HLine);
+                    AddRune (Glyphs.HLine);
                 }
                 }
                 else if (i == 0 && p == 0 && _host.UseSubMenusSingleFrame && item.Parent!.Parent is { })
                 else if (i == 0 && p == 0 && _host.UseSubMenusSingleFrame && item.Parent!.Parent is { })
                 {
                 {
-                    Driver.AddRune (Glyphs.LeftArrow);
+                    AddRune (Glyphs.LeftArrow);
                 }
                 }
 
 
                 // This `- 3` is left border + right border + one row in from right
                 // This `- 3` is left border + right border + one row in from right
                 else if (p == Frame.Width - 3 && _barItems?.SubMenu (_barItems.Children [i]!) is { })
                 else if (p == Frame.Width - 3 && _barItems?.SubMenu (_barItems.Children [i]!) is { })
                 {
                 {
-                    Driver.AddRune (Glyphs.RightArrow);
+                    AddRune (Glyphs.RightArrow);
                 }
                 }
                 else
                 else
                 {
                 {
-                    Driver.AddRune ((Rune)' ');
+                    AddRune ((Rune)' ');
                 }
                 }
             }
             }
 
 
@@ -911,9 +910,8 @@ internal sealed class Menu : View
             {
             {
                 if (BorderStyle != LineStyle.None && SuperView?.Frame.Right - Frame.X > Frame.Width)
                 if (BorderStyle != LineStyle.None && SuperView?.Frame.Right - Frame.X > Frame.Width)
                 {
                 {
-                    Point s = ViewportToScreen (new Point (Frame.Width - 2, i));
-                    Driver.Move (s.X, s.Y);
-                    Driver.AddRune (Glyphs.RightTee);
+                    Move (Frame.Width - 2, i);
+                    AddRune (Glyphs.RightTee);
                 }
                 }
 
 
                 continue;
                 continue;
@@ -950,9 +948,9 @@ internal sealed class Menu : View
 
 
             Point screen = ViewportToScreen (new Point (0, i));
             Point screen = ViewportToScreen (new Point (0, i));
 
 
-            if (screen.X < Driver.Cols)
+            if (screen.X < Application.Screen.Width)
             {
             {
-                Driver.Move (screen.X + 1, screen.Y);
+                Move (1, i);
 
 
                 if (!item.IsEnabled ())
                 if (!item.IsEnabled ())
                 {
                 {
@@ -991,16 +989,16 @@ internal sealed class Menu : View
                 int col = Frame.Width - l - 3;
                 int col = Frame.Width - l - 3;
                 screen = ViewportToScreen (new Point (col, i));
                 screen = ViewportToScreen (new Point (col, i));
 
 
-                if (screen.X < Driver.Cols)
+                if (screen.X < Application.Screen.Width)
                 {
                 {
-                    Driver.Move (screen.X, screen.Y);
-                    Driver.AddStr (item.Help);
+                    Move (col, i);
+                    AddStr (item.Help);
 
 
                     // The shortcut tag string
                     // The shortcut tag string
                     if (!string.IsNullOrEmpty (item.ShortcutTag))
                     if (!string.IsNullOrEmpty (item.ShortcutTag))
                     {
                     {
-                        Driver.Move (screen.X + l - item.ShortcutTag.GetColumns (), screen.Y);
-                        Driver.AddStr (item.ShortcutTag);
+                        Move (col + l - item.ShortcutTag.GetColumns (), i);
+                        AddStr (item.ShortcutTag);
                     }
                     }
                 }
                 }
             }
             }

+ 1 - 1
Terminal.Gui/Views/Menuv1/MenuBar.cs

@@ -697,7 +697,7 @@ public class MenuBar : View, IDesignable
     internal Point GetScreenOffset ()
     internal Point GetScreenOffset ()
     {
     {
         // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
         // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
-        if (Driver is null)
+        if (Application.Screen.Height == 0)
         {
         {
             return Point.Empty;
             return Point.Empty;
         }
         }

+ 4 - 4
Terminal.Gui/Views/ProgressBar.cs

@@ -144,11 +144,11 @@ public class ProgressBar : View, IDesignable
             {
             {
                 if (Array.IndexOf (_activityPos!, i) != -1)
                 if (Array.IndexOf (_activityPos!, i) != -1)
                 {
                 {
-                    Driver?.AddRune (SegmentCharacter);
+                    AddRune (SegmentCharacter);
                 }
                 }
                 else
                 else
                 {
                 {
-                    Driver?.AddRune ((Rune)' ');
+                    AddRune ((Rune)' ');
                 }
                 }
             }
             }
         }
         }
@@ -159,12 +159,12 @@ public class ProgressBar : View, IDesignable
 
 
             for (i = 0; (i < mid) & (i < Viewport.Width); i++)
             for (i = 0; (i < mid) & (i < Viewport.Width); i++)
             {
             {
-                Driver?.AddRune (SegmentCharacter);
+                AddRune (SegmentCharacter);
             }
             }
 
 
             for (; i < Viewport.Width; i++)
             for (; i < Viewport.Width; i++)
             {
             {
-                Driver?.AddRune ((Rune)' ');
+                AddRune ((Rune)' ');
             }
             }
         }
         }
 
 

+ 1 - 1
Terminal.Gui/Views/RadioGroup.cs

@@ -375,7 +375,7 @@ public class RadioGroup : View, IDesignable, IOrientation
 
 
             string rl = _radioLabels [i];
             string rl = _radioLabels [i];
             SetAttribute (GetAttributeForRole (VisualRole.Normal));
             SetAttribute (GetAttributeForRole (VisualRole.Normal));
-            Driver?.AddStr ($"{(i == _selected ? Glyphs.Selected : Glyphs.UnSelected)} ");
+            AddStr ($"{(i == _selected ? Glyphs.Selected : Glyphs.UnSelected)} ");
             TextFormatter.FindHotKey (rl, HotKeySpecifier, out int hotPos, out Key hotKey);
             TextFormatter.FindHotKey (rl, HotKeySpecifier, out int hotPos, out Key hotKey);
 
 
             if (hotPos != -1 && hotKey != Key.Empty)
             if (hotPos != -1 && hotKey != Key.Empty)

+ 2 - 2
Terminal.Gui/Views/Slider/Slider.cs

@@ -441,13 +441,13 @@ public class Slider<T> : View, IOrientation
     private void MoveAndAdd (int x, int y, Rune rune)
     private void MoveAndAdd (int x, int y, Rune rune)
     {
     {
         Move (x, y);
         Move (x, y);
-        Driver?.AddRune (rune);
+        AddRune (rune);
     }
     }
 
 
     private void MoveAndAdd (int x, int y, string str)
     private void MoveAndAdd (int x, int y, string str)
     {
     {
         Move (x, y);
         Move (x, y);
-        Driver?.AddStr (str);
+        AddStr (str);
     }
     }
 
 
     /// <summary>Sets the dimensions of the Slider to the ideal values.</summary>
     /// <summary>Sets the dimensions of the Slider to the ideal values.</summary>

+ 1 - 1
Terminal.Gui/Views/SpinnerView/SpinnerView.cs

@@ -187,7 +187,7 @@ public class SpinnerView : View, IDesignable
         if (Sequence is { Length: > 0 } && _currentIdx < Sequence.Length)
         if (Sequence is { Length: > 0 } && _currentIdx < Sequence.Length)
         {
         {
             Move (Viewport.X, Viewport.Y);
             Move (Viewport.X, Viewport.Y);
-            Driver?.AddStr (Sequence [_currentIdx]);
+            AddStr (Sequence [_currentIdx]);
         }
         }
     }
     }
 
 

+ 19 - 20
Terminal.Gui/Views/TableView/TableView.cs

@@ -943,7 +943,7 @@ public class TableView : View, IDesignable
         SetAttribute (GetAttributeForRole (VisualRole.Normal));
         SetAttribute (GetAttributeForRole (VisualRole.Normal));
 
 
         //invalidate current row (prevents scrolling around leaving old characters in the frame
         //invalidate current row (prevents scrolling around leaving old characters in the frame
-        Driver?.AddStr (new (' ', Viewport.Width));
+        AddStr (new (' ', Viewport.Width));
 
 
         var line = 0;
         var line = 0;
 
 
@@ -1289,12 +1289,11 @@ public class TableView : View, IDesignable
     protected virtual void OnSelectedCellChanged (SelectedCellChangedEventArgs args) { SelectedCellChanged?.Invoke (this, args); }
     protected virtual void OnSelectedCellChanged (SelectedCellChangedEventArgs args) { SelectedCellChanged?.Invoke (this, args); }
 
 
     /// <summary>
     /// <summary>
-    ///     Override to provide custom multi colouring to cells.  Use <see cref="View.Driver"/> to with
-    ///     <see cref="IConsoleDriver.AddStr(string)"/>.  The driver will already be in the correct place when rendering and
-    ///     you
-    ///     must render the full <paramref name="render"/> or the view will not look right.  For simpler provision of color use
-    ///     <see cref="ColumnStyle.ColorGetter"/> For changing the content that is rendered use
-    ///     <see cref="ColumnStyle.RepresentationGetter"/>
+    ///     Override to provide custom multi-coloring to cells. Use methods like <see cref="View.AddStr(string)"/>.
+    ///     The cursor will already be in the correct position when rendering. You must render the full
+    ///     <paramref name="render"/> or the view will not look right. For simpler color provision use
+    ///     <see cref="ColumnStyle.ColorGetter"/>. For changing the content that is rendered use
+    ///     <see cref="ColumnStyle.RepresentationGetter"/>.
     /// </summary>
     /// </summary>
     /// <param name="cellAttribute"></param>
     /// <param name="cellAttribute"></param>
     /// <param name="render"></param>
     /// <param name="render"></param>
@@ -1310,19 +1309,19 @@ public class TableView : View, IDesignable
             {
             {
                 // invert the color of the current cell for the first character
                 // invert the color of the current cell for the first character
                 SetAttribute (new (cellAttribute.Foreground, cellAttribute.Background, TextStyle.Reverse));
                 SetAttribute (new (cellAttribute.Foreground, cellAttribute.Background, TextStyle.Reverse));
-                Driver?.AddRune ((Rune)render [0]);
+                AddRune ((Rune)render [0]);
 
 
                 if (render.Length > 1)
                 if (render.Length > 1)
                 {
                 {
                     SetAttribute (cellAttribute);
                     SetAttribute (cellAttribute);
-                    Driver?.AddStr (render.Substring (1));
+                    AddStr (render.Substring (1));
                 }
                 }
             }
             }
         }
         }
         else
         else
         {
         {
             SetAttribute (cellAttribute);
             SetAttribute (cellAttribute);
-            Driver?.AddStr (render);
+            AddStr (render);
         }
         }
     }
     }
 
 
@@ -1349,10 +1348,10 @@ public class TableView : View, IDesignable
     /// <returns></returns>
     /// <returns></returns>
     internal int GetHeaderHeightIfAny () { return ShouldRenderHeaders () ? GetHeaderHeight () : 0; }
     internal int GetHeaderHeightIfAny () { return ShouldRenderHeaders () ? GetHeaderHeight () : 0; }
 
 
-    private void AddRuneAt (IConsoleDriver d, int col, int row, Rune ch)
+    private void AddRuneAt (int col, int row, Rune ch)
     {
     {
         Move (col, row);
         Move (col, row);
-        d?.AddRune (ch);
+        AddRune (ch);
     }
     }
 
 
     /// <summary>
     /// <summary>
@@ -1534,14 +1533,14 @@ public class TableView : View, IDesignable
     /// <param name="width"></param>
     /// <param name="width"></param>
     private void ClearLine (int row, int width)
     private void ClearLine (int row, int width)
     {
     {
-        if (Driver is null)
+        if (Application.Screen.Height == 0)
         {
         {
             return;
             return;
         }
         }
 
 
         Move (0, row);
         Move (0, row);
         SetAttribute (GetAttributeForRole (VisualRole.Normal));
         SetAttribute (GetAttributeForRole (VisualRole.Normal));
-        Driver.AddStr (new (' ', width));
+        AddStr (new (' ', width));
     }
     }
 
 
     private void ClearMultiSelectedRegions (bool keepToggledSelections)
     private void ClearMultiSelectedRegions (bool keepToggledSelections)
@@ -1734,7 +1733,7 @@ public class TableView : View, IDesignable
                 }
                 }
             }
             }
 
 
-            AddRuneAt (Driver, c, row, rune);
+            AddRuneAt (c, row, rune);
         }
         }
     }
     }
 
 
@@ -1762,7 +1761,7 @@ public class TableView : View, IDesignable
 
 
             Move (current.X, row);
             Move (current.X, row);
 
 
-            Driver?.AddStr (TruncateOrPad (colName, colName, current.Width, colStyle));
+            AddStr (TruncateOrPad (colName, colName, current.Width, colStyle));
 
 
             if (Style.ExpandLastColumn == false && current.IsVeryLast)
             if (Style.ExpandLastColumn == false && current.IsVeryLast)
             {
             {
@@ -1810,9 +1809,9 @@ public class TableView : View, IDesignable
                 }
                 }
             }
             }
 
 
-            if (Driver is { })
+            if (Application.Screen.Height > 0)
             {
             {
-                AddRuneAt (Driver, c, row, rune);
+                AddRuneAt (c, row, rune);
             }
             }
         }
         }
     }
     }
@@ -1906,7 +1905,7 @@ public class TableView : View, IDesignable
                 }
                 }
             }
             }
 
 
-            AddRuneAt (Driver, c, row, rune);
+            AddRuneAt (c, row, rune);
         }
         }
     }
     }
 
 
@@ -1934,7 +1933,7 @@ public class TableView : View, IDesignable
         }
         }
 
 
         SetAttribute (attribute.Value);
         SetAttribute (attribute.Value);
-        Driver?.AddStr (new (' ', Viewport.Width));
+        AddStr (new (' ', Viewport.Width));
 
 
         // Render cells for each visible header for the current row
         // Render cells for each visible header for the current row
         for (var i = 0; i < columnsToRender.Length; i++)
         for (var i = 0; i < columnsToRender.Length; i++)

+ 1 - 1
Terminal.Gui/Views/TableView/TreeTableSource.cs

@@ -178,7 +178,7 @@ public class TreeTableSource<T> : IEnumerableTableSource<T>, IDisposable where T
 
 
         Branch<T> branch = RowToBranch (hit.Value.Y);
         Branch<T> branch = RowToBranch (hit.Value.Y);
 
 
-        if (branch.IsHitOnExpandableSymbol (Application.Driver, offsetX.Value))
+        if (branch.IsHitOnExpandableSymbol (offsetX.Value))
         {
         {
             T m = branch.Model;
             T m = branch.Model;
 
 

+ 3 - 3
Terminal.Gui/Views/TextInput/TextField.cs

@@ -973,7 +973,7 @@ public class TextField : View, IDesignable
 
 
             if (col + cols <= width)
             if (col + cols <= width)
             {
             {
-                Driver?.AddRune (Secret ? Glyphs.Dot : rune);
+                AddRune (Secret ? Glyphs.Dot : rune);
             }
             }
 
 
             if (!TextModel.SetCol (ref col, width, cols))
             if (!TextModel.SetCol (ref col, width, cols))
@@ -992,7 +992,7 @@ public class TextField : View, IDesignable
         // Fill rest of line with spaces
         // Fill rest of line with spaces
         for (int i = col; i < width; i++)
         for (int i = col; i < width; i++)
         {
         {
-            Driver?.AddRune ((Rune)' ');
+            AddRune ((Rune)' ');
         }
         }
 
 
         PositionCursor ();
         PositionCursor ();
@@ -1717,7 +1717,7 @@ public class TextField : View, IDesignable
             render = render [..Viewport.Width];
             render = render [..Viewport.Width];
         }
         }
 
 
-        Driver?.AddStr (render);
+        AddStr (render);
     }
     }
 
 
     private void SetClipboard (IEnumerable<Rune> text)
     private void SetClipboard (IEnumerable<Rune> text)

+ 4 - 4
Terminal.Gui/Views/TextInput/TextValidateField.cs

@@ -177,7 +177,7 @@ public class TextValidateField : View, IDesignable
         if (_provider is null)
         if (_provider is null)
         {
         {
             Move (0, 0);
             Move (0, 0);
-            Driver?.AddStr ("Error: ITextValidateProvider not set!");
+            AddStr ("Error: ITextValidateProvider not set!");
 
 
             return true;
             return true;
         }
         }
@@ -194,7 +194,7 @@ public class TextValidateField : View, IDesignable
 
 
         for (var i = 0; i < marginLeft; i++)
         for (var i = 0; i < marginLeft; i++)
         {
         {
-            Driver?.AddRune ((Rune)' ');
+            AddRune ((Rune)' ');
         }
         }
 
 
         // Content
         // Content
@@ -203,7 +203,7 @@ public class TextValidateField : View, IDesignable
         // Content
         // Content
         for (var i = 0; i < _provider.DisplayText.Length; i++)
         for (var i = 0; i < _provider.DisplayText.Length; i++)
         {
         {
-            Driver?.AddRune ((Rune)_provider.DisplayText [i]);
+            AddRune ((Rune)_provider.DisplayText [i]);
         }
         }
 
 
         // Right Margin
         // Right Margin
@@ -211,7 +211,7 @@ public class TextValidateField : View, IDesignable
 
 
         for (var i = 0; i < marginRight; i++)
         for (var i = 0; i < marginRight; i++)
         {
         {
-            Driver?.AddRune ((Rune)' ');
+            AddRune ((Rune)' ');
         }
         }
 
 
         return true;
         return true;

+ 1 - 1
Terminal.Gui/Views/TreeView/Branch.cs

@@ -454,7 +454,7 @@ internal class Branch<T> where T : class
     /// <param name="driver"></param>
     /// <param name="driver"></param>
     /// <param name="x"></param>
     /// <param name="x"></param>
     /// <returns></returns>
     /// <returns></returns>
-    internal bool IsHitOnExpandableSymbol (IConsoleDriver driver, int x)
+    internal bool IsHitOnExpandableSymbol (int x)
     {
     {
         // if leaf node then we cannot expand
         // if leaf node then we cannot expand
         if (!CanExpand ())
         if (!CanExpand ())

+ 3 - 3
Terminal.Gui/Views/TreeView/TreeView.cs

@@ -1065,7 +1065,7 @@ public class TreeView<T> : View, ITreeView where T : class
                 return false;
                 return false;
             }
             }
 
 
-            bool isExpandToggleAttempt = clickedBranch.IsHitOnExpandableSymbol (Driver, me.Position.X);
+            bool isExpandToggleAttempt = clickedBranch.IsHitOnExpandableSymbol (me.Position.X);
 
 
             // If we are already selected (double click)
             // If we are already selected (double click)
             if (Equals (SelectedObject, clickedBranch.Model))
             if (Equals (SelectedObject, clickedBranch.Model))
@@ -1157,7 +1157,7 @@ public class TreeView<T> : View, ITreeView where T : class
         if (TreeBuilder is null)
         if (TreeBuilder is null)
         {
         {
             Move (0, 0);
             Move (0, 0);
-            Driver?.AddStr (NoBuilderError);
+            AddStr (NoBuilderError);
 
 
             return true;
             return true;
         }
         }
@@ -1179,7 +1179,7 @@ public class TreeView<T> : View, ITreeView where T : class
                 // Else clear the line to prevent stale symbols due to scrolling etc
                 // Else clear the line to prevent stale symbols due to scrolling etc
                 Move (0, line);
                 Move (0, line);
                 SetAttribute (GetAttributeForRole (VisualRole.Normal));
                 SetAttribute (GetAttributeForRole (VisualRole.Normal));
-                Driver?.AddStr (new (' ', Viewport.Width));
+                AddStr (new (' ', Viewport.Width));
             }
             }
         }
         }
 
 

+ 3 - 2
Terminal.sln

@@ -1,7 +1,7 @@
 
 
 Microsoft Visual Studio Solution File, Format Version 12.00
 Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio Version 18
 # Visual Studio Version 18
-VisualStudioVersion = 18.0.11018.127 d18.0
+VisualStudioVersion = 18.0.11018.127
 MinimumVisualStudioVersion = 10.0.40219.1
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Terminal.Gui", "Terminal.Gui\Terminal.Gui.csproj", "{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}"
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Terminal.Gui", "Terminal.Gui\Terminal.Gui.csproj", "{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}"
 EndProject
 EndProject
@@ -32,7 +32,7 @@ EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GitHub", "GitHub", "{13BB2C46-B324-4B9C-92EB-CE6184D4736E}"
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GitHub", "GitHub", "{13BB2C46-B324-4B9C-92EB-CE6184D4736E}"
 	ProjectSection(SolutionItems) = preProject
 	ProjectSection(SolutionItems) = preProject
 		.github\workflows\api-docs.yml = .github\workflows\api-docs.yml
 		.github\workflows\api-docs.yml = .github\workflows\api-docs.yml
-		.github\workflows\build-release.yml = .github\workflows\build-release.yml
+		.github\workflows\build.yml = .github\workflows\build.yml
 		.github\workflows\check-duplicates.yml = .github\workflows\check-duplicates.yml
 		.github\workflows\check-duplicates.yml = .github\workflows\check-duplicates.yml
 		copilot-instructions.md = copilot-instructions.md
 		copilot-instructions.md = copilot-instructions.md
 		GitVersion.yml = GitVersion.yml
 		GitVersion.yml = GitVersion.yml
@@ -47,6 +47,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{C7A51224-5
 		.github\CODEOWNERS = .github\CODEOWNERS
 		.github\CODEOWNERS = .github\CODEOWNERS
 		CODE_OF_CONDUCT.md = CODE_OF_CONDUCT.md
 		CODE_OF_CONDUCT.md = CODE_OF_CONDUCT.md
 		CONTRIBUTING.md = CONTRIBUTING.md
 		CONTRIBUTING.md = CONTRIBUTING.md
+		.github\copilot-instructions.md = .github\copilot-instructions.md
 		README.md = README.md
 		README.md = README.md
 	EndProjectSection
 	EndProjectSection
 EndProject
 EndProject

+ 1 - 1
Tests/UnitTests/Application/ApplicationTests.cs

@@ -584,7 +584,7 @@ public class ApplicationTests
     [AutoInitShutdown]
     [AutoInitShutdown]
     public void Invoke_Adds_Idle ()
     public void Invoke_Adds_Idle ()
     {
     {
-        var top = new Toplevel ();
+        Toplevel top = new ();
         RunState rs = Application.Begin (top);
         RunState rs = Application.Begin (top);
 
 
         var actionCalled = 0;
         var actionCalled = 0;

+ 9 - 13
Tests/UnitTests/Dialogs/WizardTests.cs

@@ -20,8 +20,8 @@ public class WizardTests ()
     public void Finish_Button_Closes ()
     public void Finish_Button_Closes ()
     {
     {
         // https://github.com/gui-cs/Terminal.Gui/issues/1833
         // https://github.com/gui-cs/Terminal.Gui/issues/1833
-        var wizard = new Wizard ();
-        var step1 = new WizardStep { Title = "step1" };
+        Wizard wizard = new ();
+        WizardStep step1 = new () { Title = "step1" };
         wizard.AddStep (step1);
         wizard.AddStep (step1);
 
 
         var finishedFired = false;
         var finishedFired = false;
@@ -31,11 +31,10 @@ public class WizardTests ()
         wizard.Closed += (s, e) => { closedFired = true; };
         wizard.Closed += (s, e) => { closedFired = true; };
 
 
         RunState runstate = Application.Begin (wizard);
         RunState runstate = Application.Begin (wizard);
-        var firstIteration = true;
-        Application.RunIteration (ref runstate, firstIteration);
+        AutoInitShutdownAttribute.RunIteration ();
 
 
         wizard.NextFinishButton.InvokeCommand (Command.Accept);
         wizard.NextFinishButton.InvokeCommand (Command.Accept);
-        Application.RunIteration (ref runstate, firstIteration);
+        AutoInitShutdownAttribute.RunIteration ();
         Application.End (runstate);
         Application.End (runstate);
         Assert.True (finishedFired);
         Assert.True (finishedFired);
         Assert.True (closedFired);
         Assert.True (closedFired);
@@ -44,10 +43,9 @@ public class WizardTests ()
 
 
         // Same test, but with two steps
         // Same test, but with two steps
         wizard = new ();
         wizard = new ();
-        firstIteration = false;
         step1 = new() { Title = "step1" };
         step1 = new() { Title = "step1" };
         wizard.AddStep (step1);
         wizard.AddStep (step1);
-        var step2 = new WizardStep { Title = "step2" };
+        WizardStep step2 = new () { Title = "step2" };
         wizard.AddStep (step2);
         wizard.AddStep (step2);
 
 
         finishedFired = false;
         finishedFired = false;
@@ -57,7 +55,7 @@ public class WizardTests ()
         wizard.Closed += (s, e) => { closedFired = true; };
         wizard.Closed += (s, e) => { closedFired = true; };
 
 
         runstate = Application.Begin (wizard);
         runstate = Application.Begin (wizard);
-        Application.RunIteration (ref runstate, firstIteration);
+        AutoInitShutdownAttribute.RunIteration ();
 
 
         Assert.Equal (step1.Title, wizard.CurrentStep.Title);
         Assert.Equal (step1.Title, wizard.CurrentStep.Title);
         wizard.NextFinishButton.InvokeCommand (Command.Accept);
         wizard.NextFinishButton.InvokeCommand (Command.Accept);
@@ -77,7 +75,6 @@ public class WizardTests ()
 
 
         // Same test, but with two steps but the 1st one disabled
         // Same test, but with two steps but the 1st one disabled
         wizard = new ();
         wizard = new ();
-        firstIteration = false;
         step1 = new() { Title = "step1" };
         step1 = new() { Title = "step1" };
         wizard.AddStep (step1);
         wizard.AddStep (step1);
         step2 = new() { Title = "step2" };
         step2 = new() { Title = "step2" };
@@ -91,7 +88,7 @@ public class WizardTests ()
         wizard.Closed += (s, e) => { closedFired = true; };
         wizard.Closed += (s, e) => { closedFired = true; };
 
 
         runstate = Application.Begin (wizard);
         runstate = Application.Begin (wizard);
-        Application.RunIteration (ref runstate, firstIteration);
+        AutoInitShutdownAttribute.RunIteration ();
 
 
         Assert.Equal (step2.Title, wizard.CurrentStep.Title);
         Assert.Equal (step2.Title, wizard.CurrentStep.Title);
         Assert.Equal (wizard.GetLastStep ().Title, wizard.CurrentStep.Title);
         Assert.Equal (wizard.GetLastStep ().Title, wizard.CurrentStep.Title);
@@ -458,13 +455,12 @@ public class WizardTests ()
                 Glyphs.LRCornerDbl
                 Glyphs.LRCornerDbl
             }";
             }";
 
 
-        var wizard = new Wizard { Title = title, Width = width, Height = height };
+        Wizard wizard = new () { Title = title, Width = width, Height = height };
         wizard.AddStep (new() { Title = stepTitle });
         wizard.AddStep (new() { Title = stepTitle });
 
 
         //wizard.LayoutSubViews ();
         //wizard.LayoutSubViews ();
-        var firstIteration = false;
         RunState runstate = Application.Begin (wizard);
         RunState runstate = Application.Begin (wizard);
-        Application.RunIteration (ref runstate, firstIteration);
+        AutoInitShutdownAttribute.RunIteration ();
 
 
         // TODO: Disabled until Dim.Auto is used in Dialog
         // TODO: Disabled until Dim.Auto is used in Dialog
         //DriverAsserts.AssertDriverContentsWithFrameAre (
         //DriverAsserts.AssertDriverContentsWithFrameAre (

+ 2 - 2
Tests/UnitTests/View/Adornment/BorderTests.cs

@@ -222,7 +222,7 @@ public class BorderTests (ITestOutputHelper output)
     [InlineData (10)]
     [InlineData (10)]
     public void Border_With_Title_Border_Double_Thickness_Top_Three_Size_Width (int width)
     public void Border_With_Title_Border_Double_Thickness_Top_Three_Size_Width (int width)
     {
     {
-        var win = new Window
+        Window win = new ()
         {
         {
             Title = "1234", Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.Double
             Title = "1234", Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.Double
         };
         };
@@ -231,7 +231,7 @@ public class BorderTests (ITestOutputHelper output)
         RunState rs = Application.Begin (win);
         RunState rs = Application.Begin (win);
 
 
         AutoInitShutdownAttribute.FakeResize(new Size(width, 4));
         AutoInitShutdownAttribute.FakeResize(new Size(width, 4));
-        Application.RunIteration (ref rs, false);
+        AutoInitShutdownAttribute.RunIteration ();
         var expected = string.Empty;
         var expected = string.Empty;
 
 
         switch (width)
         switch (width)

+ 3 - 3
Tests/UnitTests/View/Draw/ClearViewportTests.cs

@@ -321,7 +321,7 @@ public class ClearViewportTests (ITestOutputHelper output)
     {
     {
         ConfigurationManager.Enable (ConfigLocations.LibraryResources);
         ConfigurationManager.Enable (ConfigLocations.LibraryResources);
 
 
-        var root = new View { Width = 20, Height = 10 };
+        View root = new () { Width = 20, Height = 10 };
 
 
         string text = new ('c', 100);
         string text = new ('c', 100);
 
 
@@ -335,10 +335,10 @@ public class ClearViewportTests (ITestOutputHelper output)
 
 
         root.Add (v);
         root.Add (v);
 
 
-        var top = new Toplevel ();
+        Toplevel top = new ();
         top.Add (root);
         top.Add (root);
         RunState runState = Application.Begin (top);
         RunState runState = Application.Begin (top);
-        Application.RunIteration (ref runState);
+        AutoInitShutdownAttribute.RunIteration ();
 
 
         if (label)
         if (label)
         {
         {

+ 6 - 6
Tests/UnitTests/Views/LabelTests.cs

@@ -91,20 +91,20 @@ public class LabelTests (ITestOutputHelper output)
     [AutoInitShutdown]
     [AutoInitShutdown]
     public void Label_Draw_Fill_Remaining ()
     public void Label_Draw_Fill_Remaining ()
     {
     {
-        var tfSize = new Size (80, 1);
+        Size tfSize = new (80, 1);
 
 
-        var label = new Label { Text = "This label needs to be cleared before rewritten.", Width = tfSize.Width, Height = tfSize.Height };
+        Label label = new () { Text = "This label needs to be cleared before rewritten.", Width = tfSize.Width, Height = tfSize.Height };
 
 
-        var tf1 = new TextFormatter { Direction = TextDirection.LeftRight_TopBottom, ConstrainToSize = tfSize };
+        TextFormatter tf1 = new () { Direction = TextDirection.LeftRight_TopBottom, ConstrainToSize = tfSize };
         tf1.Text = "This TextFormatter (tf1) without fill will not be cleared on rewritten.";
         tf1.Text = "This TextFormatter (tf1) without fill will not be cleared on rewritten.";
 
 
-        var tf2 = new TextFormatter { Direction = TextDirection.LeftRight_TopBottom, ConstrainToSize = tfSize, FillRemaining = true };
+        TextFormatter tf2 = new () { Direction = TextDirection.LeftRight_TopBottom, ConstrainToSize = tfSize, FillRemaining = true };
         tf2.Text = "This TextFormatter (tf2) with fill will be cleared on rewritten.";
         tf2.Text = "This TextFormatter (tf2) with fill will be cleared on rewritten.";
 
 
-        var top = new Toplevel ();
+        Toplevel top = new ();
         top.Add (label);
         top.Add (label);
         RunState runState = Application.Begin (top);
         RunState runState = Application.Begin (top);
-        Application.RunIteration (ref runState);
+        AutoInitShutdownAttribute.RunIteration ();
 
 
         Assert.False (label.TextFormatter.FillRemaining);
         Assert.False (label.TextFormatter.FillRemaining);
         Assert.False (tf1.FillRemaining);
         Assert.False (tf1.FillRemaining);

+ 8 - 9
Tests/UnitTests/Views/Menuv1/MenuBarv1Tests.cs

@@ -467,7 +467,7 @@ public class MenuBarv1Tests (ITestOutputHelper output)
         Button.DefaultShadow = ShadowStyle.None;
         Button.DefaultShadow = ShadowStyle.None;
 
 
         Toplevel top = new ();
         Toplevel top = new ();
-        var win = new Window ();
+        Window win = new ();
         top.Add (win);
         top.Add (win);
         RunState rsTop = Application.Begin (top);
         RunState rsTop = Application.Begin (top);
         AutoInitShutdownAttribute.FakeResize(new Size(40, 15))    ;
         AutoInitShutdownAttribute.FakeResize(new Size(40, 15))    ;
@@ -503,8 +503,8 @@ public class MenuBarv1Tests (ITestOutputHelper output)
             "Save As",
             "Save As",
             "Delete"
             "Delete"
         };
         };
-        var dialog = new Dialog { X = 2, Y = 2, Width = 15, Height = 4 };
-        var menu = new MenuBar { X = Pos.Center (), Width = 10 };
+        Dialog dialog = new () { X = 2, Y = 2, Width = 15, Height = 4 };
+        MenuBar menu = new () { X = Pos.Center (), Width = 10 };
 
 
         menu.Menus = new MenuBarItem []
         menu.Menus = new MenuBarItem []
         {
         {
@@ -572,7 +572,7 @@ public class MenuBarv1Tests (ITestOutputHelper output)
         }
         }
 
 
         RunState rsDialog = Application.Begin (dialog);
         RunState rsDialog = Application.Begin (dialog);
-        Application.RunIteration (ref rsDialog);
+        AutoInitShutdownAttribute.RunIteration ();
 
 
         Assert.Equal (new (2, 2, 15, 4), dialog.Frame);
         Assert.Equal (new (2, 2, 15, 4), dialog.Frame);
 
 
@@ -598,7 +598,7 @@ public class MenuBarv1Tests (ITestOutputHelper output)
 
 
         Assert.Equal ("File", menu.Menus [0].Title);
         Assert.Equal ("File", menu.Menus [0].Title);
         menu.OpenMenu ();
         menu.OpenMenu ();
-        Application.RunIteration (ref rsDialog);
+        AutoInitShutdownAttribute.RunIteration ();
 
 
         DriverAssert.AssertDriverContentsWithFrameAre (
         DriverAssert.AssertDriverContentsWithFrameAre (
                                                       @"
                                                       @"
@@ -624,8 +624,7 @@ public class MenuBarv1Tests (ITestOutputHelper output)
 
 
         // Need to fool MainLoop into thinking it's running
         // Need to fool MainLoop into thinking it's running
         Application.MainLoop.Running = true;
         Application.MainLoop.Running = true;
-        bool firstIteration = true;
-        Application.RunIteration (ref rsDialog, firstIteration);
+        AutoInitShutdownAttribute.RunIteration ();
         Assert.Equal (items [0], menu.Menus [0].Title);
         Assert.Equal (items [0], menu.Menus [0].Title);
 
 
         DriverAssert.AssertDriverContentsWithFrameAre (
         DriverAssert.AssertDriverContentsWithFrameAre (
@@ -654,13 +653,13 @@ public class MenuBarv1Tests (ITestOutputHelper output)
 
 
             Application.RaiseMouseEvent (new () { ScreenPosition = new (20, 5 + i), Flags = MouseFlags.Button1Clicked });
             Application.RaiseMouseEvent (new () { ScreenPosition = new (20, 5 + i), Flags = MouseFlags.Button1Clicked });
 
 
-            Application.RunIteration (ref rsDialog);
+            AutoInitShutdownAttribute.RunIteration ();
             Assert.Equal (items [i], menu.Menus [0].Title);
             Assert.Equal (items [i], menu.Menus [0].Title);
         }
         }
 
 
         AutoInitShutdownAttribute.FakeResize(new Size(20, 15));
         AutoInitShutdownAttribute.FakeResize(new Size(20, 15));
         menu.OpenMenu ();
         menu.OpenMenu ();
-        Application.RunIteration (ref rsDialog);
+        AutoInitShutdownAttribute.RunIteration ();
 
 
         DriverAssert.AssertDriverContentsWithFrameAre (
         DriverAssert.AssertDriverContentsWithFrameAre (
                                                       @"
                                                       @"

+ 2 - 2
Tests/UnitTests/Views/TextViewTests.cs

@@ -4813,7 +4813,7 @@ This is the second line.
     public void Selected_Text_Shows ()
     public void Selected_Text_Shows ()
     {
     {
         // Proves #3022 is fixed (TextField selected text does not show in v2)
         // Proves #3022 is fixed (TextField selected text does not show in v2)
-        var top = new Toplevel ();
+        Toplevel top = new ();
         top.Add (_textView);
         top.Add (_textView);
         RunState rs = Application.Begin (top);
         RunState rs = Application.Begin (top);
 
 
@@ -4833,7 +4833,7 @@ This is the second line.
 
 
         _textView.NewKeyDownEvent (Key.CursorRight.WithCtrl.WithShift);
         _textView.NewKeyDownEvent (Key.CursorRight.WithCtrl.WithShift);
 
 
-        Application.RunIteration (ref rs, true);
+        AutoInitShutdownAttribute.RunIteration ();
         Assert.Equal (new (4, 0), _textView.CursorPosition);
         Assert.Equal (new (4, 0), _textView.CursorPosition);
 
 
         //                                             TAB to jump between text fields.
         //                                             TAB to jump between text fields.

+ 2 - 0
docfx/docs/View.md

@@ -36,6 +36,8 @@ See the [Layout Deep Dive](layout.md) and the [Arrangement Deep Dive](arrangemen
 
 
 See the [Drawing Deep Dive](drawing.md).
 See the [Drawing Deep Dive](drawing.md).
 
 
+Views should use viewport-relative coordinates for all drawing operations. The `View.Move(col, row)` method positions the cursor using viewport-relative coordinates. For screen dimensions, use @Terminal.Gui.App.Application.Screen instead of accessing the driver directly.
+
 ### Navigation
 ### Navigation
 
 
 See the [Navigation Deep Dive](navigation.md).
 See the [Navigation Deep Dive](navigation.md).

+ 23 - 7
docfx/docs/drivers.md

@@ -151,7 +151,7 @@ When `Application.Shutdown()` is called:
 
 
 ### IConsoleDriver
 ### IConsoleDriver
 
 
-The main driver interface that applications interact with. Provides:
+The main driver interface that the framework uses internally. Provides:
 
 
 - **Screen Management**: `Screen`, `Cols`, `Rows`, `Contents`
 - **Screen Management**: `Screen`, `Cols`, `Rows`, `Contents`
 - **Drawing Operations**: `AddRune()`, `AddStr()`, `Move()`, `FillRect()`
 - **Drawing Operations**: `AddRune()`, `AddStr()`, `Move()`, `FillRect()`
@@ -161,6 +161,12 @@ The main driver interface that applications interact with. Provides:
 - **Events**: `KeyDown`, `KeyUp`, `MouseEvent`, `SizeChanged`
 - **Events**: `KeyDown`, `KeyUp`, `MouseEvent`, `SizeChanged`
 - **Platform Features**: `SupportsTrueColor`, `Force16Colors`, `Clipboard`
 - **Platform Features**: `SupportsTrueColor`, `Force16Colors`, `Clipboard`
 
 
+**Note:** The driver is internal to Terminal.Gui. View classes should not access `Driver` directly. Instead:
+- Use @Terminal.Gui.App.Application.Screen to get screen dimensions
+- Use @Terminal.Gui.ViewBase.View.Move for positioning (with viewport-relative coordinates)
+- Use @Terminal.Gui.ViewBase.View.AddRune and @Terminal.Gui.ViewBase.View.AddStr for drawing
+- ViewBase infrastructure classes (in `Terminal.Gui/ViewBase/`) can access Driver when needed for framework implementation
+
 ### IConsoleDriverFacade
 ### IConsoleDriverFacade
 
 
 Extended interface for v2 drivers that exposes the internal components:
 Extended interface for v2 drivers that exposes the internal components:
@@ -215,18 +221,23 @@ This ensures Terminal.Gui applications can be debugged directly in Visual Studio
 - Captures output for verification
 - Captures output for verification
 - Always used when `Application._forceFakeConsole` is true
 - Always used when `Application._forceFakeConsole` is true
 
 
-## Example: Accessing Driver Components
+## Example: Checking Driver Capabilities
 
 
 ```csharp
 ```csharp
 Application.Init();
 Application.Init();
 
 
-// Access the driver
-IConsoleDriver driver = Application.Driver;
+// The driver is internal - access through Application properties
+// Check screen dimensions
+var screenWidth = Application.Screen.Width;
+var screenHeight = Application.Screen.Height;
+
+// Check if 24-bit color is supported
+bool supportsTrueColor = Application.Driver?.SupportsTrueColor ?? false;
 
 
-// Check if it's a v2 driver with facade
-if (driver is IConsoleDriverFacade facade)
+// Access advanced components (for framework/infrastructure code only)
+if (Application.Driver is IConsoleDriverFacade facade)
 {
 {
-    // Access individual components
+    // Access individual components for advanced scenarios
     IInputProcessor inputProcessor = facade.InputProcessor;
     IInputProcessor inputProcessor = facade.InputProcessor;
     IOutputBuffer outputBuffer = facade.OutputBuffer;
     IOutputBuffer outputBuffer = facade.OutputBuffer;
     IWindowSizeMonitor sizeMonitor = facade.WindowSizeMonitor;
     IWindowSizeMonitor sizeMonitor = facade.WindowSizeMonitor;
@@ -239,6 +250,11 @@ if (driver is IConsoleDriverFacade facade)
 }
 }
 ```
 ```
 
 
+**Important:** View subclasses should not access `Application.Driver`. Use the View APIs instead:
+- `View.Move(col, row)` for positioning
+- `View.AddRune()` and `View.AddStr()` for drawing
+- `Application.Screen` for screen dimensions
+
 ## Custom Drivers
 ## Custom Drivers
 
 
 To create a custom driver, implement `IComponentFactory<T>`:
 To create a custom driver, implement `IComponentFactory<T>`:

+ 22 - 2
docfx/docs/migratingfromv1.md

@@ -225,7 +225,7 @@ The cursor and focus system has been redesigned in v2 to be more consistent and
 
 
 ### Cursor
 ### Cursor
 
 
-In v1, whether the cursor (the flashing caret) was visible or not was controlled by `View.CursorVisibility` which was an enum extracted from Ncruses/Terminfo. It only works in some cases on Linux, and only partially with `WindowsDriver`. The position of the cursor was the same as `ConsoleDriver.Row`/`Col` and determined by the last call to `ConsoleDriver.Move`. `View.PositionCursor()` could be overridden by views to cause `Application` to call `ConsoleDriver.Move` on behalf of the app and to manage setting `CursorVisibility`. This API was confusing and bug-prone.
+In v1, whether the cursor (the flashing caret) was visible or not was controlled by `View.CursorVisibility` which was an enum extracted from Ncruses/Terminfo. It only works in some cases on Linux, and only partially with `WindowsDriver`. The position of the cursor was determined by the last call to the driver's Move method. `View.PositionCursor()` could be overridden by views to cause `Application` to call the driver's positioning method on behalf of the app and to manage setting `CursorVisibility`. This API was confusing and bug-prone.
 
 
 In v2, the API is (NOT YET IMPLEMENTED) simplified. A view simply reports the style of cursor it wants and the Viewport-relative location:
 In v2, the API is (NOT YET IMPLEMENTED) simplified. A view simply reports the style of cursor it wants and the Viewport-relative location:
 
 
@@ -237,7 +237,7 @@ In v2, the API is (NOT YET IMPLEMENTED) simplified. A view simply reports the st
 	- If `null` the default cursor style is used.
 	- If `null` the default cursor style is used.
 	- If `{}` specifies the style of cursor. See [cursor.md](cursor.md) for more.
 	- If `{}` specifies the style of cursor. See [cursor.md](cursor.md) for more.
 * `Application` now has APIs for querying available cursor styles.
 * `Application` now has APIs for querying available cursor styles.
-* The details in `ConsoleDriver` are no longer available to applications.	
+* The driver details are no longer directly accessible to View subclasses.	
 
 
 #### How to Fix (Cursor API)
 #### How to Fix (Cursor API)
 
 
@@ -245,6 +245,26 @@ In v2, the API is (NOT YET IMPLEMENTED) simplified. A view simply reports the st
 * Set @Terminal.Gui.ViewBase.View.CursorVisibility to the cursor style you want to use.
 * Set @Terminal.Gui.ViewBase.View.CursorVisibility to the cursor style you want to use.
 * Remove any overrides of `OnEnter` and `OnLeave` that explicitly change the cursor.
 * Remove any overrides of `OnEnter` and `OnLeave` that explicitly change the cursor.
 
 
+### Driver Access
+
+In v1, Views could access `Driver` directly (e.g., `Driver.Move()`, `Driver.Rows`, `Driver.Cols`). In v2, `Driver` is internal and View subclasses should not access it directly. ViewBase provides all necessary abstractions for Views to function without needing direct driver access.
+
+#### How to Fix (Driver Access)
+
+* Replace `Driver.Rows` and `Driver.Cols` with @Terminal.Gui.App.Application.Screen.Height and @Terminal.Gui.App.Application.Screen.Width
+* Replace direct `Driver.Move(screenX, screenY)` calls with @Terminal.Gui.ViewBase.View.Move using viewport-relative coordinates
+* Use @Terminal.Gui.ViewBase.View.AddRune and @Terminal.Gui.ViewBase.View.AddStr for drawing
+* ViewBase infrastructure classes (in `Terminal.Gui/ViewBase/`) can still access Driver for framework implementation needs
+
+```diff
+- if (x >= Driver.Cols) return;
++ if (x >= Application.Screen.Width) return;
+
+- Point screenPos = ViewportToScreen(new Point(col, row));
+- Driver.Move(screenPos.X, screenPos.Y);
++ Move(col, row);  // Move handles viewport-to-screen conversion
+```
+
 ### Focus
 ### Focus
 
 
 See [navigation.md](navigation.md) for more details.
 See [navigation.md](navigation.md) for more details.

+ 4 - 4
docfx/docs/multitasking.md

@@ -89,7 +89,7 @@ public class ClockView : View
         Add(timeLabel);
         Add(timeLabel);
         
         
         // Update every second
         // Update every second
-        timerToken = Application.MainLoop.AddTimeout(
+        timerToken = Application.AddTimeout(
             TimeSpan.FromSeconds(1), 
             TimeSpan.FromSeconds(1), 
             UpdateTime
             UpdateTime
         );
         );
@@ -105,7 +105,7 @@ public class ClockView : View
     {
     {
         if (disposing && timerToken != null)
         if (disposing && timerToken != null)
         {
         {
-            Application.MainLoop.RemoveTimeout(timerToken);
+            Application.RemoveTimeout(timerToken);
         }
         }
         base.Dispose(disposing);
         base.Dispose(disposing);
     }
     }
@@ -220,7 +220,7 @@ Task.Run(() =>
 ### ❌ Don't: Forget to clean up timers
 ### ❌ Don't: Forget to clean up timers
 ```csharp
 ```csharp
 // Memory leak - timer keeps running after view is disposed
 // Memory leak - timer keeps running after view is disposed
-Application.MainLoop.AddTimeout(TimeSpan.FromSeconds(1), UpdateStatus);
+Application.AddTimeout(TimeSpan.FromSeconds(1), UpdateStatus);
 ```
 ```
 
 
 ### ✅ Do: Remove timers in Dispose
 ### ✅ Do: Remove timers in Dispose
@@ -229,7 +229,7 @@ protected override void Dispose(bool disposing)
 {
 {
     if (disposing && timerToken != null)
     if (disposing && timerToken != null)
     {
     {
-        Application.MainLoop.RemoveTimeout(timerToken);
+        Application.RemoveTimeout(timerToken);
     }
     }
     base.Dispose(disposing);
     base.Dispose(disposing);
 }
 }