3 changed files with 275 additions and 2 deletions
@ -0,0 +1,167 @@
@@ -0,0 +1,167 @@
|
||||
const { app, screen } = require('electron') |
||||
const path = require('path') |
||||
const fs = require('fs') |
||||
|
||||
class WindowStateManager { |
||||
constructor(windowName = 'main') { |
||||
this.windowName = windowName |
||||
this.statePath = path.join(app.getPath('userData'), `${windowName}-window-state.json`) |
||||
} |
||||
|
||||
// 加载窗口状态
|
||||
loadState() { |
||||
try { |
||||
if (!this.hasSavedState()) { |
||||
return this.getDefaultState() |
||||
} |
||||
|
||||
const stateData = fs.readFileSync(this.statePath, 'utf8') |
||||
const state = JSON.parse(stateData) |
||||
|
||||
// 验证状态数据
|
||||
if (!this.validateState(state)) { |
||||
return this.getDefaultState() |
||||
} |
||||
|
||||
// 调整状态到屏幕边界内
|
||||
const adjustedState = this.adjustStateToScreen(state) |
||||
return adjustedState |
||||
} catch (error) { |
||||
console.error(`加载窗口状态失败 (${this.windowName}):`, error) |
||||
return this.getDefaultState() |
||||
} |
||||
} |
||||
|
||||
// 获取默认状态
|
||||
getDefaultState() { |
||||
return { |
||||
width: 1200, |
||||
height: 800, |
||||
x: undefined, // 让Electron自动居中
|
||||
y: undefined, // 让Electron自动居中
|
||||
isMaximized: false, |
||||
isFullScreen: false |
||||
} |
||||
} |
||||
|
||||
// 验证状态数据
|
||||
validateState(state) { |
||||
return state &&
|
||||
typeof state.width === 'number' &&
|
||||
typeof state.height === 'number' && |
||||
state.width > 0 &&
|
||||
state.height > 0 && |
||||
(state.x === undefined || (typeof state.x === 'number' && state.x >= 0)) && |
||||
(state.y === undefined || (typeof state.y === 'number' && state.y >= 0)) |
||||
} |
||||
|
||||
// 调整状态到屏幕边界内
|
||||
adjustStateToScreen(state) { |
||||
try { |
||||
const displays = screen.getAllDisplays() |
||||
if (displays.length === 0) { |
||||
return state |
||||
} |
||||
|
||||
// 使用主显示器
|
||||
const primaryDisplay = displays.find(d => d.bounds.x === 0 && d.bounds.y === 0) || displays[0] |
||||
const { bounds: screenBounds } = primaryDisplay |
||||
|
||||
let { width, height, x, y, isMaximized, isFullScreen } = state |
||||
|
||||
// 如果窗口太大,调整到屏幕大小
|
||||
if (width > screenBounds.width) { |
||||
width = Math.max(800, screenBounds.width - 100) |
||||
} |
||||
if (height > screenBounds.height) { |
||||
height = Math.max(600, screenBounds.height - 100) |
||||
} |
||||
|
||||
// 如果窗口太小,设置最小尺寸
|
||||
if (width < 800) width = 800 |
||||
if (height < 600) height = 600 |
||||
|
||||
// 调整位置,确保窗口完全在屏幕内
|
||||
if (x !== undefined && y !== undefined) { |
||||
// 确保窗口右边界不超出屏幕
|
||||
if (x + width > screenBounds.width) { |
||||
x = screenBounds.width - width |
||||
} |
||||
// 确保窗口下边界不超出屏幕
|
||||
if (y + height > screenBounds.height) { |
||||
y = screenBounds.height - height |
||||
} |
||||
// 确保窗口左边界不超出屏幕
|
||||
if (x < screenBounds.x) { |
||||
x = screenBounds.x |
||||
} |
||||
// 确保窗口上边界不超出屏幕
|
||||
if (y < screenBounds.y) { |
||||
y = screenBounds.y |
||||
} |
||||
} |
||||
|
||||
return { width, height, x, y, isMaximized, isFullScreen } |
||||
} catch (error) { |
||||
console.error(`调整窗口状态到屏幕边界失败:`, error) |
||||
return state |
||||
} |
||||
} |
||||
|
||||
// 保存窗口状态
|
||||
saveState(window) { |
||||
try { |
||||
if (!window || window.isDestroyed()) { |
||||
return false |
||||
} |
||||
|
||||
const bounds = window.getBounds() |
||||
const state = { |
||||
width: bounds.width, |
||||
height: bounds.height, |
||||
x: bounds.x, |
||||
y: bounds.y, |
||||
isMaximized: window.isMaximized(), |
||||
isFullScreen: window.isFullScreen() |
||||
} |
||||
|
||||
// 确保目录存在
|
||||
const dir = path.dirname(this.statePath) |
||||
if (!fs.existsSync(dir)) { |
||||
fs.mkdirSync(dir, { recursive: true }) |
||||
} |
||||
|
||||
fs.writeFileSync(this.statePath, JSON.stringify(state, null, 2)) |
||||
return true |
||||
} catch (error) { |
||||
console.error(`保存窗口状态失败 (${this.windowName}):`, error) |
||||
return false |
||||
} |
||||
} |
||||
|
||||
// 检查是否有保存的状态
|
||||
hasSavedState() { |
||||
return fs.existsSync(this.statePath) |
||||
} |
||||
|
||||
// 获取状态文件路径
|
||||
getStatePath() { |
||||
return this.statePath |
||||
} |
||||
|
||||
// 重置状态(删除保存的状态文件)
|
||||
resetState() { |
||||
try { |
||||
if (this.hasSavedState()) { |
||||
fs.unlinkSync(this.statePath) |
||||
return true |
||||
} |
||||
return false |
||||
} catch (error) { |
||||
console.error(`重置窗口状态失败 (${this.windowName}):`, error) |
||||
return false |
||||
} |
||||
} |
||||
} |
||||
|
||||
module.exports = WindowStateManager |
Loading…
Reference in new issue