mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-08-11 09:34:45 +00:00
Closes #918. The renderer's keydown handler required event.metaKey and explicitly rejected event.ctrlKey, so every shortcut was dead outside macOS: on Windows and Linux metaKey is the Super key, which the OS shell takes. Navigation (1-8), Settings (,) and Refresh (R) all did nothing. The sidebar and footer hints also hardcoded the Cmd glyph, so a Windows user was shown chords that could not fire. Add app/renderer/lib/platform.ts as the single source of truth for platform-aware shortcuts, reading the platform the preload already exposes (window.codeburn.platform) with a user-agent fallback for the non-Electron cases. isModifierChord accepts Cmd-without-Ctrl on darwin and Ctrl-without-Cmd elsewhere; altKey stays rejected on both, because AltGr on European Windows layouts arrives as Ctrl+Alt and must not hijack a typed character. Every visible shortcut label now resolves through shortcutLabel() at render time, so the sidebar shows Ctrl+1 where macOS shows the Cmd glyph. The mac chord condition is unchanged: the old guard admitted metaKey && !altKey && !ctrlKey && !shiftKey, and the new one admits exactly the same set on darwin. The Electron application menu is deliberately left alone. It ships no reload/forceReload role and no CmdOrCtrl+R accelerator, which is what leaves Ctrl+R free for the renderer to handle on Windows. Also corrects the Settings navigation hint, which read 1-7 while the sidebar has eight numbered destinations. Tests cover both platforms for labels and dispatch, including the negatives: Meta on win32, Ctrl on darwin, and the Ctrl+Alt AltGr shape.
46 lines
2 KiB
TypeScript
46 lines
2 KiB
TypeScript
// Single source of truth for platform-aware shortcut behaviour. The preload
|
|
// exposes `window.codeburn.platform` (process.platform); when the bridge is
|
|
// absent (unit tests, vite in a plain browser) fall back to the user agent.
|
|
// All functions read platform state at call time, never at module load, so
|
|
// the preload bridge may appear after this module is imported.
|
|
|
|
function bridgePlatform(): string | undefined {
|
|
if (typeof window === 'undefined') return undefined
|
|
return (window as unknown as { codeburn?: { platform?: string } }).codeburn?.platform
|
|
}
|
|
|
|
function userAgentPlatform(): string | undefined {
|
|
if (typeof navigator === 'undefined') return undefined
|
|
if (/mac/i.test(navigator.userAgent)) return 'darwin'
|
|
const platform = navigator.platform
|
|
if (typeof platform === 'string' && /mac/i.test(platform)) return 'darwin'
|
|
return undefined
|
|
}
|
|
|
|
/** True when the Electron preload reports darwin (or the UA matches a Mac). */
|
|
export function isMacPlatform(): boolean {
|
|
const platform = bridgePlatform()
|
|
if (platform) return platform === 'darwin'
|
|
return userAgentPlatform() === 'darwin'
|
|
}
|
|
|
|
/** The modifier keycap label: '⌘' on mac, 'Ctrl+' elsewhere. */
|
|
export function modKeyLabel(): string {
|
|
return isMacPlatform() ? '⌘' : 'Ctrl+'
|
|
}
|
|
|
|
/** A full shortcut label, e.g. '⌘R' on mac, 'Ctrl+R' on Windows. */
|
|
export function shortcutLabel(key: string): string {
|
|
return modKeyLabel() + key
|
|
}
|
|
|
|
/**
|
|
* True when the event is the platform's modifier chord and no other modifier
|
|
* is held. On mac: Meta (Cmd) without Ctrl. Elsewhere: Ctrl without Meta.
|
|
* altKey stays rejected on every platform: AltGr on European layouts arrives
|
|
* as Ctrl+Alt, and Ctrl+Alt+<key> must not hijack a typed character.
|
|
*/
|
|
export function isModifierChord(event: { metaKey: boolean; ctrlKey: boolean; altKey: boolean; shiftKey: boolean }): boolean {
|
|
if (event.altKey || event.shiftKey) return false
|
|
return isMacPlatform() ? event.metaKey && !event.ctrlKey : event.ctrlKey && !event.metaKey
|
|
}
|