// src/main/win-state.ts import { app, screen, BrowserWindow } from 'electron' import { join } from 'path' import { readFileSync, writeFile } from 'fs' interface WinState { x: number | null y: number | null width: number height: number maximized: boolean } const STATE_FILE = join(app.getPath('userData'), 'jrdm-win-state.json') const MIN_WIDTH = 900 const MIN_HEIGHT = 600 const DEFAULT_WIDTH = 1200 const DEFAULT_HEIGHT = 800 function parseJson(str: string): WinState | null { try { return JSON.parse(str) } catch { return null } } function getLastState(): WinState { try { const raw = readFileSync(STATE_FILE, 'utf-8') const state = parseJson(raw) if (state) { const display = screen.getPrimaryDisplay().workArea if (state.x != null && (state.x < 0 || state.x > display.width - 100)) { state.x = null; state.y = null } if (state.y != null && (state.y < 0 || state.y > display.height - 100)) { state.x = null; state.y = null } state.width = Math.max(state.width || DEFAULT_WIDTH, MIN_WIDTH) state.height = Math.max(state.height || DEFAULT_HEIGHT, MIN_HEIGHT) return state } } catch { /* file doesn't exist yet */ } return { x: null, y: null, width: DEFAULT_WIDTH, height: DEFAULT_HEIGHT, maximized: false } } function saveState(win: BrowserWindow): void { const bounds = win.getBounds() const state = { ...bounds, maximized: win.isMaximized() } writeFile(STATE_FILE, JSON.stringify(state), 'utf-8', () => {}) } export function restoreAndTrack(win: BrowserWindow): void { const lastState = getLastState() if (lastState.x != null && lastState.y != null) { win.setBounds({ x: lastState.x, y: lastState.y, width: lastState.width, height: lastState.height }) } if (lastState.maximized) { win.maximize() } win.on('close', () => saveState(win)) }