61 lines
1.8 KiB
TypeScript
61 lines
1.8 KiB
TypeScript
// 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))
|
|
}
|