Trackpad and touch gestures across the macOS app

未關閉
#4,071 0 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 1 天內回覆

還沒有人認領這個 Issue。

評估

難度
5/5
預估耗時
一週以上
新手友好度
25/100
Issue 類型
功能
描述清晰度
描述清楚
活躍度
活躍
技術堆疊
swift

研究方向

Start with the listed entry points: ViewMenuBuilder.swift, ZoomCommandResponding.swift, DataGridTableView.swift, EditorTabInteractionView.swift, and TableProTextEngine/TextView+NSTextInput.swift. Read the relevant AppKit gesture APIs and the linked WWDC26 and TN3212 guidance, then map each proposed gesture to its menu command and surface. Done means the specified gestures, system preferences, accessibility behavior, and hardware checks work across the listed surfaces.

由索引模型根據 Issue 內容生成。

描述

enhancement platform-macos
Problem
  • Only the ER diagram, EXPLAIN diagram and maps answer trackpad gestures. The welcome window has native row swipe actions.
  • The data grid and SQL editor have Zoom In/Out and Back/Forward commands, but no pinch and no page swipe.
  • macOS 27 adds direct touch. Custom mouse loops and hover-only controls do not get it for free.
  • Goal: one gesture policy for the whole macOS app.
    • Native AppKit APIs only. No raw touch recognizers, event taps or private defaults keys.
    • Follow System Settings > Trackpad and Touch. No TablePro gesture setting.
    • Every gesture maps to a menu command with a shortcut.
Current state
  • Back/Forward: apple/TablePro/Core/Menu/ViewMenuBuilder.swift:146, :152. History is per tab (apple/TablePro/Views/Main/Extensions/MainContentCoordinator+NavigationHistory.swift:69), table tabs only (:29), behind the discard-changes prompt (:105).
  • Zoom In/Out write the shared editor and grid font-size settings, so every window changes: apple/TablePro/Core/Menu/ZoomCommandResponding.swift:40, :42.
  • Diagrams: allowsMagnification at apple/TablePro/Views/Components/MagnifiableCanvasView.swift:197, Cmd+scroll zoom at apple/TablePro/Views/Components/DiagramScrollView.swift:54.
  • Maps are MKMapView (apple/TablePro/Views/Results/ResultMapSurface.swift:19). Inspector map rotation is off on purpose (apple/TablePro/Views/Results/InspectorMapSurfacePool.swift:105).
  • Welcome rows: NSTableViewRowAction Delete, Edit, Favorite at apple/TablePro/Views/Welcome/WelcomeOutlineCoordinator.swift:368.
  • The editor tab strip turns horizontal scroll into strip scrolling: apple/TablePro/Views/Main/EditorTabInteractionView.swift:205.
  • The SQL editor is a custom NSView that implements NSTextInputClient (apple/Packages/TableProEditor/Sources/TableProTextEngine/TextView/TextView+NSTextInput.swift:28), with hit testing at :378. What Look Up does there today is untested.
  • No swipe(with:), magnify(with:), smartMagnify(with:), quickLook(with:) or pressureChange(with:) override in the app.
Decisions
  • Zoom is a view zoom. Pinch and View > Zoom In / Zoom Out / Actual Size magnify the pane under the pointer (pinch) or the focused pane (menu). Font sizes stay in Settings as the base. Actual Size returns to 100% of that base. Zoom is not persisted app-wide. Precedent: Notes (View > Zoom vs default text size), Numbers, Preview. Safari keeps pinch separate from its saved page zoom.
  • Back/Forward follows the active tab's history. Table history stays as is. SQL editor locations join only once there is a real semantic jump history, as in Xcode's per-editor history. Typing, caret moves, runs and tab switches are never history entries.
  • Look Up targets the text under the pointer. Pass the cell or line string with a zero-length range at the hit character to showDefinition, and the system picks the word or phrase. A whole-value preview stays a separate action. Selecting a cell is not selecting text.
  • Query history gets one trailing swipe action, Delete. Leading edge stays empty. Load, Copy and Save as Favorite stay in the menu. Run in New Tab, Restore Previous Values and Clear History never sit on a swipe. Precedent: Mail, Notes, Safari Reading List.
  • Touch uses separate preferences. NSEvent.isTouchSwipeNavigationEnabled for touch, isSwipeTrackingFromScrollEventsEnabled for trackpad. Neither requires the other.
Proposed gestures
Surface Gesture AppKit API Command Notes
Table tab content Swipe between pages wantsScrollEventsForSwipeTracking(on:), NSEvent.trackSwipeEvent(...); swipe(with:) for discrete swipes Navigate Back / Forward AppKit forwards the swipe only when the grid is already at the horizontal edge when the gesture starts. Commit once on success, nothing on cancel. Same discard prompt.
Data grid, incl. frozen pane, structure, dashboard sessions, data files, compare Pinch NSScrollView.allowsMagnification, magnification Zoom In / Out / Actual Size Frozen pane and headers stay aligned. Check editing, selection and hit testing at each scale.
SQL editor, DDL editor Pinch NSScrollView.allowsMagnification, magnification Zoom In / Out / Actual Size Check caret, selection, gutter, overlays and scroll position.
Grid text cells, SQL text Look Up (force click or three-finger tap, per settings) quickLook(with:), showDefinition(for:range:options:baselineOriginProvider:) New Look Up menu item Test what the editor already gets through NSTextInputClient before adding a handler. No pressure threshold.
Image preview, inspector image, image pop-out Pinch, smart zoom NSScrollView + NSImageView, allowsMagnification Zoom In / Out / Actual Size Today it is .scaledToFit() only, apple/TablePro/Views/Results/CellImagePreviewView.swift:43.
Query history Row swipe, trailing tableView(_:rowActionsForRow:edge:) on FieldDrivenTableView Delete Deletes by entry ID (apple/TablePro/ViewModels/HistoryPanelViewModel.swift:188).
EXPLAIN diagram Smart zoom on a node rectForSmartMagnification(at:in:) Existing zoom Optional. AppKit keeps the animation.

No new gesture, keep native behavior:

  • ER and EXPLAIN diagrams: pinch and smart zoom already work.
  • Maps: MapKit owns pan, zoom and rotate.
  • Welcome window: row actions already native.
  • Editor tab strip, window tabs, result set tabs: switching on swipe would change what the same motion does today. Switching stays on Previous/Next Tab and Previous/Next Result.
  • Sidebar, connection rail, lists, forms, sheets, settings, AI chat, charts: native scrolling only.
  • No swipe or pressure that drops objects, runs, approves, terminates, applies or submits anything.
Touch (macOS 27)

New in the macOS 27 SDK: NSScrollView.isTouchScrollingEnabled, scrollGestureForRelationships, NSGestureRecognizer.isCancellableByScrollGesture, NSView.exclusiveGestureBehavior, NSTextSelectionManager, NSView.beginDraggingSession(items:gesture:source:), NSScreen.touchCapabilities, NSEvent.isTouchSwipeNavigationEnabled. NSGestureRecognizer.allowedTouchTypes now defaults to .direct.

  • Standard controls and NSScrollView work on touch. Custom mouseDown / nextEvent loops do not, per WWDC26 "Modernize your AppKit app" and TN3212.
  • Move custom tracking loops to gesture recognizers:
    • Grid selection: apple/TablePro/Views/DataGrid/DataGridTableView.swift:239, loop at apple/TablePro/Views/DataGrid/DataGridViewController+Selection.swift:341.
    • Editor tab strip: apple/TablePro/Views/Main/EditorTabInteractionView.swift:266.
    • Inspector resize handle: apple/TablePro/Views/RowInspector/FieldEditors/FieldResizeHandle.swift:95.
    • Statement run ribbon: apple/Packages/TableProEditor/Sources/TableProEditorKit/StatementRunning/StatementRunRibbonView.swift:143.
  • SQL editor: adopt NSTextSelectionManager for touch selection.
  • Hover-only controls need a touch path:
    • Unselected tab accessories: apple/TablePro/Views/Main/EditorTabStrip.swift:454.
    • Favorite star: apple/TablePro/Views/Sidebar/FavoriteStarButton.swift:18.
  • Grow touch hit regions, not the Mac layout. Apple's sample uses 36 pt.
  • Long press uses the native context menu and drag APIs, not a timer.
  • Not in the 27.0 SDK yet, though Apple's tech talk shows them: NSWindow.disablesDirectTouchSystemGestures, SwiftUI directTouchSystemGesturesDisabled(). Gate by availability.
  • Unconfirmed: whether direct touch drives trackSwipeEvent page navigation.
Risks
  • Grid horizontal scroll vs page swipe. Rely on the AppKit edge-at-start rule, not a delta threshold. Momentum must not cross into navigation.
  • A responder that gets scrollWheel before an NSScrollView must check NSEvent.isSwipeTrackingFromScrollEventsEnabled itself.
  • Natural scrolling is already in the deltas. Do not invert twice or hardcode finger counts.
  • Zoom In/Out change behavior: today they write the shared font setting, after this they magnify one pane. The font setting stays in Settings.
  • Magnifying the grid and editor is untested with the frozen pane, floating gutter and custom drawing.
  • The existing canvases record wrong SwiftUI points under magnification (MagnifiableCanvasView.swift:184). Keep pointer input in AppKit views in any newly magnified view.
  • Reduce Motion: no large page-slide animation when accessibilityDisplayShouldReduceMotion is on.
  • XCUITest scroll is pixel scrolling, not a gesture. Hardware pass needed:
    • Page swipe set to two fingers, three fingers, either and off.
    • Natural scrolling on and off.
    • Force Touch and non Force Touch trackpads, Magic Mouse, wheel mouse.
    • Touchscreen Mac, VoiceOver, Reduce Motion.
Sources
主要語言
Swift
星號
6.2k
分支
412
平均合併
3 小時 56 分鐘
30 天內合併 PR
669

環境準備

這個專案沒有提供開發容器、Dockerfile 或貢獻指南,環境需要你自己搭建:先看它的 README,通用步驟見我們的新手貢獻指南。

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

TableProApp/TablePro 的其他 Issue

查看 TableProApp/TablePro 的全部 Issue

相似的 Issue

更多 Swift Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。