dirty: stash a string as a "virtual" CWD, ala #5506

In the dirtiest way possible, this seems to work for most "start with this CWD" scenarios.
This commit is contained in:
Mike Griese
2023-05-01 14:19:22 -05:00
parent 1da6131cb2
commit 816f8b2026
7 changed files with 42 additions and 12 deletions

View File

@@ -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; };
};

View File

@@ -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<std::wstring>() };
auto restoreCwd = wil::scope_exit([&originalCwd]() {
// auto originalRealCwd{ wil::GetCurrentDirectoryW<std::wstring>() };
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<std::wstring>() };
// auto cwdString{ wil::GetCurrentDirectoryW<std::wstring>() };
auto cwdString{ _WindowProperties.VirtualWorkingDirectory().c_str() };
std::filesystem::path cwd{ cwdString };
cwd /= settings.StartingDirectory().c_str();
newWorkingDirectory = winrt::hstring{ cwd.wstring() };

View File

@@ -51,6 +51,8 @@ namespace TerminalApp
String WindowNameForDisplay { get; };
String WindowIdForDisplay { get; };
String VirtualWorkingDirectory { get; set; };
Boolean IsQuakeWindow();
};

View File

@@ -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<const winrt::hstring> args)
int32_t TerminalWindow::SetStartupCommandline(array_view<const winrt::hstring> 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;

View File

@@ -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<const winrt::hstring> actions);
int32_t SetStartupCommandline(array_view<const winrt::hstring> actions, winrt::hstring cwd);
void SetStartupContent(const winrt::hstring& content, const Windows::Foundation::IReference<Windows::Foundation::Rect>& contentBounds);
int32_t ExecuteCommandline(array_view<const winrt::hstring> actions, const winrt::hstring& cwd);
void SetSettingsStartupArgs(const std::vector<winrt::Microsoft::Terminal::Settings::Model::ActionAndArgs>& actions);

View File

@@ -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<Windows.Foundation.Rect> bounds);
Int32 ExecuteCommandline(String[] commands, String cwd);
String ParseCommandlineMessage { get; };

View File

@@ -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())
{