Trackpad and touch gestures across the macOS app
維護者通常 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 內容生成。
描述
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:
allowsMagnificationatapple/TablePro/Views/Components/MagnifiableCanvasView.swift:197, Cmd+scroll zoom atapple/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:
NSTableViewRowActionDelete, Edit, Favorite atapple/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
NSViewthat implementsNSTextInputClient(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:)orpressureChange(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.isTouchSwipeNavigationEnabledfor touch,isSwipeTrackingFromScrollEventsEnabledfor 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
NSScrollViewwork on touch. CustommouseDown/nextEventloops 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 atapple/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.
- Grid selection:
- SQL editor: adopt
NSTextSelectionManagerfor 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.
- Unselected tab accessories:
- 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, SwiftUIdirectTouchSystemGesturesDisabled(). Gate by availability. - Unconfirmed: whether direct touch drives
trackSwipeEventpage 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
scrollWheelbefore anNSScrollViewmust checkNSEvent.isSwipeTrackingFromScrollEventsEnableditself. - 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
accessibilityDisplayShouldReduceMotionis 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
- HIG: Pointing devices, Gestures, Designing for macOS
- Touch: WWDC26 Modernize your AppKit app, TN3212, Bring Touch to your Mac app, Design for touch on Mac
wantsScrollEventsForSwipeTracking(on:),trackSwipeEvent,isSwipeTrackingFromScrollEventsEnabledallowsMagnification,smartMagnify(with:),rectForSmartMagnification(at:in:)quickLook(with:),showDefinition(for:range:options:baselineOriginProvider:)tableView(_:rowActionsForRow:edge:)- Apple apps: Notes zoom, Numbers zoom, Preview zoom, Safari zoom, Xcode history, Mail swipe, Notes gestures
- Mac gestures, Force click
- 主要語言
- Swift
- 星號
- 6.2k
- 分支
- 412
- 平均合併
- 3 小時 56 分鐘
- 30 天內合併 PR
- 669
環境準備
這個專案沒有提供開發容器、Dockerfile 或貢獻指南,環境需要你自己搭建:先看它的 README,通用步驟見我們的新手貢獻指南。
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
TableProApp/TablePro 的其他 Issue
-
Linux: Remember Password fails silently when there is no default keyring可能已有人在做 @datlechin 今天認領。 未關閉bug platform-linux
難度 2/5 1-3 小時 新手友好度 75/100
TableProApp/TablePro#4098 ·
維護者通常 1 天內回覆
-
bug platform-linux
難度 2/5 1-3 小時 新手友好度 35/100
TableProApp/TablePro#4101 ·
維護者通常 1 天內回覆
-
bug platform-linux
難度 4/5 3-5 天 新手友好度 48/100
TableProApp/TablePro#4099 · 3 則留言 ·
維護者通常 1 天內回覆
-
enhancement platform-macos
難度 3/5 1-2 天 新手友好度 66/100
TableProApp/TablePro#4070 ·
維護者通常 1 天內回覆
-
bug
難度 3/5 1-2 天 新手友好度 45/100
TableProApp/TablePro#4037 · 4 則留言 ·
維護者通常 1 天內回覆
查看 TableProApp/TablePro 的全部 Issue
相似的 Issue
-
難度 2/5 1-3 小時 新手友好度 83/100
OneBusAway/vehicle-positions#260 ·
維護者通常 1 天內回覆
-
難度 1/5 1 小時以內 新手友好度 85/100
eliasstravik/herdr-projects#789 · 1 則留言 ·
-
follow-up needs-triage S3: minor
難度 1/5 1-3 小時 新手友好度 85/100
manaflow-ai/cmux#38032 · 1 則留言 ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 67/100
arkavo-org/ArkavoKit#70 ·
維護者通常 1 天內回覆
-
bug
難度 2/5 1-3 小時 新手友好度 70/100
vorssaint/vorssaint-utils#3933 · 1 則留言 ·
維護者通常 2 天內回覆