@@ -20,6 +20,7 @@ import {
2020 type BaseRenderable ,
2121 type CliRenderer ,
2222 type KeyEvent ,
23+ type MouseEvent ,
2324 type TextChunk ,
2425} from "@opentui/core"
2526
@@ -3998,8 +3999,8 @@ export function copyAllTargets(shell: AppShell): boolean {
39983999
39994000/**
40004001 * Alt+M: take DEC mouse reporting, or hand it back to the terminal.
4001- * Reporting is off by default so drag-select and the terminal's own copy keep
4002- * working; taking it enables click-to-expand and drag-scroll at that cost .
4002+ * Reporting is on by default so wheel scroll and click-to-expand work;
4003+ * releasing it restores the terminal's own drag-select and copy .
40034004 * Returns the new enabled state, or null when the host exposes no control.
40044005 */
40054006export function toggleMouseCapture ( shell : AppShell ) : boolean | null {
@@ -4497,6 +4498,33 @@ export function handleCtrlC(
44974498 } )
44984499}
44994500
4501+ /**
4502+ * Wheel/trackpad scroll landing on the prompt scrolls the chat instead.
4503+ *
4504+ * The prompt textarea is an editable buffer with its own `scrollY`, so
4505+ * OpenTUI's default routing — whichever renderable the wheel event hits, or
4506+ * the focused renderable when the hit misses — happily scrolls the prompt's
4507+ * own (usually one-screen, nothing-to-scroll) content. The prompt also holds
4508+ * keyboard focus for the whole session, so it is the fallback target for any
4509+ * wheel event that lands off the transcript's hit-tested rows. Overriding the
4510+ * scroll case here — rather than teaching the transcript's own scroll lease
4511+ * about wheel events — keeps the fix to exactly where wheel input actually
4512+ * arrives, without touching transcript viewport internals.
4513+ */
4514+ function routePromptWheelToTranscript (
4515+ prompt : BaseRenderable ,
4516+ transcript : ScrollBoxRenderable ,
4517+ ) : void {
4518+ ; ( prompt as unknown as { onMouseEvent : ( event : MouseEvent ) => void } ) . onMouseEvent = (
4519+ event : MouseEvent ,
4520+ ) => {
4521+ if ( event . type !== "scroll" ) return
4522+ ; (
4523+ transcript as unknown as { onMouseEvent : ( event : MouseEvent ) => void }
4524+ ) . onMouseEvent ( event )
4525+ }
4526+ }
4527+
45004528/**
45014529 * Build the app shell frame on an OpenTUI renderer.
45024530 * Mounts sticky transcript / overlay host / transient notice / prompt box.
@@ -4727,6 +4755,7 @@ export function createAppShell(
47274755 cursorColor : UI . text ,
47284756 placeholderColor : UI . textFaint ,
47294757 } )
4758+ routePromptWheelToTranscript ( prompt , transcript )
47304759 promptField . add ( prompt )
47314760 promptBox . add ( promptTopRule )
47324761 promptBox . add ( promptField )
0 commit comments