@@ -872,70 +872,27 @@ namespace winrt::TerminalApp::implementation
872872 }
873873 }
874874
875- // Function Description:
876- // - Helper to launch a new WT instance. It can either launch the instance
877- // elevated or unelevated.
878- // - To launch elevated, it will as the shell to elevate the process for us.
879- // This might cause a UAC prompt. The elevation is performed on a
880- // background thread, as to not block the UI thread.
881- // Arguments:
882- // - newTerminalArgs: A NewTerminalArgs describing the terminal instance
883- // that should be spawned. The Profile should be filled in with the GUID
884- // of the profile we want to launch.
885- // Return Value:
886- // - <none>
887- // Important: Don't take the param by reference, since we'll be doing work
888- // on another thread.
889- safe_void_coroutine TerminalPage::_OpenNewWindow (const INewContentArgs newContentArgs)
875+ // Ask the WindowEmperor (in-process) to create a brand-new window whose
876+ // first tab is described by `contentArgs`. This will bubble up to AppHost,
877+ // who will call WindowEmperor::CreateNewWindow.
878+ void TerminalPage::_OpenNewWindow (const INewContentArgs& contentArgs)
890879 {
891- auto terminalArgs{ newContentArgs.try_as <NewTerminalArgs>() };
892-
893- // Do nothing for non-terminal panes.
894- //
895- // Theoretically, we could define a `IHasCommandline` interface, and
896- // stick `ToCommandline` on that interface, for any kind of pane that
897- // wants to be convertable to a wt commandline.
898- //
899- // Another idea we're thinking about is just `wt do {literal json for an
900- // action}`, which might be less leaky
901- if (terminalArgs == nullptr )
880+ if (!contentArgs)
902881 {
903- co_return ;
882+ return ;
904883 }
905884
906- // ShellExecuteExW may block, so do it on a background thread.
907- //
908- // NOTE: All remaining code of this function doesn't touch `this`, so we don't need weak/strong_ref.
909- // NOTE NOTE: Don't touch `this` when you make changes here.
910- co_await winrt::resume_background ();
911-
912- // This will get us the correct exe for dev/preview/release. If you
913- // don't stick this in a local, it'll get mangled by ShellExecute. I
914- // have no idea why.
915- const auto exePath{ GetWtExePath () };
916-
917- // Build the commandline to pass to wt for this set of NewTerminalArgs
918- // `-w -1` will ensure a new window is created.
919- const auto commandline = terminalArgs.ToCommandline ();
920- const auto cmdline = fmt::format (FMT_COMPILE (L" -w -1 new-tab {}" ), commandline);
921-
922- // Build the args to ShellExecuteEx. We need to use ShellExecuteEx so we
923- // can pass the SEE_MASK_NOASYNC flag. That flag allows us to safely
924- // call this on the background thread, and have ShellExecute _not_ call
925- // back to us on the main thread. Without this, if you close the
926- // Terminal quickly after the UAC prompt, the elevated WT will never
927- // actually spawn.
928- SHELLEXECUTEINFOW seInfo{ 0 };
929- seInfo.cbSize = sizeof (seInfo);
930- seInfo.fMask = SEE_MASK_NOASYNC ;
931- // `open` will just run the executable normally.
932- seInfo.lpVerb = L" open" ;
933- seInfo.lpFile = exePath.c_str ();
934- seInfo.lpParameters = cmdline.c_str ();
935- seInfo.nShow = SW_SHOWNORMAL ;
936- LOG_IF_WIN32_BOOL_FALSE (ShellExecuteExW (&seInfo));
937-
938- co_return ;
885+ ActionAndArgs newTabAction{};
886+ newTabAction.Action (ShortcutAction::NewTab);
887+ newTabAction.Args (NewTabArgs{ contentArgs });
888+
889+ auto actions = winrt::single_threaded_vector<ActionAndArgs>({ std::move (newTabAction) });
890+
891+ // It's fine to pass `0` as the window ID, since this event path will
892+ // always land in CreateNewWindow, which will just ignore it.
893+ winrt::TerminalApp::WindowRequestedArgs request{ 0 , winrt::TerminalApp::CommandlineArgs{} };
894+ request.StartupActions (std::move (actions));
895+ RequestNewWindow.raise (*this , request);
939896 }
940897
941898 void TerminalPage::_HandleNewWindow (const IInspectable& /* sender*/ ,
@@ -959,13 +916,13 @@ namespace winrt::TerminalApp::implementation
959916 newContentArgs = NewTerminalArgs{};
960917 }
961918
962- if (const auto & terminalArgs{ newContentArgs.try_as <NewTerminalArgs>() })
919+ // Manually fill in the evaluated profile
920+ if (const auto terminalArgs{ newContentArgs.try_as <NewTerminalArgs>() })
963921 {
964922 const auto profile{ _settings.GetProfileForArgs (terminalArgs) };
965923 terminalArgs.Profile (::Microsoft::Console::Utils::GuidToString (profile.Guid ()));
966924 }
967925
968- // Manually fill in the evaluated profile.
969926 _OpenNewWindow (newContentArgs);
970927 actionArgs.Handled (true );
971928 }
0 commit comments