"BrowserWindow는 Electron 앱의 창 그 자체" — 크기, 위치, 프레임, 투명도까지 데스크톱 앱다운 UI를 만들려면 이 API를 잘 다뤄야 합니다.


BrowserWindow 기본 생성

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

const win = new BrowserWindow({
  width: 1200,          // 창 너비
  height: 800,          // 창 높이
  minWidth: 400,        // 최소 너비
  minHeight: 300,       // 최소 높이
  title: '내 앱',       // 타이틀바 텍스트
  icon: 'assets/icon.png',  // 앱 아이콘
  show: false,          // 준비될 때까지 숨김
  webPreferences: {
    preload: path.join(__dirname, 'preload.js'),
    contextIsolation: true,
    nodeIntegration: false,
  },
});

// 콘텐츠가 준비되면 보여주기 — 깜빡임 방지
win.once('ready-to-show', () => {
  win.show();
});

win.loadFile('index.html');

show: falseready-to-show 이벤트 조합은 창이 뜨기 전 흰 화면이 깜빡이는 것을 방지하는 필수 패턴입니다.


주요 생성 옵션

크기와 위치

JAVASCRIPT
const win = new BrowserWindow({
  width: 1200,
  height: 800,
  x: 100,              // 화면 왼쪽에서의 위치
  y: 100,              // 화면 위에서의 위치
  center: true,         // 화면 중앙에 배치 (x, y보다 우선)
  minWidth: 600,
  minHeight: 400,
  maxWidth: 1920,
  maxHeight: 1080,
  resizable: true,      // 크기 조절 가능 여부
  movable: true,        // 이동 가능 여부
});

외형 옵션

JAVASCRIPT
const win = new BrowserWindow({
  frame: true,           // false면 타이틀바 없는 프레임리스 윈도우
  titleBarStyle: 'hiddenInset',  // macOS 전용: 타이틀바 스타일
  transparent: false,    // 투명 윈도우
  opacity: 1.0,          // 불투명도 (0.0 ~ 1.0)
  roundedCorners: true,  // macOS: 둥근 모서리
  backgroundColor: '#ffffff',  // 배경색
  vibrancy: 'sidebar',  // macOS: 블러 효과
});

동작 옵션

JAVASCRIPT
const win = new BrowserWindow({
  alwaysOnTop: false,    // 항상 위에 표시
  fullscreen: false,     // 전체 화면
  fullscreenable: true,  // 전체 화면 전환 가능 여부
  skipTaskbar: false,    // 작업표시줄에 표시 안 함
  closable: true,        // 닫기 가능 여부
  minimizable: true,     // 최소화 가능 여부
  maximizable: true,     // 최대화 가능 여부
  focusable: true,       // 포커스 가능 여부
});

윈도우 이벤트

BrowserWindow는 다양한 이벤트를 발생시킵니다. 주요 이벤트를 정리합니다.

JAVASCRIPT
// 닫기 이벤트 — 저장 확인 다이얼로그를 띄울 수 있음
win.on('close', (event) => {
  if (hasUnsavedChanges) {
    event.preventDefault();  // 닫기 차단
    dialog.showMessageBox(win, {
      type: 'question',
      buttons: ['저장', '저장 안 함', '취소'],
      message: '저장하지 않은 변경사항이 있습니다.',
    }).then(({ response }) => {
      if (response === 0) saveAndClose();
      if (response === 1) win.destroy();  // 강제 닫기
      // 2(취소)면 아무것도 안 함
    });
  }
});

// 윈도우가 닫힌 후
win.on('closed', () => {
  // 참조 정리
  mainWindow = null;
});

// 포커스/블러
win.on('focus', () => console.log('윈도우에 포커스'));
win.on('blur', () => console.log('포커스를 잃음'));

// 크기 변경
win.on('resize', () => {
  const [width, height] = win.getSize();
  console.log(`새 크기: ${width}x${height}`);
});

// 이동
win.on('move', () => {
  const [x, y] = win.getPosition();
  console.log(`새 위치: ${x}, ${y}`);
});

// 최대화/최소화
win.on('maximize', () => console.log('최대화됨'));
win.on('unmaximize', () => console.log('최대화 해제'));
win.on('minimize', () => console.log('최소화됨'));
win.on('restore', () => console.log('복원됨'));

// 전체 화면
win.on('enter-full-screen', () => console.log('전체 화면'));
win.on('leave-full-screen', () => console.log('전체 화면 해제'));

윈도우 상태 저장/복원

사용자가 앱을 다시 열었을 때 이전 크기와 위치를 기억하는 패턴입니다.

JAVASCRIPT
const Store = require('electron-store');
const store = new Store();

function createWindow() {
  // 저장된 상태 불러오기
  const bounds = store.get('windowBounds', {
    width: 1200,
    height: 800,
  });

  const win = new BrowserWindow({
    ...bounds,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
    },
  });

  // 크기/위치 변경 시 저장
  win.on('resized', () => {
    store.set('windowBounds', win.getBounds());
  });

  win.on('moved', () => {
    store.set('windowBounds', win.getBounds());
  });

  return win;
}

윈도우 조작 메서드

JAVASCRIPT
// 크기 변경
win.setSize(1024, 768);
win.setMinimumSize(400, 300);

// 위치 변경
win.setPosition(100, 100);
win.center();

// 표시/숨김
win.show();
win.hide();
win.focus();

// 최대화/최소화
win.maximize();
win.minimize();
win.restore();

// 전체 화면
win.setFullScreen(true);

// 항상 위에
win.setAlwaysOnTop(true);

// 제목 변경
win.setTitle('새 제목');

// 진행률 표시 (작업표시줄)
win.setProgressBar(0.5);  // 0.0 ~ 1.0, -1로 제거

// 윈도우 닫기
win.close();     // close 이벤트 발생 (차단 가능)
win.destroy();   // 강제 닫기 (이벤트 없음)

부모-자식 윈도우

JAVASCRIPT
// 부모 윈도우
const parent = new BrowserWindow({ width: 800, height: 600 });

// 자식 윈도우 — 부모 위에 표시됨
const child = new BrowserWindow({
  parent: parent,      // 부모 설정
  modal: true,         // 모달 윈도우 (부모 조작 차단)
  width: 400,
  height: 300,
  show: false,
});

child.once('ready-to-show', () => child.show());
child.loadFile('dialog.html');

modal: true로 설정하면 자식 윈도우가 열려 있는 동안 부모 윈도우를 클릭할 수 없습니다. 설정 화면이나 확인 다이얼로그에 유용합니다.


면접 포인트 정리

  • show: false + ready-to-show 패턴은 깜빡임 방지의 기본
  • close 이벤트에서 event.preventDefault()로 닫기를 차단할 수 있음
  • destroy()는 이벤트 없이 강제 닫기, close()는 이벤트 발생
  • 윈도우 상태(크기/위치) 저장은 UX의 기본
  • parent + modal로 모달 다이얼로그 구현 가능

BrowserWindow의 옵션을 이해했으면, 다음은 preload 스크립트와 contextBridge를 깊이 알아볼 차례입니다.

댓글 로딩 중...