diff --git a/src/cascadia/Remoting/Peasant.idl b/src/cascadia/Remoting/Peasant.idl index 89e2b52db2c..64ff512a1b4 100644 --- a/src/cascadia/Remoting/Peasant.idl +++ b/src/cascadia/Remoting/Peasant.idl @@ -10,7 +10,7 @@ namespace Microsoft.Terminal.Remoting CommandlineArgs(String[] args, String cwd, UInt32 showWindowCommand); String[] Commandline { get; set; }; - String CurrentDirectory(); + String CurrentDirectory { get; }; UInt32 ShowWindowCommand { get; }; }; diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 99a1fdafde9..3b4becfcfe7 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -554,13 +554,24 @@ namespace winrt::TerminalApp::implementation // back once we're done. This looks weird though, because we have to set // up the scope_exit _first_. We'll release the scope_exit if we don't // actually need it. - auto originalCwd{ wil::GetCurrentDirectoryW() }; - auto restoreCwd = wil::scope_exit([&originalCwd]() { + // auto originalRealCwd{ wil::GetCurrentDirectoryW() }; + + if (initial) + { + // _WindowProperties.VirtualWorkingDirectory(cwd.empty() ? originalRealCwd.c_str() : cwd.c_str()); + LOG_IF_WIN32_BOOL_FALSE(SetCurrentDirectory(L"%SystemRoot%\\System32")); + } + + auto originalVirtualCwd{ _WindowProperties.VirtualWorkingDirectory() }; + auto restoreCwd = wil::scope_exit([&originalVirtualCwd, this /*&originalCwd, &initial*/]() { // ignore errors, we'll just power on through. We'd rather do // something rather than fail silently if the directory doesn't // actually exist. - LOG_IF_WIN32_BOOL_FALSE(SetCurrentDirectory(originalCwd.c_str())); + // LOG_IF_WIN32_BOOL_FALSE(SetCurrentDirectory(L"%SystemRoot%\\System32")); + + _WindowProperties.VirtualWorkingDirectory(originalVirtualCwd); }); + if (cwd.empty()) { restoreCwd.release(); @@ -570,9 +581,15 @@ namespace winrt::TerminalApp::implementation // ignore errors, we'll just power on through. We'd rather do // something rather than fail silently if the directory doesn't // actually exist. - LOG_IF_WIN32_BOOL_FALSE(SetCurrentDirectory(cwd.c_str())); + // LOG_IF_WIN32_BOOL_FALSE(SetCurrentDirectory(cwd.c_str())); + _WindowProperties.VirtualWorkingDirectory(cwd); } + // if (initial) + // { + // _WindowProperties.VirtualWorkingDirectory(cwd.empty() ? originalCwd : cwd); + // } + if (auto page{ weakThis.get() }) { for (const auto& action : actions) @@ -1226,10 +1243,13 @@ namespace winrt::TerminalApp::implementation // process until later, on another thread, after we've already // restored the CWD to its original value. auto newWorkingDirectory{ settings.StartingDirectory() }; - if (newWorkingDirectory.size() == 0 || newWorkingDirectory.size() == 1 && - !(newWorkingDirectory[0] == L'~' || newWorkingDirectory[0] == L'/')) + const bool looksLikeLinux = newWorkingDirectory.size() == 1 && + (newWorkingDirectory[0] == L'~' || newWorkingDirectory[0] == L'/'); + // if (newWorkingDirectory.size() == 0 || looksLikeLinux) + if (!looksLikeLinux) { // We only want to resolve the new WD against the CWD if it doesn't look like a Linux path (see GH#592) - auto cwdString{ wil::GetCurrentDirectoryW() }; + // auto cwdString{ wil::GetCurrentDirectoryW() }; + auto cwdString{ _WindowProperties.VirtualWorkingDirectory().c_str() }; std::filesystem::path cwd{ cwdString }; cwd /= settings.StartingDirectory().c_str(); newWorkingDirectory = winrt::hstring{ cwd.wstring() }; diff --git a/src/cascadia/TerminalApp/TerminalPage.idl b/src/cascadia/TerminalApp/TerminalPage.idl index 92052ed1677..4375c000738 100644 --- a/src/cascadia/TerminalApp/TerminalPage.idl +++ b/src/cascadia/TerminalApp/TerminalPage.idl @@ -51,6 +51,8 @@ namespace TerminalApp String WindowNameForDisplay { get; }; String WindowIdForDisplay { get; }; + String VirtualWorkingDirectory { get; set; }; + Boolean IsQuakeWindow(); }; diff --git a/src/cascadia/TerminalApp/TerminalWindow.cpp b/src/cascadia/TerminalApp/TerminalWindow.cpp index e62d25c4e99..ebbb04b8428 100644 --- a/src/cascadia/TerminalApp/TerminalWindow.cpp +++ b/src/cascadia/TerminalApp/TerminalWindow.cpp @@ -1013,8 +1013,10 @@ namespace winrt::TerminalApp::implementation // Return Value: // - the result of the first command who's parsing returned a non-zero code, // or 0. (see TerminalWindow::_ParseArgs) - int32_t TerminalWindow::SetStartupCommandline(array_view args) + int32_t TerminalWindow::SetStartupCommandline(array_view args, winrt::hstring cwd) { + _WindowProperties->SetInitialCwd(cwd); + // This is called in AppHost::ctor(), before we've created the window // (or called TerminalWindow::Initialize) const auto result = _appArgs.ParseArgs(args); @@ -1336,6 +1338,7 @@ namespace winrt::TerminalApp::implementation CATCH_LOG(); } } + uint64_t WindowProperties::WindowId() const noexcept { return _WindowId; diff --git a/src/cascadia/TerminalApp/TerminalWindow.h b/src/cascadia/TerminalApp/TerminalWindow.h index 2d288ccfddf..fa5e0cd3884 100644 --- a/src/cascadia/TerminalApp/TerminalWindow.h +++ b/src/cascadia/TerminalApp/TerminalWindow.h @@ -48,8 +48,13 @@ namespace winrt::TerminalApp::implementation winrt::hstring WindowNameForDisplay() const noexcept; bool IsQuakeWindow() const noexcept; + WINRT_OBSERVABLE_PROPERTY(winrt::hstring, VirtualWorkingDirectory, _PropertyChangedHandlers, L""); + WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler); + public: + void SetInitialCwd(const winrt::hstring& cwd) { _VirtualWorkingDirectory = cwd; }; + private: winrt::hstring _WindowName{}; uint64_t _WindowId{ 0 }; @@ -71,7 +76,7 @@ namespace winrt::TerminalApp::implementation bool HasCommandlineArguments() const noexcept; - int32_t SetStartupCommandline(array_view actions); + int32_t SetStartupCommandline(array_view actions, winrt::hstring cwd); void SetStartupContent(const winrt::hstring& content, const Windows::Foundation::IReference& contentBounds); int32_t ExecuteCommandline(array_view actions, const winrt::hstring& cwd); void SetSettingsStartupArgs(const std::vector& actions); diff --git a/src/cascadia/TerminalApp/TerminalWindow.idl b/src/cascadia/TerminalApp/TerminalWindow.idl index 912663e4a0b..d91de2dce88 100644 --- a/src/cascadia/TerminalApp/TerminalWindow.idl +++ b/src/cascadia/TerminalApp/TerminalWindow.idl @@ -53,7 +53,7 @@ namespace TerminalApp Boolean HasCommandlineArguments(); - Int32 SetStartupCommandline(String[] commands); + Int32 SetStartupCommandline(String[] commands, String cwd); void SetStartupContent(String json, Windows.Foundation.IReference bounds); Int32 ExecuteCommandline(String[] commands, String cwd); String ParseCommandlineMessage { get; }; diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 163d056df88..b80ec25777a 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -175,7 +175,7 @@ void AppHost::_HandleCommandlineArgs(const Remoting::WindowRequestedArgs& window } else if (args) { - const auto result = _windowLogic.SetStartupCommandline(args.Commandline()); + const auto result = _windowLogic.SetStartupCommandline(args.Commandline(), args.CurrentDirectory()); const auto message = _windowLogic.ParseCommandlineMessage(); if (!message.empty()) {