Skip to content

Drag a sidebar tab onto another project to move it#93

Open
thdxg wants to merge 6 commits into
mainfrom
claude/issue-91-15ket8
Open

Drag a sidebar tab onto another project to move it#93
thdxg wants to merge 6 commits into
mainfrom
claude/issue-91-15ket8

Conversation

@thdxg

@thdxg thdxg commented Jun 19, 2026

Copy link
Copy Markdown
Owner

What

Makes sidebar tabs draggable onto projects: drag a tab row and drop it on any project to move that tab — with its live panes and running shells — into that project. The target project highlights while a tab hovers over it.

Why

Follow-up to #92 (issue #91). That PR added a Move to Project context-menu command, but the original issue asked to drag a tab from one project into another, which was never wired up. This adds the direct-manipulation path; the context menu stays as a keyboard/right-click fallback.

How

Mirrors the existing pane drag-and-drop pattern (PaneDragDrop.swift):

  • New Macterm/Views/TabDragDrop.swift defines a com.thdxg.macterm.tab-id UTType, an NSItemProvider factory carrying the tab's UUID bytes, and a TabDropDelegate that reads the payload synchronously off the drag pasteboard (the drag never leaves the app).
  • SidebarTabRow gains .onDrag; SidebarProjectRow gains .onDrop plus a drop-target highlight.
  • The drop hands off to the existing AppState.moveTab, so the TerminalTab object (and its surfaces) is reused — no shell restarts. A new AppState.projectID(containingTab:) resolves the source project from the dragged tab's ID (the drop only knows the destination).
  • Registered the new exported type in Info.plist alongside the pane one.

Verified

  • Added unit tests for projectID(containingTab:) (lookup + tracking a moved tab); existing moveTab tests still cover the move itself.
  • mise run format, mise run lint, mise run testnot run; this session's environment is Linux with no Xcode/Swift toolchain, so the macOS suite can't run here. Please run locally before merge.
  • Built and ran in the app — same toolchain limitation.

Notes for reviewers

I couldn't runtime-test the drag here. The one interaction worth confirming in mise run run: that adding .onDrag to tab rows doesn't disturb the existing .onMove tab-reordering (SwiftUI List can be finicky about combining the two). Please verify both drag-to-reorder within a project and drag-to-move across projects. If reordering regresses, the fallback is to drive the tab drag through an AppKit NSDraggingSource exactly like the panes do, rather than SwiftUI .onDrag.

🤖 Generated with Claude Code


Generated by Claude Code

claude added 4 commits June 18, 2026 10:42
Closes #91. Lets a tab — with its live panes and running shells — be
relocated from one project to another via the sidebar tab context menu,
for the common case of starting work in the wrong project. The tab
object is reused as-is so surfaces stay valid, and the destination
becomes active with the moved tab selected.
The merged Move to Project command only added a context-menu entry; the
issue asked to drag a tab between projects directly. Make each sidebar
tab row a drag source carrying its UUID and each project row a drop
target, reusing the existing AppState.moveTab path so the tab's live
panes and shells move intact. Mirrors the pane drag-and-drop pattern
(custom UTType + DropDelegate, payload read off the drag pasteboard).
@github-actions github-actions Bot added area:ui Views, Settings UI area:state AppState, models, persistence area:tests Test changes area:release Release workflow, Info.plist labels Jun 19, 2026
claude added 2 commits June 19, 2026 04:34
SwiftUI ignores .onDrop for views inside a List on macOS, so the
project-row drop target never fired and dragging a tab between projects
did nothing. Switch to the List-native .onInsert hook on each project's
tab ForEach (the same family as the .onMove that already reorders tabs
within a project), fed by the tab row's existing .onDrag payload. Drop
the unusable TabDropDelegate.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:release Release workflow, Info.plist area:state AppState, models, persistence area:tests Test changes area:ui Views, Settings UI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants