@@ -107,26 +107,21 @@ export class HoverPreviewController {
107107 this . unsubscribeInput = this . deps . registerInputListener ( handler ) ;
108108 this . transition ( { kind : "armed-on-mount" } , "mount" ) ;
109109
110- // There is no portable positive acknowledgement for terminal mouse mode.
111- // Keep a bounded, unref'd fallback: hosts that never deliver an SGR report
112- // get one warning and the controller relinquishes its mode lease.
113- this . mouseSupportTimer = setTimeout (
114- ( ) => {
115- if ( this . mounted && ! this . disposed ) this . abandonMouseSupport ( ) ;
116- } ,
117- Math . max ( 1_000 , this . cfg . leaseTtlMs ) ,
118- ) ;
119- const maybeUnref = this . mouseSupportTimer as ReturnType <
120- typeof setTimeout
121- > & {
122- unref ?: ( ) => void ;
123- } ;
124- maybeUnref . unref ?.( ) ;
110+ // A widget can mount before the first subagent frame exists. Do not start
111+ // the bounded mouse-support fallback until there is something the pointer
112+ // can actually hover; a slow spawn wave must not consume the whole grace
113+ // period.
114+ if ( this . hitMap . length > 0 ) this . armMouseSupportTimer ( ) ;
125115 this . deps . onDebug ( `[hover-preview] mounted gen=${ mountedGeneration } ` ) ;
126116 }
127117
128118 updateHitMap ( regions : ReadonlyArray < HitRegion > ) : void {
129119 this . hitMap = regions . map ( ( region ) => ( { ...region } ) ) ;
120+ if ( this . hitMap . length === 0 ) {
121+ this . clearMouseSupportTimer ( ) ;
122+ } else {
123+ this . armMouseSupportTimer ( ) ;
124+ }
130125 }
131126
132127 cprForFirstLine ( line : string , lineIndex : number ) : string {
@@ -402,6 +397,34 @@ export class HoverPreviewController {
402397 }
403398 }
404399
400+ private armMouseSupportTimer ( ) : void {
401+ if (
402+ ! this . mounted ||
403+ this . disposed ||
404+ this . mouseUnsupported ||
405+ this . mouseSupportTimer !== null
406+ ) {
407+ return ;
408+ }
409+
410+ // There is no portable positive acknowledgement for terminal mouse mode.
411+ // Keep a bounded, unref'd fallback: hosts that never deliver an SGR report
412+ // get one warning and the controller relinquishes its mode lease. This
413+ // timer starts only once a visible frame exists (see updateHitMap()).
414+ this . mouseSupportTimer = setTimeout (
415+ ( ) => {
416+ if ( this . mounted && ! this . disposed ) this . abandonMouseSupport ( ) ;
417+ } ,
418+ Math . max ( 1_000 , this . cfg . leaseTtlMs ) ,
419+ ) ;
420+ const maybeUnref = this . mouseSupportTimer as ReturnType <
421+ typeof setTimeout
422+ > & {
423+ unref ?: ( ) => void ;
424+ } ;
425+ maybeUnref . unref ?.( ) ;
426+ }
427+
405428 private clearHoverTimers ( ) : void {
406429 this . clearHoverIntentTimer ( ) ;
407430 this . clearStickyTimer ( ) ;
0 commit comments