Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix missing paths when items dropped from archive #14648

Merged
8 commits merged into from
Jan 11, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 48 additions & 8 deletions src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ using namespace winrt::Windows::UI::ViewManagement;
using namespace winrt::Windows::UI::Input;
using namespace winrt::Windows::System;
using namespace winrt::Windows::ApplicationModel::DataTransfer;
using namespace winrt::Windows::Storage::Streams;

// The minimum delay between updates to the scroll bar's values.
// The updates are throttled to limit power usage.
Expand Down Expand Up @@ -2526,16 +2527,55 @@ namespace winrt::Microsoft::Terminal::Control::implementation

if (items.Size() > 0)
{
std::wstring allPaths;
for (auto item : items)
std::vector<std::wstring> fullPaths;

// GH#14628: Workaround for GetStorageItemsAsync() only returning 16 items
// at most when dragging and dropping from archives (zip, 7z, rar, etc.)
if (items.Size() == 16 && e.DataView().Contains(winrt::hstring{ L"FileDrop" }))
{
// Join the paths with spaces
if (!allPaths.empty())
auto fileDropData = co_await e.DataView().GetDataAsync(winrt::hstring{ L"FileDrop" });
if (fileDropData != nullptr)
{
auto stream = fileDropData.as<IRandomAccessStream>();
stream.Seek(0);

const uint32_t streamSize = gsl::narrow_cast<uint32_t>stream.Size();
carlos-zamora marked this conversation as resolved.
Show resolved Hide resolved
const Buffer buf(streamSize);
const auto buffer = co_await stream.ReadAsync(buf, streamSize, InputStreamOptions::None);

const HGLOBAL hGlobal = buffer.data();
DHowett marked this conversation as resolved.
Show resolved Hide resolved
const auto count = DragQueryFile((HDROP)hGlobal, 0xFFFFFFFF, nullptr, 0);
DHowett marked this conversation as resolved.
Show resolved Hide resolved
fullPaths.reserve(count);

for (unsigned int i = 0; i < count; i++)
{
WCHAR szPath[MAX_PATH];
const auto charsCopied = DragQueryFile((HDROP)hGlobal, i, szPath, MAX_PATH);
DHowett marked this conversation as resolved.
Show resolved Hide resolved

if (charsCopied > 0)
{
fullPaths.push_back(std::wstring{ szPath });
DHowett marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
}
else
{
fullPaths.reserve(items.Size());
for (auto item : items)
{
allPaths += L" ";
fullPaths.push_back(std::wstring{ item.Path() });
DHowett marked this conversation as resolved.
Show resolved Hide resolved
}
}

std::wstring fullPath{ item.Path() };
std::wstring allPathsString;
for (auto fullPath : fullPaths)
DHowett marked this conversation as resolved.
Show resolved Hide resolved
{
// Join the paths with spaces
if (!allPathsString.empty())
{
allPathsString += L" ";
}

// Fix path for WSL
// In the fullness of time, we should likely plumb this up
Expand Down Expand Up @@ -2591,10 +2631,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
fullPath += L"\"";
}

allPaths += fullPath;
allPathsString += fullPath;
}

_core.PasteText(winrt::hstring{ allPaths });
_core.PasteText(winrt::hstring{ allPathsString });
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalControl/dll/TerminalControl.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@

<ItemDefinitionGroup>
<Link>
<AdditionalDependencies>dwrite.lib;dxgi.lib;d2d1.lib;d3d11.lib;shcore.lib;winmm.lib;pathcch.lib;propsys.lib;uiautomationcore.lib;Shlwapi.lib;ntdll.lib;user32.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>dwrite.lib;dxgi.lib;d2d1.lib;d3d11.lib;shcore.lib;winmm.lib;pathcch.lib;propsys.lib;uiautomationcore.lib;Shlwapi.lib;ntdll.lib;user32.lib;shell32.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<!--
ControlLib contains a DllMain that we need to force the use of.
If you don't have this, then you'll see an error like
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalControl/pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include <winrt/Windows.ui.xaml.shapes.h>
#include <winrt/Windows.ApplicationModel.DataTransfer.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Storage.Streams.h>
#include <winrt/Windows.UI.Xaml.Shapes.h>

#include <winrt/Microsoft.Terminal.TerminalConnection.h>
Expand All @@ -59,6 +60,7 @@
TRACELOGGING_DECLARE_PROVIDER(g_hTerminalControlProvider);
#include <telemetry/ProjectTelemetry.h>

#include <shellapi.h>
#include <ShlObj_core.h>
#include <WinUser.h>

Expand Down