@@ -82,6 +82,7 @@ public partial class MainWindow :
8282 private readonly DispatcherTimer _notificationTimer ;
8383 private PixelPoint ? _normalPosition ;
8484 private WindowSizeState _normalSize = new ( ) ;
85+ private KeyModifiers _newTabButtonModifiers ;
8586
8687 public MainWindow ( ) : this ( 0 , string . Empty , null )
8788 {
@@ -145,11 +146,12 @@ public MainWindow(
145146 var newTabShortcut = _settings . ActionMap
146147 . GetKeyBindingForAction ( "Terminal.OpenNewTab" ) ?
147148 . ToDisplayString ( ) ;
148- ToolTip . SetTip (
149- NewTabButton ,
150- string . IsNullOrWhiteSpace ( newTabShortcut )
151- ? "New tab"
152- : $ "New tab ({ newTabShortcut } )") ;
149+ ToolTip . SetTip ( NewTabButton , NewTabButtonTooltip ( newTabShortcut ) ) ;
150+ NewTabButton . AddHandler (
151+ PointerPressedEvent ,
152+ ( _ , e ) => _newTabButtonModifiers = e . KeyModifiers ,
153+ RoutingStrategies . Tunnel ,
154+ handledEventsToo : true ) ;
153155 ApplyWindowChrome ( ) ;
154156 RefreshJumpList ( ) ;
155157 _stateStore = stateStore ?? SettingsService . LoadApplicationState ( ) ;
@@ -373,8 +375,28 @@ activation.Actions[0] is
373375 } &&
374376 terminal == new NewTerminalArgs ( ) ) ) ;
375377
376- private async void NewTab_OnClick ( object ? sender , RoutedEventArgs e ) =>
377- await CreateTabAsync ( _settings . GetDefaultProfile ( ) ) . ConfigureAwait ( true ) ;
378+ private async void NewTab_OnClick ( object ? sender , RoutedEventArgs e )
379+ {
380+ var modifiers = _newTabButtonModifiers ;
381+ _newTabButtonModifiers = KeyModifiers . None ;
382+ await LaunchProfileAsync ( _settings . GetDefaultProfile ( ) , modifiers ) . ConfigureAwait ( true ) ;
383+ }
384+
385+ private static string NewTabButtonTooltip ( string ? newTabShortcut )
386+ {
387+ var lines = new List < string >
388+ {
389+ string . IsNullOrWhiteSpace ( newTabShortcut ) ? "New tab" : $ "New tab ({ newTabShortcut } )",
390+ "Alt+Click to split the current window" ,
391+ "Shift+Click to open a new window" ,
392+ } ;
393+ if ( OperatingSystem . IsWindows ( ) )
394+ {
395+ lines . Add ( "Ctrl+Click to open as administrator" ) ;
396+ }
397+
398+ return string . Join ( Environment . NewLine , lines ) ;
399+ }
378400
379401 private void Menu_OnClick ( object ? sender , RoutedEventArgs e )
380402 {
@@ -507,29 +529,26 @@ private MenuItem CreateMenuItem(ResolvedNewTabMenuItem item)
507529 menu . Icon = CreateTabIcon ( ProfileVisualDefaults . Icon ( item . Profile ) ) ;
508530 menu . InputGesture = ProfileMenuGesture ( item . Profile ) ;
509531 var profile = item . Profile ;
510- var shiftHeld = false ;
511- if ( OperatingSystem . IsWindows ( ) )
512- {
513- ToolTip . SetTip ( menu , profile . Elevate
514- ? "Opens as administrator"
515- : "Shift-click to open as administrator" ) ;
516- menu . AddHandler (
517- PointerPressedEvent ,
518- ( _ , e ) => shiftHeld = e . KeyModifiers . HasFlag ( KeyModifiers . Shift ) ,
519- RoutingStrategies . Tunnel ,
520- handledEventsToo : true ) ;
521- menu . AddHandler (
522- KeyDownEvent ,
523- ( _ , e ) => shiftHeld = e . KeyModifiers . HasFlag ( KeyModifiers . Shift ) ,
524- RoutingStrategies . Tunnel ,
525- handledEventsToo : true ) ;
526- }
532+ var pressedModifiers = KeyModifiers . None ;
533+ ToolTip . SetTip (
534+ menu ,
535+ profile . Elevate ? "Opens as administrator" : NewTabButtonTooltip ( newTabShortcut : null ) ) ;
536+ menu . AddHandler (
537+ PointerPressedEvent ,
538+ ( _ , e ) => pressedModifiers = e . KeyModifiers ,
539+ RoutingStrategies . Tunnel ,
540+ handledEventsToo : true ) ;
541+ menu . AddHandler (
542+ KeyDownEvent ,
543+ ( _ , e ) => pressedModifiers = e . KeyModifiers ,
544+ RoutingStrategies . Tunnel ,
545+ handledEventsToo : true ) ;
527546
528547 menu . Command = new RelayCommand ( ( ) =>
529548 {
530- var elevate = shiftHeld ;
531- shiftHeld = false ;
532- _ = CreateTabAsync ( NewTabMenuResolver . ForMenuLaunch ( profile , elevate ) ) ;
549+ var modifiers = pressedModifiers ;
550+ pressedModifiers = KeyModifiers . None ;
551+ _ = LaunchProfileAsync ( profile , modifiers ) ;
533552 } ) ;
534553 }
535554 else if ( item . ActionId is { } actionId &&
@@ -545,6 +564,51 @@ private MenuItem CreateMenuItem(ResolvedNewTabMenuItem item)
545564 return menu ;
546565 }
547566
567+ private void OpenNewWindow ( INewContentArgs ? content )
568+ {
569+ content ??= new NewTerminalArgs ( ) ;
570+ if ( _newWindowRequested is not null )
571+ {
572+ _newWindowRequested ( new (
573+ null ,
574+ null ,
575+ null ,
576+ null ,
577+ TerminalWindowLaunchMode . Default ,
578+ [ new ( ShortcutAction . NewTab , new NewTabArgs ( content ) ) ] ) ) ;
579+ }
580+ else
581+ {
582+ new MainWindow ( ResolveProfile ( content ) ) . Show ( ) ;
583+ }
584+ }
585+
586+ /// <summary>
587+ /// Launches <paramref name="profile"/> honoring the same click modifiers as Windows Terminal:
588+ /// Alt splits the current pane, Shift opens a new window, and Ctrl opens elevated (Windows only).
589+ /// </summary>
590+ private async Task LaunchProfileAsync ( ProfileSettings profile , KeyModifiers modifiers )
591+ {
592+ var elevate = OperatingSystem . IsWindows ( ) && modifiers . HasFlag ( KeyModifiers . Control ) ;
593+ var effectiveProfile = NewTabMenuResolver . ForMenuLaunch ( profile , elevate ) ;
594+
595+ if ( modifiers . HasFlag ( KeyModifiers . Alt ) )
596+ {
597+ await SplitActivePaneAsync ( PaneSplitOrientation . Vertical , effectiveProfile ) . ConfigureAwait ( true ) ;
598+ return ;
599+ }
600+
601+ if ( modifiers . HasFlag ( KeyModifiers . Shift ) )
602+ {
603+ OpenNewWindow ( new NewTerminalArgs (
604+ Profile : profile . Guid ?? profile . Name ,
605+ Elevate : elevate ? true : null ) ) ;
606+ return ;
607+ }
608+
609+ await CreateTabAsync ( effectiveProfile ) . ConfigureAwait ( true ) ;
610+ }
611+
548612 private async Task CreateTabAsync ( ProfileSettings profile )
549613 {
550614 TerminalPane ? pane = null ;
@@ -2023,22 +2087,7 @@ args with
20232087 } ) ;
20242088 Register ( ShortcutAction . NewWindow , ActionScope . Application , _ => true , action =>
20252089 {
2026- var content = ( action . Args as NewWindowArgs ) ? . ContentArgs ?? new NewTerminalArgs ( ) ;
2027- if ( _newWindowRequested is not null )
2028- {
2029- _newWindowRequested ( new (
2030- null ,
2031- null ,
2032- null ,
2033- null ,
2034- TerminalWindowLaunchMode . Default ,
2035- [ new ( ShortcutAction . NewTab , new NewTabArgs ( content ) ) ] ) ) ;
2036- }
2037- else
2038- {
2039- new MainWindow ( ResolveProfile ( content ) ) . Show ( ) ;
2040- }
2041-
2090+ OpenNewWindow ( ( action . Args as NewWindowArgs ) ? . ContentArgs ) ;
20422091 return Task . CompletedTask ;
20432092 } ) ;
20442093 Register ( ShortcutAction . CloseWindow , ActionScope . Window , _ => true , _ =>
0 commit comments