Keep internal tab drags out of Finder

This commit is contained in:
Lawrence Chen 2026-03-10 21:41:01 -07:00
parent c4e2d0c63c
commit 1c25c6bd30
3 changed files with 37 additions and 13 deletions

View file

@ -93,27 +93,15 @@
</array>
</dict>
</array>
<key>UTExportedTypeDeclarations</key>
<key>UTImportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeIdentifier</key>
<string>com.splittabbar.tabtransfer</string>
<key>UTTypeDescription</key>
<string>Bonsplit Tab Transfer</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.cmux.sidebar-tab-reorder</string>
<key>UTTypeDescription</key>
<string>cmux Sidebar Tab Reorder</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
</dict>
</array>
<key>NSAppTransportSecurity</key>

View file

@ -82,6 +82,40 @@ func sidebarSelectedWorkspaceForegroundNSColor(opacity: CGFloat) -> NSColor {
let clampedOpacity = max(0, min(opacity, 1))
return NSColor.white.withAlphaComponent(clampedOpacity)
}
#if compiler(>=6.2)
@available(macOS 26.0, *)
enum InternalTabDragConfigurationProvider {
// These drags only make sense inside cmux. Outside the app, Finder should
// reject them instead of materializing placeholder files from the payload.
static let value = DragConfiguration(
operationsWithinApp: .init(allowCopy: false, allowMove: true, allowDelete: false),
operationsOutsideApp: .init(allowCopy: false, allowMove: false, allowDelete: false)
)
}
#endif
private struct InternalTabDragConfigurationModifier: ViewModifier {
@ViewBuilder
func body(content: Content) -> some View {
#if compiler(>=6.2)
if #available(macOS 26.0, *) {
content.dragConfiguration(InternalTabDragConfigurationProvider.value)
} else {
content
}
#else
content
#endif
}
}
extension View {
func internalOnlyTabDrag() -> some View {
modifier(InternalTabDragConfigurationModifier())
}
}
struct ShortcutHintPillBackground: View {
var emphasis: Double = 1.0
@ -9662,6 +9696,7 @@ private struct TabItemView: View {
dropIndicator = nil
return SidebarTabDragPayload.provider(for: tab.id)
}
.internalOnlyTabDrag()
.onDrop(of: SidebarTabDragPayload.dropContentTypes, delegate: SidebarTabDropDelegate(
targetTabId: tab.id,
tabManager: tabManager,

View file

@ -106,6 +106,7 @@ struct WorkspaceContentView: View {
workspace.bonsplitController.focusPane(paneId)
}
}
.internalOnlyTabDrag()
// Split zoom swaps Bonsplit between the full split tree and a single pane view.
// Recreate the Bonsplit subtree on zoom enter/exit so stale pre-zoom pane chrome
// cannot remain stacked above portal-hosted browser content.