Summary
I maintain a downstream consumer of TextControlBox-WinUI (a Windows search tool called Yagu, which embeds it as the built-in full-file editor). Over the last while I've re-architected the editor's scroll/render pipeline in my fork to handle very large / very long-line files and to support diagonal (2-axis) precision-touchpad scrolling. These changes are implemented and battle-tested in production, and I'd love to contribute them back — but they're substantial and build on one another, so I wanted to open an issue and get your read on appetite and preferred shape before dropping a large unsolicited PR.
(For context: I'm the author of the recently merged #28–#32.)
What I'd like to upstream
Four related pieces, each building on the previous one:
-
Pixel-based scroll-offset seam — a small IScrollOffsetSource abstraction so the editor's scroll position is expressed in pixels rather than legacy scrollbar units (SingleLineHeight / DefaultVerticalScrollSensitivity). Phase 1 keeps the two ScrollBar primitives backing it; it's the seam everything else needs.
-
Long-line horizontal virtualization — for pathological single lines (I regularly handle files that are effectively one line of multiple MB), the renderer slices the visible horizontal window (IsHorizontallyVirtualized / HorizontalSliceStart) so Win2D text-layout cost is bounded. Without this, a multi-MB single-line file will hang or fail-fast the Win2D layout.
-
Word-wrap visual-row model — a visual-row layer (StartVisualRow, EnsureWrapMetrics, GetVisibleVisualRowCount, GetVisualRowForCursorPosition, MoveCursorByVisualRows) so scrolling / paging / cursor movement work correctly when a logical line spans multiple visual rows.
-
Diagonal (2-axis) precision-touchpad scrolling — the headline UX win. A real ScrollViewer owns scroll input and the CanvasControls become sticky content children (counter-translated to stay pinned to the viewport), instead of the current single-axis wheel handler. This gives free diagonal panning on precision touchpads, which the current model structurally can't do.
Why
- Performance / robustness on huge and long-line files — the horizontal virtualization + pixel seam are what let the editor open multi-MB single-line files without hanging.
- Modern touchpad UX — diagonal panning is expected behaviour on precision touchpads; the current wheel-only path can only move one axis at a time.
The honest catch
These are entangled — they substantially rework ScrollManager and the renderer, and diagonal scroll depends on the other three. Upstream today has none of the underlying infrastructure (OffsetSource, WordWrap visual-row model, IsHorizontallyVirtualized), so a single "diagonal scroll" PR isn't feasible in isolation.
Proposed approach
I'd suggest a staged PR series in dependency order:
- pixel-offset scroll seam (
IScrollOffsetSource),
- long-line horizontal virtualization,
- word-wrap visual-row model,
- diagonal 2-axis touchpad scrolling.
Each PR is independently reviewable and leaves the control working.
Questions for you
- Is this a direction you want for the library, or is it too large a change to the scroll/render core?
- Would you prefer the staged series above, one larger PR, or something else?
- If you're open to it, I'm happy to start with a draft PR for step 1 (the pixel-offset seam) so you can review the approach before I invest in the rest.
Thanks for the great control — happy to adapt to whatever fits your plans for it.
Summary
I maintain a downstream consumer of TextControlBox-WinUI (a Windows search tool called Yagu, which embeds it as the built-in full-file editor). Over the last while I've re-architected the editor's scroll/render pipeline in my fork to handle very large / very long-line files and to support diagonal (2-axis) precision-touchpad scrolling. These changes are implemented and battle-tested in production, and I'd love to contribute them back — but they're substantial and build on one another, so I wanted to open an issue and get your read on appetite and preferred shape before dropping a large unsolicited PR.
(For context: I'm the author of the recently merged #28–#32.)
What I'd like to upstream
Four related pieces, each building on the previous one:
Pixel-based scroll-offset seam — a small
IScrollOffsetSourceabstraction so the editor's scroll position is expressed in pixels rather than legacy scrollbar units (SingleLineHeight / DefaultVerticalScrollSensitivity). Phase 1 keeps the twoScrollBarprimitives backing it; it's the seam everything else needs.Long-line horizontal virtualization — for pathological single lines (I regularly handle files that are effectively one line of multiple MB), the renderer slices the visible horizontal window (
IsHorizontallyVirtualized/HorizontalSliceStart) so Win2D text-layout cost is bounded. Without this, a multi-MB single-line file will hang or fail-fast the Win2D layout.Word-wrap visual-row model — a visual-row layer (
StartVisualRow,EnsureWrapMetrics,GetVisibleVisualRowCount,GetVisualRowForCursorPosition,MoveCursorByVisualRows) so scrolling / paging / cursor movement work correctly when a logical line spans multiple visual rows.Diagonal (2-axis) precision-touchpad scrolling — the headline UX win. A real
ScrollViewerowns scroll input and theCanvasControls become sticky content children (counter-translated to stay pinned to the viewport), instead of the current single-axis wheel handler. This gives free diagonal panning on precision touchpads, which the current model structurally can't do.Why
The honest catch
These are entangled — they substantially rework
ScrollManagerand the renderer, and diagonal scroll depends on the other three. Upstream today has none of the underlying infrastructure (OffsetSource,WordWrapvisual-row model,IsHorizontallyVirtualized), so a single "diagonal scroll" PR isn't feasible in isolation.Proposed approach
I'd suggest a staged PR series in dependency order:
IScrollOffsetSource),Each PR is independently reviewable and leaves the control working.
Questions for you
Thanks for the great control — happy to adapt to whatever fits your plans for it.