Browse Source

增加窗口状态保持。

master
hejl 2 weeks ago
parent
commit
9fade2542b
  1. 1
      .gitignore
  2. 109
      gofaster/app/src/main/index.js
  3. 167
      gofaster/app/src/main/windowState.js

1
.gitignore vendored

@ -13,3 +13,4 @@ @@ -13,3 +13,4 @@
/gofaster/app/dist
/gofaster/backend/logs
/gofaster/tmp/
/gofaster/app/dist/*/*/

109
gofaster/app/src/main/index.js

@ -2,6 +2,10 @@ const { app, BrowserWindow, ipcMain } = require('electron') @@ -2,6 +2,10 @@ const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('path')
const fs = require('fs')
const os = require('os')
const WindowStateManager = require('./windowState')
// 创建窗口状态管理器
const windowStateManager = new WindowStateManager('main')
// 设置进程编码,确保中文正常显示
process.env.LANG = 'zh_CN.UTF-8'
@ -167,9 +171,14 @@ if (isDev && process.argv.includes('--watch')) { @@ -167,9 +171,14 @@ if (isDev && process.argv.includes('--watch')) {
function createWindow() {
try {
// 加载保存的窗口状态
const windowState = windowStateManager.loadState()
mainWindow = new BrowserWindow({
width: 1200,
height: 800,
width: windowState.width,
height: windowState.height,
x: windowState.x,
y: windowState.y,
autoHideMenuBar: true,
webPreferences: {
nodeIntegration: false,
@ -194,6 +203,13 @@ function createWindow() { @@ -194,6 +203,13 @@ function createWindow() {
show: false // 先隐藏窗口,等加载完成后再显示
})
// 如果保存的状态是最大化或全屏,应用这些状态
if (windowState.isMaximized) {
mainWindow.maximize()
} else if (windowState.isFullScreen) {
mainWindow.setFullScreen(true)
}
console.log('Main window created');
// 开发环境下抑制安全警告
@ -313,8 +329,51 @@ function createWindow() { @@ -313,8 +329,51 @@ function createWindow() {
})
}
// 添加窗口状态监听器
// 窗口大小改变时保存状态(防抖)
let resizeTimeout
mainWindow.on('resize', () => {
clearTimeout(resizeTimeout)
resizeTimeout = setTimeout(() => {
if (!mainWindow.isMaximized() && !mainWindow.isFullScreen()) {
windowStateManager.saveState(mainWindow)
}
}, 500) // 500ms防抖
})
// 窗口移动时保存状态(防抖)
let moveTimeout
mainWindow.on('move', () => {
clearTimeout(moveTimeout)
moveTimeout = setTimeout(() => {
if (!mainWindow.isMaximized() && !mainWindow.isFullScreen()) {
windowStateManager.saveState(mainWindow)
}
}, 500) // 500ms防抖
})
// 窗口最大化状态变化时保存状态
mainWindow.on('maximize', () => {
windowStateManager.saveState(mainWindow)
})
mainWindow.on('unmaximize', () => {
windowStateManager.saveState(mainWindow)
})
// 窗口全屏状态变化时保存状态
mainWindow.on('enter-full-screen', () => {
windowStateManager.saveState(mainWindow)
})
mainWindow.on('leave-full-screen', () => {
windowStateManager.saveState(mainWindow)
})
// 窗口关闭事件
mainWindow.on('closed', () => {
// 保存窗口状态
windowStateManager.saveState(mainWindow)
mainWindow = null
})
@ -456,6 +515,52 @@ ipcMain.handle('get-local-ip', async () => { @@ -456,6 +515,52 @@ ipcMain.handle('get-local-ip', async () => {
}
});
// 窗口状态管理相关的IPC处理器
ipcMain.handle('reset-window-state', async () => {
try {
const result = windowStateManager.resetState()
return {
success: result,
message: result ? '窗口状态已重置' : '没有找到保存的窗口状态'
}
} catch (error) {
console.error('重置窗口状态失败:', error)
return {
success: false,
message: '重置窗口状态失败: ' + error.message
}
}
})
ipcMain.handle('get-window-state-info', async () => {
try {
const hasState = windowStateManager.hasSavedState()
const statePath = windowStateManager.getStatePath()
let currentState = null
if (hasState) {
try {
const stateData = fs.readFileSync(statePath, 'utf8')
currentState = JSON.parse(stateData)
} catch (error) {
console.error('读取当前窗口状态失败:', error)
}
}
return {
hasSavedState: hasState,
statePath: statePath,
currentState: currentState
}
} catch (error) {
console.error('获取窗口状态信息失败:', error)
return {
success: false,
message: '获取窗口状态信息失败: ' + error.message
}
}
})
}); // 闭合 app.whenReady().then() 的回调函数
app.on('window-all-closed', () => {

167
gofaster/app/src/main/windowState.js

@ -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…
Cancel
Save