Add getFrameController() for application-owned text selection - #984
Open
chiga0 wants to merge 2 commits into
Open
Add getFrameController() for application-owned text selection#984chiga0 wants to merge 2 commits into
getFrameController() for application-owned text selection#984chiga0 wants to merge 2 commits into
Conversation
Expose the composited frame as a read-only grid of cells that apps owning their input (e.g. alternate-screen apps handling mouse events) can subscribe to, and let them push a selection region that Ink highlights before serialization. Frames are only generated while subscribers are registered, listeners are notified outside the render pass with coalesced notifications, and selections are normalized to reading order so reverse drags work.
This was referenced Aug 3, 2026
Cover the gaps found in self-review: the controller is no longer reachable after unmount, and the selection highlight reaches the terminal through the throttled, non-debug interactive render path (log-update writes), not just debug mode.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is the first part of the split suggested in #980: a small, opt-in, read-only frame controller for apps that own their alternate-screen viewport and implement selection themselves. Selection semantics for
Text(flows, boundaries,selectableand friends) are left for a follow-up once the bridge is proven by a real consumer.What's included
getFrameController(stdout)with:getFrame()— a read-onlycells[y][x]grid; each cell exposes onlyvalue+fullWidth. Wide characters occupy two cells: the leading cell hasfullWidth: true, the trailing placeholder has an emptyvalue. No internal style data is exposed.getSelection()/setSelection()— Ink highlights the region before serialization. Repaints go through the regular render throttle, and identical selections are deduplicated.subscribe()— frame listener, returning an unsubscribe function.Concerns from #980 addressed
setSelection()call from a listener schedules a new render instead of re-entering the one in flight; notifications are coalesced and frames delivered in order.getFrameControllerreturns the read-only view); no internal style data is exposed; frames and rows are frozen and deeply readonly-typed.setSelection(), covered by tests.Textprops.Also included
renderInteractiveFramere-asserts the app's current cursor intent before each interactive render: log-update only applies a cursor position set since the previous render, so without this a repaint triggered bysetSelection()would move the cursor from itsuseCursor()position to the end of the output.The alternate-screen
clearTerminalfrom #980 is deliberately not included here: it's an unrelated behavior change and can be a separate proposal if desired.