Update the Sourcegraph detector to recognize the newly released token formats. Currently the detector only handles `sgp_<40 lowercase hex chars>`. The new formats are:

1. `sgp_<16 hex chars>_<40 hex chars>` (case-insensitive alphanumeric)
2. `sgp_local_<40 hex chars>` (case-insensitive, where `local` replaces the 16-char segment)
3. Standalone 40-character hex strings (no `sgp_` prefix), accepting both uppercase and lowercase hex digits.

The existing `sgp_<40 hex chars>` variant must also become case-insensitive. All patterns should keep the `\b` word boundaries to limit false positives; the standalone 40-char match is expected to be noisy and relies on verification to filter out invalid tokens.

Additionally, every result returned by the Sourcegraph detector must include an `extra_data` dictionary with the key `rotation_guide` and the value `https://howtorotate.com/docs/tutorials/sourcegraph/`. The key should be populated on any match, regardless of verification status.

Update the regex in `pkg/detectors/sourcegraph/sourcegraph.go` accordingly and ensure the `FromData` method always attaches the rotation guide `extra_data` to each result.

Updated trufflehog sourcegraph secret format (#2254)


The JDBC detector currently attempts to verify any SQL Server connection URL it constructs, including strings that are syntactically invalid as URLs. This can cause noisy verification attempts on malformed candidates. Modify the `parseSqlServer` helper in `pkg/detectors/jdbc` to validate the built `sqlserver://` URL with `url.Parse` before returning it. If the URL is invalid, log a debug message (using the context logger at `V(3)`) and return an error, causing the scanner to skip verification for that candidate. Ensure the function signature accepts the logger context so the log message is associated with the scan. Update the `supportedSubprotocols` map and callers (`newJDBC`, `parseSqlServer`) accordingly. No other behavior should change; valid SQL Server URLs should continue to be verified exactly as before.

fix(jdbc): ignore invalid sqlserver URLs (#3429)


The FTP detector ignores the global timeout provided via `--detector-timeout` and does not close its connections after verification.

- **Timeout behavior**: currently, the detector uses either a hardcoded default (5s) or an explicit `s.verificationTimeout` if set. It should also respect any deadline set on the context—typically from the `--detector-timeout` flag. When a context deadline exists (and no explicit `verificationTimeout` is set), use the remaining time until that deadline; otherwise fall back to the default.
- **Connection cleanup**: after a verification attempt (successful or not), the FTP connection must be explicitly terminated with `Quit()` to avoid leaked connections.
- The explicit `verificationTimeout` override (used for integration tests) must still take precedence when set to a positive value.

[INS-37] Fixed the issue of ftp connection ignoring the detector's co… (#4590)


Add a concurrency option to the filesystem source so directory scans process multiple files in parallel. Accept a concurrency limit when initializing the source, and use a bounded worker pool to scan files concurrently while walking the directory tree. Ensure:

- `Init` receives and stores a concurrency parameter.
- During `Chunks`, walking continues independently of per-file errors; errors from individual files are surfaced at `Error` level.
- All chunks produced by concurrent scans are sent to the chunks channel; `Chunks` must not return until all file scans finish.
- The `io.EOF` check in `Chunks` handles wrapped errors correctly.
- The total output must remain complete and deterministic in content, though chunk ordering may vary (consumers must not rely on order).

[feat] - concurently scan the filesystem source (#2364)


The `Engine` struct in `pkg/engine/engine.go` uses a custom `verificationOverlapTracker` type to count verification overlaps during testing. This type wraps an `int` behind a `sync.Mutex` and exposes an `increment()` method. The same behavior can be achieved with a standard `sync/atomic.Int32`, which is simpler, more idiomatic, and removes unnecessary custom code.

**Expected behavior**
Replace the custom `verificationOverlapTracker` struct and its `increment()` method with a plain `*atomic.Int32`. The field in the `Engine` struct should become `verificationOverlapTracker *atomic.Int32`. The call site in `verificationOverlapWorker` should use `Add(1)` instead of `increment()`, and test reads should use `Load()` instead of accessing the struct’s integer field directly.

**Impact**
- Eliminates a bespoke type and its locking boilerplate.
- Reduces code surface area, lowering maintenance burden.
- Makes the test seam consistent with other Go codebases that use `atomic.Int32` for single-value counters.
- No behavioral change—the tracker remains a test-only facility, and the atomic operation provides the same thread-safety guarantees.


**Feature Request: Resume Support for GitLab Source**

**Summary**
The GitHub source can already resume interrupted scans from encoded resume information. The GitLab source should support the same capability, using a shared resume utility to avoid duplication across source packages.

**Acceptance Criteria**

1. **Scan resumption on restart**
   - When a GitLab scan is interrupted and later restarted with the same source configuration, only repositories that were **not** previously completed are scanned again.
   - Previously completed repositories must **not** be re-scanned, regardless of their position in the sorted repository list.

2. **Progress reporting integrity**
   - The reported progress (e.g., “Repo: 3/10”) must account for any repositories that were skipped because they were already completed. The index and total counts should reflect the **original** scan scope, not just the remaining subset, so the user sees a continuous progression.

3. **Resume information storage**
   - After each repository finishes scanning successfully, the resume information for that repository is removed from the stored resume state.
   - The resume state is represented as a tab-separated list of repository URLs, consistent with the GitHub source format.

4. **Safe concurrent access**
   - Multiple repositories may be scanned in parallel. The resume state must be updated atomically and safely to avoid race conditions, lost updates, or duplicate scans.

5. **Handling gaps in resume info**
   - Because scanning is parallel, some repositories listed in the resume info may have been skipped at the time of interruption while later ones were completed. In that case, **all repositories after the last matched completed repository** must still be scanned, even if they are not in the resume info.

6. **Shared resume logic**
   - The functions for encoding, decoding, filtering, and updating the resume info must be extracted into a common location (e.g., `pkg/sources/resume.go`) and used by both GitHub and GitLab sources. Existing GitHub behavior must remain unchanged.

**Constraints & Edge Cases**
- If resume info is empty, all repositories are scanned.
- If the resume info contains repository URLs that no longer exist in the current repository list, they are ignored, but repositories appearing after the last matched URL are still scanned.
- The repository list must be sorted before resuming to ensure correct filtering.

Allow gitlab to resume from encoded resume info (#611)


**Title:** Broken link generation for GitHub Wiki repositories

**Background**
When TruffleHog finds a secret in a file, it generates a direct link to the line in the source repository so users can quickly inspect the leak. This link is constructed by `GenerateLink` in `pkg/giturl/giturl.go`.

**Problem**
For repositories that are GitHub Wikis (i.e., remote URLs ending with `.wiki.git`), the generated links are malformed. Instead of pointing to the wiki page at its correct URL, the function applies the standard branch/blob pattern or other fallback logic that does not work for wikis.

**Expected behavior**
- For any repository whose URL ends with `.wiki.git`, the generated link should follow the GitHub Wiki URL convention:
  `https://github.com/<owner>/<repo>/wiki/<page>/<commit>#L<line>`
- The page name must be the file name **without its extension** (e.g., `Home.md` → `Home`). Use any file extension, not just `.md`, and trim it.
- If a `commit` is provided, append it after the page path. If `commit` is empty, still produce a valid path ending with `/` (e.g., `.../wiki/Home/`).
- If `line` is greater than 0, append `#L<line>` to the link.
- When the `file` parameter is empty, the link should point to the wiki root (`.../wiki/`), with the commit appended if present.

**Scope & constraints**
- Only alter the logic inside `GenerateLink`; the new handling should be added *before* existing logic processes the url, specifically when the repo suffix is `.wiki.git`.
- Do not change behavior for any other repo types (GitHub, GitLab, Bitbucket, Azure, etc.).
- Ensure normalisation and encoding of the page path behave as expected (spaces and special characters remain URL‑safe through the existing path).

**Acceptance criteria**
- A wiki repo such as `https://github.com/hxnyk/hxnyk.wiki.git` with `file=Home.md`, `commit=e5fdc764`, and `line=5` produces `https://github.com/hxnyk/hxnyk/wiki/Home/e5fdc764#L5`.
- Same repo with `file=Home.md`, `commit=e5fdc764`, no line produces the same URL without the `#L` anchor.
- Same repo with `file=Home.md`, no commit, no line produces `https://github.com/hxnyk/hxnyk/wiki/Home/`.


When using a GitHub personal access token (PAT) with TruffleHog to scan repositories, only public repositories belonging to the scanned GitHub user are discovered and scanned. Private repositories that the token grants access to are silently ignored, even when the token has the necessary `repo` scope. This makes scanning with a token nearly useless for teams that rely on private repositories.

**Steps to reproduce**:
1. Generate a GitHub PAT with `repo` (and optionally `read:org`) scope.
2. Run TruffleHog with that token against a GitHub organization or user that owns private repos (e.g., `trufflehog github --org=my-org` or `trufflehog github` when the token belongs to a user with private repos).
3. Observe that only public repositories are enumerated, while private repositories owned by the authenticated user are missing from the scan.

**Expected behavior**:
When a valid token is provided, the scanner should enumerate and scan all repositories visible to the authenticated user, including private repositories the user owns and any private repositories within organizations that the token can access. Specifically, for a user account, it should use the GitHub “List repositories for the authenticated user” endpoint to discover private repos the user owns personally.

**Impact**:
Credentials leaked in private repositories remain undetected, leading to a false sense of security. Users who rely on PAT scanning to audit their own accounts will miss critical findings until they manually list and scan private repos, undermining the automation value of TruffleHog.

**Additional context**:
Unauthenticated scans correctly skip private repos (as expected), but authenticated scans with a properly scoped token must respect the token’s visibility. This behavior is inconsistent with common expectations for authenticated API access and security scanning tools.

Scan Github Private Repositories With Token (#4426)


Improve the Pusher channel key detector verification and deduplication:

- Before verifying, deduplicate extracted app IDs, keys, and secrets so that each unique (app, key, secret) combination is checked at most once per scan.
- Read and close HTTP response bodies during verification to prevent resource leaks.
- Treat verification outcome strictly: `Verified=true` only on HTTP 200, `Verified=false` with no error on 401/403, and `Verified=false` with an error for any other status code.
- Move verification logic into a separate function with clear return values (bool, error) to keep `FromData` readable and testable.

updated pusher channel key detector and fixed it's integration tests (#3782)


--- Bug: TableView scroll offsets become invalid when bound table has zero rows/columns or is replaced by a smaller table ---

**Observed behavior**
When using `Terminal.Gui.TableView`, if the bound `DataTable` contains no rows or no columns, or when the `Table` property is replaced with a smaller table (fewer rows / columns), the `ColumnOffset` and `RowOffset` properties can hold negative values or values that exceed the valid range. Additionally, calling `EnsureSelectedCellIsVisible()` on a `TableView` whose table has zero columns throws an exception.

**Expected behavior**
`ColumnOffset` should always be clamped to the range `0 .. max(0, table.Columns.Count - 1)`.
`RowOffset` should always be clamped to the range `0 .. max(0, table.Rows.Count - 1)`.
If the table has no columns, `EnsureSelectedCellIsVisible()` should return immediately without attempting to access column count logic.

**Steps to reproduce**
1. Create a `TableView`, assign a large `DataTable` (e.g., 25 columns, 50 rows), and set `RowOffset` and `ColumnOffset` to non‑zero values.
2. Replace the `Table` with a new, empty `DataTable` (zero columns, zero rows) or with a smaller table (e.g., 2 columns, 2 rows).
3. Observe that `ColumnOffset` and `RowOffset` are not adjusted to a valid range; when the table has no columns, `ColumnOffset` can become -1.
4. With a table that has zero columns, call `EnsureSelectedCellIsVisible()` → a runtime exception occurs because the implementation assumes at least one column exists.

**Impact**
Applications that dynamically replace or clear the table data can encounter rendering glitches or unhandled exceptions, making the control unreliable for scenarios where the data source may become empty or shrink.

Fixed namespace, comments and added tests


## Bug Report: Button creates and immediately destroys shadow infrastructure when subclass doesn’t need a shadow

### Observed behavior
When a `Button` is constructed, its constructor unconditionally sets `base.ShadowStyle = DefaultShadow`. That call allocates a full `Margin.View` with shadow views (even for subclasses where a shadow is never needed, such as `ScrollButton` and `ArrangerButton`). Those subclasses immediately override the setting in their own constructors by executing `base.ShadowStyle = null`, which destroys the just-created infrastructure. This create-then-destroy pattern wastes time and forces unnecessary layout/rendering work.

### Expected behavior
The framework should allow subclasses (and external consumers) to prevent allocation of shadow infrastructure *before* it occurs, without relying on post-creation cleanup. For example, a protected virtual method or an event that fires early enough in the construction pipeline could let the caller signal “no shadow” (e.g., by setting a future `ShadowStyle` to `null` or marking the initialization as handled). The default `Button` behavior should remain unchanged: if nothing intervenes, `DefaultShadow` is applied. However, `ScrollButton` and `ArrangerButton` (and any other internal buttons that never display a shadow) should not allocate any shadow-related views at all.

### Impact
- **Performance**: Avoids unnecessary `View` allocation and disposal during construction, which is especially noticeable when many buttons are created (e.g., in scroll bars or arrangement UI).
- **Cleaner initialization**: Subclasses no longer have to compensate for an incorrect default by immediately destroying work that shouldn’t have happened.
- **Consistent mechanism**: Exposing a customization point (e.g., by raising a “before shadow is applied” event) also enables external users to supply a different initial `ShadowStyle` without the double-allocation pattern.

### Suggested implementation direction
Introduce a new protected virtual method `OnInitializingShadowStyle` that receives `ValueChangingEventArgs<ShadowStyles?>` with `NewValue` preset to `DefaultShadow`. Subclasses can override this to set `args.NewValue = null` (or set `args.Handled = true`). A public event `InitializingShadowStyle` exposed on `Button` would allow external code to customize or suppress the shadow. The default constructor should invoke this chain before applying the shadow style, so the subsystem never allocates shadow views when the eventual answer is “no shadow.”

Fixes #4843. Button: avoid create-then-destroy shadow allocation via CWP InitializingShadowStyle event (#5012)


**Title:** `LineCanvas` mis-handles zero-length lines – intersections treated as starts/ends instead of pass-through points

**Area:** `Terminal.Gui/Core/Graphs/LineCanvas.cs`
**Type:** Bug / behavioral deficiency
**Severity:** Medium – prevents composing intersection shapes with zero-length segments

---

### Problem

`LineCanvas` incorrectly resolves **intersection runes** when a line has a length of 0 (a “dot”).
Currently a zero-length line is either caught by `IsDot()` and forced to `IntersectionType.Dot`, or it falls through to logic that treats it as a **start** endpoint (`StartUp` / `StartDown` for vertical orientations). Neither is correct for constructing T-junctions (`├`, `┤`, `┬`, `┴`), crosshairs (`┼`), or mixed-style intersections (e.g. `╡`, `╞`, `╤`) where one of the crossing segments is a zero-length line.

### Desired behaviour

A **zero-length line** should behave as if both ends are at the same point and **cross over** that point, not start or end there. This means:

- For a **vertical** line of length 0, `StraightLine.Intersects` must return an intersection type that represents a **pass-through** (e.g. `PassOverVertical`) when querying the line’s only point.
- The early `IsDot()` shortcut that returns `IntersectionType.Dot` must be **removed** (or made to delegate to the length‑aware logic) so that zero‑length lines participate in the same intersection classification as longer lines.
- Horizontal zero‑length lines should similarly produce a pass‑over horizontal type (though the immediate failure case only exposes the vertical path).

This allows patterns such as:

```csharp
lc.AddLine (new Point (0, 0), 1, Orientation.Horizontal, BorderStyle.Double);   // ═
lc.AddLine (new Point (1, 0), 0, Orientation.Vertical,   BorderStyle.Single);    // zero‑length connector
```

to correctly yield glyph `╡` (double‑horizontal, single‑vertical pass‑through), instead of being resolved as if the vertical line is starting at (1,0).

### Constraints & safety

- The change must **not** alter the rendering of lines with non‑zero length.
- Intersection rune selection for mixed border styles (Single, Double, Rounded) must continue to respect the existing `IntersectionRuneResolver` rules; the change is only in **how** the set of `IntersectionDefinition` objects is built, not in how they are combined.
- The `Intersects` method must remain side‑effect free and purely a query.
- The new helper `GetTypeByLength` introduced in the patch is an implementation detail; any approach that correctly maps `Length == 0` to a pass‑through type for the relevant orientation is acceptable.

### Acceptance criteria

1. A vertical line with `Length == 0` reports `PassOverVertical` (or equivalent) when intersecting at its start/end point.
2. The testable example drawing `═╡` using a `1`‑width horizontal and a `0‑length` vertical line produces the expected rune.
3. Existing window and corner intersection tests pass without modification.
4. The `IsDot()` path no longer short‑circuits intersection classification for zero‑length lines.

### Notes

This issue was observed while trying to draw box‑edge decorations (e.g., `╔╡ Title ╞══╗`) where clipped‑zero‑length segments are used to anchor mixed‑style T‑junctions. Currently such compositions either fall back to wrong glyphs or cause missing intersections.

WIP: Add some complexity to LineCanvas when length is 0


**Title:** ScrollBarView should accept real content size from hosts, not adjusted for internal offset

**Background:**
When a `ScrollBarView` is used as a hosted scrollbar (constructed with a host `View`), the host is currently required to set `Size` to `Lines + 1` (vertical) or `Maxlength + 1` (horizontal) to account for the extra line/column that the scrollbar itself occupies in the viewport. This shift is an internal implementation detail that leaks into the host API, making it fragile and unintuitive. Hosts such as `TextView`, `ListView`, and `ComboBox` must remember to add or subtract 1 in multiple places.

**Request:**
Change the behavior of the hosted `ScrollBarView` so that the host can set `Size` to the actual content dimension (e.g., total number of lines, total width of the longest line) and the scrollbar automatically applies the `+1` offset internally when necessary. The public API should be: “Set the size of the content you want to scroll through.”

**Concrete behavioral changes:**

- A hosted vertical `ScrollBarView` whose `Size` is set to `N` should correctly represent `N` lines of content, allow scrolling to the appropriate maximum position, and correctly size the thumb taking into account that one viewport line is occupied by the scrollbar itself.
- A hosted horizontal `ScrollBarView` should behave analogously for column counts.
- Non-hosted scrollbars (created without a host or via the general-purpose constructors) must remain unaffected; `Size` should mean exactly what is passed, without automatic adjustment.
- The `Position` setter should also handle the extra offset so that setting the position to the end of the content (e.g., `Size - viewportHeight`) does not prematurely stop at a value off-by-one.
- When both scrollbars are hosted and both are visible, the bottom-right corner indicator must appear and disappear correctly (no logic regressions).

**Interface simplification for hosts:**
After this change, hosts should set `_scrollBar.Size = _textView.Lines` directly (instead of `Lines - 1` or `Lines + 1`), and similarly for the other scrollbar. All compensation for the single-character width/height of the scrollbar track must be confined within `ScrollBarView`.

**Notes/edge cases:**
- The special case where a scrollbar is `hosted` and the other scrollbar is also `hosted` (the common dual-scrollbar layout) should still work seamlessly: both bars add the offset independently and the occupied-corner logic remains intact.
- Any existing dependencies on the old off-by-one behavior (e.g., internal calculations of bar size via `GetBarsize`, `CanScroll`, or thumb drawing) need to be updated to use the automatically adjusted size rather than the raw host setting.

The host only need to pass the real sizes and the ScrollBarView automatically consider the extra line and column.


**Title:** `SetNeedsDraw` union math incorrectly widens dirty region to viewport, preventing accurate partial redraws

**Background**
When a view calls `SetNeedsDraw(Rectangle viewPortRelativeRegion)` with a small sub-rectangle (e.g. a single changed line), the `NeedsDrawRect` property should accumulate only the areas that have actually been marked dirty. Instead, the current implementation forces the value to nearly the entire **current** viewport on every call – regardless of how narrow the requested region was. This makes `NeedsDrawRect` useless for shrinking draw work and blocks adoption of region-aware `ClearViewport` (issue #5358).

**Observable behavior that is wrong**
- Call `SetNeedsDraw` twice with two *non-overlapping* rectangles → `NeedsDrawRect` becomes `Rectangle(0,0,Viewport.Width,Viewport.Height)` (the full viewport) instead of the minimal bounding box of those two rectangles.
- Change the view’s `Frame` (which updates `Viewport`) after a `SetNeedsDraw` → `NeedsDrawRect` is effectively reset/overwritten to the new viewport rectangle, losing the previously marked dirty areas.
- Scroll by assigning a new `Viewport` → the dirty rect is again clamped to the new viewport, not accumulated with previously dirty areas relative to the content coordinate space.

**Desired behavior (acceptance criteria)**
1. **True union accumulation**
   `NeedsDrawRect` MUST be the `Rectangle.Union` of (`NeedsDrawRect` at the time of the call, `viewPortRelativeRegion`).
   After `ClearNeedsDraw()` (or a successful draw pass), the accumulation resets to `Empty`.
   Example:
   - `SetNeedsDraw(new Rectangle(2,2,3,3))` then `SetNeedsDraw(new Rectangle(8,8,2,2))` on a view with large viewport → `NeedsDrawRect` is `Rectangle(2,2,8,8)`, **not** `(0,0,viewportWidth,viewportHeight)`.

2. **Survive viewport changes (scroll / frame resize)**
   When `Frame` or `Viewport` is set, any implicit `SetNeedsDraw` calls that follow MUST **add** to the existing `NeedsDrawRect` (via union), not replace it. A prior dirty rect relative to content coordinates must remain part of `NeedsDrawRect` unless it has already been drawn/cleared.
   *Concretely:* Mark an area dirty, then scroll → the dirty rect expands to include both the old and the new viewport-relative region, not reduced to the current viewport.

3. **No artificial viewport ceiling**
   The final `NeedsDrawRect` must never be artificially expanded to `Viewport` size by the union logic itself. If the caller only marks a small rectangle, the resulting `NeedsDrawRect` must be exactly that rectangle (or the union of several small rectangles), not forced to a viewport-wide rectangle.

**Affected API surface**
- `View.SetNeedsDraw(Rectangle viewPortRelativeRegion)` – the buggy union calculation.
- `View.NeedsDrawRect` (internal getter) – its value is the accumulated dirty rect consumed by `Draw()` and friends.

**Why this matters**
A correct dirty rect is a prerequisite for region-aware `ClearViewport`, which is being introduced in issue #5358 to avoid clearing and re-rendering the entire view when only a portion changed. Without this fix, `ClearViewport` cannot narrow its work because `NeedsDrawRect` is always ~viewport-sized.

**Non-goals / safety**
- The union must still be clipped/adjusted to the valid content area where applicable, but the fundamental arithmetic must switch from “max with viewport” to “union with previous dirty rect”.
- The change must not break existing `NeedsDraw == true/false` toggles; a view that has *any* dirty rect still reports `NeedsDraw == true`.
- Performance: union of rectangles is a trivial operation; no new allocations or heavy checks are required.

Fix SetNeedsDraw union math to accumulate dirty regions accurately


**Bug: `CanFocus` setter does not update `TabIndex` and `TabStop`, breaking keyboard navigation**

**Observed Behavior**
When a `View`’s `CanFocus` property is changed after the view has been added to a parent container (`SuperView`), the view’s `TabIndex` and `TabStop` are not adjusted to match the new focusability.
- A view that was originally unfocusable and is later made focusable keeps `TabIndex` = -1 and `TabStop` = false, so it cannot be reached by pressing Tab.
- A view that was focusable and is later made unfocusable retains a positive `TabIndex` and often `TabStop` = true, leaving it in the tab order and causing tab navigation to jump to a view that no longer accepts focus.

The `TabIndexes` collection of the container also becomes out of sync, because views with `CanFocus = false` may still be present in the list, and focusable views that were added or became focusable later may be missing.

**Expected Behavior**
Setting `CanFocus` should immediately adjust `TabIndex` and `TabStop` to keep the view’s tab-order state consistent with its focusability:

1. When `CanFocus` is set to `true`:
   - The view should receive a valid `TabIndex` that reflects its position among the focusable siblings in the `SuperView`.
   - `TabStop` should become `true` (provided the view’s own `TabStop` setting allows it).
2. When `CanFocus` is set to `false`:
   - `TabIndex` must become -1, and `TabStop` must become `false`.
   - The view should be removed from the `SuperView`’s tab-order list so it no longer participates in keyboard navigation.

Additionally, the tab indexes of all remaining focusable views in the same container should be **compacted** to a contiguous sequence starting from 0, excluding any views with `CanFocus = false` (which have `TabIndex = -1`). For example, if a view at position 1 becomes unfocusable, the view that was at position 2 should move to 1.

Non-focusable control types such as `Label` (i.e., a `View` constructed with only text content) should default to `CanFocus = false`, `TabIndex = -1`, and `TabStop = false` so they never interfere with tab navigation.

**Impact**
Dynamically toggling focusability is impossible because the tab order does not stay in sync. Interactive scenarios (e.g., enabling/disabling controls, showing/hiding panels) become unreliable; users may find that pressing Tab skips over newly focusable views or lands on disabled ones, breaking keyboard-only workflows.

**Reproduction Steps (conceptual)**
1. Create a container `View` (`r`).
2. Add two child views (`v1`, `v2`) that were not created with focus.
3. Set `v2.CanFocus = true`.
4. Observe `v2.TabIndex` remains -1, `v2.TabStop` is false, and pressing Tab while the container is focused does not move focus to `v2`.
5. Set `v2.CanFocus = false` again (after making `v1` focusable as well).
   `v2` may remain in the `TabIndexes` collection with a positive index, causing Tab to stop on a view that does not respond.

**Desired Resolution**
The property setters for `CanFocus` (and related `TabIndex` setter) must enforce the rules above, ensuring that any change to `CanFocus` immediately and correctly updates the view’s `TabIndex` and `TabStop`, and maintains a valid, compact tab order for the container.

Setting CanFocus also sets TabIndex and TabStop accordingly.


The `GetColumns` method currently returns the sum of all rune column widths, which overcounts strings containing grapheme clusters (e.g., family emoji, ZWJ sequences, combining marks). A terminal renders each grapheme cluster as a single glyph that occupies the maximum column width of any rune within the cluster. Fix `GetColumns` to:

- Return the **rendered column width** of the entire string, not the sum of individual rune widths.
- For each grapheme cluster (as defined by `StringInfo.GetTextElementEnumerator`), take the **maximum** `GetColumns` value of its runes and add that to the total.
- Gracefully handle `null` and empty strings by returning `0`.
- Preserve correct behavior for non-BMP characters that are not part of a cluster (e.g., single emoji like "🙂" width 2), ordinary narrow characters (width 1), and wide characters like CJK (width 2).

Examples of sequences that must yield a single cluster width (typical target width 2):
- `👨👩👧👦` (family emoji sequence)
- `👩🏽🚒` (woman firefighter with skin tone)
- `कि` (Hindi consonant + vowel sign)

No behavioral changes for strings without grapheme clusters; they should continue to return the same width as before.

Fixes #4382. StringExtensions.GetColumns method should only return the total text width and not the sum of all runes width (#4383)


**Title:** Vertical scrollbar drifts leftwards on vertical scrolling

**Description**
I’m using Terminal.Gui v2 beta. When a `TextView` has `ScrollBars = true` and enough content to make the vertical scrollbar visible, scrolling down (either by clicking the scrollbar, dragging the slider, or using keyboard navigation) causes the vertical scrollbar to gradually move left. After several scroll steps the scrollbar overlaps the text content instead of staying anchored at the right edge of the view.

**Steps to reproduce**
1. Create a `Window` containing a `TextView` with `ScrollBars = true`.
2. Fill the `TextView` with many lines (e.g., 200 lines) so that the vertical scrollbar appears.
3. Run the application and scroll the vertical scrollbar down multiple times (e.g., step 5, 10, 15…).
4. Observe the horizontal position of the vertical scrollbar.

**Expected behavior**
The vertical scrollbar should remain at the rightmost edge of the `TextView`’s content area (or the edge of its `PaddingView`, if any). Scrolling should not change the scrollbar’s X coordinate. The padding on the right should stay constant after the scrollbar first becomes visible.

**Actual behavior**
The vertical scrollbar shifts left with each scroll. Its X position drifts inward over time, eventually overlapping and obscuring the content. This happens even when the scrollbar `VisibilityMode` is set to `Auto` (the default).

**Additional notes**
- The issue also appears on any `View` that uses `ViewportSettings.HasVerticalScrollBar` with an auto-visibility vertical scrollbar.
- The problem seems related to the right padding thickness incrementing on each scroll step, which pushes the `Pos.AnchorEnd()`-based scrollbar left.
- Setting visibility mode to `Manual` may work around it, but the default `Auto` mode should behave correctly.

**Impact**
Makes scrollable views unusable for any application that relies on vertical scrolling – the scrollbar position becomes unpredictable and obscures content. This breaks the common expectation that scrollbars are static at the view’s edge.

Fixes #4890 - Vertical scrollbar moves to left (#4991)


**Title:** SplitView layout breaks when nested or after splitter interaction: tile anchorage relative to origin, splitter line reset, and position validation bypass

**Description:**

1. **Tile anchoring uses absolute 0 instead of the SplitView’s actual bounds origin.**
   When a `SplitView` is placed inside another container (e.g., a nested SplitView, a panel at a non-zero offset), the first tile’s position is computed relative to coordinate 0 rather than the SplitView’s `Bounds.X`/`Bounds.Y`. This causes tiles to be drawn at wrong screen locations. The fix should make the tile positioning respect the container’s bounds origin (`X` for vertical orientation, `Y` for horizontal orientation) instead of hardcoding 0.

2. **Splitter line coordinates are not fully reset during layout.**
   In `SplitView`’s layout setup (when computing tile sizes and splitter line placements), the code sets the splitter line’s primary axis coordinate (e.g., `X` for vertical orientation, `Y` for horizontal) but does not explicitly reset the orthogonal axis coordinate to 0 (or the appropriate edge). This can leave stale values from a prior layout pass (for example after an orientation change), leading to rendering artefacts or misaligned drag handles. The fix should ensure that both axes are explicitly assigned during setup – the primary axis from the splitter distance, and the orthogonal axis to 0 (or the view’s edge).

3. **Splitter movement finalisation bypasses `SetSplitterPos` validation.**
   When a splitter line is dragged with the keyboard or mouse, the final position is written directly into the internal `splitterDistances` list. `SetSplitterPos` is the public API that validates allowed position types (only `Percent` and `Absolute` are supported). By circumventing it, a call to the splitter can end up storing a `PosCombine`, `PosFunc`, or other unsupported type, which later causes an `ArgumentException` with an inaccurate message. The internal finalisation should go through `SetSplitterPos` so that the same validation and error reporting apply consistently.

**Acceptance criteria:**

- A `SplitView` that is not at `(0,0)` lays out its tiles correctly, with the first tile anchored to the view’s origin rather than to the screen origin.
- After orientation changes or repeated layout passes, splitter lines do not retain stale coordinates from the previous axis; they appear at the correct position and can be interacted with normally.
- Dragging a splitter (keyboard or mouse) that would result in an unsupported position type fails early, with the same exception message that `SetSplitterPos` produces for invalid input. Direct manipulation to a supported type (e.g., a plain integer `Pos.At(...)`) still works.
- No regression for the base case where a `SplitView` starts at `(0,0)` and no orientation change occurs.


**Feature Request: Per‑Node Color Overrides in TreeView**

### Summary
Allow applications to assign distinct colors to individual nodes in a `TreeView` based on the node’s underlying data object, while keeping the tree lines and expansion symbols unchanged.

### Background
Currently, all tree nodes share the same `ColorScheme` and there is no way to visually distinguish nodes that represent different categories, states, or priorities. A per-node coloring mechanism would enable richer data visualisation.

### Acceptance Criteria

1. **Node-specific color callback**
   The `TreeView` (generic `TreeView<T>`) must expose a property that accepts a callback receiving the node’s data object (`T`).
   The callback returns either a `ColorScheme` or `null`.

2. **Color application**
   - When the callback returns a `ColorScheme`, the node’s label is rendered using `ColorScheme.Normal` in the unselected state and `ColorScheme.Focus` when the node is selected.
   - When the callback returns `null`, the node’s label falls back to the tree’s default `ColorScheme`.

3. **Non‑node elements are unaffected**
   Tree branch lines and expand/collapse symbols continue to use the tree’s overall `ColorScheme` and are not influenced by the per-node callback.

4. **Dynamic updates**
   Changing the callback and triggering a redraw (e.g., via `SetNeedsDisplay`) immediately repaints the tree with the updated colors. Expanding/collapsing nodes or scrolling does not revert colors to the default.

5. **Works with any generic TreeView**
   The solution must work with `TreeView<T>` for any `T`, including the non‑generic `TreeView` (which is `TreeView<ITreeNode>`).

### Example Use Case
```csharp
treeView.ColorGetter = (item) =>
    item is IImportant ? importantColorScheme : null;
```

### Constraints
- No changes to the public API of `ITreeNode` or `Branch`.
- Existing default rendering behavior must be preserved when the callback is not set.


**Bug Report: Autocomplete popup overlay stays visible when suggestions become empty**

When using a `TextView` (or any control) with autocomplete enabled, the popup overlay does not hide itself when the underlying suggestion list becomes empty. The `Visible` property on the autocomplete instance may be `false`, but the visual popup remains on screen, which is confusing and leaves a stale overlay.

**Steps to reproduce**
1. Create a `TextView` with autocomplete enabled (default `PopupAutocomplete`).
2. Type characters that produce suggestions; the popup appears.
3. Delete characters until no suggestions match (the `Suggestions` collection is empty).
   Or, while the popup is visible, press a cursor-movement key (e.g., left/right arrow) that results in an empty suggestion list.
4. Observe that the popup overlay does not disappear even though `Visible` is `false`.

**Expected behavior**
When the autocomplete has no suggestions, the popup overlay must be fully hidden—both the logical `Visible` flag and the visual element—so that nothing is drawn on top of the host control and the screen looks correct.

**Actual behavior**
The popup overlay remains visible (the dropdown area is still drawn or not removed) even after the suggestion count drops to zero. Setting `Visible = false` alone is insufficient; the internal popup view is not updated to match.

**Impact**
This is a visual regression that degrades the user experience: stale autocomplete panels stay on screen when they should be gone. Applications relying on autocomplete exhibit flashing or leftover overlays after the user’s input invalidates all suggestions.

Fixes #4127. PopupAutocomplete visible not updating when there are no suggestions (#4128)


**Title:** Key binding scope enforcement is inconsistent in keyboard dispatch

---

**Background**

We have a `KeyBindingScope` enum (`Focused`, `HotKey`, `Application`) that controls _when_ a key binding should fire.
- `Focused` bindings should only trigger when the target view actually has keyboard focus.
- `HotKey` bindings should fire regardless of focus, during hotkey traversal (e.g. when a superview processes an unhandled key down its subtree).

Two problems have surfaced:

### 1. `Focused`-scope bindings leak during superview key traversal

When a superview walks its subviews looking for a key binding (hotkey path), it calls the subview’s `OnInvokingKeyBindings` (or equivalent path). The traversal does not distinguish between scopes: a subview that registered a binding with `KeyBindingScope.Focused` will have its handler invoked _even when the subview does not have focus_.

**Expected:** If a binding has scope `Focused` and the subview `HasFocus == false`, the handler should be skipped for that subview.

**Edge case:** When the subview _does_ have focus, `Focused`-scope bindings are fair game and must still fire.

### 2. Application-level key processing bypasses `OnInvokingKeyBindings`

When `Application.OnKeyDown` dispatches to views that have registered application-scoped key bindings, it currently calls `InvokeCommands` directly. This skips `OnInvokingKeyBindings` entirely, meaning:
- The `InvokingKeyBindings` event never fires for those key strokes.
- Scope information from the binding is ignored; the binding’s commands are executed unconditionally.

**Expected:** The application dispatch path should route through `OnInvokingKeyBindings` (passing the binding’s actual `Scope`) so that the event fires and scope is honored consistently across all key dispatch paths.

---

**Acceptance criteria**

- A `Focused`-scope key binding on a subview that does not have focus must not execute when the superview processes a matching key.
- A `HotKey`-scope key binding on a subview _must_ still execute during the same traversal (non-focused subviews are fine for `HotKey`).
- Application-level key dispatch must fire `InvokingKeyBindings` and respect the binding’s scope.


We need a way to select all cells in a `TableView` at once, enumerate all selected cells (including multi-region selections and full-row selection), and keep the selection state valid when the underlying table dimensions shrink.

**Acceptance Criteria**

1. **Select-All keyboard shortcut**
   When `MultiSelect` is `true` and the table contains at least one row, pressing `Ctrl+A` must replace any existing selection regions with a single region that covers every column and row of the table. The origin of the region should be set to the currently active cell so that subsequent extend-selection operations (e.g., `Shift+Right`) behave consistently.
   If `MultiSelect` is `false` or the table is null or has zero rows, `Ctrl+A` must have no effect.

2. **Enumerate all selected cells**
   Provide a public method that returns every cell that is considered selected, taking into account:
   - Any rectangular regions stored in `MultiSelectedRegions`.
   - Whether `FullRowSelect` is enabled (when `true`, all cells in selected rows should be included; when `false`, only the exact columns within the regions are included).
   - When no multi-region selection exists, the method must fall back to the active cell (`SelectedColumn`, `SelectedRow`), expanding to the entire row if `FullRowSelect` is on.
   The method must be safe to call when the table is null or has no rows (yield break).

3. **Automatic selection correction when table dimensions change**
   After rows or columns are removed from the table, calling `EnsureValidSelection` must:
   - Clamp `SelectedColumn` and `SelectedRow` to the new column/row count.
   - Discard any multi-selection region that is now entirely below the last row or entirely to the right of the last column.
   - For remaining regions, clamp the `Origin` point and the `Rect` so that the region does not extend beyond the new column/row bounds.
   This ensures that subsequent queries for selected cells never produce out-of-range coordinates even after table size reductions.

4. **Mutable `TableSelection` properties**
   To support the above adjustments, the `Origin` and `Rect` properties of `TableSelection` must have public setters. (Previously they were read-only.)

5. **Demo editor integration**
   In the `TableEditor` scenario, pressing the `Delete` key must:
   - When `FullRowSelect` is on: delete every distinct row that is currently selected (using the new selection enumeration). Rows should be removed in reverse index order to avoid index shifts.
   - When `FullRowSelect` is off: set the value of every selected cell to `DBNull.Value`, then refresh the view.
   The operation must be ignored if no cells are selected or the table is empty.

**Constraints / Non‑functional notes**

- The select-all region should always be a single rectangular region, not multiple pieces.
- The cell enumeration must be efficient: only iterate the bounding box of all selection regions, not the entire table.
- Selection validation must never throw an exception due to invalid indices, even if regions were created before a table shrink.
- The demo delete behavior is only an example; the core `TableView` itself should not implement cell deletion/clearing.

Added SelectAll, better selection iteration and validation


**Title:** SelectorBase.TabBehavior (and similar property setters) cause CheckBox visual checked state to desync from Value after subview recreation

**Background:**
`SelectorBase` (and its subclass `OptionSelector`) uses `CreateSubViews()` to rebuild internal `CheckBox` subviews when certain properties change (`Styles`, `Values`, `Labels`, `TabBehavior`). The checked state of the checkboxes is supposed to be updated afterwards via `UpdateChecked()`, but several property setters call `CreateSubViews()` without a subsequent `UpdateChecked()`, leaving the checkboxes visually unchecked even though `Value` still references a valid option.

Additionally, if `Labels`/`Values` is changed to a set where the current `Value` no longer exists, the behaviour is unspecified and can lead to an invalid state (no checkbox checked while `Value` remains pointing to a non-existent entry).

**Observed behaviour:**
1. Create an `OptionSelector` with labels `["A","B"]` and values `[10,20]`. The first checkbox is checked and `Value` is 10.
2. Change `TabBehavior` (or `Styles`, etc.) after the view is already added to the UI. The checkboxes are recreated but none is checked, while `Value` remains 10.
3. The result is a visual state where no option appears selected, contradicting the internal `Value`.
4. Similarly, if `Labels`/`Values` is changed to `["X","Y"]` and `[30,40]` while `Value` remains 10, no checkbox matches and the UI is left in an invalid state.

**Expected invariants:**
- After any property change that calls `CreateSubViews()`, the checked state of the checkboxes must be synchronized with the current `Value` before the view is repainted.
- If the current `Value` is not present in the new `Values` list, `Value` must be automatically set to the first element of the new list, and the corresponding checkbox must be checked. This should happen atomically with the recreation, so the `ValueChanging`/`ValueChanged` events fire in that case.

**Affected classes/members:**
`SelectorBase.TabBehavior` setter, `SelectorBase.Styles` setter, `SelectorBase.Values` setter, `SelectorBase.Labels` setter, and any other path that calls `CreateSubViews()` without ensuring `UpdateChecked()` runs immediately.

**Proposed resolution (conceptual):**
- Move the `UpdateChecked()` call inside `CreateSubViews()` so that every subview recreation inherently restores the correct checked state.
- Enhance `OptionSelector.UpdateChecked()` (and any similar override) to handle the case where the current `Value` is not in the available checkbox values. In that scenario, it should default `Value` to the first checkbox’s value and check that checkbox, raising the appropriate value-changing events.

**Acceptance criteria:**
- Setting `TabBehavior`, `Styles`, `Labels`, or `Values` on an already-populated `SelectorBase` (e.g., `OptionSelector`) never results in a visual state where no checkbox is checked while `Value` points to a valid option.
- Changing `Labels`/`Values` to a list that doesn’t contain the current `Value` forces `Value` to the first option in the new list, and the first checkbox becomes checked.
- The `ValueChanging`/`ValueChanged` events fire appropriately when the value is implicitly reset.

Fixes #5040. SelectorBase.TabBehavior setter calls CreateSubViews() without UpdateChecked(), desyncing CheckBox visual state (#5044)


This is a bug report requesting that nullable reference type annotations be enabled in the layout dimension subsystem to eliminate warnings and improve safety.

---

**Title:** Enable nullable reference types for layout dimension classes and View size properties

**Area:** Layout – `Dim` hierarchy, `View.Width`/`View.Height`

**Severity:** Medium

**Problem**

When consuming `Terminal.Gui` in a .NET project with `<Nullable>enable</Nullable>`, many nullable analysis warnings are produced because the dimension classes (e.g., `Dim`, `DimAbsolute`, `DimAuto`, `DimCombine`, `DimPercent`, `DimFill`, `DimFunc`, `DimView`) and the `View.Width`/`View.Height` properties lack proper null annotations. The same warnings flood the library’s own compilation when nullable is enabled, masking real potential null-reference bugs and making it impossible for consumers to use the library in a fully annotated context.

Examples of issues:

- Factory methods like `Dim.Absolute`, `Dim.Auto`, `Dim.Fill`, and `Dim.Percent` return a non-null `Dim`, but callers that assign the result to a `Dim?` variable or field produce warnings when the value is subsequently treated as non-null.
- The `+` and `-` operators on `Dim` do not accept nullable operands, causing friction when caller variables are nullable.
- `DimAuto` and `DimCombine` constructors and properties (`MinimumContentDim`, `MaximumContentDim`, `Left`, `Right`) do not indicate that their parameters / properties can accept `null`.
- `View.Width` and `View.Height` are implemented with a setter that throws on `null`, yet the property type is not annotated to help callers or to enable diagnostic checks for uninitialised reads (e.g., in DEBUG builds).
- Internal code paths that provably receive non-null inputs at runtime nevertheless trigger compiler warnings that obscure genuine problems.

**Expected behavior**

- `#nullable enable` is added to the layout dimension files (primarily `Dim.cs` and `ViewLayout.cs`).
- All public and internal signatures are updated with explicit `?` annotations where values can legally be `null`:
  - Factory methods that never return `null` may remain non-nullable, but the null-state of the return type should be unambiguous.
  - `+`/`-` operators accept `Dim?` left/right operands; null operands are handled by existing fallback logic (or are guaranteed non-null by callers).
  - `DimAuto` and `DimCombine` parameters / properties that may be `null` are marked `Dim?`.
  - `View.Width` and `View.Height` setter rejects `null` with an `ArgumentNullException`; the getter may return a nullable type to support debug-time diagnostics that warn when the property is read before the view is initialised.
- Where the runtime invariants guarantee non-null but the compiler cannot prove it, null-forgiving operators (`!`) are used to suppress remaining warnings while keeping the code safe.
- Stale unnecessary `using` statements (e.g., `System.Drawing`) are removed during cleanup.

**Impact**

Without these annotations, it’s currently impossible to use `Terminal.Gui` in a project with nullable enabled without either disabling nullable or adding numerous pragmas. Enabling annotations will allow consumers to benefit from compile-time null checks, prevent accidental null-reference exceptions in user code, and make the library itself safer during maintenance.


In `TabView`, the `OnTabClicked` event currently fires only when a mouse click lands on a tab header. **Make it fire for clicks anywhere in the tab bar area**, including empty space to the right of the last tab or to the left of the first tab. When the click is in empty space, the `Tab` property of the `TabMouseEventArgs` should be `null`.

In the `Notepad` scenario, the right-click context menu currently appears on **any** mouse click. **Restrict it to right-clicks only** (`Button3Clicked`). When right-clicking in empty tab bar space, show a context menu with an **Open** item. When right-clicking on a tab, show the existing **Save** and **Close** items. No context menu should appear for other mouse buttons.

Make OnTabClicked fire for clicks in empty space and fix Notepad to only show context menu on right click.


In `CollectionNavigator` search-by-typing, `IsCompatibleKey` currently allows keys that include Alt or Ctrl modifiers as long as the resulting rune is valid and non-control. This causes unwanted navigation when users press Alt+letter or Ctrl+letter for other purposes (menu shortcuts, etc.).

Modify `IsCompatibleKey` to reject any `Key` where `IsAlt` or `IsCtrl` is true, regardless of the rune value. This must apply even when `AssociatedText` is set (e.g., Kitty keyboard protocol) and would otherwise produce a valid rune. Unmodified letters, digits, space, and Shift+letter combinations should remain compatible.

Ensures `CollectionNavigator` does not repond to alt or ctrl keys (#5014)


Implement independent dimension resizing for `AutoSize`:

- Currently `AutoSize = true` only takes effect when *both* width and height can be set to their auto‑computed sizes. If either dimension is constrained (e.g., `Width = Dim.Fill()` or an absolute value), the entire auto‑size is suppressed.
- Change `AutoSize` so that each dimension is handled independently: auto‑size the width if possible, auto‑size the height if possible; if a dimension’s layout constraint prevents auto‑sizing, leave that dimension unchanged.
- This logic must live in `SetWidthHeight` (and any related flow in `ResizeView`) so that `SetWidth`/`SetHeight` outcomes are applied separately, and the view’s bounds are updated accordingly when at least one dimension could be sized.
- Additionally, the `Label` view should default to `AutoSize = true` so that newly created Labels automatically fit their text content. Ensure all `Label` constructors initialise this property to `true`.

Fixes the restriction of the AutoSize = true of only being true if both the width and the height are true.


# TextField double-click word selection broken for accented/multi-byte characters

**Issue:** #2333 — When double-clicking a word in a `TextField` that contains accented characters or combined Unicode sequences, the selection is often incorrect. For example, with the text `"Les Misérables movie."`, double-clicking on the word `movie` may select only part of the word or miss letters entirely.

**Root cause:** The double-click handling in `MouseEvent` (around the `WordBackward` call) uses the `Text` property indexer (`Text[x-1]`, `Text[x]`) to decide whether to move the start-of-selection to the beginning of the word. Because `Text` returns a `ustring`, its indexer does not necessarily return the same code points as the internal `List<Rune> text` when combining characters are involved, leading to wrong character comparisons and misidentified word boundaries. Additionally, the parentheses grouping in the condition may be misleading and could contribute to logical errors; the intent is three independent top-level conditions, not a nested `||` inside a single `&&`.

**Required behavior change:**

- In the `MouseEvent` handler, when handling `Button1DoubleClicked`, replace all uses of `Text[x]` with the internal `text[x]` (the `List<Rune>` field) so that character comparisons for spaces and non-spaces operate on the actual rune data. This ensures correct detection of word boundaries regardless of Unicode representation.
- Ensure the condition that triggers `sbw = WordBackward(x)` is expressed as three top-level `||`-joined conditions:
  1. `x == text.Count` (cursor at the very end)
  2. `x > 0 && (char)text[x - 1] != ' '` (character to the left is not a space, i.e., we are inside a word)
  3. `x > 0 && (char)text[x] == ' '` (cursor is on a space at a word boundary)
  The grouping must be explicit so that the `||` between (2) and (3) is at the same level as the first `||`, not nested inside the `x > 0` guard. (Behaviorally this is equivalent to the original grouping but ensures maintainability and avoids future misunderstanding.)

- `WordBackward` and `WordForward` already operate on `text` (the `List<Rune>`); no change is needed there. The fix should only ensure that the double-click code uses the same internal representation to decide *when* to call `WordBackward`.

**Expected outcome:** Double-clicking any word in a `TextField` — especially words containing combining characters, precomposed accented letters, or multi-code-point grapheme clusters — selects the entire word correctly, matching the behavior for plain ASCII text.

Fixes #2333. TextField is selecting badly a word on double click.


Fixes and improvements in the Notepad tile removal and focus tracking:

- When the last tab in a split panel (TabView inside a TileView) is closed, the empty TabView should be removed from the TileView, and the splitter should collapse.
  - If that causes the parent TileView to become empty, recursively remove the parent from its own parent TileView.
  - The top-level root TileView must never be removed (even if its last child becomes empty), so that the user can still open new documents.

- All tab-oriented actions (New, Open, Save, Save As, Close, Split) must target the **currently focused** TabView, not the initial root one.
  The focused TabView is the one that last received input focus.

- Save As must properly handle cancellation of the file dialog (ignoring the operation if canceled).

- In the `TileView` class:
  - Rename `TryTileView` to `TrySplitTile` (the old name was misleading).
  - Expose a public `IsRootTileView` property/query and a `GetParentTileView()` method to support the nested-removal logic.

Fixes and improvements in Notepad Tile removal


**Bug Report: Application.Run<T>() fails without prior Application.Init**

When using the generic convenience method `Application.Run<T>()` where `T` is a custom `Toplevel` subclass, and no explicit `Application.Init()` call has been made, the application crashes. The stack trace shows that the `Toplevel` constructor tries to access `Application` static properties that have not been initialized yet. This happens because `Run<T>()` currently constructs `T` before the internal initialization routines have run.

**Expected behavior**
- `Application.Run<T>()` should work without a prior `Init()` call, just as the parameterless `Application.Run()` does. It must perform the necessary internal initialization **before** creating the `T` instance.
- If a `ConsoleDriver` is passed to `Run<T>()`, that driver should be used during the implicit initialization.
- When `Init()` has already been called, `Run<T>()` must keep its current behavior (no double initialization).
- The overload `Application.Run(Toplevel)`, which receives an already-constructed instance, must **not** attempt to auto-initialize. If `Init()` hasn't been called, it must throw an `InvalidOperationException` whose message explains that `Run()` or `Run<T>()` can be used without explicit `Init`, but `Run(Toplevel)` requires it.
- The XML documentation comment on `Run(Toplevel)` must be updated to reflect this contract.

**Why the distinction matters**
A caller who constructs a `Toplevel` while `Application` is uninitialized may already have caused failures in the constructor. Auto-initializing after the fact would hide the real error and lead to further issues. For `Run<T>()`, the toolkit controls the construction timing, so it can safely initialize first.

Fixes #3536. Application.Run<T> is broken by not calling Init before initializing T.


**Fix Scroll and ScrollBar behaviors: slider sizing, increment, layout, and event correctness**

- **Slider size calculation**
  The slider should reflect the proportion of viewport to total content size (`Size`) without subtracting 2 from `Size` in the denominator. This ensures the slider length correctly represents how much content is visible.

- **ContentPosition clamping when content is smaller than the viewport**
  When `Size < ViewportDimension`, `ContentPosition` must be clamped to a maximum of `Math.Max(0, Size - ViewportDimension)` to avoid invalid negative positions.

- **Configurable increment for mouse wheel and button clicks**
  Introduce an `Increment` property on `Scroll` (default 1). Mouse wheel events (vertical/horizontal) on `Scroll` should change `ContentPosition` by that value instead of always ±1. The `ScrollBar.Increment` property should delegate to the inner `Scroll.Increment`, and both the decrement and increment buttons must use it when clicked.

- **Horizontal ScrollBar layout**
  Fix the horizontal orientation layout so the scroll track (slider area) is positioned to the right of the decrease button rather than below it, and occupies the remaining width.

- **Avoid unnecessary events when position doesn’t change**
  `SliderPosition` setter should not raise `SliderPositionChanging`/`SliderPositionChanged` events if the new value equals the current position. If the value exceeds the valid range, skip entirely.
  The `ContentPosition` setter should similarly ignore redundant assignments.

- **Canceled position change should not revert the slider position**
  When `OnSliderPositionChanging` returns `true` (canceled), the slider’s internal position must not be forced back to the previous value; simply do nothing.

- **Layout update on Size change**
  Setting `Scroll.Size` should call `SetNeedsLayout()` so the slider size recalculates immediately.

- **Safe percentage display in ScrollSlider**
  `ScrollSlider.ShowPercent` must handle `SuperView` being null gracefully, avoiding null-reference exceptions during draw.


**Title:** Alphanumeric keystrokes ignored when running Terminal.Gui on Windows under remote desktop or SSH (ConsoleKey.Packet)

**Description:**
When running a Terminal.Gui application on Windows through a remote connection (e.g., RDP, SSH, or similar remoting tools), typing regular letters and digits does not produce any input. The application receives the key down events, but the framework fails to recognize them as normal keys.

**Steps to reproduce:**
1. Connect to a Windows machine via a remote desktop or SSH session.
2. Launch any Terminal.Gui application (e.g., a sample text entry form).
3. Press alphanumeric keys such as `'a'`, `'Z'`, `'0'`.

**Expected behavior:**
The keys should be processed as usual: pressing `'a'` should be handled as `ConsoleKey.A`, `'Z'` as `ConsoleKey.Z` (with shift state preserved), and digits as the corresponding console keys. Key bindings and text input should work identically to a local console session.

**Actual behavior:**
No visible reaction occurs. The application receives a key event where the virtual key code is 231 (`ConsoleKey.Packet`), but it is not mapped to any standard `ConsoleKey`. Consequently, text input, menu accelerators, and other key-bound actions stop working.

**Additional context:**
- Only the **WindowsDriver** (`Terminal.Gui/ConsoleDrivers/WindowsDriver.cs`) is affected.
- The OS provides the actual character in the `UnicodeChar` field of the `KeyEventRecord`, but the driver discards it when reporting the key.
- A plausible fix would involve inspecting the `ConsoleKey.Packet` event, extracting the `UnicodeChar`, and reinterpreting it as the corresponding `ConsoleKey` value (e.g., `'A'` → `ConsoleKey.A`). Care must be taken to preserve the original character and modifier flags.
- This issue was reported in detail in [GitHub issue #2008](https://github.com/gui-cs/Terminal.Gui/issues/2008).

Support for remapping basic unicode keychars that come from OS with ConsoleKey.Packet.  Affects only WindowsDriver


**Title:** `Application.Invoke` executes on the UI thread even when `Application.Top` is not running, causing premature action execution

**Description**
`Application.Invoke(action)` is meant to schedule the action safely on the main UI thread. When called from the main thread, the current implementation checks only the thread identity and executes the action immediately. This causes the action to run even when `Application.Top` is `null` or its `Running` property is `false` – e.g., before `Application.Run` has started, after a shutdown request, or during teardown. Code that assumes the application is fully active (for example, accessing `Application.Top` or its children) then fails with null references or incorrect state.

Similarly, the `NetInput` disposal writes CSI sequences to disable mouse events even in unit-test contexts, interfering with test harnesses.

**Expected behavior**
1. `Application.Invoke` must defer the action to the idle/timer queue whenever `Application.Top` is `null` or `Application.Top.Running` is `false`, even if called from the main UI thread.
   - Only when `Application.Top` is non-null *and* `Running` may the action be executed synchronously.
2. `NetInput.Dispose` (the dotnet console input driver) must skip writing the mouse‑disable CSI sequences when `ConsoleDriver.RunningUnitTests` is `true`, avoiding unwanted console output in test runs.

**Acceptance criteria**
- Calling `Application.Invoke(someAction)` from the main thread before `Application.Run()` does **not** execute `someAction` inline; the action is instead posted and processed once the main loop is running.
- Calling `Application.Invoke(someAction)` after `Application.RequestStop` similarly defers the action.
- Existing tests that use `Invoke` followed by explicit timer/idle processing continue to pass (timed events are correctly advanced without requiring a full `Application.Run`).
- No CSI mouse‑disable escape sequences are written when running under the unit‑testing console driver.

**Observable constraints**
- `Application.Invoke` must not throw when `Application.Top` is `null`.
- The fix must not break the normal case where `Invoke` on the UI thread while the top is running continues to execute synchronously (preserving the existing performance shortcut).

Fixes #4325. ApplicationImpl.Invoke is sometimes running on UI thread when Application.Top is null (#4339)


```
Fixes #2681 - SpinnerView animation should be advanced explicitly, not via SetNeedsDisplay

SpinnerView currently relies on View.SetNeedsDisplay() being called externally to advance its animation. This is problematic because SetNeedsDisplay is a general-purpose draw-request method, not an animation step – coupling animation state with drawing unnecessarily.

Add a public method (e.g., AdvanceAnimation()) that advances the spinner's animation frame, respecting the existing SpinDelay throttling, and then calls SetNeedsDisplay to trigger a redraw. Update the AutoSpin feature to schedule calls to this new method instead of SetNeedsDisplay.

Also fix the initial display: right after constructing a SpinnerView, the spinner should show the first animation frame immediately, without requiring an external call to advance animation.

Update the UICatalog Scenario "Progress" that currently calls Spinner.SetNeedsDisplay() to instead use the new method.

Update XML documentation comments to reflect the new API for manual animation advancement.
```

Fixes  #2681- SpinnerView should not use SetNeedsDisplay for advancing its animations (#2710)


**Title:** SpinnerView.AutoSpin does not start animation when set before the application is running

**Description**
When `AutoSpin = true` is set on a `SpinnerView` before the view is added to a running application, the spinner remains stuck on its initial frame and never animates. The documentation states that `AutoSpin` should automatically advance the animation, but this fails when the property is configured early (for example, in a constructor or initializer).

**Steps to Reproduce**
1. Create a new `SpinnerView` and set `AutoSpin = true`.
2. Start the application.
3. Add the spinner to a window and call `app.Run()`.

The spinner appears but does **not** animate – only a single frame is displayed.

**Expected Behavior**
The spinner should begin auto-spinning as soon as it becomes part of the running application, regardless of when `AutoSpin` was set.

**Actual Behavior**
The spinner stays on its first frame. Manually calling `AdvanceAnimation()` still works, but automatic frame updates never occur.

**Impact**
- Users cannot pre‑configure spinners before adding them to the UI, which complicates initialization code.
- The `AutoSpin` getter may return `false` even after `AutoSpin = true` was set, misleading code that checks the property.
- The only reliable workaround is to set `AutoSpin` after the view has been added to a running window, which is undocumented and fragile.

**Additional Context**
This affects all spinner styles (Line, Dots, etc.). The issue is also visible in interactive scenarios; for example, a checkbox that toggles `AutoSpin` works correctly only if the spinner was already part of a running view, but fails if the spinner was created with `AutoSpin = true` initially.

Fixes #4879. SpinnerView AutoSpin does not advance animation (#4882)


## Bug Report: Wizard Accept Key Routing Incorrect for Non-IAcceptTarget Views

**Title:** Pressing Enter in a TextField or ListView on a Wizard step fails to advance to the next step

**Severity:** Medium — breaks expected keyboard navigation flow

**Observed Behavior:**

When a view that is **not** an `IAcceptTarget` (such as `TextField` or `ListView`) has focus inside a `WizardStep`, pressing Enter does not advance the wizard to the next step. Instead, the wizard's own `Accepting` event fires (as if the dialog itself were being accepted), which is incorrect for intermediary steps. On the final step this may prematurely complete the wizard without calling `GoNext` / `GoFinish` or raising `MovingNext`.

Additionally, even when the Next/Finish button is invoked programmatically, the `MovingNext` cancel result is not honored—`GoNext()` is called unconditionally regardless of whether `MovingNext` subscribers set `CancelEventArgs.Cancel = true`.

**Expected Behavior:**

1. When a focused subview on a non-final step does **not** implement `IAcceptTarget`, pressing Enter should act as if the Next button was pressed:
   - Fire the `MovingNext` event.
   - If `MovingNext` is **not** cancelled, advance to the next step via `GoNext()`.
   - If `MovingNext` **is** cancelled, stop and do not advance.
2. When a focused subview on the **final** step does not implement `IAcceptTarget`, pressing Enter should act as if the Finish button was pressed (triggering `MovingNext` + `GoNext()` which in turn triggers the wizard's `Accepting`).
3. When a focused subview **does** implement `IAcceptTarget`, the existing Accept routing should be preserved (the subview handles Enter itself, and the wizard's own Accept behavior should remain unchanged from standard Dialog behavior).

**Steps to Reproduce:**

1. Create a `Wizard` with at least two steps.
2. Add a `TextField` or `ListView` to the first step (neither implements `IAcceptTarget`).
3. Run the wizard modally, focus the `TextField`/`ListView`.
4. Press Enter.

**Actual:** The wizard does not advance. The wizard's `Accepting` event fires (or nothing happens), depending on current state.

**Expected:** The wizard advances to the next step, and the `MovingNext` event is raised.

**Additional Constraints:**

- The fix must not break Enter handling for views that **do** implement `IAcceptTarget` (e.g., `Button`). Those views should still receive and process Enter normally.
- The `MovingNext` cancellation path must be respected: if a subscriber sets `CancelEventArgs.Cancel = true`, `GoNext()` must **not** be called and the step must not change.
- The fix should work for all step positions (first, middle, last) and correctly transition between Next and Finish button behavior depending on whether the current step is the last enabled step.


**Bug: Hotkey bindings on unfocused views no longer invoke commands; ContextMenu dismiss broken**

After recent refactoring, keyboard hotkey handling stopped working for views that do not have focus. Pressing a key bound with `KeyBindingScope.HotKey` on any unfocused `View` no longer invokes the associated `Command`. This regression breaks `ContextMenu`: pressing the configured context-menu key a second time fails to dismiss the menu, leaving it open.

Restore the expected behavior:
- During key-down dispatch, hotkey bindings (`KeyBindingScope.HotKey`) must be checked on all subviews, not just the focused view.
- `ContextMenu` should register its own key as an application-level hotkey (`Application.KeyBindings`) with `Command.Cancel` when shown, and remove it when disposed/hidden, so the menu can be dismissed reliably.

Ensure that focused-scope bindings (`KeyBindingScope.Focused`) and hotkey-scope bindings are handled independently in the dispatch path, and that no hotkey command is lost because of a view’s focus state.


We need a clear, public way to control whether a View’s content size tracks the viewport or can be set independently, and `DimAutoStyle.Content` must respect this distinction.

### Background
Currently `DimAutoStyle.Content` uses the following heuristic: if `_contentSize` (private) is `null`, it inspects subviews to determine the auto-size; otherwise it uses the explicitly set `ContentSize`. Users have no way to query or control which mode they are in.

### Required behavior
- Add a public boolean property `ContentSizeTracksViewport` to **View**.
  - Defaults to `true`, preserving existing behavior: `ContentSize` equals the viewport size, and `DimAutoStyle.Content` computes the dimension based on the largest subview position+size.
  - When set to `false`:
    - `ContentSize` is independent of the viewport and can be set explicitly (enabling virtual scrolling).
    - `DimAutoStyle.Content` must use the explicitly assigned `ContentSize`, completely ignoring subviews.
    - Calling `Add`/`Remove` on subviews **must not** alter `ContentSize` when `ContentSizeTracksViewport` is `false`.
- Update the XML doc comments for `DimAutoStyle.Content` and `DimAutoStyle.Auto` to describe the new property’s role, removing mentions of the old implicit null check.

### Edge cases / invariants
- Setting `ContentSizeTracksViewport = true` after an explicit `ContentSize` was set reverts to tracking: `ContentSize` must immediately reflect the viewport size.
- `DimAutoStyle.Content` behavior must switch accordingly at layout time, not rely on any internal `null` guards.
- Negative `ContentSize` values remain prohibited.
- The existing `LayoutSubviews` validation that checks for conflicting `DimAuto` usage must use `ContentSizeTracksViewport` instead of an internal null check.


```
ContextMenu.MouseFlagsChanged event should provide both old and new values (like KeyChanged does)

Currently, `ContextMenu.MouseFlagsChanged` is declared as `event Action<MouseFlags>` and, when
invoked, only passes the old value. This makes it impossible for subscribers to know what the
new value is without re-reading the property themselves, and it is inconsistent with the
neighbouring `KeyChanged` event, which uses a dedicated `EventArgs` subclass to deliver both
the old key and the new key.

We should bring `MouseFlagsChanged` into line with the same pattern:

- Introduce an `EventArgs` subclass (analogous to `KeyChangedEventArgs`) that exposes `OldValue`
  and `NewValue` properties of type `MouseFlags`.
- Change the event declaration from `Action<MouseFlags>` to
  `EventHandler<MouseFlagsChangedEventArgs>`.
- Update the `MouseFlags` property setter to instantiate the new args class with both the old
  and new values and pass `this` as the sender.
- Adjust any internal callers and the test that verifies the event receives the old value so
  they continue to work correctly with the new signature.

Acceptance criteria:
- `MouseFlagsChanged` provides the old and new `MouseFlags` values to subscribers.
- The API is consistent with the `KeyChanged` event on the same class.
- All existing tests that exercise `MouseFlagsChanged` continue to pass.
```


# Ticket: Improve clarity and correctness of Attribute initialization and validity

**Context**
The `Attribute` struct (in `Terminal.Gui/Core/ConsoleDriver.cs`) carries a driver-specific integer `Value`, a `Foreground` and a `Background` color, and an `IsInitialized` flag. Its current behavior has a few issues that lead to confusion and subtle bugs:

- `IsInitialized` is set inconsistently. For example, the `Attribute(int value)` constructor always marks the attribute as initialized even when `Application.Driver` is null, even though the colors cannot be determined.
- When no driver is loaded and a color cannot be resolved, `Foreground`/`Background` default to `Color.Black` (a valid color) instead of `Color.Invalid`. This means `IsValid()` may return `true` for attributes that are in fact not usable.
- The method name `IsValid()` doesn’t clearly convey what it validates, and having both `IsInitialized` and `IsValid` is confusing.

**Requested Changes**

1. **Rename the initialization flag** for clarity.
   - Replace `IsInitialized` with a more purpose-revealing name (e.g., `Initialized`).
   - The flag must be `true` **only** when the attribute was created in the context of a loaded driver (`Application.Driver != null`) **and** the driver successfully resolved the colors.

2. **Enforce that uninitialized attributes expose `Color.Invalid` colors**.
   - When a driver is not available, the `Foreground` and `Background` properties of the attribute **must be `Color.Invalid`** (not default/`Color.Black`). This ensures that clients can reliably detect that the attribute lacks valid color values.

3. **Replace the `IsValid()` method with a more descriptive property**.
   - Provide a read-only property (e.g., `HasValidColors`) that returns `true` **only** when both `Foreground` and `Background` are not equal to `Color.Invalid`.
   - Remove the old `IsValid()` method to avoid ambiguity.

4. **Update all internal consumers** to use the new property and flag:
   - In `ColorScheme` setters (`Normal`, `Focus`, `HotNormal`, `HotFocus`, `Disabled`), reject assignments where the new validity property is `false` (i.e., do not update the scheme if the attribute has invalid colors).
   - In the implicit conversion `operator int(Attribute)`, emit the existing debug warning when the renamed initialization flag is `false`.
   - In `ConsoleDriver.SetAttribute`, also use the renamed flag for the debug assertion.

5. **No other behavioral changes**. All existing public API contracts (e.g., `Make`, `Get`, constructors) must remain compatible except for the specific clarifications above.


```
Feature Request: Accurate supported cultures for self-contained single-file apps

Currently, when a Terminal.Gui app is published as a self-contained single-file,
the `Application.SupportedCultures` property returns a fixed, hardcoded list of cultures
(fr-FR, ja-JP, pt-PT, zh-Hans) regardless of which localization resources were actually
included in the build. This is misleading: if a developer includes only a subset of
those languages, or includes additional ones, the reported cultures do not match
what is available at runtime.

Desired behavior:
- `SupportedCultures` should reflect the set of cultures for which the application
  actually contains embedded localization strings. Those strings live in the
  `Terminal.Gui.Resources.Strings` resource set.
- The detection must work for self-contained (single-file) deployments.
- When the project is configured with `<InvariantGlobalization>true</InvariantGlobalization>`,
  no additional cultures should be reported (the list should be empty).
- The assembly-based culture detection that works for non-self-contained deployments
  must remain unchanged.
- The self-contained sample application that ships with the repository should
  accurately validate that `SupportedCultures` matches the actual embedded cultures,
  instead of asserting a fixed count.

Rationale:
Developers moving to self-contained publishing should get accurate information
about which UI cultures their app supports, without manually hardcoding a list
that gets out of sync.
```

Fixes #3632. Automatize getting cultures from the embedded resources strings for self-contained app.


Subject: `Key.Equals` considers `Handled` but `GetHashCode` does not, breaking `ConcurrentDictionary<Key, KeyBinding>` lookups

### Description

When a `Key` is used as the key in a hash-based collection (specifically `ConcurrentDictionary<Key, KeyBinding>`), lookups fail if the `Handled` property on the lookup key differs from the stored key, even when both keys represent the same keyboard input (`KeyCode` matches).

### Steps to Reproduce

1. Create two `Key` instances with the same `KeyCode` (e.g. `Key.F1`) but set `Handled` to `false` on one and `true` on the other.
2. Store a value in a `ConcurrentDictionary<Key, TValue>` using the `Handled = false` key.
3. Attempt a lookup (`TryGetValue`) using the `Handled = true` key.

### Expected Behavior

The lookup succeeds because the keys are logically the same input binding. `Handled` is per-event state that changes as the event propagates and should not be part of the key’s identity. This matches the behavior already implemented by `KeyEqualityComparer`, which compares only `KeyCode`. Additionally, the .NET contract that **equal objects must have equal hash codes** must hold.

### Actual Behavior

The lookup fails. `GetHashCode` returns only `_keyCode.GetHashCode()`, so both keys produce the same hash code and land in the same bucket. However, `Equals` includes `Handled` in the comparison, so the two keys are considered not equal, and the dictionary cannot find the value.

### Impact

`KeyBindings` (a `ConcurrentDictionary<Key, KeyBinding>`) is broken whenever a `Key`’s `Handled` state changes between storing a binding and later looking it up during event handling. This causes user-defined key bindings to silently stop working.

### Required Fix

- Remove `Handled` from the `Key.Equals(object?)` implementation so that equality depends only on `KeyCode`, consistent with `GetHashCode` and with `KeyEqualityComparer`.
- The `Equals` override should be updated to match the already-correct `GetHashCode` and the `KeyEqualityComparer` logic. No changes to `GetHashCode` or `KeyEqualityComparer` are needed.

fix: Key.Equals honors GetHashCode contract; drops Handled from identity (#5170) (#5179)


We occasionally see `Application.MainLoop.Invoke` actions silently lost under concurrent use. When multiple threads call `Invoke` rapidly (or add idle handlers directly via `AddIdle`), some callbacks never execute, causing the application to hang or timeout waiting for a logical completion. This appears to be a race condition inside `MainLoop`’s idle handler list management.

The desired behavior:

1. All idle handlers added via `AddIdle`—including those added internally by `Invoke`—must be reliably processed. In particular, when `RunIdle` empties the handler list (`idleHandlers = new List<>()`), any handler added concurrently must end up in the new list and not be lost.
2. `RemoveIdle` must correctly synchronize with the same lock used by `AddIdle` and `RunIdle`, so removal cannot corrupt the list or miss a handler.
3. The `IdleHandlers` property must return a snapshot of the current handler collection; this snapshot must be safe to enumerate even while the underlying collection is being modified from another thread, and the returned type should indicate that the collection is read-only (e.g., `ReadOnlyCollection<Func<bool>>`).
4. The entire idle handler list must be protected by a dedicated lock object, not by locking the list reference itself, because the reference is replaced during iteration. Consistency must be maintained across all accesses to the list.

Acceptance criteria:
- Under heavy concurrent calls to `Application.MainLoop.Invoke`, every posted action eventually executes; no observable loss occurs over thousands of invocations.
- The `IdleHandlers` property returns a copy that does not change while being enumerated, and its static type is an immutable collection.
- Removing an idle handler while the main loop is running is thread-safe and does not cause exceptions or missed removals.
- No breaking change to the public API beyond the type of `IdleHandlers` (formerly `List<Func<bool>>`, now returning something like `ReadOnlyCollection<Func<bool>>`), and the core scheduling behavior remains compatible with existing idle handler contracts.

Fixes #1994. BREAKING CHANGE. Ensure only a single IdleHandlers list can exist. (#1997)


**Feature Request: TextField should auto-select all text when focused via keyboard**

**Summary**
Currently, when a `TextField` gains focus (e.g., by pressing Tab or calling `SetFocus()`), the text is not selected. This makes it impossible to immediately replace the existing text by typing, which is the expected behavior in many GUI toolkits.

We want the `TextField` to automatically select its entire contents when it receives focus through keyboard navigation, but **not** when focus is obtained via mouse click.

---

### Acceptance Criteria

1. **Keyboard focus selects all text**
   Given a `TextField` with the text `"Hello World"` and no focus,
   When `SetFocus()` is called (simulating keyboard navigation like Tab),
   Then `SelectedText` must be `"Hello World"`, `SelectedLength` must be `11`, and any subsequent typing replaces the selected text.

2. **Empty field is unaffected**
   When a `TextField` is empty (`Text == ""`),
   Calling `SetFocus()` must **not** produce any selection (`SelectedText` stays `null`, `SelectedLength` remains `0`).

3. **Re‑focus selects again**
   If a `TextField` already has focus and `SetFocus()` is called again (e.g., the focus cycle returns to it),
   The entire text must be selected once more, even if the user had manually positioned the cursor or cleared the selection.

4. **Mouse focus does **not** auto‑select**
   When a `MouseEvent` with a button press (e.g., left click) occurs on an unfocused `TextField`,
   The field gains focus but the cursor moves to the click position, and no text is selected.
   Any existing selection (including a previous keyboard‑initiated select‑all) must be cleared.

5. **Existing mouse gestures remain unchanged**
   - Double‑click still selects the word under the pointer (with trailing space).
   - Triple‑click still selects all text.

---

### Constraints & Invariants

- The auto‑select behavior must **only** trigger when focus is obtained through `SetFocus()` (the typical keyboard‑focus pathway).
- Mouse clicks that cause focus acquisition must continue to place the cursor at the exact column the user clicked, preserving the current (click‑based) insertion‑point logic.
- The feature must not interfere with read‑only mode or secret mode; those behaviors are separate.
- Existing selection state before gaining focus is irrelevant – keyboard focus always results in a fresh full‑text selection.

Implement TextField select all text on keyboard focus


### Request: Allow oversized dialogs/toplevels to be dragged beyond the left, right, and bottom terminal edges

When a `Toplevel` (e.g., a `Dialog`) has a width greater than the console’s columns or a height greater than the console’s rows, the current drag logic prevents the user from moving it past the left, right, or bottom boundaries of the screen. This makes it impossible to view content that falls outside the visible area on those sides.

#### Acceptance criteria

1. **Dragging an oversized toplevel left/right**
   - If `toplevel.Width > console_columns`, moving the toplevel to the left should allow its `X` coordinate to become negative, effectively shifting the right portion of the view off-screen.
   - Similarly, moving it to the right should allow `X + Width` to exceed the console’s width without being clamped.

2. **Dragging an oversized toplevel down**
   - If `toplevel.Height > console_rows`, moving the toplevel downward should allow `Y + Height` to exceed the console’s height, so the top part can be hidden and the bottom content becomes visible.
   - Moving up should still be limited by the top boundary (e.g., below any menu bar) and must not overshoot above it.

3. **Non-oversized toplevels unchanged**
   - A toplevel whose width fits within the console columns and whose height fits within the rows (accounting for menu/status bars) must continue to be fully confined to the visible area when dragged in any direction.

4. **Runtime resize**
   - If the terminal is resized so that the console becomes smaller than the toplevel’s dimensions, the toplevel must immediately become draggable beyond the left, right, and bottom edges as described above.

5. **Drag position cleanup**
   - When a `Toplevel` instance is disposed, its associated drag state must not leak or affect subsequent drag operations on other toplevels.

Fixes #2434. Dialog bounds bigger than Cols and Rows must be allowed to drag beyond left, right and bottom.


```
Title: SubViewLayout event handler changes to content size are ignored during child layout

Terminal.Gui v2, observed on current main.

When a custom View overrides content size by calling SetContentSize inside a SubViewLayout
event handler, the SubViews are laid out against the content size that was captured before
the event fired, not the updated size.

Steps to reproduce:
1. Create a View that subscribes to its own SubViewLayout event and calls SetContentSize
   with a larger size in the handler.
2. Add a child with Width = Dim.Fill(), Height = Dim.Fill().
3. Layout the view.
4. The child's frame uses the old (smaller) content size, not the size set by the handler.

This is inconsistent with the OnSubViewLayout virtual method, where LayoutSubViews already
re-reads GetContentSize() after the virtual returns (fix from #4863). The SubViewLayout
event is raised immediately after OnSubViewLayout, but without a corresponding re-read,
so a handler that calls SetContentSize is effectively ignored.

The fix should ensure that when SubViewLayout event handlers modify the content size, the
updated value is used when laying out the SubViews — matching the behavior already provided
for OnSubViewLayout overrides.

Related: #4522 (NeedsLayout lifecycle)
```

#4522: Document NeedsLayout invariant, complete content-size re-read, add layout-convergence guards


**Title:** Allow `Dim.Fill` margin to be a dynamic `Dim` instead of only `int`

**Background**
`Dim.Fill(int margin = 0)` currently accepts only a static integer margin. This prevents using a margin that depends on layout context or the dimensions of other views — for example, filling the remaining space but leaving a margin equal to the height of a status bar or a sibling view.

**Request**
Change `Dim.Fill` so that the margin can be specified as a `Dim`, not only an `int`. This makes `Fill` consistent with other dimension types (e.g., `Dim.Auto` already accepts `Dim?` parameters) and removes the need for fragile workarounds like subtracting a `Dim` from a zero-margin `Fill`.

**Specifics**
- Replace the `int margin` parameter with a `Dim margin` parameter in the `Fill` factory method.
- Provide a parameterless `Fill()` overload that maps to a margin of `Dim.Absolute(0)`. This preserves the common zero-margin case without requiring callers to wrap in `Dim.Absolute`.
- Update the internal `DimFill` record so that its `Margin` property is of type `Dim` and `GetAnchor` evaluates the margin through `Margin.GetAnchor(0)` rather than using a raw integer.
- The `ToString()` representation should reflect the margin as a `Dim` (e.g., `Fill(Absolute(0))` rather than `Fill(0)`).
- This is a breaking API change for any caller currently passing an `int`. Since we are in v2 pre-alpha, that is acceptable. Existing callers must be updated to wrap integer margins in `Dim.Absolute` or to use the parameterless overload where appropriate.
- Also check internal usages (e.g., in `KeyBindingsDialog`) where a dynamic expression like `Dim.Fill() - Dim.Func(...)` could be more cleanly expressed as `Dim.Fill(Dim.Func(...))` now that `Fill` accepts a `Dim` margin directly.

Dim.Fill now takes a Dim, instead of an int


### TreeView<T>.ColorGetter ignores Scheme.Active when tree isn't focused

The `ColorGetter` delegate on `TreeView<T>` lets callers return a per-item `Scheme` for custom coloring. The expected semantics are view‑style: use `Scheme.Normal` for unselected rows, `Scheme.Focus` for the selected row when the tree view has focus, and `Scheme.Active` for the selected row when the tree view does **not** have focus.

Currently the rendering always picks `Scheme.Focus` for the selected row, regardless of whether the tree view is focused. This means a custom color scheme effectively ignores the `Active` attribute entirely — the selected row looks identical whether the tree or another control has focus, which is inconsistent with the rest of the toolkit.

We need to:
- Pick `Scheme.Active` from the returned scheme when a row is selected and the tree view does not have focus.
- Keep the existing behavior of picking `Scheme.Focus` when focused and `Scheme.Normal` when not selected.
- Update the XML documentation on `ColorGetter` to explicitly state that TreeView only uses the `Normal`, `Focus`, and `Active` roles from the returned scheme, and to describe what each role represents (unselected, focused‑selected, inactive‑selected).

A demonstration of this behavior is also missing from the UICatalog TreeView scenario. Adding a toggle that assigns per‑type color schemes with a distinct `Active` attribute, and then shows the selected row’s appearance changing as focus moves away, would help validate the fix.

Fixes #5509 branch color getter invoker now applies Active attribute (#5510)


**Request: Clean up Toplevel disposal workaround in UICatalog and document current lifecycle behavior**

### Background
Issue #520 in `Terminal.Gui` causes the initial `Toplevel` created by `Application.Init` to remain undisposed after `Application.Shutdown`. Some UICatalog scenarios that call `Application.Run<T>()` contain a workaround that manually disposes that initial `Toplevel` before running their own. This workaround is fragile and may interfere with other scenarios or the intended lifecycle.

### Desired behavior
1. **Remove the manual disposal workaround** from the `BackgroundWorkerCollection` scenario (and any other scenario that uses `Application.Run<T>()`). The scenario should no longer dispose `Application.Top` explicitly; it should rely on the standard `Init`/`Shutdown` lifecycle managed by `UICatalogApp`.
   *Acceptance:* Running the `BackgroundWorkerCollection` scenario from UICatalog does not attempt to call `Dispose` on the initial `Toplevel`, and the scenario starts and ends cleanly without crashes or double-dispose errors.

2. **Rename the scenario selection entry point** in `UICatalogApp`. The current `SelectScenario` method is a static function that runs the catalog UI top-level and returns the chosen scenario. Rename it to `RunUICatalogTopLevel` to better describe its role, and move it to a position consistent with its usage (it acts as a sub-process for the catalog UI). The main loop in `Main` must call this renamed method.
   *Acceptance:* The UICatalog app compiles and works identically; the only visible change is the renamed internal method (no user-facing impact).

3. **Add unit tests that document the current Toplevel disposal behavior** as baseline for the known bug #520:
   - After `Application.Init` followed by `Application.Shutdown`, exactly one `Toplevel` instance exists in `Responder.Instances`, and **it is not disposed**.
   - In a flow using `Application.Begin`/`Application.End` with a non‑MDI `Toplevel`, the Toplevel passed to `Begin` is properly disposed by `End`, while the initial Toplevel from `Init` remains undisposed.
   - In a flow using `Application.Begin`/`Application.End` with an MDI `Toplevel` (`IsMdiContainer = true`), the same invariant holds: the MDI Toplevel is disposed after `End`, and the initial Toplevel is not.
   *Acceptance:* The tests pass on the current codebase, serving as a faithful record of the #520 behavior. When #520 is fixed later, those tests will be updated to assert full disposal. The tests must be placed in the existing `ApplicationTests` and `MdiTests` test classes and follow the project’s testing style (xUnit `[Fact]`, explicit `Init`/`Shutdown` calls, using `FakeDriver` and `FakeMainLoop`).

### Constraints
- The existing `Init`/`Shutdown` pairing in `UICatalogApp.Main` must remain correct: each scenario’s `Init` call is matched by a `Shutdown` call, and the catalog’s own top-level runs with its own `Application.Run<UICatalogTopLevel>` / `Shutdown` cycle. Do not change the overall bracketing.
- The renamed method must remain `static` and return `Scenario`, just like `SelectScenario` did.


```
Title: GradientFill returns incorrect colors when area is not at origin

Description:
When creating a GradientFill using a Rectangle that does not start at (0,0), the GetColor method returns unexpected colors, often black (the default fallback color). For example, a diagonal red-to-blue gradient over the area (5,5,10,10) should return red at the top-left corner (5,5) and blue at the bottom-right (14,14), but currently all corners return black.

This happens even though the same gradient works perfectly when the area is positioned at the origin (0,0,10,10).

Expected behavior:
GetColor should correctly map any point within the area to the appropriate gradient color, regardless of where the area is located on screen. The internal color mapping should be shifted so that points relative to the area are properly aligned with the absolute screen coordinates passed to GetColor.

Reproduction:
```csharp
var gradient = new Gradient(new[] { new Color(255,0,0), new Color(0,0,255) }, new[] { 5, 5 });
var area = new Rectangle(5, 5, 10, 10);
var fill = new GradientFill(area, gradient, GradientDirection.Diagonal);
var color = fill.GetColor(new Point(5, 5)); // Expected: red (255,0,0), actual: black (0,0,0)
```

Likely cause:
The dictionary built in GradientFill’s constructor using Gradient.BuildCoordinateColorMapping stores keys that are relative to the area’s local coordinate system (0-based), but GetColor receives absolute screen coordinates. When the area is not at the origin, those absolute coordinates never match the local keys. The mapping should be offset by area.X and area.Y to convert the local coordinates to the global coordinate space used by GetColor.

Impact:
Any UI element that places a GradientFill at a non-zero position will display wrong colors or fallback black, breaking visual output for all non-origin gradient fills.
```