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 摘要。