11using System ;
22using System . Collections . Generic ;
33using System . Diagnostics ;
4+ using System . Linq ;
45using System . Threading . Tasks ;
56using CodingWithCalvin . LaunchyBar . Models ;
67using CodingWithCalvin . Otel4Vsix ;
@@ -18,6 +19,7 @@ namespace CodingWithCalvin.LaunchyBar.Services;
1819public sealed class LaunchService : ILaunchService
1920{
2021 private readonly AsyncPackage _package ;
22+ private readonly IConfigurationService _configurationService ;
2123
2224 /// <summary>
2325 /// Maps VS View commands to their tool window GUIDs for toggle support.
@@ -37,9 +39,10 @@ public sealed class LaunchService : ILaunchService
3739 { "View.GitWindow" , new Guid ( "1c64b9c2-e352-428e-a56d-0ace190b99a6" ) } ,
3840 } ;
3941
40- public LaunchService ( AsyncPackage package )
42+ public LaunchService ( AsyncPackage package , IConfigurationService configurationService )
4143 {
4244 _package = package ;
45+ _configurationService = configurationService ;
4346 }
4447
4548 /// <inheritdoc/>
@@ -147,10 +150,57 @@ private async Task ToggleToolWindowAsync(LaunchItem item)
147150 }
148151 }
149152
150- // Window not found or hidden - show it via command
153+ // Window not found or hidden - hide other configured tool windows, then show this one
154+ await HideOtherToolWindowsAsync ( item ) ;
151155 await VS . Commands . ExecuteAsync ( item . Target ) ;
152156 }
153157
158+ private async Task HideOtherToolWindowsAsync ( LaunchItem currentItem )
159+ {
160+ await ThreadHelper . JoinableTaskFactory . SwitchToMainThreadAsync ( ) ;
161+
162+ var shell = await _package . GetServiceAsync ( typeof ( SVsUIShell ) ) as IVsUIShell ;
163+ if ( shell == null ) return ;
164+
165+ // Collect GUIDs of other configured tool window items
166+ var otherGuids = _configurationService . Configuration . Items
167+ . Where ( i => i . Type == LaunchItemType . ToolWindow
168+ && ! i . Target . Equals ( currentItem . Target , StringComparison . OrdinalIgnoreCase ) )
169+ . Select ( i => ToolWindowGuids . TryGetValue ( i . Target , out var g ) ? g : ( Guid ? ) null )
170+ . Where ( g => g . HasValue )
171+ . Select ( g => g ! . Value )
172+ . ToHashSet ( ) ;
173+
174+ if ( otherGuids . Count == 0 ) return ;
175+
176+ shell . GetToolWindowEnum ( out var windowEnum ) ;
177+ if ( windowEnum == null ) return ;
178+
179+ var frames = new IVsWindowFrame [ 1 ] ;
180+ while ( windowEnum . Next ( 1 , frames , out var fetched ) == 0 && fetched == 1 )
181+ {
182+ var frame = frames [ 0 ] ;
183+ if ( frame == null ) continue ;
184+
185+ try
186+ {
187+ frame . GetGuidProperty ( ( int ) __VSFPROPID . VSFPROPID_GuidPersistenceSlot , out var persistGuid ) ;
188+ if ( otherGuids . Contains ( persistGuid ) )
189+ {
190+ frame . IsOnScreen ( out var isOnScreen ) ;
191+ if ( isOnScreen != 0 )
192+ {
193+ frame . Hide ( ) ;
194+ }
195+ }
196+ }
197+ catch
198+ {
199+ // Some frames may throw
200+ }
201+ }
202+ }
203+
154204 private async Task ToggleDebugAsync ( )
155205 {
156206 await ThreadHelper . JoinableTaskFactory . SwitchToMainThreadAsync ( ) ;
0 commit comments