Electron 빌드에서 전체화면이 적용되지 않을 때 점검할 항목
Electron 게임에서 설정 UI는 전체화면을 켰다고 표시하지만, 실제 창이 1920×1080 크기의 borderless 창으로 좌측 상단에 남는 경우가 있습니다. 이 문제는 HTML Fullscreen API보다 BrowserWindow의 상태와 창 설정 호출 순서를 먼저 확인해야 합니다.
이 글은 Windows의 2560×1440 화면에서 실제로 확인한 진단 흐름을 정리한 것입니다. 핵심은 추측으로 옵션을 바꾸지 않고, 요청 전후의 창 ID·bounds·전체화면 상태·모니터 배율을 함께 로그로 남기는 것입니다.
먼저 확인할 호출 목록
프로젝트 전체에서 아래 호출을 검색해 호출 위치와 실행 순서를 적어 두세요.
setFullScreen,setSize,setContentSize,setBounds,setContentBoundsmaximize,unmaximize,restore,center,setPositionfullscreen,fullscreenable,resizabledevicePixelRatio,scaleFactor,screenToDipRect,dipToScreenRect
렌더러의 THREE.WebGLRenderer.setSize()는 캔버스 해상도 조정용입니다. BrowserWindow의 setSize()와 이름은 비슷하지만, 서로 다른 계층의 호출입니다. 문제의 창 크기를 바꾸는 것은 메인 프로세스의 BrowserWindow API인지 먼저 구분하세요.
창 설정 적용을 한 곳으로 모으기
전체화면 직후에 setSize()나 center()가 실행되면 전체화면 상태를 덮어쓸 수 있습니다. 해상도 변경, 설정 로드, IPC 요청, 전체화면 해제에서 창 설정을 각각 적용하지 말고 메인 프로세스 함수 하나로 모으세요.
function applyDisplaySettings(win, settings) {
const { width, height } = WINDOW_PRESETS[settings.resolution];
if (settings.fullscreen) {
// Windows에서 fixed-size 창은 이 준비 단계가 필요할 수 있습니다.
win.setResizable(true);
win.setFullScreen(true);
return win.isFullScreen();
}
win.setFullScreen(false);
win.setSize(width, height);
win.center();
win.setResizable(false);
return win.isFullScreen();
}전체화면 분기에는 창 크기나 위치를 바꾸는 호출을 넣지 않는 것이 중요합니다. 창 모드로 돌아갈 때만 선택한 프리셋 크기와 중앙 정렬을 적용하세요.
resizable: false가 전체화면을 막는지 비교하기
고정 크기 창은 게임 UI 비율을 지키는 데 편리하지만, Windows 환경에서는 전체화면 전환을 방해할 수 있습니다. 실제 진단에서 resizable: false 상태로 setFullScreen(true)를 호출했을 때는 isFullScreen()이 true였지만 창 bounds가 1920×1080에 머물렀습니다.
같은 창에서 setResizable(true)를 먼저 호출한 뒤 전체화면으로 전환하자 bounds가 2560×1440으로 확장됐습니다. 따라서 창 모드에서만 다시 setResizable(false)로 잠그면, 고정 프리셋 정책과 전체화면을 함께 유지할 수 있습니다.
fullscreenable도 활성화해야 합니다. 다만 Windows의 실제 전환을 검증할 때는 fullscreenable: true만 확인하지 말고, 반드시 전환 후 bounds까지 확인하세요. Electron BrowserWindow 문서에서 setFullScreen(), setResizable(), getBounds()의 플랫폼별 동작을 확인할 수 있습니다.
요청 전후 상태를 모두 로그로 남기기
screen.getDisplayMatching()으로 대상 모니터와 Windows 배율을 함께 기록하면 DPI 이중 변환을 빠르게 제외할 수 있습니다.
const { screen } = require('electron');
function logWindowState(label, win, requestedFullscreen) {
const bounds = win.getBounds();
const display = screen.getDisplayMatching(bounds);
console.log('[Window]', label, {
requestedFullscreen,
windowId: win.id,
isFullScreen: win.isFullScreen(),
isResizable: win.isResizable(),
bounds,
display: {
bounds: display.bounds,
workArea: display.workArea,
scaleFactor: display.scaleFactor,
},
});
}다음 값이 한 로그 묶음에 있어야 원인을 비교할 수 있습니다.
- 전체화면 요청값과 대상
BrowserWindowID - 요청 전후
isFullScreen()및getBounds() - 모니터 bounds, work area,
scaleFactor - 전체화면 요청 뒤 실행된
setSize,setBounds,center호출 위치
윈도우 크기를 scaleFactor나 렌더러 devicePixelRatio로 나누거나 곱하는 코드는 별도로 확인하세요. BrowserWindow의 DIP 크기와 WebGL의 픽셀 비율을 한 계산에 섞으면 창이 예상보다 작거나 크게 보일 수 있습니다.
이벤트의 즉시 상태를 그대로 UI에 보내지 않기
Windows에서는 enter-full-screen 이벤트가 발생한 직후 isFullScreen()이 아직 이전 값을 반환할 수 있습니다. 이벤트 안에서 즉시 렌더러에 설정을 보내면 UI가 “전체화면 꺼짐”으로 되돌아갈 수 있습니다.
이벤트는 기록용으로 먼저 남기고, 짧은 지연 뒤 실제 상태를 다시 읽어 UI에 전달하세요.
win.on('enter-full-screen', () => {
logWindowState('enter-full-screen', win, true);
setTimeout(() => {
const fullscreen = win.isFullScreen();
webContents.send('window:settings-changed', { fullscreen });
}, 100);
});IPC 응답도 저장하려던 값이 아니라 win.isFullScreen()으로 확인한 결과를 반환해야 합니다. 렌더러는 이 응답과 상태 변경 이벤트를 기준으로 토글 UI를 갱신하세요.
UI·IPC를 건너뛴 진단 모드
전체화면 토글을 누르지 않아도 원인을 분리할 수 있도록, 개발 전용 인자를 두는 방법이 유용합니다.
if (process.argv.includes('--fullscreen-diagnostic')) {
setTimeout(() => {
logWindowState('before direct fullscreen', mainWindow, true);
mainWindow.setResizable(true);
mainWindow.setFullScreen(true);
logWindowState('after direct fullscreen', mainWindow, true);
}, 1000);
}이 진단에서도 창이 작게 남으면 렌더러·preload·IPC 문제가 아닙니다. 반대로 직접 요청은 정상인데 UI 토글만 실패한다면 preload 경로, IPC 채널 이름, 설정을 다시 덮어쓰는 렌더러 코드를 확인하세요.
배포 전 체크리스트
- 전체화면과 창 모드 적용이 하나의 메인 프로세스 함수만 거치는가?
- 전체화면 분기 뒤에
setSize,setBounds,center가 실행되지 않는가? - 고정 크기 창이라면 전체화면 진입 전에
resizable제약을 해제하는가? - 전체화면 해제 후에만 프리셋 크기와 중앙 정렬을 적용하는가?
- UI가 저장값이 아니라 실제
win.isFullScreen()결과를 표시하는가? - 100%, 125%, 150% Windows 배율과 다중 모니터에서 bounds·scaleFactor 로그를 확인했는가?
- 패키징된 Electron 빌드에서도 진단 로그와 전체화면 전환을 확인했는가?
한 번의 API 호출이 성공처럼 보여도 실제 bounds가 모니터와 같지 않으면 전체화면 문제는 해결된 것이 아닙니다. 상태, 창 경계, 모니터 정보를 같은 로그에서 비교하는 습관이 재현하기 어려운 데스크톱 문제를 가장 빠르게 좁혀 줍니다.