Trackpad and touch gestures across the macOS app
Mantenedores costumam responder em até 1 dia
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 5/5
- Tempo estimado
- Mais de uma semana
- Facilidade para iniciantes
- 25/100
- Tipo de issue
- Funcionalidade
- Clareza
- Claramente especificada
- Status de atividade
- Ativa
- Stack de tecnologia
- swift
- Domínio
- databases, desktop, developer-experience
Direção de pesquisa
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.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
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
- Linguagem predominante
- Swift
- Estrelas
- 6.2k
- Forks
- 412
- Merge médio
- 3h 56min
- PRs com merge (30d)
- 669
Preparar o ambiente
Este projeto não oferece contêiner de desenvolvimento, Dockerfile nem guia de contribuição, então a configuração fica por sua conta: comece pelo README e veja nosso guia da primeira contribuição para os passos gerais.
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de TableProApp/TablePro
-
Linux: Remember Password fails silently when there is no default keyringTalvez já em andamento @datlechin assumiu hoje. Abertabug platform-linux
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 75/100
TableProApp/TablePro#4098 ·
Mantenedores costumam responder em até 1 dia
-
bug platform-linux
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 35/100
TableProApp/TablePro#4101 ·
Mantenedores costumam responder em até 1 dia
-
bug platform-linux
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 48/100
TableProApp/TablePro#4099 · 3 comentários ·
Mantenedores costumam responder em até 1 dia
-
enhancement platform-macos
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 66/100
TableProApp/TablePro#4070 ·
Mantenedores costumam responder em até 1 dia
-
bug
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 45/100
TableProApp/TablePro#4037 · 4 comentários ·
Mantenedores costumam responder em até 1 dia
Todas as issues de TableProApp/TablePro
Issues semelhantes
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 83/100
OneBusAway/vehicle-positions#260 ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 85/100
eliasstravik/herdr-projects#789 · 1 comentário ·
-
follow-up needs-triage S3: minor
Dificuldade 1/5 1-3 horas Facilidade para iniciantes 85/100
manaflow-ai/cmux#38032 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 67/100
arkavo-org/ArkavoKit#70 ·
Mantenedores costumam responder em até 1 dia
-
bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 70/100
vorssaint/vorssaint-utils#3933 · 1 comentário ·
Mantenedores costumam responder em até 2 dias