@@ -22,8 +22,8 @@ public sealed class TerminalUI : MonoBehaviour
2222 {
2323 private const string TerminalRootName = "TerminalRoot" ;
2424 private const float LauncherAutoCompleteSpacing = 6f ;
25- private const float LauncherEstimatedSuggestionRowHeight = 28f ;
26- private const float LauncherEstimatedHistoryRowHeight = 24f ;
25+ private const float LauncherEstimatedSuggestionRowHeight = 32f ;
26+ private const float LauncherEstimatedHistoryRowHeight = 28f ;
2727
2828 private enum ScrollBarCaptureState
2929 {
@@ -230,6 +230,8 @@ private enum ScrollBarCaptureState
230230 private VisualElement _terminalContainer ;
231231 private ScrollView _logScrollView ;
232232 private ScrollView _autoCompleteContainer ;
233+ private VisualElement _autoCompleteViewport ;
234+ private VisualElement _logViewport ;
233235 private VisualElement _inputContainer ;
234236 private TextField _commandInput ;
235237 private Button _runButton ;
@@ -246,6 +248,9 @@ private enum ScrollBarCaptureState
246248 ) ;
247249 private readonly List < VisualElement > _autoCompleteChildren = new ( ) ;
248250
251+ private float _launcherSuggestionContentHeight ;
252+ private float _launcherHistoryContentHeight ;
253+
249254 // Cached for performance (avoids allocations)
250255 private readonly Action _focusInput ;
251256#if UNITY_EDITOR
@@ -757,6 +762,11 @@ private void ResetWindowIdempotent()
757762 int width = Screen . width ;
758763 float oldTargetHeight = _targetWindowHeight ;
759764 bool wasLauncher = _launcherMetricsInitialized ;
765+ if ( _state != TerminalState . OpenLauncher )
766+ {
767+ _launcherSuggestionContentHeight = 0f ;
768+ _launcherHistoryContentHeight = 0f ;
769+ }
760770 try
761771 {
762772 switch ( _state )
@@ -789,6 +799,8 @@ private void ResetWindowIdempotent()
789799 ( computedMetrics . InsetPadding * 2f ) + reservedEstimate ;
790800 _launcherMetrics = computedMetrics ;
791801 _launcherMetricsInitialized = true ;
802+ _launcherSuggestionContentHeight = 0f ;
803+ _launcherHistoryContentHeight = 0f ;
792804 _realWindowHeight = _launcherMetrics . Height ;
793805 if ( ! wasLauncher )
794806 {
@@ -893,13 +905,45 @@ private void SetupUI()
893905 _logScrollView . name = "LogScrollView" ;
894906 _logScrollView . AddToClassList ( "log-scroll-view" ) ;
895907 _terminalContainer . Add ( _logScrollView ) ;
908+ _logViewport = _logScrollView . contentViewport ;
909+ if ( _logViewport != null )
910+ {
911+ _logViewport . style . flexGrow = 1f ;
912+ _logViewport . style . flexShrink = 1f ;
913+ _logViewport . style . minHeight = 0f ;
914+ _logViewport . style . overflow = Overflow . Hidden ;
915+ }
916+ VisualElement logContent = _logScrollView . contentContainer ;
917+ logContent . style . flexDirection = FlexDirection . Column ;
918+ logContent . style . alignItems = Align . Stretch ;
919+ logContent . style . minHeight = 0f ;
920+ logContent . RegisterCallback < GeometryChangedEvent > ( OnLogContentGeometryChanged ) ;
896921
897922 _autoCompleteContainer = new ScrollView ( ScrollViewMode . Horizontal )
898923 {
899924 name = "AutoCompletePopup" ,
900925 } ;
901926 _autoCompleteContainer . AddToClassList ( "autocomplete-popup" ) ;
902927 _terminalContainer . Add ( _autoCompleteContainer ) ;
928+ _autoCompleteViewport = _autoCompleteContainer . contentViewport ;
929+ if ( _autoCompleteViewport != null )
930+ {
931+ _autoCompleteViewport . style . flexDirection = FlexDirection . Row ;
932+ _autoCompleteViewport . style . flexGrow = 0f ;
933+ _autoCompleteViewport . style . flexShrink = 0f ;
934+ _autoCompleteViewport . style . minHeight = 0f ;
935+ _autoCompleteViewport . style . overflow = Overflow . Visible ;
936+ _autoCompleteViewport . RegisterCallback < GeometryChangedEvent > (
937+ OnAutoCompleteGeometryChanged
938+ ) ;
939+ }
940+ VisualElement autoContent = _autoCompleteContainer . contentContainer ;
941+ autoContent . style . flexDirection = FlexDirection . Row ;
942+ autoContent . style . alignItems = Align . Center ;
943+ autoContent . style . minHeight = 0f ;
944+ autoContent . style . justifyContent = Justify . FlexStart ;
945+ autoContent . style . flexWrap = Wrap . NoWrap ;
946+ autoContent . RegisterCallback < GeometryChangedEvent > ( OnAutoCompleteGeometryChanged ) ;
903947
904948 _inputContainer = new VisualElement { name = "InputContainer" } ;
905949 _inputContainer . AddToClassList ( "input-container" ) ;
@@ -1375,6 +1419,7 @@ private void ApplyStandardLayout(float screenWidth)
13751419 _autoCompleteContainer . style . maxHeight = new StyleLength ( StyleKeyword . Null ) ;
13761420 _autoCompleteContainer . style . maxWidth = new StyleLength ( StyleKeyword . Null ) ;
13771421 _autoCompleteContainer . style . height = new StyleLength ( StyleKeyword . Null ) ;
1422+ _autoCompleteContainer . style . minHeight = new StyleLength ( StyleKeyword . Null ) ;
13781423 _autoCompleteContainer . style . marginBottom = 0 ;
13791424 _autoCompleteContainer . style . marginTop = 0 ;
13801425 _autoCompleteContainer . style . marginLeft = 0 ;
@@ -1442,6 +1487,7 @@ private void ApplyLauncherLayout(float screenWidth, float screenHeight)
14421487 _logScrollView . style . display = DisplayStyle . None ;
14431488 _logScrollView . style . height = 0 ;
14441489 _logScrollView . style . maxHeight = 0 ;
1490+ _launcherHistoryContentHeight = 0f ;
14451491 _logScrollView . style . marginTop = 0 ;
14461492 }
14471493
@@ -2779,6 +2825,7 @@ private void UpdateLauncherLayoutMetrics()
27792825 _autoCompleteContainer . style . alignSelf = Align . Stretch ;
27802826 _autoCompleteContainer . style . flexGrow = 0 ;
27812827 _autoCompleteContainer . style . flexShrink = 0 ;
2828+ _autoCompleteContainer . style . minHeight = 0f ;
27822829
27832830 bool hasSuggestions = false ;
27842831 int suggestionChildCount = _autoCompleteContainer . contentContainer . childCount ;
@@ -2810,23 +2857,40 @@ private void UpdateLauncherLayoutMetrics()
28102857 {
28112858 _autoCompleteContainer . style . display = DisplayStyle . None ;
28122859 _autoCompleteContainer . style . height = 0 ;
2860+ if ( _autoCompleteViewport != null )
2861+ {
2862+ _autoCompleteViewport . style . height = 0 ;
2863+ }
28132864 _autoCompleteContainer . style . marginTop = 0 ;
2865+ _launcherSuggestionContentHeight = 0f ;
2866+ }
2867+
2868+ float effectiveSuggestionHeight = _launcherSuggestionContentHeight ;
2869+ if ( effectiveSuggestionHeight <= 0f && hasSuggestions )
2870+ {
2871+ effectiveSuggestionHeight = LauncherEstimatedSuggestionRowHeight ;
28142872 }
28152873
28162874 float suggestionsHeight = hasSuggestions
2817- ? Mathf . Min ( LauncherEstimatedSuggestionRowHeight , _launcherMetrics . HistoryHeight )
2875+ ? Mathf . Clamp ( effectiveSuggestionHeight , 0f , _launcherMetrics . HistoryHeight )
28182876 : 0f ;
28192877 if ( hasSuggestions )
28202878 {
28212879 _autoCompleteContainer . style . height = Mathf . Max ( 0f , suggestionsHeight ) ;
2880+ if ( _autoCompleteViewport != null )
2881+ {
2882+ _autoCompleteViewport . style . height = Mathf . Max ( 0f , suggestionsHeight ) ;
2883+ }
28222884 }
28232885 _autoCompleteContainer . style . marginBottom = 0 ;
28242886
2825- float reservedForSuggestions = (
2826- hasSuggestions
2827- ? suggestionsHeight + LauncherAutoCompleteSpacing
2828- : LauncherAutoCompleteSpacing
2829- ) ;
2887+ float spacingAboveLog = hasSuggestions
2888+ ? LauncherAutoCompleteSpacing
2889+ : Mathf . Max ( LauncherAutoCompleteSpacing , padding * 0.25f ) ;
2890+
2891+ float reservedForSuggestions = hasSuggestions
2892+ ? suggestionsHeight + spacingAboveLog
2893+ : spacingAboveLog ;
28302894
28312895 VisualElement historyContent = _logScrollView . contentContainer ;
28322896 int visibleHistoryCount = 0 ;
@@ -2848,26 +2912,34 @@ private void UpdateLauncherLayoutMetrics()
28482912 pendingLogs ,
28492913 _launcherMetrics . HistoryVisibleEntryCount
28502914 ) ;
2915+ if ( visibleHistoryCount == 0 )
2916+ {
2917+ _launcherHistoryContentHeight = 0f ;
2918+ }
28512919 }
28522920
2853- float desiredHistoryHeight = Mathf . Min (
2854- visibleHistoryCount * LauncherEstimatedHistoryRowHeight ,
2855- _launcherMetrics . HistoryHeight
2856- ) ;
2857- if ( desiredHistoryHeight < 0f )
2921+ float historyHeightFromContent =
2922+ visibleHistoryCount > 0 ? _launcherHistoryContentHeight : 0f ;
2923+ if ( float . IsNaN ( historyHeightFromContent ) || historyHeightFromContent < 0f )
28582924 {
2859- desiredHistoryHeight = 0f ;
2925+ historyHeightFromContent = 0f ;
28602926 }
28612927
2862- if ( visibleHistoryCount > 0 )
2863- {
2864- desiredHistoryHeight = Mathf . Max (
2865- desiredHistoryHeight ,
2866- Mathf . Min (
2867- visibleHistoryCount * LauncherEstimatedHistoryRowHeight ,
2928+ float estimatedHistoryHeight =
2929+ visibleHistoryCount > 0
2930+ ? visibleHistoryCount * LauncherEstimatedHistoryRowHeight
2931+ : 0f ;
2932+
2933+ float desiredHistoryHeight =
2934+ visibleHistoryCount > 0
2935+ ? Mathf . Min (
2936+ Mathf . Max ( historyHeightFromContent , estimatedHistoryHeight ) ,
28682937 _launcherMetrics . HistoryHeight
28692938 )
2870- ) ;
2939+ : 0f ;
2940+ if ( desiredHistoryHeight < 0f )
2941+ {
2942+ desiredHistoryHeight = 0f ;
28712943 }
28722944
28732945 float minimumHeight = padding * 2f + inputHeight + reservedForSuggestions ;
@@ -2905,6 +2977,7 @@ private void UpdateLauncherLayoutMetrics()
29052977 _logScrollView . style . display = DisplayStyle . None ;
29062978 _logScrollView . style . height = 0 ;
29072979 _logScrollView . style . maxHeight = 0 ;
2980+ _launcherHistoryContentHeight = 0f ;
29082981 }
29092982 else
29102983 {
@@ -2913,8 +2986,52 @@ private void UpdateLauncherLayoutMetrics()
29132986 _logScrollView . style . maxHeight = availableForHistory ;
29142987 }
29152988
2916- float logTopMargin = LauncherAutoCompleteSpacing ;
2917- _logScrollView . style . marginTop = logTopMargin ;
2989+ _logScrollView . style . marginTop = spacingAboveLog ;
2990+ }
2991+
2992+ private void OnAutoCompleteGeometryChanged ( GeometryChangedEvent evt )
2993+ {
2994+ if ( evt == null )
2995+ {
2996+ return ;
2997+ }
2998+
2999+ float newHeight = Mathf . Max ( evt . newRect . height , 0f ) ;
3000+ if ( float . IsNaN ( newHeight ) )
3001+ {
3002+ newHeight = 0f ;
3003+ }
3004+
3005+ bool isViewport = evt . target == _autoCompleteViewport ;
3006+ bool hasChildren = _autoCompleteContainer ? . contentContainer ? . childCount > 0 ;
3007+ if ( isViewport && newHeight <= 0f && hasChildren )
3008+ {
3009+ return ;
3010+ }
3011+
3012+ if ( ! Mathf . Approximately ( newHeight , _launcherSuggestionContentHeight ) )
3013+ {
3014+ _launcherSuggestionContentHeight = newHeight ;
3015+ }
3016+ }
3017+
3018+ private void OnLogContentGeometryChanged ( GeometryChangedEvent evt )
3019+ {
3020+ if ( evt == null )
3021+ {
3022+ return ;
3023+ }
3024+
3025+ float newHeight = Mathf . Max ( evt . newRect . height , 0f ) ;
3026+ if ( float . IsNaN ( newHeight ) )
3027+ {
3028+ newHeight = 0f ;
3029+ }
3030+
3031+ if ( ! Mathf . Approximately ( newHeight , _launcherHistoryContentHeight ) )
3032+ {
3033+ _launcherHistoryContentHeight = newHeight ;
3034+ }
29183035 }
29193036
29203037 private void StartHeightAnimation ( )
0 commit comments