157af4399f
- 恢复 IPC 类型声明 (src/electron-api.d.ts),修复 31 个 TS2339 错误 - 修复构建断裂:vite.config.ts 改回 electron.vite.config.ts - 修复 2 个 verbatimModuleSyntax type-import 报错 - 修正 .gitignore 构建产物路径 (electron-dist/ -> dist-electron/ + release/) - 清理 55+ 处过时路径注释 - 更新 AGENTS.md 架构文档与 IPC 通道表 - 修正 docs/ROADMAP.md 过时引用
60 lines
1.8 KiB
TypeScript
60 lines
1.8 KiB
TypeScript
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))
|
|
}
|