Skip to content

fix(desktop): show platform-specific hotkey symbols#348

Closed
saddlepaddle wants to merge 1 commit intomainfrom
fix/hotkey-display-platform-specific
Closed

fix(desktop): show platform-specific hotkey symbols#348
saddlepaddle wants to merge 1 commit intomainfrom
fix/hotkey-display-platform-specific

Conversation

@saddlepaddle
Copy link
Copy Markdown
Collaborator

@saddlepaddle saddlepaddle commented Dec 13, 2025

Summary

  • Shows platform-appropriate modifier key symbols in keyboard shortcuts UI
    • Mac: ⌘ ⌃ ⌥ ⇧
    • Windows: Win Ctrl Alt Shift
    • Linux: Super Ctrl Alt Shift
  • Refactors hotkey system to pre-compute .display at build time using PLATFORM constants
  • Removes formatKeysForDisplay export and useIsMac hook - consuming code now just uses HOTKEYS.X.display
  • Centralizes all platform detection logic in hotkeys.ts

Replaces #346 with a cleaner implementation that uses existing infrastructure (PLATFORM constants) instead of runtime navigator.userAgent parsing.

Test plan

  • Verify Mac shows ⌘ ⌃ ⌥ ⇧ symbols
  • Verify Windows shows Win/Ctrl/Alt/Shift text
  • Verify Linux shows Super/Ctrl/Alt/Shift text
  • Check keyboard shortcuts settings page
  • Check tooltips (sidebar toggle, settings button, help menu)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Refactor
    • Centralized and standardized keyboard shortcut definitions and display handling so modifier keys and workspace jump labels render consistently across platforms. No visible changes to UI text or shortcut behavior for end users.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 13, 2025

Walkthrough

Replaces runtime hotkey formatting with precomputed display arrays in the shared HOTKEYS config and updates UI components to read hotkey.display. Adds formatKeys and hotkey helpers, a new HotkeyWithDisplay type, and removes the old formatKeysForDisplay usage across several components.

Changes

Cohort / File(s) Summary
Hotkeys core configuration
apps/desktop/src/shared/hotkeys.ts
Adds platform modifier mapping and KEY_MAP; introduces formatKeys() and hotkey() to compute a display: string[] for each hotkey; exports HotkeyWithDisplay; updates getHotkeysByCategory() to return display-bearing hotkeys; removes formatKeysForDisplay.
Settings / Keyboard shortcuts UI
apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx
Replaces runtime mac/isMac logic with HOTKEYS.*.display; HotkeyRow and consolidateWorkspaceJumps now accept/return HotkeyWithDisplay and use hotkey.display for rendering and meta-key composition.
TopBar components
apps/desktop/src/renderer/screens/main/components/TopBar/{HelpMenu.tsx,SettingsButton.tsx,SidebarControl.tsx}
Removes formatKeysForDisplay imports and local formatting; components now iterate HOTKEYS.<...>.display to render key badges.
Workspace / Empty tab view
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/EmptyTabView.tsx
Uses shortcut.display for rendering shortcut keys instead of calling formatKeysForDisplay.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

  • Review hotspots:
    • apps/desktop/src/shared/hotkeys.ts — verify formatKeys logic, platform modifier mapping, and that existing matchers (matchesHotkey, findMatchingHotkey, isAppHotkey) remain correct with new types.
    • KeyboardShortcutsSettings.tsx — confirm consolidateWorkspaceJumps preserves expected displays and meta-key assignment.
    • TopBar and EmptyTabView components — ensure rendering of display arrays matches previous visuals.

Possibly related PRs

Poem

🐰 I hopped through keys and mapped each sign,

From runtime tricks to display by design.
No extra calls at render time, hooray—
Now shortcuts bloom from config's array.
A tiny rabbit cheers the new, neat way 🌿

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(desktop): show platform-specific hotkey symbols' accurately describes the main change: updating keyboard shortcuts to display platform-appropriate modifier symbols.
Description check ✅ Passed The PR description covers the key aspects: what changed (platform-specific symbols), how it was implemented (pre-computed display at build time), what was removed (formatKeysForDisplay and useIsMac), and includes a test plan with checkboxes.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/hotkey-display-platform-specific

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e6188f3 and 188c470.

📒 Files selected for processing (6)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx (6 hunks)
  • apps/desktop/src/renderer/screens/main/components/TopBar/HelpMenu/HelpMenu.tsx (2 hunks)
  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx (2 hunks)
  • apps/desktop/src/renderer/screens/main/components/TopBar/SidebarControl.tsx (2 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/EmptyTabView.tsx (2 hunks)
  • apps/desktop/src/shared/hotkeys.ts (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/EmptyTabView.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/SidebarControl.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/HelpMenu/HelpMenu.tsx
🧰 Additional context used
📓 Path-based instructions (6)
apps/desktop/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc

Files:

  • apps/desktop/src/shared/hotkeys.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: Please use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary

Files:

  • apps/desktop/src/shared/hotkeys.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Use Biome for code formatting and linting, running at root level for speed

Files:

  • apps/desktop/src/shared/hotkeys.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Avoid any type and prioritize type safety in TypeScript code

Files:

  • apps/desktop/src/shared/hotkeys.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx
**/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/components/**/*.{ts,tsx}: Structure project folders as one folder per component with PascalCase naming (ComponentName/ComponentName.tsx + index.ts barrel export)
Co-locate component dependencies (utils, hooks, constants, config, tests, stories) next to the file using them
Use one component per file (no multi-component files)

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx
apps/desktop/src/renderer/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Call IPC methods from renderer process using window.ipcRenderer.invoke with type-safe object parameters

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx
🧠 Learnings (1)
📚 Learning: 2025-11-24T21:33:13.267Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.267Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Please use alias as defined in `tsconfig.json` when possible

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx
🧬 Code graph analysis (1)
apps/desktop/src/shared/hotkeys.ts (1)
apps/desktop/src/shared/constants.ts (1)
  • PLATFORM (5-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Deploy Admin
  • GitHub Check: Deploy Web
  • GitHub Check: Deploy Docs
  • GitHub Check: Deploy API
  • GitHub Check: Deploy Marketing
  • GitHub Check: Build
🔇 Additional comments (11)
apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx (4)

5-10: LGTM! Clean imports using proper alias.

Imports correctly use the shared/hotkeys alias as defined in tsconfig.json, and properly import the new HotkeyWithDisplay type and HOTKEYS constant. Based on learnings, alias usage is preferred.


20-41: LGTM! Component correctly uses the new HotkeyWithDisplay type.

The HotkeyRow component is cleanly refactored to use the pre-computed display array. The implementation is straightforward and type-safe.


46-67: Clean consolidation logic with consistent platform-specific symbols.

Good approach to reuse the meta key symbol from an existing hotkey's display property, ensuring the consolidated "1-9" entry matches the platform-specific modifier used elsewhere.


69-97: LGTM! Correct usage of pre-computed display data.

The component properly extracts the modifier key from HOTKEYS.SHOW_HOTKEYS.display for the help text, maintaining consistency with the platform-specific symbols.

apps/desktop/src/shared/hotkeys.ts (7)

6-28: Well-structured platform-specific key mapping.

The MODIFIER_MAP correctly implements platform-specific symbols as specified in the PR objectives, and KEY_MAP cleanly extends it with common special keys. Good use of the centralized PLATFORM constants.


30-36: LGTM! Clean key formatting logic.

The function correctly maps key strings to display arrays using KEY_MAP with a sensible fallback to uppercase for unmapped keys.


38-41: Nice helper pattern for type-safe hotkey definition.

The generic hotkey helper preserves the input type while adding the display property, enabling good type inference throughout the codebase.


50-59: Interface definition is clear and well-documented.


65-205: LGTM! Consistent hotkey definitions with proper type constraints.

The use of as const satisfies Record<string, HotkeyDefinition & { display: string[] }> is excellent—it preserves literal types for HotkeyId while ensuring all entries conform to the expected shape.


207-231: LGTM! Clean type export and updated function signature.

The HotkeyWithDisplay type is correctly exported for consumer components, and getHotkeysByCategory properly returns the enriched type.


233-299: Good encapsulation—internal helpers are now private.

matchesHotkey and findMatchingHotkey are correctly kept as module-private functions, with only isAppHotkey exposed as the public API for hotkey matching.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Dec 13, 2025

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

Service Status
Neon Database (Neon)

Thank you for your contribution! 🎉


Preview resources have been processed for cleanup

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx (1)

20-21: Consider exporting HotkeyWithDisplay from shared/hotkeys.ts to avoid duplication.

The HotkeyWithDisplay type mirrors the shape defined in hotkeys.ts via the satisfies clause. Exporting this type from the shared module would centralize the definition and ensure consistency.

// In apps/desktop/src/shared/hotkeys.ts, add:
+export type HotkeyWithDisplay = HotkeyDefinition & { display: string[] };

// Then in KeyboardShortcutsSettings.tsx:
-type HotkeyWithDisplay = HotkeyDefinition & { display: string[] };
+import {
+	getHotkeysByCategory,
+	HOTKEYS,
+	type HotkeyCategory,
+	type HotkeyDefinition,
+	type HotkeyWithDisplay,
+} from "shared/hotkeys";
apps/desktop/src/shared/hotkeys.ts (1)

6-6: Consider using path alias if available.

The coding guidelines recommend using aliases as defined in tsconfig.json when possible. If an alias exists for the shared directory (e.g., @shared/constants), consider using it instead of the relative path.

Apply this diff if an alias is available:

-import { PLATFORM } from "./constants";
+import { PLATFORM } from "@shared/constants";
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3de53d0 and e6188f3.

📒 Files selected for processing (6)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx (6 hunks)
  • apps/desktop/src/renderer/screens/main/components/TopBar/HelpMenu/HelpMenu.tsx (2 hunks)
  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx (2 hunks)
  • apps/desktop/src/renderer/screens/main/components/TopBar/SidebarControl.tsx (2 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/EmptyTabView.tsx (2 hunks)
  • apps/desktop/src/shared/hotkeys.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
apps/desktop/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc

Files:

  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx
  • apps/desktop/src/shared/hotkeys.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/EmptyTabView.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/HelpMenu/HelpMenu.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/SidebarControl.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: Please use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary

Files:

  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx
  • apps/desktop/src/shared/hotkeys.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/EmptyTabView.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/HelpMenu/HelpMenu.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/SidebarControl.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Use Biome for code formatting and linting, running at root level for speed

Files:

  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx
  • apps/desktop/src/shared/hotkeys.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/EmptyTabView.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/HelpMenu/HelpMenu.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/SidebarControl.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Avoid any type and prioritize type safety in TypeScript code

Files:

  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx
  • apps/desktop/src/shared/hotkeys.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/EmptyTabView.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/HelpMenu/HelpMenu.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/SidebarControl.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx
**/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/components/**/*.{ts,tsx}: Structure project folders as one folder per component with PascalCase naming (ComponentName/ComponentName.tsx + index.ts barrel export)
Co-locate component dependencies (utils, hooks, constants, config, tests, stories) next to the file using them
Use one component per file (no multi-component files)

Files:

  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/EmptyTabView.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/HelpMenu/HelpMenu.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/SidebarControl.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx
apps/desktop/src/renderer/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Call IPC methods from renderer process using window.ipcRenderer.invoke with type-safe object parameters

Files:

  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/EmptyTabView.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/HelpMenu/HelpMenu.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/SidebarControl.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx
🧠 Learnings (1)
📚 Learning: 2025-11-24T21:33:13.267Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.267Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Please use alias as defined in `tsconfig.json` when possible

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx
🧬 Code graph analysis (4)
apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx (1)
apps/desktop/src/shared/hotkeys.ts (1)
  • HOTKEYS (65-205)
apps/desktop/src/renderer/screens/main/components/TopBar/HelpMenu/HelpMenu.tsx (1)
apps/desktop/src/shared/hotkeys.ts (1)
  • HOTKEYS (65-205)
apps/desktop/src/renderer/screens/main/components/TopBar/SidebarControl.tsx (1)
apps/desktop/src/shared/hotkeys.ts (1)
  • HOTKEYS (65-205)
apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx (1)
apps/desktop/src/shared/hotkeys.ts (2)
  • HotkeyDefinition (50-59)
  • HOTKEYS (65-205)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Deploy Web
  • GitHub Check: Deploy Marketing
  • GitHub Check: Deploy Admin
  • GitHub Check: Deploy Docs
  • GitHub Check: Deploy API
  • GitHub Check: Build
🔇 Additional comments (10)
apps/desktop/src/renderer/screens/main/components/TopBar/SidebarControl.tsx (1)

32-34: LGTM!

Clean refactor that aligns with the data-driven hotkey display approach. The import uses the correct alias as per tsconfig.json.

One minor note: using key as the React key assumes display arrays never contain duplicate entries. This is a safe assumption for typical hotkey combinations.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/EmptyTabView.tsx (1)

3-5: LGTM!

The refactor correctly uses shortcut.display directly from the HOTKEYS configuration. The iteration pattern is consistent with other components in this PR.

Also applies to: 20-22

apps/desktop/src/renderer/screens/main/components/TopBar/HelpMenu/HelpMenu.tsx (1)

19-19: LGTM!

Clean simplification that removes the formatKeysForDisplay dependency and directly uses the pre-computed display array from HOTKEYS.SHOW_HOTKEYS.

Also applies to: 76-78

apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx (1)

5-5: LGTM!

Consistent refactor that aligns with the other components. The Settings button correctly displays the SHOW_HOTKEYS shortcut in its tooltip.

Also applies to: 26-28

apps/desktop/src/renderer/screens/main/components/SettingsView/KeyboardShortcutsSettings.tsx (2)

59-66: LGTM!

Good approach to extract the platform-specific meta key symbol from an existing hotkey's display array. This ensures the consolidated "1-9" shortcut displays correctly across all platforms without hardcoding symbols.


78-80: No action needed. The type safety is correct: getHotkeysByCategory() returns Record<HotkeyCategory, HotkeyWithDisplay[]>, and hotkeysByCategory[category] properly resolves to HotkeyWithDisplay[], which matches the expected parameter type for consolidateWorkspaceJumps(hotkeys: HotkeyWithDisplay[]). The display field is guaranteed by the HotkeyWithDisplay type.

apps/desktop/src/shared/hotkeys.ts (4)

30-41: LGTM! Clean pre-computation design.

The formatKeys helper and hotkey wrapper provide an elegant solution for pre-computing display strings at module load time. The generic type preservation in hotkey<T> ensures type safety while augmenting the definition with the display field.


65-205: Excellent use of as const satisfies pattern.

The consistent wrapping of all hotkey definitions with hotkey() ensures every entry gets a pre-computed display field. The type assertion as const satisfies Record<string, HotkeyDefinition & { display: string[] }> at line 205 provides both immutability and type safety, guaranteeing that all entries conform to the expected shape at compile time.


209-231: Type-safe category grouping.

The introduction of HotkeyWithDisplay and the updated getHotkeysByCategory signature correctly reflect that all hotkeys now include the pre-computed display field. The implementation maintains type safety while preserving the existing grouping logic.


9-13: PLATFORM constants are properly available at module load time.

PLATFORM is statically defined in src/shared/constants.ts using process.platform comparisons, which are synchronously available during module evaluation. No async initialization is required, and MODIFIER_MAP can safely be computed at module load time.

- Mac: ⌘ ⌃ ⌥ ⇧
- Windows: Win Ctrl Alt Shift
- Linux: Super Ctrl Alt Shift

Refactored hotkey system to pre-compute display symbols at build time
using PLATFORM constants instead of runtime navigator parsing. This:

- Adds `.display` property to all HOTKEYS entries
- Removes `formatKeysForDisplay` export (now internal)
- Removes `useIsMac` hook from components
- Centralizes all platform logic in hotkeys.ts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@JakeRoggenbuck
Copy link
Copy Markdown
Contributor

Works on Linux!

image

@saddlepaddle
Copy link
Copy Markdown
Collaborator Author

Thanks for checking! Closing this one in favor of one with shared credit at #353

@Kitenite Kitenite deleted the fix/hotkey-display-platform-specific branch December 13, 2025 20:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants