fix(macos): platform-aware keyboard shortcuts, native traffic lights & error resilience (#114)
* feat(keyboard): platform-aware modifier system (Phase 1) - New src/renderer/lib/platform.ts: isMac, isWindows, getPlatformModifier, isPlatformModifier helpers - normalizeKeyEvent: separate ctrlKey→'ctrl' and metaKey→'cmd' (was conflating both to 'ctrl') - matchesShortcut: macOS cross-modifier aliasing (cmd+k matches ctrl+k config) - formatKeyForDisplay: 'cmd' token renders as ⌘ on macOS, 'ctrl' as ⌃ - Backward compatible: existing 'ctrl+...' config entries work on all platforms - Tests updated for new behavior * fix(keyboard): hardcoded shortcuts now use platform modifier (Phase 2) - Ctrl+S/Save, Ctrl+B/File explorer: use isPlatformModifier (⌘ on macOS, Ctrl on Windows) - Ctrl+W/Close tab: macOS uses ⌘+W, Ctrl+W in terminal passes through to shell (backward-kill-word) - Project switch (Ctrl/Cmd+1-9): already worked, unchanged - Fixes: ⌘+S, ⌘+W, ⌘+B now work on macOS - Fixes: Ctrl+W in terminal no longer intercepted on macOS - Use ref for handleCloseTerminal to avoid declaration-order TS error * fix(terminal): macOS copy/paste convention + Ctrl passthrough (Phase 3) - Clipboard operations (copy/paste/select-all) use platform modifier: macOS: ⌘+C/V/A, Windows/Linux: Ctrl+C/V/A - Ctrl+C without selection still sends SIGINT on all platforms - On macOS terminal, Ctrl+key shortcuts pass through to shell: Ctrl+R → reverse-i-search (not intercepted by app command history) Ctrl+W → backward-kill-word (not intercepted by close tab) - ⌘+key shortcuts still intercepted by app as expected * feat(ui): add React ErrorBoundary at root and per-pane level (Phase 4a) - New ErrorBoundary component with default fallback UI and retry button - ErrorFallback in separate file (react-refresh compliance) - Wraps entire app root in TauriApp to prevent blank screen on crash - Wraps each PaneContent in PaneRenderer to isolate pane-level errors - Catches WebGL terminal crashes, browser webview mount errors, etc. - Logs error + component stack to console for debugging * fix(macos): Alt/Option key no longer intercepted on macOS (Phase 4b) - usePreventAltMenu now only activates on Windows - On macOS, Alt/Option is needed for typing special characters (@, €, £, etc.) - Fixes inability to type special chars in terminals and editors on macOS * chore(logging): improve default log levels for debug/release (Phase 4d) - Debug builds: default to 'debug' level - Release builds: default to 'warn' level - Both overridable via RUST_LOG env var - File-based logging deferred to v0.4.1 (requires fern/log4rs crate) * test: update clipboard test for platform-aware modifier - Test now uses platform-appropriate modifier (Ctrl on non-mac, Cmd on mac) - Fixes test failure in jsdom where isMac=false and metaKey is not the clipboard modifier * feat(keyboard): make close tab, save file, and file explorer shortcuts customizable - Add closeTab (Ctrl+W), saveFile (Ctrl+S), toggleFileExplorer (Ctrl+B) to DEFAULT_KEYBOARD_SHORTCUTS — now user-customizable via settings - Replace hardcoded key checks in WorkspaceLayout with matchesShortcut() - macOS Ctrl+W terminal passthrough still works (isMac check preserved) - Update test mock to include new shortcut entries * feat(macos): native traffic lights via Rust setup hook - In Rust setup (#[cfg(target_os = "macos")]): set_decorations(true) + set_title_bar_style(Overlay) before window is shown - TitleBar.tsx: hide custom minimize/maximize/close on macOS - Add 70px left spacer for native traffic lights on macOS - Windows/Linux: custom window controls unchanged - Rust compile clean, all 920 tests pass * fix: CodeRabbit review fixes + browser tab panic CodeRabbit findings: - lib.rs: log decoration/titlebar setup failures instead of swallowing - lib.rs: remove redundant `use tauri::Manager` (already in scope) - matchesShortcut: reject ctrl+... on macOS before exact-match check, preventing double-fire (shell passthrough + app shortcut) on macOS - tests: add shell passthrough guard test, split platform branches Browser tab panic: - Replace `tokio::spawn` with `tauri::async_runtime::spawn` in ExitRequested handler — the run callback fires on threads without a Tokio reactor (e.g. macOS WKWebView delegate threads)
A
Anaz S. Aji committed
592ddeb06379007c7a72e478fe4af32e19ffe4d4
Parent: afcbb35
Committed by GitHub <noreply@github.com>
on 5/7/2026, 5:02:58 AM