# PRD: Trackpad Gesture Integration for TagLauncher Date: 2026-06-27 Status: Implemented in 8.1.5 and included in 8.1.6 release QA Owner: Product / macOS platform Target area: Hotkeys, external activation, help documentation Minimum macOS: macOS 14.0 ## 1. Summary Some Mac users built muscle memory around the old trackpad gesture that opens Launchpad: pinch with thumb and three fingers. On newer macOS versions where the old Launchpad experience is no longer available in the same way, that gesture may no longer produce a useful launcher result for these users. The product question is whether TagLauncher can bind itself directly to that trackpad gesture. Decision: TagLauncher should not attempt to capture or register the system-level trackpad gesture directly. The stable and App Store-safe path is to provide reliable invocation endpoints, then document how advanced users can map a third-party gesture tool to those endpoints. Recommended product shape: - TagLauncher provides a first-party invocation endpoint: - `taglauncher://show` - existing CLI handoff can remain an advanced fallback: `--show-overlay` - TagLauncher documents third-party gesture mapping: - BetterTouchTool as the primary trackpad-gesture example. - Keyboard Maestro as a macro automation example only if verified. - Hammerspoon as free/open-source automation, but not promised as the primary trackpad gesture solution unless the exact gesture is verified. - TagLauncher does not use private multitouch APIs or global gesture interception. ## 2. Background Existing TagLauncher behavior: - TagLauncher already has global keyboard shortcuts. - TagLauncher already has a menu bar entry. - TagLauncher already has a duplicate-instance handoff path: - `src/Apptag/ProcessSingleton.swift` - A second launch with `--show-overlay` posts `TagLauncherExternalActivationRequested`. - The running instance handles it and calls `showOrFocusOverlay()`. Relevant existing code: - `src/Apptag/ProcessSingleton.swift:35` - reads process arguments. - `src/Apptag/ProcessSingleton.swift:36` - checks `--show-overlay`. - `src/Apptag/ProcessSingleton.swift:52` - posts the external activation distributed notification. - `src/Apptag/ApptagApp.swift:1733` - observes external activation requests. - `src/Apptag/ApptagApp.swift:1742` - handles the activation request. - `src/Apptag/ApptagApp.swift:1748` - calls `showOrFocusOverlay()`. This means the project already has most of the internal activation path needed. The missing product layer is a clean public invocation surface and documentation. ## 3. Product Goals 1. Help users recreate a Launchpad-like trackpad launcher habit with TagLauncher. 2. Keep TagLauncher App Store-safe and compatible with macOS permission models. 3. Avoid fragile private APIs and system gesture interception. 4. Provide a simple supportable setup path for advanced users. 5. Preserve existing global keyboard shortcut behavior. ## 4. Non-Goals Do not implement: - Direct registration of the system Launchpad gesture. - Global capture of thumb + three-finger pinch inside TagLauncher. - Use of private `MultitouchSupport.framework`. - Use of undocumented IOKit multitouch device parsing. - A background gesture daemon inside TagLauncher. - Accessibility-required raw gesture capture in the main app. - A default feature that asks every user to grant Accessibility/Input Monitoring permissions. - Replacing system Trackpad settings. - App Store review-risky gesture interception. ## 5. Technical Position ### 5.1 Why TagLauncher Should Not Capture the Gesture Directly macOS does not provide a public, App Store-friendly API that lets a third-party app claim the system-level thumb + three-finger pinch gesture globally. AppKit gesture events are designed for the active application and its responder/view hierarchy. They are not a stable registration mechanism for background launcher apps. Low-level event taps are not a clean solution for this specific system gesture: - They are not a public "register global trackpad gesture" API. - They may require additional privacy permissions. - They can be brittle across macOS versions. - They are hard to explain to users. - They introduce App Store review and maintenance risk. Private multitouch frameworks or raw device parsing are explicitly out of scope. ### 5.2 Recommended Integration Model Use this chain: ```text User trackpad gesture -> third-party gesture tool -> TagLauncher public invocation endpoint -> existing showOrFocusOverlay path ``` TagLauncher owns: - Stable invocation endpoint. - Documentation. - Settings-page guidance. - QA for invocation behavior. Third-party tools own: - Trackpad gesture capture. - Per-user gesture mapping. - Permissions required for gesture capture. ## 6. Recommended Product Changes ### 6.1 Add URL Scheme Add a custom URL scheme: ```text taglauncher://show ``` Expected behavior: - If TagLauncher is already running, show/focus App Grid overlay. - If TagLauncher is not running, launch TagLauncher and show App Grid overlay. - If overlay is already visible, keep or focus it; do not create duplicate windows. Recommended future URL, optional: ```text taglauncher://quick-search ``` Not required for first release unless product wants a separate Quick Search gesture. ### 6.2 Keep CLI Handoff as Advanced Fallback Existing internal path: ```text TagLauncher --show-overlay ``` For advanced documentation, the macOS `open` command can call the app with args: ```bash open -na "TagLauncher" --args --show-overlay ``` Do not make this the primary user-facing recommendation if URL Scheme exists. URL Scheme is simpler for external tools. ### 6.3 Add Help Documentation Create a Help section: Title: ```text Use a Trackpad Gesture to Open TagLauncher ``` Chinese title: ```text 用触摸板手势打开 TagLauncher ``` Core message: ```text macOS does not let TagLauncher directly claim the system Launchpad gesture. To use a trackpad gesture, map the gesture in a third-party automation tool to taglauncher://show or to your TagLauncher global shortcut. ``` Chinese draft: ```text macOS 不允许 TagLauncher 直接接管系统级启动台手势。你可以使用第三方自动化工具,把触摸板手势映射到 taglauncher://show,或映射到 TagLauncher 的全局快捷键。 ``` ### 6.4 Add Settings Copy In Settings > Hotkeys, add a small help note or help button. Recommended text: ```text Want to open TagLauncher with a trackpad gesture? Map your gesture to taglauncher://show using a gesture utility. ``` Chinese draft: ```text 想用触摸板手势唤出 TagLauncher?可用手势工具将手势映射到 taglauncher://show。 ``` Keep this as secondary help text. Do not make it a large settings section. ## 7. Third-Party Tool Guidance ### 7.1 Recommended Tool Positioning Primary documented tool: - BetterTouchTool - Strong fit for trackpad gestures. - Commercial. - Good for non-technical users who explicitly want gesture mapping. Mention with caution: - Keyboard Maestro - Commercial macro tool. - Useful if it can be configured for the target gesture or for another input trigger. - Must be verified before official step-by-step docs claim support for this exact gesture. Open-source/free option: - Hammerspoon - Free and open-source. - Good for technical users. - Strong for hotkey/URL automation. - Do not promise reliable thumb + three-finger pinch capture unless QA verifies that exact gesture path on target macOS versions. ### 7.2 Recommended User-Facing Wording Avoid: ```text TagLauncher supports the Launchpad gesture. ``` Use: ```text You can map a trackpad gesture to TagLauncher using a gesture utility. ``` Chinese: ```text 你可以使用手势工具,把触摸板手势映射到 TagLauncher。 ``` This avoids implying TagLauncher owns or overrides system gestures. ## 8. Implementation Requirements ### 8.1 URL Scheme Registration Add `CFBundleURLTypes` to `Info.plist`. Suggested scheme: ```text taglauncher ``` Supported routes: ```text taglauncher://show ``` Optional later: ```text taglauncher://quick-search taglauncher://settings/hotkeys ``` ### 8.2 URL Handling Implement URL handling in the AppDelegate path. Expected AppKit delegate method: ```swift func application(_ application: NSApplication, open urls: [URL]) ``` For `taglauncher://show`: - Dismiss conflicting transient state if needed. - Call existing `showOrFocusOverlay()` path. - Respect current fullscreen/Split View overlay behavior. - Do not create duplicate windows. For unknown URL: - Ignore safely. - Optionally log diagnostics. ### 8.3 Cold Launch Behavior If TagLauncher is not running and user opens: ```text taglauncher://show ``` Expected: 1. App launches. 2. Defaults and localization initialize normally. 3. Overlay shows after app is ready. 4. No duplicate Dock icon is created. 5. No settings window is opened. Implementation note: If URL handling arrives before the app is fully initialized, queue a pending `showOverlay` request and execute it after `applicationDidFinishLaunching`. ### 8.4 Running Instance Behavior If TagLauncher is already running: - `taglauncher://show` should route to the existing instance. - The app should show/focus overlay exactly like the menu bar command or global hotkey. - If overlay is already visible, behavior should match existing toggle/focus policy decided by product. Recommended: - `taglauncher://show` should show/focus, not toggle-hide. Reason: External gesture tools may send repeated or delayed activations. A deterministic "show" command is safer than toggle. ### 8.5 CLI Compatibility Keep `--show-overlay` working. Add tests or QA steps for: ```bash open -na "TagLauncher" --args --show-overlay ``` This gives power users and automation tools a fallback if URL Scheme is unavailable. ## 9. UX Requirements ### 9.1 Settings > Hotkeys Add a small secondary entry under the existing hotkey information: - Title: `Trackpad gesture` - Body: `Use a gesture utility to map a trackpad gesture to taglauncher://show.` - Optional action: `Open Help` Chinese draft: - Title: `触摸板手势` - Body: `可用手势工具将触摸板手势映射到 taglauncher://show。` - Action: `查看帮助` Do not add: - Gesture recorder. - Permission prompt. - System Trackpad settings clone. - Tool-specific configuration UI. ### 9.2 Help Document Help document should include: 1. Why TagLauncher cannot directly claim the system gesture. 2. Recommended approach using a gesture utility. 3. BetterTouchTool example. 4. Generic URL Scheme example: ```text taglauncher://show ``` 5. CLI fallback: ```bash open -na "TagLauncher" --args --show-overlay ``` 6. Testing checklist: - Normal desktop. - Fullscreen app. - Split View. - External display. ### 9.3 BetterTouchTool Example Flow Document only after verifying labels in the current BetterTouchTool UI. Intended flow: 1. Open BetterTouchTool. 2. Choose Trackpad. 3. Add a gesture. 4. Select thumb + three-finger pinch, or the closest available gesture. 5. Set action to open URL: ```text taglauncher://show ``` 6. Test on normal desktop. 7. Test in fullscreen and Split View. If BetterTouchTool cannot open URL directly in the selected action type, use command fallback: ```bash open "taglauncher://show" ``` or: ```bash open -na "TagLauncher" --args --show-overlay ``` ## 10. Privacy and Permissions TagLauncher should not request new permissions for this feature. Expected: - TagLauncher does not request Accessibility permission for gesture capture. - TagLauncher does not request Input Monitoring. - Third-party gesture tools may request their own permissions. - Help text must make it clear those permissions belong to the external tool, not TagLauncher. This keeps TagLauncher simpler for App Store review and user trust. ## 11. QA Requirements ### 11.1 TagLauncher Endpoint QA Test `taglauncher://show`: - App not running. - App running in menu bar only. - App running with overlay hidden. - Overlay already visible. - Settings window open. - Quick Search open. - Fullscreen Space. - Split View. - Multiple displays if available. Expected: - Overlay shows or focuses. - No duplicate visible instance. - No Dock icon flicker beyond existing behavior. - No Space jump regression. - No broken Quick Search session. ### 11.2 CLI Fallback QA Test: ```bash open -na "TagLauncher" --args --show-overlay ``` Scenarios: - App not running. - App already running. - App hidden as menu bar/accessory app. - Fullscreen Space. - Split View. Expected: - Existing handoff path works. - Existing app receives request. - No duplicate instance remains. ### 11.3 Help Documentation QA Verify: - Instructions do not claim native gesture support. - Instructions do not claim Hammerspoon supports the exact gesture unless verified. - BetterTouchTool steps match the actual current UI before release. - Paid/commercial nature of third-party tools is not hidden if mentioned. - Hammerspoon is described accurately as free/open-source but technical. ### 11.4 Optional Third-Party Smoke QA If BetterTouchTool is available: - Configure thumb + three-finger pinch gesture. - Bind it to `taglauncher://show`. - Test normal desktop, fullscreen, Split View. If Hammerspoon is evaluated: - Verify whether the exact trackpad gesture is actually capturable. - If not reliable, do not publish Hammerspoon as the trackpad-pinch recipe. ## 12. Acceptance Criteria The feature is accepted when: 1. `taglauncher://show` is registered and works. 2. Cold launch through `taglauncher://show` opens TagLauncher overlay. 3. Running-instance invocation through `taglauncher://show` focuses/shows the existing overlay. 4. `--show-overlay` remains working. 5. No new TagLauncher privacy permission is required. 6. Settings copy is short and non-invasive. 7. Help documentation clearly states that gesture capture is handled by third-party tools. 8. QA confirms fullscreen/Split View behavior remains stable. 9. App Store review risk from private gesture APIs is avoided. ## 13. Rejected Alternatives ### 13.1 Native Global Gesture Registration Rejected. Reason: No stable public API exists for a third-party app to claim the system Launchpad gesture globally. ### 13.2 Raw Multitouch Capture Rejected. Reason: Requires private or brittle implementation paths, creates permission and App Store risk, and is likely to break across macOS releases. ### 13.3 Built-In Gesture Recorder Rejected for first release. Reason: Would imply TagLauncher owns gesture capture, increase complexity, and create user-support burden. ### 13.4 Make BetterTouchTool a Hard Dependency Rejected. Reason: TagLauncher should remain useful without external tools. BetterTouchTool can be documented as an optional integration, not a dependency. ## 14. Open Questions 1. Should the first release include only `taglauncher://show`, or also `taglauncher://quick-search`? 2. Should Settings > Hotkeys include an `Open Help` button, or only static help text? 3. Should the help document mention BetterTouchTool by name, or use generic "gesture utility" wording plus examples? 4. Should the App Store version include the same help text as direct-download builds? Recommended answers: 1. First release only `taglauncher://show`. 2. Include `Open Help` if the help page exists; otherwise static text. 3. Use generic wording first, then examples. 4. Yes, because TagLauncher itself is not doing gesture capture. ## 15. References Apple: - Mac trackpad gestures: https://support.apple.com/en-us/102482 - Handling trackpad events: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/EventOverview/HandlingTouchEvents/HandlingTouchEvents.html - Defining a custom URL scheme: https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app External tools: - BetterTouchTool: https://folivora.ai - Keyboard Maestro: https://www.keyboardmaestro.com - Hammerspoon: https://www.hammerspoon.org https://github.com/Hammerspoon/hammerspoon ## 16. Final Recommendation Do not build native trackpad gesture capture into TagLauncher. Build and document a robust invocation endpoint instead: ```text taglauncher://show ``` Then let users map trackpad gestures to that endpoint with their preferred gesture utility. This is the lowest-risk path for macOS 26 compatibility, App Store review, privacy permissions, and long-term maintenance.