Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
7fca62c
Update Examples link in README.md (#5104)
tig Apr 28, 2026
e4388c8
Reframe layout docs around responsive UI and instructional style (#5110)
Copilot Apr 28, 2026
3df9137
Merge branch 'develop' into backmerge/v2.0.0
tig Apr 29, 2026
8442c55
Merge pull request #5113 from gui-cs/backmerge/v2.0.0
tig Apr 29, 2026
bf83d8d
Fix XML comment has cref attribute 'Buttons' that could not be resolv…
BDisp Apr 29, 2026
1b4f221
docs: tweak hero gif stats per #5108 (#5121)
livlign Apr 29, 2026
b43d101
Fixes #5088 - Margin Shadow sizing wrong (#5101)
tig Apr 29, 2026
41da905
Fixes #5114. Remove main from publish branch triggers; use tags only …
tig Apr 29, 2026
0410158
Fixes #5072. TableView reserves space for later columns when laying o…
harder Apr 29, 2026
96fbe8a
Fixes #5119. Popover isn't recalculating it's position when terminal …
BDisp Apr 29, 2026
af8bbe5
Fixes #5122. Visible popovers are always layout and redrawn in every …
BDisp Apr 30, 2026
d079d36
Fixes #5075. TableView ShowVerticalCellLines renders incorrectly with…
harder Apr 30, 2026
6361f33
Fixes #5132. TableView Home/End navigation with FullRowSelect (#5133)
Copilot May 1, 2026
c50a81e
Fixes #5068. TableView appends ellipsis indicator when cell content i…
harder May 1, 2026
688c292
Reverts #5133. Revert TableView Home/End FullRowSelect change (#5136)
tig May 1, 2026
57f49fd
Fixes #5130. Fix OutputBufferImpl race condition on Contents referenc…
tig May 1, 2026
4b4bcfd
Fixes #5137 - BREAKING CHANGE - Rename `TableSelection.Cursor` to `Ta…
Copilot May 3, 2026
b2167f6
Fixes #5145. ReadOnly TextView mouse selection still cannot include f…
BDisp May 3, 2026
93f0d23
Fixes #5137. Add custom header styling for TableView (#5138)
Copilot May 3, 2026
8157d73
Fixes #5112. AOT config warning cleanup (#5134)
harder May 3, 2026
ef9a96a
Fixes #5149. Improve DropDownList keyboard use when closed (#5151)
Copilot May 4, 2026
4718f6f
Fixes #5157. Add `RunAsync(IRunnable, CancellationToken)` (#5159)
Copilot May 4, 2026
020c3ff
Fixes #5158. Refactor `FileDialog` base type from Dialog to Dialog<IR…
Copilot May 4, 2026
b152222
Fixes #5103. Disable NerdFonts default in FileDialogExamples scenario…
Copilot May 4, 2026
3a782c9
fix: Key.Equals honors GetHashCode contract; drops Handled from ident…
tig May 5, 2026
2d6b1a6
docs: clarify AI test markers — // Claude and // CoPilot are both acc…
tig May 5, 2026
74aa1d4
fix: UnixRawModeHelper safe restore on crash + valid-state guard (#51…
tig May 5, 2026
d6c9519
docs: clarify SessionBegun/SessionEnded as token lifecycle hooks (#51…
tig May 5, 2026
ea8f237
fix: ApplicationImpl.Invoke throws NotInitializedException after Disp…
tig May 5, 2026
9cbb8b8
fix: ConcurrentDictionaryJsonConverter rejects duplicate keys (#5173)…
tig May 5, 2026
787d306
refactor: remove Region.DrawOuterBoundary debug API (#5168) (#5183)
tig May 5, 2026
5cfc86f
fix: KeyBindings preserves Key on bindings created via Add (#5171) (#…
tig May 5, 2026
a6c72fa
fix: Region.XOR computes correct symmetric difference (#5167) (#5178)
tig May 5, 2026
7fd4806
Fixes #issue. Correct AI guidance API entries for typed views and wra…
Copilot May 5, 2026
64502ab
Fixes #5148. Add selection and copy-to-clipboard to Markdown view (#5…
Copilot May 5, 2026
80f741e
Fixes #3995. Add notify-clet.yml: dispatch to gui-cs/clet on develop …
Copilot May 5, 2026
e409f3a
Fixes #5192. Fix MarkdownView GetContentHeight overestimating height …
Copilot May 5, 2026
ceddb29
Fixes #5193. Emit OSC 8 hyperlink sequences in Driver.ToAnsi() (#5195)
Copilot May 5, 2026
4003aca
notify-clet: deterministic version handoff + flat-container poll (#5198)
tig May 5, 2026
842b607
Update package versions and remove nullable from tests
tig May 6, 2026
59962ad
Fixes #3961. Replace ColorPicker TextField+autocomplete with DropDown…
Copilot May 6, 2026
03d26c7
Fixes #5203 - Add TrySetValueFromString to IValue for IParsable-based…
Copilot May 6, 2026
4f000d0
Fixes #4859. Render to /dev/tty when stdout is redirected (#5208)
Copilot May 6, 2026
14c7834
Fixes #5209. TableView header separator lines draw with focus attribu…
Copilot May 6, 2026
ed1d7f4
Fixes #5211. FlagSelector ENTER should not toggle, just accept. (#5212)
Copilot May 6, 2026
9a37328
Fixes #5202 - BREAKING CHANGE- Refactor LinearRange to implement IVal…
tig May 6, 2026
85c955f
Fixes #5213. Security: fix PowerShell command injection in WSLClipboa…
Copilot May 6, 2026
ffab857
Fixes #5216. FileDialog: reject path-traversal in Rename/New and skip…
Copilot May 6, 2026
985536d
Fixes #5215. Sanitize control characters to prevent terminal escape i…
Copilot May 6, 2026
f031d10
Fixes #5214. Security: restrict Link.OpenUrl to safe URI schemes; rep…
Copilot May 6, 2026
af8b27d
Fixes #5215. Bound ANSI parser held content to prevent memory DoS (#5…
Copilot May 6, 2026
814be23
Fixes #5227. Make links inside markdown table cells fully interactive…
Copilot May 7, 2026
981f3ca
Revise security policy for supported versions (#5235)
tig May 7, 2026
f979f73
Fixes #5206. Add IValue<int> support to ScrollSlider (#5229)
Copilot May 7, 2026
c0387f3
Fixes #5153. Make Markdown work like Label (#5231)
harder May 7, 2026
ff37f84
Fixes #5140. TableView: support CollectionNavigator = null to disable…
harder May 7, 2026
385d224
Fixes #5126. TableView: don't raise Activating when click is outside …
harder May 7, 2026
15033b3
Fixes #5076. Allow hiding TableView outer vertical lines (#5234)
harder May 7, 2026
836db66
Fixes #5230 - Markdown checklist glyph rendering (#5236)
Copilot May 7, 2026
6ec0175
Fixes #5237. Fix Markdown table row height calculation (#5238)
Copilot May 7, 2026
86c3fde
Fixes #5239. AOT configuration initialization crash (#5240)
Copilot May 7, 2026
d867dd7
Back-merge v2.1.0-beta.1 from main into develop (#5244)
tig May 7, 2026
11d6e27
Fixes #5259. AOT: use source-generated JSON serializer for dictionary…
Copilot May 7, 2026
3599134
Set release label to 'rc' for v2.1.0-rc.1
github-actions[bot] May 7, 2026
94dca98
Merge remote-tracking branch 'origin/main' into release/v2.1.0-rc.1
Copilot May 7, 2026
9ff2ecc
Apply style fix from validation feedback
Copilot May 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 74 additions & 27 deletions .claude/cookbook/common-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
8. [Data Table](#data-table)
9. [Tree View](#tree-view)
10. [Status Bar with Shortcuts](#status-bar-with-shortcuts)
11. [Scrollable Content Container](#scrollable-content-container)
12. [Standard Application Layout](#standard-application-layout)

---

Expand Down Expand Up @@ -552,7 +554,12 @@ public sealed class TreeWindow : Runnable

## Status Bar with Shortcuts

Application status bar with keyboard shortcuts.
`StatusBar` auto-positions at the bottom (`Y = Pos.AnchorEnd ()`, `Width = Dim.Fill ()`)
— **do NOT set `Y` or `Width` manually**. Content above it should use `Dim.Fill (1)` to
leave room.

For shortcuts that need to work app-wide (not just when focused), set `BindKeyToApplication = true`
and handle the `Accepting` event (not `Action`).

```csharp
public sealed class StatusBarApp : Runnable
Expand All @@ -563,46 +570,86 @@ public sealed class StatusBarApp : Runnable

TextView editor = new ()
{
X = 0,
Y = 0,
Width = Dim.Fill (),
Height = Dim.Fill (1) // Leave room for status bar
Height = Dim.Fill (1) // Leave 1 row for StatusBar
};

StatusBar statusBar = new ()
StatusBar statusBar = new ();
// StatusBar auto-positions at bottom — do NOT set Y or Width

Shortcut saveShortcut = new ()
{
Y = Pos.AnchorEnd (1),
Visible = true
Title = "Save",
Key = Key.S.WithCtrl,
BindKeyToApplication = true
};

statusBar.Add (
new Shortcut
{
Title = "New",
Key = Key.N.WithCtrl,
Action = () => MessageBox.Query (App!, "New", "Creating new file...", "OK")
},
new Shortcut
{
Title = "Save",
Key = Key.S.WithCtrl,
Action = () => MessageBox.Query (App!, "Save", "Saving file...", "OK")
},
new Shortcut
{
Title = "Quit",
Key = Key.Q.WithCtrl,
Action = () => App!.RequestStop ()
}
);
saveShortcut.Accepting += (_, e) =>
{
MessageBox.Query (App!, "Save", "Saving...", "OK");
e.Handled = true;
};

Shortcut quitShortcut = new ()
{
Title = "Quit",
Key = Key.Q.WithCtrl,
BindKeyToApplication = true
};

quitShortcut.Accepting += (_, e) =>
{
App?.RequestStop ();
e.Handled = true;
};

statusBar.Add (saveShortcut, quitShortcut);
Add (editor, statusBar);
}
}
```

---

## Scrollable Content Container

To make a `View` scrollable, set `ViewportSettings |= ViewportSettingsFlags.HasVerticalScrollBar`.
**Do NOT create custom subclasses just for scrolling** — the built-in scrollbar handles mouse
wheel, drag, and viewport management automatically.

```csharp
// ✅ Correct — just set the flag on a plain View
View container = new ()
{
Width = Dim.Fill (),
Height = Dim.Fill (),
CanFocus = true
};

container.ViewportSettings |= ViewportSettingsFlags.HasVerticalScrollBar;

// Add subviews stacked vertically
View? previous = null;

foreach (View item in items)
{
item.Y = previous is { } ? Pos.Bottom (previous) : 0;
item.Width = Dim.Fill ();
container.Add (item);
previous = item;
}

// ❌ Wrong — do NOT create a custom subclass just for scrolling
// internal class ScrollableContainer : View { ... AddCommand(...) ... }
```

Only subclass (like `AllViewsView` does) when you need **additional** keyboard command
bindings (e.g., arrow keys for line-by-line scrolling, PageUp/PageDown, Home/End) beyond
what the scrollbar provides. Even then, prefer adding bindings in the owning `Runnable`
if possible.

---

## Tips for All Patterns

1. **Always use `e.Handled = true`** in `Accepting` event handlers
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/build-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
name: Build All Configurations
runs-on: ubuntu-latest

timeout-minutes: 10
timeout-minutes: 15
steps:

- name: Checkout code
Expand Down Expand Up @@ -56,5 +56,8 @@ jobs:
dotnet build ./Examples/NativeAot/NativeAot.csproj --configuration Release -property:NoWarn=0618%3B0612
dotnet build ./Examples/SelfContained/SelfContained.csproj --configuration Release -property:NoWarn=0618%3B0612

- name: AOT Publish (catches trimming and reflection errors)
run: dotnet publish ./Examples/NativeAot/NativeAot.csproj --configuration Release -property:NoWarn=0618%3B0612

- name: Build Release Solution
run: dotnet build --configuration Release --no-restore -property:NoWarn=0618%3B0612
16 changes: 16 additions & 0 deletions Examples/NativeAot/NativeAot.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,20 @@
<ProjectReference Include="..\..\Terminal.Gui\Terminal.Gui.csproj" />
</ItemGroup>

<!-- Link AOT-safe editor files from UICatalog (no reflection, no heavy deps) -->
<ItemGroup>
<Compile Include="..\UICatalog\Scenarios\EditorsAndHelpers\ExpanderButton.cs" Link="Editors\ExpanderButton.cs" />
<Compile Include="..\UICatalog\Scenarios\EditorsAndHelpers\EditorBase.cs" Link="Editors\EditorBase.cs" />
<Compile Include="..\UICatalog\Scenarios\EditorsAndHelpers\ViewPropertiesEditor.cs" Link="Editors\ViewPropertiesEditor.cs" />
</ItemGroup>

<!-- Global usings needed by the linked UICatalog editor files -->
<ItemGroup>
<Using Include="Terminal.Gui.App" />
<Using Include="Terminal.Gui.Drawing" />
<Using Include="Terminal.Gui.Input" />
<Using Include="Terminal.Gui.ViewBase" />
<Using Include="Terminal.Gui.Views" />
</ItemGroup>

</Project>
Loading
Loading