[PR #14901] [MERGED] Enable dragging tabs between windows #30295

Open
opened 2026-01-31 09:39:54 +00:00 by claunia · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/microsoft/terminal/pull/14901
Author: @zadjii-msft
Created: 2/23/2023
Status: Merged
Merged: 3/30/2023
Merged by: @zadjii-msft

Base: mainHead: dev/migrie/oop/3/akallabeth


📝 Commits (10+)

  • 713ea71 Revert "this is important for moving, yknow, the panes"
  • 57d1dd4 [ainulindale] Clean tear down the App when the process exits
  • 631f690 remove the old control when the content gets moved
  • 17057d1 (maybe valaquenta) well, the keybindings stuff is... better?
  • 427a4a5 [ainulindale] "fix" hot reload
  • 40046c3 one shot one opportunity
  • a20201f [silmarillion] Update the validation for the moveTab action
  • c282797 [silmarillion] Detach on moveTab, but not on drag
  • ba7b5ae [silmarillion] Pull DetachTab into a method
  • 828695e Detaching during tearout too

📊 Changes

21 files changed (+364 additions, -14 deletions)

View changed files

📝 src/cascadia/Remoting/Monarch.cpp (+35 -0)
📝 src/cascadia/Remoting/Monarch.h (+1 -0)
📝 src/cascadia/Remoting/Monarch.idl (+2 -2)
📝 src/cascadia/Remoting/Peasant.cpp (+6 -0)
📝 src/cascadia/Remoting/Peasant.h (+17 -0)
📝 src/cascadia/Remoting/Peasant.idl (+10 -1)
📝 src/cascadia/Remoting/WindowManager.cpp (+5 -0)
📝 src/cascadia/Remoting/WindowManager.h (+1 -0)
📝 src/cascadia/Remoting/WindowManager.idl (+1 -0)
📝 src/cascadia/TerminalApp/TabBase.cpp (+13 -0)
📝 src/cascadia/TerminalApp/TabManagement.cpp (+7 -1)
📝 src/cascadia/TerminalApp/TerminalPage.cpp (+187 -4)
📝 src/cascadia/TerminalApp/TerminalPage.h (+24 -1)
📝 src/cascadia/TerminalApp/TerminalPage.idl (+9 -1)
📝 src/cascadia/TerminalApp/TerminalWindow.cpp (+7 -0)
📝 src/cascadia/TerminalApp/TerminalWindow.h (+2 -0)
📝 src/cascadia/TerminalApp/TerminalWindow.idl (+3 -1)
📝 src/cascadia/TerminalControl/ControlInteractivity.idl (+2 -2)
📝 src/cascadia/UnitTests_Remoting/RemotingTests.cpp (+3 -0)
📝 src/cascadia/WindowsTerminal/AppHost.cpp (+19 -1)

...and 1 more files

📄 Description

Behold, the penultimate chapter in the saga of tear-out! This significant update bestows upon the user the power to transport tabs betwixt Terminal windows. Alas, the drag and drop capabilities of TabView are not yet refined, so this PR primarily concerns itself with the intricacies of plumbing. When a tab is extracted and deposited elsewhere, it is necessary to have the recipient make an inquiry to the Monarch, who in turn will beseech the sender to transmit the tab content, akin to the act of moving a tab. Curious it may seem, but the method has proven effective.

The penultimate tear-out PR. This PR enables the user to move tabs from one Terminal window to another. The TabView drag/drop APIs have some rough edges, so this PR is mostly plumbing. When a tab is drag/dropped, we need to get the recipient to ask the Monarch to ask the sender to send the tab content, like a MoveTab action. Wacky, but it works.

There's a LONG tail of UX gaps. Those I'm going to track in #14900. It is more valuable for us to merge this now than to figure out workarounds immediately.

The next PR will be the last main PR in this saga - in which we enable dragging a tab out of the window and dropping to create a new window.

Detailed description

As I mentioned, it's mostly plumbing. The order that we get tab drag events is... unfortunate... for our use case. So we do a lot of sending RequestReceiveContentArgs up and down between windows, just to communicate who the tab was dropped on to whomever the tab was dragged from.

There's a diagram for this that I originally put in https://github.com/microsoft/terminal/issues/5000#issuecomment-1435328038:

sequenceDiagram
    participant Source
    participant Target
    participant Monarch

    Note Left of Source: _onTabDragStarting
    Source --> Source: stash dragged content
    Source --> Source: pack window ID into DataPackage

    Source ->> Target: Drag tab
    Note right of Target: _onTabStripDragOver
    Target ->> Target: AcceptedOperation(DataPackageOperation::Move)
    
    Source --> Target: Release mouse (to drop)
    
    Note right of Target: _onTabStripDrop
    Target --> Target: get WindowID from DataPackage
    Target -) Monarch: Request that WindowID sends content to us<br>RequestRecieveContent
    Monarch -) Source: Tell to send content to Target.Id<br>RequestSendContent, SendContent
    Source --> Source: detach our content
    Source -) Monarch: RequestMoveContent(stashed, target.id)
    Monarch -) Target: AttachContent(stashed)

    # Target -->> Source: 
    # Note Left of Source: TabViewTabDragStartingEventArgs<br>.OperationCompleted
    # Note Left of Source: _onTabDroppedCompleted

Really really though, let's try to avoid nits about the UX at this time. This PR works with what we've got. Mail threads are percolating. I've got 19 chapters worth of Hobbit branch names to use for those follow ups.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/microsoft/terminal/pull/14901 **Author:** [@zadjii-msft](https://github.com/zadjii-msft) **Created:** 2/23/2023 **Status:** ✅ Merged **Merged:** 3/30/2023 **Merged by:** [@zadjii-msft](https://github.com/zadjii-msft) **Base:** `main` ← **Head:** `dev/migrie/oop/3/akallabeth` --- ### 📝 Commits (10+) - [`713ea71`](https://github.com/microsoft/terminal/commit/713ea71725d0a0425a1c77329b4d42ad29acc3a3) Revert "this is important for moving, yknow, the panes" - [`57d1dd4`](https://github.com/microsoft/terminal/commit/57d1dd435828aebfa2b81e93680da00a89132296) [ainulindale] Clean tear down the `App` when the process exits - [`631f690`](https://github.com/microsoft/terminal/commit/631f690e425db3e0d97b2724cee143d16b76e52f) remove the old control when the content gets moved - [`17057d1`](https://github.com/microsoft/terminal/commit/17057d147d0b49484222103c29732769f5b1f4bc) (maybe valaquenta) well, the keybindings stuff is... better? - [`427a4a5`](https://github.com/microsoft/terminal/commit/427a4a51c5f57a01d010bab23803a0dba1b7c62c) [ainulindale] "fix" hot reload - [`40046c3`](https://github.com/microsoft/terminal/commit/40046c38dcf93a75622e8932ab5ad48738ffad0a) one shot one opportunity - [`a20201f`](https://github.com/microsoft/terminal/commit/a20201fff26589e6faf393c07b508e510dc0fc5c) [silmarillion] Update the validation for the moveTab action - [`c282797`](https://github.com/microsoft/terminal/commit/c282797cac2b7f35da5f0c3e44422e71ae2a6cb2) [silmarillion] Detach on moveTab, but not on drag - [`ba7b5ae`](https://github.com/microsoft/terminal/commit/ba7b5aec79dcf1959e47568e3da144d7eeec9265) [silmarillion] Pull DetachTab into a method - [`828695e`](https://github.com/microsoft/terminal/commit/828695ee8a962b54bb95f8302fb259ace556d25b) Detaching during tearout too ### 📊 Changes **21 files changed** (+364 additions, -14 deletions) <details> <summary>View changed files</summary> 📝 `src/cascadia/Remoting/Monarch.cpp` (+35 -0) 📝 `src/cascadia/Remoting/Monarch.h` (+1 -0) 📝 `src/cascadia/Remoting/Monarch.idl` (+2 -2) 📝 `src/cascadia/Remoting/Peasant.cpp` (+6 -0) 📝 `src/cascadia/Remoting/Peasant.h` (+17 -0) 📝 `src/cascadia/Remoting/Peasant.idl` (+10 -1) 📝 `src/cascadia/Remoting/WindowManager.cpp` (+5 -0) 📝 `src/cascadia/Remoting/WindowManager.h` (+1 -0) 📝 `src/cascadia/Remoting/WindowManager.idl` (+1 -0) 📝 `src/cascadia/TerminalApp/TabBase.cpp` (+13 -0) 📝 `src/cascadia/TerminalApp/TabManagement.cpp` (+7 -1) 📝 `src/cascadia/TerminalApp/TerminalPage.cpp` (+187 -4) 📝 `src/cascadia/TerminalApp/TerminalPage.h` (+24 -1) 📝 `src/cascadia/TerminalApp/TerminalPage.idl` (+9 -1) 📝 `src/cascadia/TerminalApp/TerminalWindow.cpp` (+7 -0) 📝 `src/cascadia/TerminalApp/TerminalWindow.h` (+2 -0) 📝 `src/cascadia/TerminalApp/TerminalWindow.idl` (+3 -1) 📝 `src/cascadia/TerminalControl/ControlInteractivity.idl` (+2 -2) 📝 `src/cascadia/UnitTests_Remoting/RemotingTests.cpp` (+3 -0) 📝 `src/cascadia/WindowsTerminal/AppHost.cpp` (+19 -1) _...and 1 more files_ </details> ### 📄 Description _Behold, the penultimate chapter in the saga of tear-out! This significant update bestows upon the user the power to transport tabs betwixt Terminal windows. Alas, the drag and drop capabilities of TabView are not yet refined, so this PR primarily concerns itself with the intricacies of plumbing. When a tab is extracted and deposited elsewhere, it is necessary to have the recipient make an inquiry to the Monarch, who in turn will beseech the sender to transmit the tab content, akin to the act of moving a tab. Curious it may seem, but the method has proven effective._ The penultimate tear-out PR. This PR enables the user to move tabs from one Terminal window to another. The TabView drag/drop APIs have some rough edges, so this PR is mostly plumbing. When a tab is drag/dropped, we need to get the recipient to ask the Monarch to ask the sender to send the tab content, like a MoveTab action. Wacky, but it works. There's a LONG tail of UX gaps. Those I'm going to track in #14900. It is more valuable for us to merge this now than to figure out workarounds immediately. The next PR will be the last main PR in this saga - in which we enable dragging a tab out of the window and dropping to create a new window. * Closes #1256 * Related to #5000 * Follow-ups get to go in #14900 ## Detailed description As I mentioned, it's mostly plumbing. The order that we get tab drag events is... unfortunate... for our use case. So we do a lot of sending `RequestReceiveContentArgs` up and down between windows, just to communicate who the tab was dropped on to whomever the tab was dragged from. There's a diagram for this that I originally put in https://github.com/microsoft/terminal/issues/5000#issuecomment-1435328038: ```mermaid sequenceDiagram participant Source participant Target participant Monarch Note Left of Source: _onTabDragStarting Source --> Source: stash dragged content Source --> Source: pack window ID into DataPackage Source ->> Target: Drag tab Note right of Target: _onTabStripDragOver Target ->> Target: AcceptedOperation(DataPackageOperation::Move) Source --> Target: Release mouse (to drop) Note right of Target: _onTabStripDrop Target --> Target: get WindowID from DataPackage Target -) Monarch: Request that WindowID sends content to us<br>RequestRecieveContent Monarch -) Source: Tell to send content to Target.Id<br>RequestSendContent, SendContent Source --> Source: detach our content Source -) Monarch: RequestMoveContent(stashed, target.id) Monarch -) Target: AttachContent(stashed) # Target -->> Source: # Note Left of Source: TabViewTabDragStartingEventArgs<br>.OperationCompleted # Note Left of Source: _onTabDroppedCompleted ``` Really really though, let's try to avoid nits about the UX at this time. This PR works with what we've got. Mail threads are percolating. I've got 19 chapters worth of Hobbit branch names to use for those follow ups. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
claunia added the pull-request label 2026-01-31 09:39:54 +00:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#30295