From 69e4590bc55c9e867969a2342fa884c7c21e6869 Mon Sep 17 00:00:00 2001
From: Vallabh Mahajan <168367584+Vallabh-1504@users.noreply.github.com>
Date: Mon, 30 Mar 2026 23:08:01 +0530
Subject: [PATCH] Add setting for customizable delimiter for file drag-and-drop
(#19799)
## Summary of the Pull Request
This PR introduces a new profile setting, `dragDropDelimiter`, which
allows users to configure the string separator used when dragging and
dropping multiple files into the terminal. The default behavior remains
a single space (`" "`) for backward compatibility.
## References and Relevant Issues
* Closes #19565
## Detailed Description of the Pull Request / Additional comments
**Implementation Details:**
* **Settings:** Added `DragDropDelimiter` to `MTSMSettings.h` and
`Profile.idl`.
* **Control:** Wired the setting through `ControlProperties.h` so the
terminal logic can see it.
* **Logic:** Updated `TermControl::OnDrop` to use the new delimiter when
joining paths.
* **UI:** Added the text box in the Advanced Settings page and updated
the ViewModel.
## Validation Steps Performed
* **Manual Verification:**
* Verified default behavior (space separator) works as before.
* Configured `dragDropDelimiter` to `", "`, `";"`, and custom strings in
`settings.json` and from settings UI.
* Confirmed dropped files are joined correctly.
* **Build:** Validated that the solution builds cleanly.
## Notes for Reviewers
1. **Delimiter Length:** Currently, there is no limit on the maximum
length of the delimiter string. Let me know if this should be changed.
3. **Localization:** I changed only `Resources/en-US` file.
4. **ViewModel:** In `ProfileViewModel.cpp`, I added the `else if` block
for the new setting, but left it empty because no other UI logic
currently depends on it.
## PR Checklist
- [x] Closes #19565
- [ ] Documentation updated
- [x] Schema updated (if necessary)
---
doc/cascadia/profiles.schema.json | 5 +++++
src/cascadia/TerminalControl/IControlSettings.idl | 1 +
src/cascadia/TerminalControl/TermControl.cpp | 7 ++++---
.../TerminalSettingsAppAdapterLib/TerminalSettings.cpp | 1 +
src/cascadia/TerminalSettingsEditor/ProfileViewModel.h | 1 +
.../TerminalSettingsEditor/ProfileViewModel.idl | 1 +
.../TerminalSettingsEditor/Profiles_Advanced.xaml | 10 ++++++++++
.../Resources/en-US/Resources.resw | 10 +++++++++-
src/cascadia/TerminalSettingsModel/MTSMSettings.h | 1 +
src/cascadia/TerminalSettingsModel/Profile.idl | 1 +
src/cascadia/inc/ControlProperties.h | 3 ++-
11 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json
index b8e6c9ab40..1756b7cc9d 100644
--- a/doc/cascadia/profiles.schema.json
+++ b/doc/cascadia/profiles.schema.json
@@ -3174,6 +3174,11 @@
"mingw"
],
"type": "string"
+ },
+ "dragDropDelimiter": {
+ "default": " ",
+ "description": "The delimiter used when dropping multiple files onto the terminal.",
+ "type": "string"
}
}
},
diff --git a/src/cascadia/TerminalControl/IControlSettings.idl b/src/cascadia/TerminalControl/IControlSettings.idl
index 19f0d70eca..4682668e92 100644
--- a/src/cascadia/TerminalControl/IControlSettings.idl
+++ b/src/cascadia/TerminalControl/IControlSettings.idl
@@ -76,6 +76,7 @@ namespace Microsoft.Terminal.Control
Boolean RepositionCursorWithMouse { get; };
PathTranslationStyle PathTranslationStyle { get; };
+ String DragDropDelimiter { get; };
// NOTE! When adding something here, make sure to update ControlProperties.h too!
};
diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp
index 9e312bd060..b93c7cd6f1 100644
--- a/src/cascadia/TerminalControl/TermControl.cpp
+++ b/src/cascadia/TerminalControl/TermControl.cpp
@@ -3060,7 +3060,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// 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.
+ // write all the paths to the terminal, separated by the configured delimiter.
// Arguments:
// - e: The DragEventArgs from the Drop event
// Return Value:
@@ -3181,12 +3181,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
std::wstring allPathsString;
+ const auto delimiter{ _core.Settings().DragDropDelimiter() };
for (auto& fullPath : fullPaths)
{
- // Join the paths with spaces
+ // Join the paths with the delimiter
if (!allPathsString.empty())
{
- allPathsString += L" ";
+ allPathsString += delimiter;
}
const auto translationStyle{ _core.Settings().PathTranslationStyle() };
diff --git a/src/cascadia/TerminalSettingsAppAdapterLib/TerminalSettings.cpp b/src/cascadia/TerminalSettingsAppAdapterLib/TerminalSettings.cpp
index 71f8695e2a..e9106f6878 100644
--- a/src/cascadia/TerminalSettingsAppAdapterLib/TerminalSettings.cpp
+++ b/src/cascadia/TerminalSettingsAppAdapterLib/TerminalSettings.cpp
@@ -353,6 +353,7 @@ namespace winrt::Microsoft::Terminal::Settings
_AllowVtChecksumReport = profile.AllowVtChecksumReport();
_AllowVtClipboardWrite = profile.AllowVtClipboardWrite();
_PathTranslationStyle = profile.PathTranslationStyle();
+ _DragDropDelimiter = profile.DragDropDelimiter();
}
// Method Description:
diff --git a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h
index f120ed7467..1112a2f8ef 100644
--- a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h
+++ b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h
@@ -145,6 +145,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
OBSERVABLE_PROJECTED_SETTING(_profile, AnswerbackMessage);
OBSERVABLE_PROJECTED_SETTING(_profile, RainbowSuggestions);
OBSERVABLE_PROJECTED_SETTING(_profile, PathTranslationStyle);
+ OBSERVABLE_PROJECTED_SETTING(_profile, DragDropDelimiter);
WINRT_PROPERTY(bool, IsBaseLayer, false);
WINRT_PROPERTY(bool, FocusDeleteButton, false);
diff --git a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.idl b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.idl
index 1fb13853a6..8b1aeba792 100644
--- a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.idl
+++ b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.idl
@@ -139,6 +139,7 @@ namespace Microsoft.Terminal.Settings.Editor
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, AnswerbackMessage);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, RainbowSuggestions);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.PathTranslationStyle, PathTranslationStyle);
+ OBSERVABLE_PROJECTED_PROFILE_SETTING(String, DragDropDelimiter);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AllowVtClipboardWrite);
}
}
diff --git a/src/cascadia/TerminalSettingsEditor/Profiles_Advanced.xaml b/src/cascadia/TerminalSettingsEditor/Profiles_Advanced.xaml
index 3f243c22bc..941f410e97 100644
--- a/src/cascadia/TerminalSettingsEditor/Profiles_Advanced.xaml
+++ b/src/cascadia/TerminalSettingsEditor/Profiles_Advanced.xaml
@@ -272,6 +272,16 @@
Style="{StaticResource ComboBoxSettingStyle}" />
+
+
+
+
+
diff --git a/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw b/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw
index dc20fbecbf..e52b4c84ac 100644
--- a/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw
+++ b/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw
@@ -2748,4 +2748,12 @@
Type to filter icons
Placeholder text for a text box to filter and select an icon.
-
\ No newline at end of file
+
+ Drag and drop delimiter
+ Header for a control to set the delimiter used when dragging multiple files into the terminal.
+
+
+ This text will be inserted between the paths of multiple files dropped into the terminal.
+ A description for what the "drag drop delimiter" setting does.
+
+
diff --git a/src/cascadia/TerminalSettingsModel/MTSMSettings.h b/src/cascadia/TerminalSettingsModel/MTSMSettings.h
index 4f99bda187..b95aad938e 100644
--- a/src/cascadia/TerminalSettingsModel/MTSMSettings.h
+++ b/src/cascadia/TerminalSettingsModel/MTSMSettings.h
@@ -108,6 +108,7 @@ Author(s):
X(bool, AllowVtChecksumReport, "compatibility.allowDECRQCRA", false) \
X(bool, AllowVtClipboardWrite, "compatibility.allowOSC52", true) \
X(bool, AllowKeypadMode, "compatibility.allowDECNKM", false) \
+ X(hstring, DragDropDelimiter, "dragDropDelimiter", L" ") \
X(Microsoft::Terminal::Control::PathTranslationStyle, PathTranslationStyle, "pathTranslationStyle", Microsoft::Terminal::Control::PathTranslationStyle::None)
// Intentionally omitted Profile settings:
diff --git a/src/cascadia/TerminalSettingsModel/Profile.idl b/src/cascadia/TerminalSettingsModel/Profile.idl
index 65de99b913..96bc79ad19 100644
--- a/src/cascadia/TerminalSettingsModel/Profile.idl
+++ b/src/cascadia/TerminalSettingsModel/Profile.idl
@@ -94,5 +94,6 @@ namespace Microsoft.Terminal.Settings.Model
INHERITABLE_PROFILE_SETTING(Boolean, AllowVtClipboardWrite);
INHERITABLE_PROFILE_SETTING(Microsoft.Terminal.Control.PathTranslationStyle, PathTranslationStyle);
+ INHERITABLE_PROFILE_SETTING(String, DragDropDelimiter);
}
}
diff --git a/src/cascadia/inc/ControlProperties.h b/src/cascadia/inc/ControlProperties.h
index 91ae711786..cb4750d5e6 100644
--- a/src/cascadia/inc/ControlProperties.h
+++ b/src/cascadia/inc/ControlProperties.h
@@ -87,4 +87,5 @@
X(bool, ShowMarks, false) \
X(winrt::Microsoft::Terminal::Control::CopyFormat, CopyFormatting, 0) \
X(bool, RightClickContextMenu, false) \
- X(winrt::Microsoft::Terminal::Control::PathTranslationStyle, PathTranslationStyle, winrt::Microsoft::Terminal::Control::PathTranslationStyle::None)
+ X(winrt::Microsoft::Terminal::Control::PathTranslationStyle, PathTranslationStyle, winrt::Microsoft::Terminal::Control::PathTranslationStyle::None) \
+ X(winrt::hstring, DragDropDelimiter, L" ")