From ddc48b8946734a6e4261a57125e16ad81276230d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ng=C3=B4=20Qu=E1=BB=91c=20=C4=90=E1=BA=A1t?= Date: Thu, 23 Apr 2026 17:12:20 +0700 Subject: [PATCH] fix: preview tab double-click detection and promotion --- .../MainSplitViewController.swift | 4 ++-- .../MainContentCoordinator+Navigation.swift | 7 ++++--- .../Views/Sidebar/DoubleClickDetector.swift | 17 +++++++++++++---- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/TablePro/Core/Services/Infrastructure/MainSplitViewController.swift b/TablePro/Core/Services/Infrastructure/MainSplitViewController.swift index af3700c8b..f05cbc8b2 100644 --- a/TablePro/Core/Services/Infrastructure/MainSplitViewController.swift +++ b/TablePro/Core/Services/Infrastructure/MainSplitViewController.swift @@ -332,11 +332,11 @@ internal final class MainSplitViewController: NSSplitViewController, InspectorVi previewCoordinator.promotePreviewTab() } else { previewCoordinator.promotePreviewTab() - coordinator.openTableTab(table.name, isView: isView) + coordinator.openTableTab(table.name, isView: isView, asPreview: false) } } else { coordinator.promotePreviewTab() - coordinator.openTableTab(table.name, isView: isView) + coordinator.openTableTab(table.name, isView: isView, asPreview: false) } }, pendingTruncates: sessionPendingTruncatesBinding, diff --git a/TablePro/Views/Main/Extensions/MainContentCoordinator+Navigation.swift b/TablePro/Views/Main/Extensions/MainContentCoordinator+Navigation.swift index ea2e9ce10..6efa1345b 100644 --- a/TablePro/Views/Main/Extensions/MainContentCoordinator+Navigation.swift +++ b/TablePro/Views/Main/Extensions/MainContentCoordinator+Navigation.swift @@ -15,7 +15,7 @@ private let navigationLogger = Logger(subsystem: "com.TablePro", category: "Main extension MainContentCoordinator { // MARK: - Table Tab Opening - func openTableTab(_ tableName: String, showStructure: Bool = false, isView: Bool = false) { + func openTableTab(_ tableName: String, showStructure: Bool = false, isView: Bool = false, asPreview: Bool? = nil) { let navigationModel = PluginMetadataRegistry.shared.snapshot( forTypeId: connection.type.pluginTypeId )?.navigationModel ?? .standard @@ -73,8 +73,9 @@ extension MainContentCoordinator { // If no tabs exist (empty state), add a table tab directly. // In preview mode, mark it as preview so subsequent clicks replace it. + let usePreview = asPreview ?? AppSettingsManager.shared.tabs.enablePreviewTabs if tabManager.tabs.isEmpty { - if AppSettingsManager.shared.tabs.enablePreviewTabs { + if usePreview { tabManager.addPreviewTableTab( tableName: tableName, databaseType: connection.type, @@ -155,7 +156,7 @@ extension MainContentCoordinator { } // Preview tab mode: reuse or create a preview tab instead of a new native window - if AppSettingsManager.shared.tabs.enablePreviewTabs { + if usePreview { openPreviewTab(tableName, isView: isView, databaseName: currentDatabase, schemaName: currentSchema, showStructure: showStructure) return } diff --git a/TablePro/Views/Sidebar/DoubleClickDetector.swift b/TablePro/Views/Sidebar/DoubleClickDetector.swift index 42433b5dc..5faacb18f 100644 --- a/TablePro/Views/Sidebar/DoubleClickDetector.swift +++ b/TablePro/Views/Sidebar/DoubleClickDetector.swift @@ -84,13 +84,22 @@ private final class SharedDoubleClickMonitor { private func handleMouseDown(_ event: NSEvent) { guard event.clickCount == 2 else { return } - for view in registeredViews.allObjects { + let views = registeredViews.allObjects + guard !views.isEmpty else { return } + + for view in views { guard let viewWindow = view.window, event.window === viewWindow else { continue } - let locationInView = view.convert(event.locationInWindow, from: nil) - if view.bounds.contains(locationInView) { + + var ancestor: NSView? = view.superview + while let current = ancestor, !(current is NSTableRowView) { + ancestor = current.superview + } + let hitView = ancestor ?? view + let locationInHitView = hitView.convert(event.locationInWindow, from: nil) + if hitView.bounds.contains(locationInHitView) { view.onDoubleClick?() - break + return } } }