Keyboard Shortcuts

December 18, 2025 ยท View on GitHub

Centralized keyboard shortcut management using native DOM event listeners.

Current Shortcuts

ShortcutMacWindows/LinuxAction
Open PreferencesCmd+,Ctrl+,Opens settings dialog
Command PaletteCmd+KCtrl+KOpens command search
Toggle Left SidebarCmd+1Ctrl+1Show/hide left panel
Toggle Right SidebarCmd+2Ctrl+2Show/hide right panel

Architecture

All shortcuts are handled in src/hooks/useMainWindowEventListeners.ts:

export function useMainWindowEventListeners() {
  const commandContext = useCommandContext()

  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.metaKey || e.ctrlKey) {
        switch (e.key) {
          case ',': {
            e.preventDefault()
            commandContext.openPreferences()
            break
          }
          case '1': {
            e.preventDefault()
            const { leftSidebarVisible, setLeftSidebarVisible } =
              useUIStore.getState()
            setLeftSidebarVisible(!leftSidebarVisible)
            break
          }
        }
      }
    }

    document.addEventListener('keydown', handleKeyDown)
    return () => document.removeEventListener('keydown', handleKeyDown)
  }, [commandContext])
}

Critical: Use getState() to access store data in event handlers to avoid render cascades. See State Management.

Adding New Shortcuts

1. Add to event handler

// src/hooks/useMainWindowEventListeners.ts
case '3': {
  e.preventDefault()
  commandContext.myNewAction()
  break
}

2. Add to native menu (if applicable)

// src/lib/menu.ts
await MenuItem.new({
  id: 'my-action',
  text: t('menu.myAction'),
  accelerator: 'CmdOrCtrl+3',
  action: handleMyAction,
})

See Menus for full menu integration details.

Modifier Keys

// Cross-platform modifier (Cmd on Mac, Ctrl elsewhere)
if (e.metaKey || e.ctrlKey) {
}

// With Shift
if ((e.metaKey || e.ctrlKey) && e.shiftKey) {
}

// Function keys (no modifier needed)
if (e.key === 'F1') {
}

Always call e.preventDefault() to prevent browser defaults (like Cmd+, opening browser settings).

Why Native DOM Events

Native DOM event listeners are used instead of libraries like react-hotkeys-hook because they provide more reliable execution in the Tauri environment.

Conventions

PatternKeys
PreferencesCmd/Ctrl + ,
Search/CommandCmd/Ctrl + K
Panel togglesCmd/Ctrl + 1,2,3...
File operationsCmd/Ctrl + N,O,S
UndoCmd/Ctrl + Z
RedoCmd/Ctrl + Shift+Z

Troubleshooting

IssueCheck
Shortcuts not firinguseMainWindowEventListeners called in MainWindow
Browser intercepts shortcutAdd e.preventDefault()
Different behavior Mac vs WindowsTest e.metaKey || e.ctrlKey