"데스크톱 앱에서 단축키는 UX의 기본" — 메뉴의 accelerator와 globalShortcut의 차이를 이해하면 효과적인 단축키 시스템을 만들 수 있습니다.


두 가지 단축키 방식

방식범위앱이 포커스 필요용도
Menu accelerator앱 내부필요메뉴 연동 단축키
globalShortcut시스템 전체불필요캡처, 미디어 제어 등

accelerator (메뉴 단축키)

JAVASCRIPT
const { Menu } = require('electron');

const template = [
  {
    label: '파일',
    submenu: [
      {
        label: '새 파일',
        accelerator: 'CmdOrCtrl+N',
        click: () => createNewFile(),
      },
      {
        label: '저장',
        accelerator: 'CmdOrCtrl+S',
        click: () => saveFile(),
      },
      {
        label: '다른 이름으로 저장',
        accelerator: 'CmdOrCtrl+Shift+S',
        click: () => saveFileAs(),
      },
    ],
  },
];

Menu.setApplicationMenu(Menu.buildFromTemplate(template));

accelerator 문법

  • CmdOrCtrl: macOS에서는 Cmd, 다른 OS에서는 Ctrl
  • Alt, Shift, Super(Windows키)
  • Plus, Space, Tab, Backspace, Delete, Escape
  • F1 ~ F24
  • 조합: CmdOrCtrl+Shift+Z, Alt+F4

globalShortcut (전역 단축키)

앱이 포커스되지 않아도 동작하는 시스템 전역 단축키입니다.

JAVASCRIPT
const { app, globalShortcut } = require('electron');

app.whenReady().then(() => {
  // 전역 단축키 등록
  const registered = globalShortcut.register('CmdOrCtrl+Shift+Space', () => {
    console.log('전역 단축키가 눌렸습니다!');
    if (mainWindow.isVisible()) {
      mainWindow.hide();
    } else {
      mainWindow.show();
      mainWindow.focus();
    }
  });

  if (!registered) {
    console.log('단축키 등록 실패 — 이미 다른 앱이 사용 중일 수 있습니다');
  }

  // 등록 여부 확인
  console.log(
    globalShortcut.isRegistered('CmdOrCtrl+Shift+Space')
  );
});

// 앱 종료 시 반드시 해제
app.on('will-quit', () => {
  globalShortcut.unregisterAll();
});

주의사항

  • 다른 앱의 전역 단축키와 충돌할 수 있음
  • 앱 종료 시 반드시 unregisterAll() 호출
  • 시스템 단축키(Ctrl+C 등)를 가로채지 않도록 주의

렌더러에서 키보드 이벤트 처리

JAVASCRIPT
// 렌더러 — 웹 표준 방식
document.addEventListener('keydown', (e) => {
  // Ctrl+S (또는 Cmd+S)로 저장
  if ((e.ctrlKey || e.metaKey) && e.key === 's') {
    e.preventDefault();
    window.electronAPI.saveFile();
  }

  // Ctrl+Shift+P로 커맨드 팔레트
  if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === 'P') {
    e.preventDefault();
    openCommandPalette();
  }
});

실전: 커스텀 단축키 설정

JAVASCRIPT
// 사용자가 단축키를 커스터마이징할 수 있게
class ShortcutManager {
  constructor(configPath) {
    this.shortcuts = this.loadConfig(configPath);
  }

  loadConfig(configPath) {
    const defaults = {
      'newFile': 'CmdOrCtrl+N',
      'save': 'CmdOrCtrl+S',
      'find': 'CmdOrCtrl+F',
      'toggleSidebar': 'CmdOrCtrl+B',
    };

    try {
      const saved = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
      return { ...defaults, ...saved };
    } catch {
      return defaults;
    }
  }

  buildMenuTemplate(actions) {
    return Object.entries(this.shortcuts).map(([action, accelerator]) => ({
      label: actions[action].label,
      accelerator,
      click: actions[action].handler,
    }));
  }
}

면접 포인트 정리

  • accelerator는 앱 포커스 시에만, globalShortcut은 시스템 전역
  • CmdOrCtrl은 크로스플랫폼 호환을 위한 필수 키워드
  • globalShortcut은 앱 종료 시 반드시 unregisterAll() 호출
  • 시스템 단축키와의 충돌을 항상 고려해야 함

단축키를 설정했으면, 다음은 알림(Notification)을 구현해봅시다.

댓글 로딩 중...