@@ -62,7 +62,6 @@ namespace winrt::TerminalApp::implementation
62
62
TerminalPage::TerminalPage (TerminalApp::WindowProperties properties, const TerminalApp::ContentManager& manager) :
63
63
_tabs{ winrt::single_threaded_observable_vector<TerminalApp::TabBase>() },
64
64
_mruTabs{ winrt::single_threaded_observable_vector<TerminalApp::TabBase>() },
65
- _startupActions{ winrt::single_threaded_vector<ActionAndArgs>() },
66
65
_manager{ manager },
67
66
_hostingHwnd{},
68
67
_WindowProperties{ std::move (properties) }
@@ -297,7 +296,7 @@ namespace winrt::TerminalApp::implementation
297
296
// GH#12267: Don't forget about defterm handoff here. If we're being
298
297
// created for embedding, then _yea_, we don't need to handoff to an
299
298
// elevated window.
300
- if (! _startupActions || IsRunningElevated () || _shouldStartInboundListener || _startupActions. Size () == 0 )
299
+ if (_startupActions. empty () || IsRunningElevated () || _shouldStartInboundListener)
301
300
{
302
301
// there aren't startup actions, or we're elevated. In that case, go for it.
303
302
return false ;
@@ -375,7 +374,7 @@ namespace winrt::TerminalApp::implementation
375
374
// - <none>
376
375
void TerminalPage::HandoffToElevated (const CascadiaSettings& settings)
377
376
{
378
- if (! _startupActions)
377
+ if (_startupActions. empty () )
379
378
{
380
379
return ;
381
380
}
@@ -489,7 +488,7 @@ namespace winrt::TerminalApp::implementation
489
488
{
490
489
_startupState = StartupState::InStartup;
491
490
492
- ProcessStartupActions (_startupActions, true );
491
+ ProcessStartupActions (std::move ( _startupActions) , true );
493
492
494
493
// If we were told that the COM server needs to be started to listen for incoming
495
494
// default application connections, start it now.
@@ -546,80 +545,56 @@ namespace winrt::TerminalApp::implementation
546
545
// nt -d .` from inside another directory to work as expected.
547
546
// Return Value:
548
547
// - <none>
549
- safe_void_coroutine TerminalPage::ProcessStartupActions (Windows::Foundation::Collections::IVector<ActionAndArgs> actions,
550
- const bool initial,
551
- const winrt::hstring cwd,
552
- const winrt::hstring env)
548
+ safe_void_coroutine TerminalPage::ProcessStartupActions (std::vector<ActionAndArgs> actions, const bool initial, const winrt::hstring cwd, const winrt::hstring env)
553
549
{
554
- auto weakThis{ get_weak () };
555
-
556
- // Handle it on a subsequent pass of the UI thread.
557
- co_await wil::resume_foreground (Dispatcher (), CoreDispatcherPriority::Normal);
550
+ const auto strong = get_strong ();
558
551
559
552
// If the caller provided a CWD, "switch" to that directory, then switch
560
- // back once we're done. This looks weird though, because we have to set
561
- // up the scope_exit _first_. We'll release the scope_exit if we don't
562
- // actually need it.
563
-
553
+ // back once we're done.
564
554
auto originalVirtualCwd{ _WindowProperties.VirtualWorkingDirectory () };
565
- auto restoreCwd = wil::scope_exit ([&originalVirtualCwd, this ]() {
566
- // ignore errors, we'll just power on through. We'd rather do
567
- // something rather than fail silently if the directory doesn't
568
- // actually exist.
569
- _WindowProperties.VirtualWorkingDirectory (originalVirtualCwd);
570
- });
571
-
572
- // Literally the same thing with env vars too
573
555
auto originalVirtualEnv{ _WindowProperties.VirtualEnvVars () };
574
- auto restoreEnv = wil::scope_exit ([&originalVirtualEnv, this ]() {
575
- _WindowProperties.VirtualEnvVars (originalVirtualEnv);
556
+ auto restoreCwd = wil::scope_exit ([&]() {
557
+ if (!cwd.empty ())
558
+ {
559
+ // ignore errors, we'll just power on through. We'd rather do
560
+ // something rather than fail silently if the directory doesn't
561
+ // actually exist.
562
+ _WindowProperties.VirtualWorkingDirectory (originalVirtualCwd);
563
+ _WindowProperties.VirtualEnvVars (originalVirtualEnv);
564
+ }
576
565
});
566
+ _WindowProperties.VirtualWorkingDirectory (cwd);
567
+ _WindowProperties.VirtualEnvVars (env);
577
568
578
- if (cwd. empty () )
569
+ for ( size_t i = 0 ; i < actions. size (); ++i )
579
570
{
580
- // We didn't actually need to change the virtual CWD, so we don't
581
- // need to restore it
582
- restoreCwd.release ();
583
- }
584
- else
585
- {
586
- _WindowProperties.VirtualWorkingDirectory (cwd);
587
- }
571
+ if (i != 0 )
572
+ {
573
+ // Each action may rely on the XAML layout of a preceding action.
574
+ // Most importantly, this is the case for the combination of NewTab + SplitPane,
575
+ // as the former appears to only have a layout size after at least 1 resume_foreground,
576
+ // while the latter relies on that information. This is also why it uses Low priority.
577
+ //
578
+ // Curiously, this does not seem to be required when using startupActions, but only when
579
+ // tearing out a tab (this currently creates a new window with injected startup actions).
580
+ // This indicates that this is really more of an architectural issue and not a fundamental one.
581
+ co_await wil::resume_foreground (Dispatcher (), CoreDispatcherPriority::Low);
582
+ }
588
583
589
- if (env.empty ())
590
- {
591
- restoreEnv.release ();
592
- }
593
- else
594
- {
595
- _WindowProperties.VirtualEnvVars (env);
584
+ _actionDispatch->DoAction (actions[i]);
596
585
}
597
586
598
- if (auto page{ weakThis.get () })
587
+ // GH#6586: now that we're done processing all startup commands,
588
+ // focus the active control. This will work as expected for both
589
+ // commandline invocations and for `wt` action invocations.
590
+ if (const auto & terminalTab{ _GetFocusedTabImpl () })
599
591
{
600
- for (const auto & action : actions )
592
+ if (const auto & content{ terminalTab-> GetActiveContent () } )
601
593
{
602
- if (auto page{ weakThis.get () })
603
- {
604
- _actionDispatch->DoAction (action);
605
- }
606
- else
607
- {
608
- co_return ;
609
- }
610
- }
611
-
612
- // GH#6586: now that we're done processing all startup commands,
613
- // focus the active control. This will work as expected for both
614
- // commandline invocations and for `wt` action invocations.
615
- if (const auto & terminalTab{ _GetFocusedTabImpl () })
616
- {
617
- if (const auto & content{ terminalTab->GetActiveContent () })
618
- {
619
- content.Focus (FocusState::Programmatic);
620
- }
594
+ content.Focus (FocusState::Programmatic);
621
595
}
622
596
}
597
+
623
598
if (initial)
624
599
{
625
600
_CompleteInitialization ();
@@ -3670,13 +3645,9 @@ namespace winrt::TerminalApp::implementation
3670
3645
// - actions: a list of Actions to process on startup.
3671
3646
// Return Value:
3672
3647
// - <none>
3673
- void TerminalPage::SetStartupActions (std::vector<ActionAndArgs>& actions)
3648
+ void TerminalPage::SetStartupActions (std::vector<ActionAndArgs> actions)
3674
3649
{
3675
- // The fastest way to copy all the actions out of the std::vector and
3676
- // put them into a winrt::IVector is by making a copy, then moving the
3677
- // copy into the winrt vector ctor.
3678
- auto listCopy = actions;
3679
- _startupActions = winrt::single_threaded_vector<ActionAndArgs>(std::move (listCopy));
3650
+ _startupActions = std::move (actions);
3680
3651
}
3681
3652
3682
3653
// Routine Description:
0 commit comments