BrowserWindow 완전 정복 — 옵션, 이벤트, 생명주기
"BrowserWindow는 Electron 앱의 창 그 자체" — 크기, 위치, 프레임, 투명도까지 데스크톱 앱다운 UI를 만들려면 이 API를 잘 다뤄야 합니다.
BrowserWindow 기본 생성
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: false와 ready-to-show 이벤트 조합은 창이 뜨기 전 흰 화면이 깜빡이는 것을 방지하는 필수 패턴입니다.
주요 생성 옵션
크기와 위치
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, // 이동 가능 여부
});
외형 옵션
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: 블러 효과
});
동작 옵션
const win = new BrowserWindow({
alwaysOnTop: false, // 항상 위에 표시
fullscreen: false, // 전체 화면
fullscreenable: true, // 전체 화면 전환 가능 여부
skipTaskbar: false, // 작업표시줄에 표시 안 함
closable: true, // 닫기 가능 여부
minimizable: true, // 최소화 가능 여부
maximizable: true, // 최대화 가능 여부
focusable: true, // 포커스 가능 여부
});
윈도우 이벤트
BrowserWindow는 다양한 이벤트를 발생시킵니다. 주요 이벤트를 정리합니다.
// 닫기 이벤트 — 저장 확인 다이얼로그를 띄울 수 있음
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('전체 화면 해제'));
윈도우 상태 저장/복원
사용자가 앱을 다시 열었을 때 이전 크기와 위치를 기억하는 패턴입니다.
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;
}
윈도우 조작 메서드
// 크기 변경
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(); // 강제 닫기 (이벤트 없음)
부모-자식 윈도우
// 부모 윈도우
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를 깊이 알아볼 차례입니다.
댓글 로딩 중...