앱을 종료할 때 - 전체 화면 모드 상태 여부, 화면 크기, 화면 위치 정보를 저장

This commit is contained in:
2026-05-18 09:39:19 +09:00
parent 3d0943b6fe
commit d74c2e055d
4 changed files with 82 additions and 23 deletions
+2 -1
View File
@@ -29,6 +29,7 @@ assets/
src/
├── main/
│ ├── index.js # Main process entry point; app.setName(), BrowserWindow, registerAll()
│ ├── config.js # Shared userData/config.json read/write helpers
│ └── ipc/
│ ├── index.js # registerAll(mainWindow) — delegates to folder and files modules
│ ├── file-utils.js # Shared main-process file helpers: image listing/data URLs,
@@ -189,4 +190,4 @@ Global shortcuts are registered in `keyboard.js`. They do not fire while any `.m
**Build output:** `electron-builder` targets DMG for arm64 and x64.
**Config persistence:** `app.getPath('userData')/config.json``lastFolder`, `previewOn` 저장.
**Config persistence:** `app.getPath('userData')/config.json``lastFolder`, `previewOn`, `sidebarWidth`, `windowState` 저장. `windowState` includes fullscreen status and normal window bounds (`x`, `y`, `width`, `height`) and is restored on startup if the saved bounds overlap an available display.
+31
View File
@@ -0,0 +1,31 @@
const { app } = require('electron');
const path = require('path');
const fs = require('fs');
const configPath = path.join(app.getPath('userData'), 'config.json');
function readConfig() {
try {
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
} catch {
return {};
}
}
function writeConfig(data) {
try {
fs.writeFileSync(configPath, JSON.stringify(data, null, 2));
} catch {}
}
function updateConfig(updater) {
const cfg = readConfig();
updater(cfg);
writeConfig(cfg);
}
module.exports = {
readConfig,
updateConfig,
writeConfig,
};
+44 -3
View File
@@ -1,15 +1,19 @@
const { app, BrowserWindow } = require('electron');
const { app, BrowserWindow, screen } = require('electron');
const path = require('path');
const { registerAll } = require('./ipc');
const { readConfig, updateConfig } = require('./config');
app.setName('Photo Renamer');
let mainWindow;
function createWindow() {
const windowState = getSavedWindowState();
mainWindow = new BrowserWindow({
width: 1200,
height: 820,
x: windowState.bounds?.x,
y: windowState.bounds?.y,
width: windowState.bounds?.width || 1200,
height: windowState.bounds?.height || 820,
minWidth: 900,
minHeight: 600,
titleBarStyle: 'hiddenInset',
@@ -27,8 +31,11 @@ function createWindow() {
mainWindow.once('ready-to-show', () => {
mainWindow.show();
if (windowState.isFullScreen) mainWindow.setFullScreen(true);
});
mainWindow.on('close', saveWindowState);
mainWindow.on('enter-full-screen', () => {
mainWindow.webContents.send('fullscreen-change', true);
});
@@ -37,6 +44,40 @@ function createWindow() {
});
}
function getSavedWindowState() {
const cfg = readConfig();
const state = cfg.windowState || {};
const bounds = isUsableBounds(state.bounds) ? state.bounds : null;
return {
bounds,
isFullScreen: state.isFullScreen === true,
};
}
function isUsableBounds(bounds) {
if (!bounds) return false;
const values = [bounds.x, bounds.y, bounds.width, bounds.height];
if (!values.every(Number.isFinite)) return false;
if (bounds.width < 900 || bounds.height < 600) return false;
return screen.getAllDisplays().some(display => rectanglesOverlap(bounds, display.workArea));
}
function rectanglesOverlap(a, b) {
return a.x < b.x + b.width &&
a.x + a.width > b.x &&
a.y < b.y + b.height &&
a.y + a.height > b.y;
}
function saveWindowState() {
if (!mainWindow) return;
const isFullScreen = mainWindow.isFullScreen();
const bounds = isFullScreen ? mainWindow.getNormalBounds() : mainWindow.getBounds();
updateConfig(cfg => {
cfg.windowState = { isFullScreen, bounds };
});
}
app.whenReady().then(() => {
createWindow();
registerAll(mainWindow);
+5 -19
View File
@@ -1,16 +1,8 @@
const { ipcMain, dialog, app, shell } = require('electron');
const { ipcMain, dialog, shell } = require('electron');
const path = require('path');
const fs = require('fs');
const os = require('os');
const configPath = path.join(app.getPath('userData'), 'config.json');
function readConfig() {
try { return JSON.parse(fs.readFileSync(configPath, 'utf8')); } catch { return {}; }
}
function writeConfig(data) {
try { fs.writeFileSync(configPath, JSON.stringify(data, null, 2)); } catch {}
}
const { readConfig, updateConfig } = require('../config');
function register(mainWindow) {
ipcMain.handle('select-folder', async () => {
@@ -33,9 +25,7 @@ function register(mainWindow) {
});
ipcMain.handle('set-last-folder', (_e, folderPath) => {
const cfg = readConfig();
cfg.lastFolder = folderPath;
writeConfig(cfg);
updateConfig(cfg => { cfg.lastFolder = folderPath; });
});
ipcMain.handle('list-directories', (_e, folderPath) => {
@@ -64,9 +54,7 @@ function register(mainWindow) {
});
ipcMain.handle('set-preview-on', (_e, on) => {
const cfg = readConfig();
cfg.previewOn = on;
writeConfig(cfg);
updateConfig(cfg => { cfg.previewOn = on; });
});
ipcMain.handle('get-sidebar-width', () => {
@@ -75,9 +63,7 @@ function register(mainWindow) {
});
ipcMain.handle('set-sidebar-width', (_e, width) => {
const cfg = readConfig();
cfg.sidebarWidth = width;
writeConfig(cfg);
updateConfig(cfg => { cfg.sidebarWidth = width; });
});
}