diff --git a/src/cascadia/TerminalControl/Resources/en-US/Resources.resw b/src/cascadia/TerminalControl/Resources/en-US/Resources.resw
index 6f69bda90c2..afcdaee51e5 100644
--- a/src/cascadia/TerminalControl/Resources/en-US/Resources.resw
+++ b/src/cascadia/TerminalControl/Resources/en-US/Resources.resw
@@ -1,17 +1,17 @@
-
@@ -137,4 +137,7 @@
Find...
The placeholder text in the search dialog TextBox
-
\ No newline at end of file
+
+ Copy path to file
+
+
diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp
index b0760a100fe..291e024c060 100644
--- a/src/cascadia/TerminalControl/TermControl.cpp
+++ b/src/cascadia/TerminalControl/TermControl.cpp
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
#include "..\..\types\inc\GlyphWidth.hpp"
#include "TermControl.g.cpp"
@@ -21,6 +22,7 @@ using namespace winrt::Windows::UI::Xaml::Automation::Peers;
using namespace winrt::Windows::UI::Core;
using namespace winrt::Windows::System;
using namespace winrt::Microsoft::Terminal::Settings;
+using namespace winrt::Windows::ApplicationModel::DataTransfer;
namespace winrt::Microsoft::Terminal::TerminalControl::implementation
{
@@ -162,6 +164,10 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
_connectionStateChangedRevoker = _connection.StateChanged(winrt::auto_revoke, [this](auto&& /*s*/, auto&& /*v*/) {
_ConnectionStateChangedHandlers(*this, nullptr);
});
+
+ _root.AllowDrop(true);
+ _root.Drop({ get_weak(), &TermControl::_DragDropHandler });
+ _root.DragOver({ get_weak(), &TermControl::_DragOverHandler });
}
// Method Description:
@@ -1390,6 +1396,12 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
}
}
+ // Method Description:
+ // - Writes the given sequence as input to the active terminal connection,
+ // Arguments:
+ // - wstr: the string of characters to write to the terminal connection.
+ // Return Value:
+ // -
void TermControl::_SendInputToConnection(const std::wstring& wstr)
{
_connection.WriteInput(wstr);
@@ -2150,6 +2162,95 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
return std::pow(cursorDistanceFromBorder, 2.0) / 25.0 + 2.0;
}
+ // Method Description:
+ // - Async handler for the "Drop" event. If a file was dropped onto our
+ // root, we'll try to get the path of the file dropped onto us, and write
+ // the full path of the file to our terminal connection. Like conhost, if
+ // the path contains a space, we'll wrap the path in quotes.
+ // - Unlike conhost, if multiple files are dropped onto the terminal, we'll
+ // write all the paths to the terminal, separated by spaces.
+ // Arguments:
+ // - e: The DragEventArgs from the Drop event
+ // Return Value:
+ // -
+ winrt::fire_and_forget TermControl::_DoDragDrop(DragEventArgs const e)
+ {
+ if (e.DataView().Contains(StandardDataFormats::StorageItems()))
+ {
+ auto items = co_await e.DataView().GetStorageItemsAsync();
+ if (items.Size() > 0)
+ {
+ std::wstring allPaths;
+ for (auto item : items)
+ {
+ // Join the paths with spaces
+ if (!allPaths.empty())
+ {
+ allPaths += L" ";
+ }
+
+ std::wstring fullPath{ item.Path() };
+ const auto containsSpaces = std::find(fullPath.begin(),
+ fullPath.end(),
+ L' ') != fullPath.end();
+
+ auto lock = _terminal->LockForWriting();
+
+ if (containsSpaces)
+ {
+ fullPath.insert(0, L"\"");
+ fullPath += L"\"";
+ }
+
+ allPaths += fullPath;
+ }
+ _SendInputToConnection(allPaths);
+ }
+ }
+ }
+
+ // Method Description:
+ // - Synchronous handler for the "Drop" event. We'll dispatch the async
+ // _DoDragDrop method to handle this, because getting information about
+ // the file that was potentially dropped onto us must be done off the UI
+ // thread.
+ // Arguments:
+ // - e: The DragEventArgs from the Drop event
+ // Return Value:
+ // -
+ void TermControl::_DragDropHandler(Windows::Foundation::IInspectable const& /*sender*/,
+ DragEventArgs const& e)
+ {
+ // Dispatch an async method to handle the drop event.
+ _DoDragDrop(e);
+ }
+
+ // Method Description:
+ // - Handle the DragOver event. We'll signal that the drag operation we
+ // support is the "copy" operation, and we'll also customize the
+ // appearance of the drag-drop UI, by removing the preview and setting a
+ // custom caption. For more information, see
+ // https://docs.microsoft.com/en-us/windows/uwp/design/input/drag-and-drop#customize-the-ui
+ // Arguments:
+ // - e: The DragEventArgs from the DragOver event
+ // Return Value:
+ // -
+ void TermControl::_DragOverHandler(Windows::Foundation::IInspectable const& /*sender*/,
+ DragEventArgs const& e)
+ {
+ // Make sure to set the AcceptedOperation, so that we can later recieve the path in the Drop event
+ e.AcceptedOperation(winrt::Windows::ApplicationModel::DataTransfer::DataPackageOperation::Copy);
+
+ // Sets custom UI text
+ e.DragUIOverride().Caption(RS_(L"DragFileCaption"));
+ // Sets if the caption is visible
+ e.DragUIOverride().IsCaptionVisible(true);
+ // Sets if the dragged content is visible
+ e.DragUIOverride().IsContentVisible(false);
+ // Sets if the glyph is visibile
+ e.DragUIOverride().IsGlyphVisible(false);
+ }
+
// -------------------------------- WinRT Events ---------------------------------
// Winrt events need a method for adding a callback to the event and removing the callback.
// These macros will define them both for you.
diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h
index a8d2ec65cb9..3bcd654c831 100644
--- a/src/cascadia/TerminalControl/TermControl.h
+++ b/src/cascadia/TerminalControl/TermControl.h
@@ -187,6 +187,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
void _ScrollbarChangeHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs const& e);
void _GotFocusHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e);
void _LostFocusHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e);
+ void _DragDropHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::DragEventArgs const& e);
+ void _DragOverHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::DragEventArgs const& e);
+ winrt::fire_and_forget _DoDragDrop(Windows::UI::Xaml::DragEventArgs const e);
void _BlinkCursor(Windows::Foundation::IInspectable const& sender, Windows::Foundation::IInspectable const& e);
void _SetEndSelectionPointAtCursor(Windows::Foundation::Point const& cursorPosition);
diff --git a/src/cascadia/TerminalControl/pch.h b/src/cascadia/TerminalControl/pch.h
index af78f0de89f..da5fe2052fe 100644
--- a/src/cascadia/TerminalControl/pch.h
+++ b/src/cascadia/TerminalControl/pch.h
@@ -37,6 +37,8 @@
#include
#include
#include
+#include
+#include
#include