@@ -188,7 +188,7 @@ export default class ScrollableTerminal extends React.PureComponent<Props, State
188
188
: { name : this . props . tabTitle , description : '' , splits : [ this . scrollbackWithWelcome ( ) ] }
189
189
190
190
this . state = {
191
- focusedIdx : 0 ,
191
+ focusedIdx : - 1 ,
192
192
splits,
193
193
notebookMetadata : { name, description }
194
194
}
@@ -621,24 +621,43 @@ export default class ScrollableTerminal extends React.PureComponent<Props, State
621
621
}
622
622
623
623
/** Owner wants us to focus on the current prompt */
624
- public doFocus ( scrollback = this . current ) {
625
- const { _activeBlock } = scrollback
624
+ private _focusDebouncer : NodeJS . Timeout
625
+ public doFocus ( scrollback = this . current , idx = this . state . focusedIdx ) {
626
+ if ( this . state . focusedIdx >= 0 && idx === this . state . focusedIdx ) {
627
+ return
628
+ }
629
+
630
+ if ( this . _focusDebouncer ) {
631
+ clearTimeout ( this . _focusDebouncer )
632
+ this . _focusDebouncer = undefined
633
+ }
626
634
627
- if ( _activeBlock ) {
628
- if ( _activeBlock . state . _block && isInViewport ( _activeBlock . state . _block ) ) {
629
- // re: isInViewport, see https://github.com/IBM/kui/issues/4739
630
- _activeBlock . doFocus ( )
635
+ const ourDebouncer = setTimeout ( ( ) => {
636
+ if ( this . _focusDebouncer !== ourDebouncer || ( this . state . focusedIdx >= 0 && idx === this . state . focusedIdx ) ) {
637
+ return
638
+ } else {
639
+ this . _focusDebouncer = undefined
631
640
}
632
- } else {
633
- // a bit of a data abstraction violation; we should figure out how to solve this better
634
- // see https://github.com/IBM/kui/issues/3945
635
- const xterm = document . querySelector ( 'textarea.xterm-helper-textarea' ) as HTMLTextAreaElement
636
- if ( xterm ) {
637
- xterm . focus ( )
641
+
642
+ const { _activeBlock } = scrollback
643
+
644
+ if ( _activeBlock ) {
645
+ if ( _activeBlock . state . _block && isInViewport ( _activeBlock . state . _block ) ) {
646
+ // re: isInViewport, see https://github.com/IBM/kui/issues/4739
647
+ _activeBlock . doFocus ( )
648
+ }
649
+ } else {
650
+ // a bit of a data abstraction violation; we should figure out how to solve this better
651
+ // see https://github.com/IBM/kui/issues/3945
652
+ const xterm = document . querySelector ( 'textarea.xterm-helper-textarea' ) as HTMLTextAreaElement
653
+ if ( xterm ) {
654
+ xterm . focus ( )
655
+ }
638
656
}
639
- }
640
657
641
- this . setFocusOnScrollback ( scrollback )
658
+ this . setFocusOnScrollback ( scrollback )
659
+ } , 10 )
660
+ this . _focusDebouncer = ourDebouncer
642
661
}
643
662
644
663
/**
@@ -866,7 +885,7 @@ export default class ScrollableTerminal extends React.PureComponent<Props, State
866
885
eventBus . emitWithTabId ( '/tab/close/request' , parent . uuid , parent )
867
886
}
868
887
869
- return { splits }
888
+ return { splits, focusedIdx : idx === 0 ? 0 : idx - 1 }
870
889
}
871
890
} )
872
891
}
@@ -1124,7 +1143,7 @@ export default class ScrollableTerminal extends React.PureComponent<Props, State
1124
1143
willRemove = { this . willRemoveBlock . bind ( this , scrollback . uuid , idx ) }
1125
1144
hasBlockAfter = { this . hasBlockAfter ( scrollback . blocks , idx ) }
1126
1145
hasBlockBefore = { this . hasBlockBefore ( idx ) }
1127
- willLoseFocus = { ( ) => this . doFocus ( scrollback ) }
1146
+ willLoseFocus = { ( ) => this . doFocus ( scrollback , idx ) }
1128
1147
willFocusBlock = { willFocusBlock }
1129
1148
isExperimental = { hasCommand ( _ ) && _ . isExperimental }
1130
1149
isFocused = { isFocused }
0 commit comments