feat(macOS): 统一文件与终端标签拖拽及双向停靠 - #228
Merged
Merged
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
TerminalTabDragPayload.loadSessionID currently uses MainActor.assumeIsolated, which can trap if invoked off the MainActor (drop callbacks aren’t guaranteed to be MainActor-isolated).
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR introduces a unified “mixed” editor tab ordering model on macOS so document tabs and editor-terminal tabs can share a single sequence, enabling cross-type reordering and bidirectional docking between the editor tab strip and the Terminal tool window.
Changes:
- Added
EditorTabItem+EditorTabOrderFeatureModelto own a mixed[document|terminal]tab order, and wired it intoAppModelfor reconciliation/reordering. - Reworked editor tab interactions to support horizontal snap reordering and insertion indicators, plus refined drop acceptance (tab bar accepts terminal drops; editor text area rejects terminal drops).
- Hardened terminal view hosting during moves to prevent the native terminal
NSViewfrom being detached by stale container updates, and expanded test coverage for the new ordering behavior.
File summaries
| File | Description |
|---|---|
| Tests/LitheTests/TerminalPlacementFeatureModelTests.swift | Adds coverage for reconciling editor-terminal order against mixed tab projection. |
| Tests/LitheTests/LitheCoreLogicTests.swift | Updates CodeTextView drag/drop expectations to ensure terminal-tab drops are rejected. |
| Tests/LitheTests/EditorTabOrderFeatureModelTests.swift | New suite validating mixed document/terminal ordering semantics. |
| Tests/LitheTests/EditorTabLayoutTests.swift | Expands drag payload + drop-geometry coverage for the new tab behaviors. |
| Sources/Lithe/Views/Terminal/TerminalView.swift | Enables dropping editor-terminal tabs back into the Terminal tool window. |
| Sources/Lithe/Views/Terminal/TerminalTabDragPayload.swift | Adjusts provider + load semantics for terminal-tab drags (process-local resolution). |
| Sources/Lithe/Views/Terminal/TerminalSurfaceView.swift | Keeps the native terminal view attached correctly across container moves. |
| Sources/Lithe/Views/Editor/EditorTabFlowLayout.swift | Extends tab drag state to support non-document items + shared drop geometry rules. |
| Sources/Lithe/Views/Editor/EditorAreaView.swift | Implements mixed tab rendering, horizontal snap reordering, and refined drop targeting. |
| Sources/Lithe/Views/Editor/CodeEditorView.swift | Removes terminal-tab drop handling from the code editor text view. |
| Sources/Lithe/Models/Editor/EditorTabItem.swift | New shared identifier for mixed editor tab items. |
| Sources/Lithe/Models/AppModel/AppModel+Terminal.swift | Integrates terminal moves with the mixed tab order model. |
| Sources/Lithe/Models/AppModel/AppModel+FeatureState.swift | Introduces moveEditorTab and routes document moves through mixed ordering. |
| Sources/Lithe/Models/AppModel/AppModel.swift | Adds EditorTabOrderFeatureModel and reconciles it with the document collection. |
| Sources/Lithe/Application/Features/TerminalPlacementFeatureModel.swift | Adds editor-session reordering reconciliation. |
| Sources/Lithe/Application/Features/EditorTabOrderFeatureModel.swift | New feature model owning the mixed tab presentation order. |
| Sources/Lithe/Application/Features/DocumentFeatureModel.swift | Adds reorderDocuments(orderedIDs:) to apply mixed-order document sequences. |
Review details
- Files reviewed: 17/17 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+48
to
+57
| guard !providers.isEmpty else { return false } | ||
| // Terminal tab drags are process-local and only one native drag can be | ||
| // active at a time. Resolve that identity immediately so a promised | ||
| // representation cannot turn a valid drop into a silent no-op. | ||
| if let sessionID = activeDrag.sessionID { | ||
| MainActor.assumeIsolated { | ||
| completion(sessionID) | ||
| } | ||
| return true | ||
| } |
Comment on lines
+14
to
+16
| // AppKit needs a concrete standard representation to establish the | ||
| // native drag session. CodeTextView explicitly rejects providers that | ||
| // also advertise the private terminal-tab type. |
Collaborator
Author
15 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


变更说明
统一编辑器中的文件标签和终端标签模型,使两类标签能够共享顺序并进行混合重排。
Closes #226
主要改动
EditorTabItem和标签顺序模型NSView被旧容器移除,导致终端标签打开后内容空白的问题交互行为
工具窗口 → 编辑器
必须将终端拖入编辑器标签栏才会完成停靠,拖入编辑器正文区域不会触发。
编辑器标签栏内部
终端标签只能沿标签栏横向重排,并显示目标位置的吸附和插入线。
编辑器 → 工具窗口
将终端标签拖入终端工具窗口即可恢复为工具窗口终端。
验证
已手动验证:
自动化测试未运行。
提交拆分
feat(editor): 统一文件与终端标签顺序fix(editor): 限制终端仅拖入编辑器标签栏feat(editor): 支持文件与终端标签横向吸附重排fix(terminal): 恢复拖回终端工具窗口fix(terminal): 停靠时保留终端原生视图