From b6f7eafe8dc29280ca690e74dd21a368d9da714b Mon Sep 17 00:00:00 2001 From: sirily11 <32106111+sirily11@users.noreply.github.com> Date: Wed, 10 Jun 2026 21:18:03 +0800 Subject: [PATCH] feat: remove folder double-click-to-open-window and enable native window tabbing Remove the double-click handlers that opened a project in a new window from the sidebar folder rows (ProjectTreeView) and the project tab button (MainView); the "Open in New Window" menu item remains. Configure main/project windows with tabbingMode = .preferred and a shared tabbingIdentifier so new windows merge into native macOS tabs instead of floating free. Co-Authored-By: Claude Opus 4.8 (1M context) --- RxCode/Views/MainView.swift | 26 +++++++++++++--------- RxCode/Views/Sidebar/ProjectTreeView.swift | 3 --- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/RxCode/Views/MainView.swift b/RxCode/Views/MainView.swift index 2aad3b7..6284322 100644 --- a/RxCode/Views/MainView.swift +++ b/RxCode/Views/MainView.swift @@ -468,19 +468,27 @@ struct DetailToolbar: View { struct UnifiedTitleBarAccessor: NSViewRepresentable { func makeNSView(context: Context) -> NSView { let view = NSView() - DispatchQueue.main.async { [weak view] in - guard let window = view?.window else { return } - window.styleMask.insert(.fullSizeContentView) - window.titlebarAppearsTransparent = true - } + configure(from: view) return view } func updateNSView(_ nsView: NSView, context: Context) { - DispatchQueue.main.async { [weak nsView] in - guard let window = nsView?.window else { return } + configure(from: nsView) + } + + private func configure(from view: NSView?) { + DispatchQueue.main.async { [weak view] in + guard let window = view?.window else { return } window.styleMask.insert(.fullSizeContentView) window.titlebarAppearsTransparent = true + // Group windows into native macOS tabs. The default `.automatic` + // mode only tabs in full screen (it honours the system "Prefer tabs + // when opening documents" setting), so opening a second window just + // floats free. `.preferred` always merges new windows into a tab + // bar; the shared identifier keeps every main/project window in one + // tab group so they can be merged together. + window.tabbingMode = .preferred + window.tabbingIdentifier = "rxcode.main" } } } @@ -490,7 +498,6 @@ struct UnifiedTitleBarAccessor: NSViewRepresentable { struct ProjectTabButton: View { @Environment(AppState.self) private var appState @Environment(WindowState.self) private var windowState - @Environment(\.openWindow) private var openWindow let project: Project let isSelected: Bool @@ -518,9 +525,6 @@ struct ProjectTabButton: View { ) } .buttonStyle(.plain) - .onTapGesture(count: 2) { - openWindow(id: "project-window", value: ProjectWindowValue(projectId: project.id, instanceId: UUID(), workspaceID: appState.activeWorkspace.id)) - } .contextMenu { let hookItems = appState.projectContextMenuItems(for: project) if !hookItems.isEmpty { diff --git a/RxCode/Views/Sidebar/ProjectTreeView.swift b/RxCode/Views/Sidebar/ProjectTreeView.swift index deec6c3..1087a87 100644 --- a/RxCode/Views/Sidebar/ProjectTreeView.swift +++ b/RxCode/Views/Sidebar/ProjectTreeView.swift @@ -466,9 +466,6 @@ private struct ProjectTreeRow: View { isExpanded.toggle() } } - .onTapGesture(count: 2) { - onOpenInNewWindow() - } .contextMenu { projectMenuItems }