- Hold-to-Quit — Cmd+Q is intercepted and requires a configurable hold (0.5s–3s) before the quit goes through
- Progress Ring — Small green circular indicator appears at your cursor showing hold duration
- Protected Apps — Default protection for Safari, Chrome, Arc, Firefox, Finder, Mail, Messages, Slack, VS Code, Xcode
- Protect All Apps — Toggle to require hold-to-quit for every app
- Add/Remove Apps — Add from running apps, remove with one click
- Sound Feedback — Subtle sound when a quit is prevented
- Launch at Login — Start automatically with macOS
- Menu Bar Only — No dock icon, minimal footprint
- macOS 13.0+ (Ventura)
- Swift 5.9+
- Accessibility permission (prompted on first launch)
git clone https://github.com/markksantos/Grip.git
cd Grip
./bundle.sh
cp -r Grip.app /Applications/Or build and run directly:
swift build
open .build/debug/GripAppGrip requires Accessibility permission to intercept Cmd+Q before it reaches apps. macOS will prompt you on first launch, or grant it manually in System Settings → Privacy & Security → Accessibility.
| Category | Technology |
|---|---|
| Language | Swift 5.9+ |
| UI | SwiftUI, AppKit |
| Event Handling | CGEventTap |
| Persistence | UserDefaults |
| Platform | macOS 13+ (Ventura) |
Grip/
├── Sources/
│ ├── GripApp/
│ │ └── GripApp.swift # App entry point with MenuBarExtra
│ ├── GripEngine/
│ │ └── QuitInterceptor.swift # CGEvent tap, hold timer, synthetic quit
│ └── GripUI/
│ ├── MenuBarView.swift # Popover with toggles, app list, slider
│ ├── ProgressRing.swift # Always-on-top ring overlay at cursor
│ └── SettingsView.swift # Launch at login toggle
├── Tests/
│ └── GripTests/
│ └── QuitInterceptorTests.swift
├── bundle.sh # Build release .app bundle
├── init.sh # Build and run
└── Package.swift
MIT License © 2025 Mark Santos