Skip to content

NeoXue-ai/ForceClickAI

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

29 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ForceClickAI

ForceClickAI is a macOS utility that translates the text you select when you Force Click the trackpad.

It is built for the interaction I wanted from macOS: select text anywhere, press a little deeper, and see the translation near the cursor without switching apps, opening a browser extension, or losing the original clipboard.

The current prototype uses a private local multitouch path because public macOS event APIs do not reliably expose Force Click pressure globally on every Mac.

What Works

  • Force Click detection from the built-in trackpad using Apple's private MultitouchSupport framework.
  • Low-force selection prefetch before the full Force Click trigger, which avoids macOS Lookup stealing focus or clearing selection.
  • Translation through DeepSeek's OpenAI-compatible chat completions API.
  • API key storage in macOS Keychain.
  • Floating translation panel near the cursor.
  • Native FC action menu for status, clipboard translation, last-result actions, saved settings, and API key management.
  • Persistent settings for target language, sensitivity, provider/model, and panel visibility.
  • Pasteboard restoration after selection capture.
  • Local .app bundle generation for double-click launch.

Demo Flow

  1. Select text in any app.
  2. Force Click the trackpad.
  3. ForceClickAI captures the selected text, translates it, and shows the result in a native floating panel.

Tested locally with QQ, Firefox, Bilibili, Terminal, and normal selectable text views.

Important Notes

This is a local power-user utility, not an App Store-ready product.

  • It uses the private MultitouchSupport framework. That is useful for local experimentation, but not suitable for Mac App Store distribution.
  • It requires Accessibility/Input Monitoring permissions so it can observe input and copy selected text.
  • Selected text is sent to the configured translation API provider. The default provider is DeepSeek.
  • API keys are never hardcoded. Use environment variables or the built-in Keychain command.

Requirements

  • macOS 13 or newer
  • Swift 6.2 toolchain / recent Xcode command line tools
  • Built-in Force Touch trackpad
  • DeepSeek API key, or another OpenAI-compatible provider
  • Accessibility/Input Monitoring permission for Terminal or the generated ForceClickAI.app

Quick Start

Clone and build:

git clone https://github.com/NeoXue-ai/ForceClickAI.git
cd ForceClickAI
swift build

Save your API key once:

swift run ForceClickAI set-key

Run the private Force Click translator:

swift run ForceClickAI private-run --target zh-Hans --force-threshold 800

Select text in another app, then Force Click.

Build The App Bundle

Create a local double-clickable app:

Scripts/build-app.sh
open dist/ForceClickAI.app

The app bundle starts the private Force Click translator with default settings:

  • target language: zh-Hans
  • force threshold: 800
  • prefetch threshold: 300
  • floating panel: enabled
  • menu bar item: enabled

The FC menu is the main control surface. It shows readiness, API key status, current language/provider, sensitivity, clipboard translation, last-result actions, and saved settings.

macOS may ask you to grant Accessibility/Input Monitoring to ForceClickAI.app the first time you use it.

Commands

swift run ForceClickAI private-run --target zh-Hans --force-threshold 800

Runs the main Force Click translator using the private multitouch force monitor.

swift run ForceClickAI app

Runs the app-style default mode from the command line. The generated .app bundle uses this mode automatically.

swift run ForceClickAI translate "Hello world"

Tests the translation API without Force Click detection.

swift run ForceClickAI copy-test --delay 3

Tests whether synthetic copy and pasteboard reading work in the focused app.

swift run ForceClickAI private-probe

Prints interpreted raw multitouch contact data. Use this when tuning force thresholds.

swift run ForceClickAI probe

Tests public AppKit/CoreGraphics pressure events. On the tested Mac, public APIs were not enough for reliable global Force Click detection.

Main Options

  • --target zh-Hans: target language passed to the translation prompt.
  • --force-threshold 800: force level that confirms the Force Click.
  • --prefetch-threshold 300: lower force level used to prefetch selected text before macOS Lookup interferes.
  • --copy-delay 0.8: fallback delay before copying after release if prefetch misses.
  • --debug-force: print force frames and selection diagnostics.
  • --no-panel: disable the floating translation panel.
  • --no-menu-bar: disable the FC menu bar item.
  • --no-escape-before-copy: disable the fallback Escape key before copying.

API Key And Provider

ForceClickAI reads API keys in this order:

  1. FORCECLICKAI_API_KEY
  2. DEEPSEEK_API_KEY
  3. OPENAI_API_KEY
  4. macOS Keychain value saved by swift run ForceClickAI set-key

In app mode, use FC > API Key > Set API Key... to save the key to Keychain without using Terminal.

Keychain helpers:

swift run ForceClickAI set-key
swift run ForceClickAI key-status
swift run ForceClickAI delete-key

Provider configuration:

  • FORCECLICKAI_BASE_URL, default: https://api.deepseek.com
  • FORCECLICKAI_MODEL, default: deepseek-v4-flash

The default request uses /chat/completions and disables thinking mode for DeepSeek v4 translation models.

How It Works

The reliable path is:

  1. MultitouchSupport reports raw contact force from the built-in trackpad.
  2. When force crosses the prefetch threshold, ForceClickAI tries to capture the current selection while it is still intact.
  3. When force crosses the trigger threshold and then releases, ForceClickAI uses the prefetched text if available.
  4. If prefetch misses, it falls back to copying after release.
  5. The previous pasteboard contents are restored.
  6. The selected text is sent to the configured OpenAI-compatible API.
  7. The translation appears in the floating panel and in the terminal.

This prefetch step is the key design choice. Copying only after Force Click release is unreliable because macOS Lookup can change focus or selection state before the app gets a chance to copy.

Troubleshooting

If nothing happens:

swift run ForceClickAI private-run --target zh-Hans --force-threshold 800 --debug-force

Check whether force values cross the threshold. If not, lower the threshold:

swift run ForceClickAI private-run --target zh-Hans --force-threshold 700

If Force Click triggers but selected text is missed, lower prefetch threshold:

swift run ForceClickAI private-run --target zh-Hans --force-threshold 800 --prefetch-threshold 220 --debug-force

If copying fails in all apps, test the copy path directly:

swift run ForceClickAI copy-test --delay 3

If the .app does not respond, grant permissions to the app:

System Settings > Privacy & Security > Accessibility / Input Monitoring > ForceClickAI.app

Privacy

ForceClickAI runs locally, but translation requires sending selected text to the configured API provider.

The app does not intentionally store selected text. The last translation is kept in memory while the app is running so the menu bar item can copy it. API keys can be stored in macOS Keychain.

Roadmap

  • First-class menu bar app packaging.
  • More controls for copy timing, fallback behavior, and app-specific capture tuning.
  • Launch at login.
  • Better floating panel controls.
  • Optional direct replacement / paste-back workflow.
  • Better provider presets.
  • More robust app-specific selection capture.

License

MIT License. See LICENSE.

Disclaimer

ForceClickAI is an independent local utility and is not affiliated with Apple or DeepSeek. It uses private macOS APIs for local experimentation, so future macOS updates may break the force monitor.

About

macOS Force Click translator with selection prefetch, DeepSeek translation, Keychain storage, and a native floating result panel

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors