refactor: 优化窗口尺寸和位置管理逻辑

This commit is contained in:
kuaifan 2026-01-12 09:02:58 +08:00
parent 790f5d4838
commit 7321ab06f0
12 changed files with 83 additions and 73 deletions

125
electron/electron.js vendored
View File

@ -17,6 +17,7 @@ const {
nativeImage, nativeImage,
globalShortcut, globalShortcut,
nativeTheme, nativeTheme,
screen,
Tray, Tray,
Menu, Menu,
WebContentsView, WebContentsView,
@ -439,8 +440,8 @@ function createUpdaterWindow(updateTitle) {
function createMediaWindow(args, type = 'image') { function createMediaWindow(args, type = 'image') {
if (mediaWindow === null) { if (mediaWindow === null) {
mediaWindow = new BrowserWindow({ mediaWindow = new BrowserWindow({
width: args.width || 970, width: Math.floor(args.width) || 970,
height: args.height || 700, height: Math.floor(args.height) || 700,
minWidth: 360, minWidth: 360,
minHeight: 360, minHeight: 360,
autoHideMenuBar: true, autoHideMenuBar: true,
@ -630,8 +631,14 @@ function createWebTabWindow(args) {
}); });
} }
// tab 模式通知标签栏创建标签window 模式不需要 // tab 模式通知标签栏创建标签window 模式设置窗口标题
if (!isWindowMode) { if (isWindowMode) {
// window 模式下,如果传入了 title 参数,设置窗口标题
if (args.title) {
webTabWindow.setTitle(args.title);
}
} else {
// tab 模式下通知标签栏创建新标签
utils.onDispatchEvent(webTabWindow.webContents, { utils.onDispatchEvent(webTabWindow.webContents, {
event: 'create', event: 'create',
id: browserView.webContents.id, id: browserView.webContents.id,
@ -655,35 +662,21 @@ function createWebTabWindow(args) {
*/ */
function createWebTabWindowInstance(windowId, position, mode = 'tab') { function createWebTabWindowInstance(windowId, position, mode = 'tab') {
const isWindowMode = mode === 'window'; const isWindowMode = mode === 'window';
const { width: screenWidth, height: screenHeight } = screen.getPrimaryDisplay().workAreaSize;
const isHighRes = screenWidth >= 2560;
// mode='window': 根据屏幕分辨率动态计算默认值 // 根据屏幕分辨率计算默认尺寸
// mode='tab': 使用 userConf 保存值或固定默认值 const screenDefault = {
let defaultWidth, defaultHeight, defaultMinWidth, defaultMinHeight; width: isHighRes ? 1440 : 1024,
if (isWindowMode) { height: isHighRes ? 900 : 768,
const { width: screenWidth } = screen.getPrimaryDisplay().workAreaSize; minWidth: 400,
const isHighRes = screenWidth >= 2560; minHeight: 300,
defaultWidth = isHighRes ? 1920 : 1024; };
defaultHeight = isHighRes ? 1080 : 768;
defaultMinWidth = 400;
defaultMinHeight = 300;
} else {
const savedBounds = userConf.get('webTabWindow') || {};
defaultWidth = savedBounds.width ?? 1280;
defaultHeight = savedBounds.height ?? 800;
defaultMinWidth = 360;
defaultMinHeight = 360;
}
const hasExplicitPosition = position?.x !== undefined && position?.y !== undefined; // 计算窗口尺寸和位置
const windowOptions = { const windowOptions = {
width: position?.width ?? defaultWidth,
height: position?.height ?? defaultHeight,
minWidth: position?.minWidth ?? defaultMinWidth,
minHeight: position?.minHeight ?? defaultMinHeight,
center: !hasExplicitPosition,
show: false, show: false,
autoHideMenuBar: true, autoHideMenuBar: true,
backgroundColor: isWindowMode ? utils.getDefaultBackgroundColor() : (nativeTheme.shouldUseDarkColors ? '#575757' : '#FFFFFF'),
webPreferences: { webPreferences: {
preload: path.join(__dirname, 'electron-preload.js'), preload: path.join(__dirname, 'electron-preload.js'),
webSecurity: true, webSecurity: true,
@ -692,23 +685,54 @@ function createWebTabWindowInstance(windowId, position, mode = 'tab') {
}, },
}; };
if (isWindowMode) {
// window 模式:使用 position 参数或屏幕默认值,永远居中
Object.assign(windowOptions, {
width: Math.floor(position?.width ?? screenDefault.width),
height: Math.floor(position?.height ?? screenDefault.height),
minWidth: Math.floor(position?.minWidth ?? screenDefault.minWidth),
minHeight: Math.floor(position?.minHeight ?? screenDefault.minHeight),
backgroundColor: utils.getDefaultBackgroundColor(),
center: true,
});
} else {
// tab 模式:使用 savedBounds 或屏幕默认值
const savedBounds = userConf.get('webTabWindow') || {};
const maxX = Math.floor(screenWidth * 0.9);
const maxY = Math.floor(screenHeight * 0.9);
Object.assign(windowOptions, {
width: savedBounds.width ?? screenDefault.width,
height: savedBounds.height ?? screenDefault.height,
minWidth: screenDefault.minWidth,
minHeight: screenDefault.minHeight,
backgroundColor: nativeTheme.shouldUseDarkColors ? '#575757' : '#FFFFFF',
center: true,
});
// 恢复保存的位置,并限制在屏幕 90% 范围内
if (savedBounds.x !== undefined && savedBounds.y !== undefined) {
Object.assign(windowOptions, {
x: Math.min(savedBounds.x, maxX),
y: Math.min(savedBounds.y, maxY),
center: false,
});
}
}
// tab 模式使用隐藏标题栏 + titleBarOverlay // tab 模式使用隐藏标题栏 + titleBarOverlay
if (!isWindowMode) { if (!isWindowMode) {
const titleBarOverlay = { const titleBarOverlay = {
height: webTabHeight height: webTabHeight
}; };
if (nativeTheme.shouldUseDarkColors) { if (nativeTheme.shouldUseDarkColors) {
titleBarOverlay.color = '#3B3B3D'; Object.assign(titleBarOverlay, {
titleBarOverlay.symbolColor = '#C5C5C5'; color: '#3B3B3D',
symbolColor: '#C5C5C5',
});
} }
windowOptions.titleBarStyle = 'hidden'; Object.assign(windowOptions, {
windowOptions.titleBarOverlay = titleBarOverlay; titleBarStyle: 'hidden',
} titleBarOverlay: titleBarOverlay,
});
// 有明确位置时设置 x/y
if (hasExplicitPosition) {
windowOptions.x = position.x;
windowOptions.y = position.y;
} }
const webTabWindow = new BrowserWindow(windowOptions); const webTabWindow = new BrowserWindow(windowOptions);
@ -884,7 +908,7 @@ function createWebTabView(windowId, args) {
utils.onBeforeOpenWindow(browserView.webContents, url).then(() => { utils.onBeforeOpenWindow(browserView.webContents, url).then(() => {
renderer.openExternal(url).catch(() => {}); renderer.openExternal(url).catch(() => {});
}); });
} else { } else if (url && url !== 'about:blank') {
// tab 模式下创建新标签 // tab 模式下创建新标签
createWebTabWindow({url, afterId: browserView.webContents.id, windowId}); createWebTabWindow({url, afterId: browserView.webContents.id, windowId});
} }
@ -895,16 +919,25 @@ function createWebTabView(windowId, args) {
if (browserView.titleFixed) { if (browserView.titleFixed) {
return; return;
} }
// 使用动态窗口ID支持标签在窗口间转移 // 使用动态窗口ID支持标签在窗口间转移
const currentWindowId = browserView.webTabWindowId; const currentWindowId = browserView.webTabWindowId;
const wd = webTabWindows.get(currentWindowId); const wd = webTabWindows.get(currentWindowId);
if (!wd || !wd.window) return; if (!wd || !wd.window) return;
utils.onDispatchEvent(wd.window.webContents, {
event: 'title', // 根据模式更新标题
id: browserView.webContents.id, if (wd.mode === 'window') {
title: title, // window 模式下直接设置窗口标题
url: browserView.webContents.getURL(), wd.window.setTitle(title);
}).then(_ => { }); } else {
// tab 模式下通知标签栏更新标题
utils.onDispatchEvent(wd.window.webContents, {
event: 'title',
id: browserView.webContents.id,
title: title,
url: browserView.webContents.getURL(),
}).then(_ => { });
}
}); });
browserView.webContents.on('did-fail-load', (event, errorCode, errorDescription, validatedURL, isMainFrame) => { browserView.webContents.on('did-fail-load', (event, errorCode, errorDescription, validatedURL, isMainFrame) => {
if (!errorDescription) { if (!errorDescription) {
@ -1035,7 +1068,7 @@ function createWebTabView(windowId, args) {
} }
/** /**
* 获取当前内置浏览器标签兼容旧API * 获取当前内置浏览器标签
* @returns {object|undefined} * @returns {object|undefined}
*/ */
function currentWebTab() { function currentWebTab() {

View File

@ -608,7 +608,7 @@ export default {
return false; return false;
} }
// 使 // 使
this.$store.dispatch("openWindow", url) this.$store.dispatch('openWindow', url)
return true return true
} }
this.$Electron.listener('browserWindowBlur', _ => { this.$Electron.listener('browserWindowBlur', _ => {

View File

@ -497,8 +497,6 @@ export default {
if (this.$Electron) { if (this.$Electron) {
const mergedConfig = Object.assign({ const mergedConfig = Object.assign({
title: appConfig.title || ' ', title: appConfig.title || ' ',
width: Math.min(window.screen.availWidth, 1440),
height: Math.min(window.screen.availHeight, 900),
}, $A.isJson(windowConfig) ? windowConfig : {}); }, $A.isJson(windowConfig) ? windowConfig : {});
await this.$store.dispatch('openWindow', { await this.$store.dispatch('openWindow', {
name: `single-apps-${$A.randomString(6)}`, name: `single-apps-${$A.randomString(6)}`,
@ -532,8 +530,6 @@ export default {
name: `external-apps-${$A.randomString(6)}`, name: `external-apps-${$A.randomString(6)}`,
path: config.url, path: config.url,
title: config.title || ' ', title: config.title || ' ',
width: Math.min(window.screen.availWidth, 1440),
height: Math.min(window.screen.availHeight, 900),
}); });
} else if (this.$isEEUIApp) { } else if (this.$isEEUIApp) {
await this.$store.dispatch('openAppChildPage', { await this.$store.dispatch('openAppChildPage', {

View File

@ -3786,8 +3786,6 @@ export default {
path: path, path: path,
title, title,
titleFixed: true, titleFixed: true,
width: Math.min(window.screen.availWidth, 1440),
height: Math.min(window.screen.availHeight, 900),
userAgent: "/hideenOfficeTitle/", userAgent: "/hideenOfficeTitle/",
}); });
} else if (this.$isEEUIApp) { } else if (this.$isEEUIApp) {

View File

@ -186,8 +186,6 @@ export default {
path: path, path: path,
title, title,
titleFixed: true, titleFixed: true,
width: Math.min(window.screen.availWidth, 1440),
height: Math.min(window.screen.availHeight, 900),
userAgent: "/hideenOfficeTitle/", userAgent: "/hideenOfficeTitle/",
}); });
} else if (this.$isEEUIApp) { } else if (this.$isEEUIApp) {

View File

@ -405,10 +405,9 @@ export default {
this.$store.dispatch('openWindow', { this.$store.dispatch('openWindow', {
name: `meeting-window`, name: `meeting-window`,
path: meetingPath, path: meetingPath,
mode: 'window',
title: this.addData.name, title: this.addData.name,
titleFixed: true, titleFixed: true,
width: Math.min(window.screen.availWidth, 1440),
height: Math.min(window.screen.availHeight, 900),
}); });
// //
this.addShow = false; this.addShow = false;

View File

@ -223,8 +223,6 @@ export default {
name: `project-log-${id}`, name: `project-log-${id}`,
path: path, path: path,
title: this.$L(title), title: this.$L(title),
width: Math.min(window.screen.availWidth, 1440),
height: Math.min(window.screen.availHeight, 900),
}); });
} else if (this.$isEEUIApp) { } else if (this.$isEEUIApp) {
e.preventDefault() e.preventDefault()

View File

@ -109,8 +109,6 @@ export default {
path: `/single/report/detail/${row.id}`, path: `/single/report/detail/${row.id}`,
title: row.title, title: row.title,
titleFixed: true, titleFixed: true,
width: Math.min(window.screen.availWidth, 1440),
height: Math.min(window.screen.availHeight, 900),
}); });
} else { } else {
this.showDetailDrawer = true; this.showDetailDrawer = true;
@ -127,8 +125,6 @@ export default {
name: `report-edit-${id}`, name: `report-edit-${id}`,
path: `/single/report/edit/${id}`, path: `/single/report/edit/${id}`,
title: this.$L(id > 0 ? '修改报告' : '新增报告'), title: this.$L(id > 0 ? '修改报告' : '新增报告'),
width: Math.min(window.screen.availWidth, 1440),
height: Math.min(window.screen.availHeight, 900),
}); });
} else { } else {
this.reportId = id; this.reportId = id;

View File

@ -174,8 +174,6 @@ export default {
path: path, path: path,
title: title, title: title,
titleFixed: true, titleFixed: true,
width: Math.min(window.screen.availWidth, 1440),
height: Math.min(window.screen.availHeight, 900),
}); });
} else if (this.$isEEUIApp) { } else if (this.$isEEUIApp) {
this.$store.dispatch('openAppChildPage', { this.$store.dispatch('openAppChildPage', {

View File

@ -1963,8 +1963,6 @@ export default {
path: path, path: path,
title: `${file.name} (${$A.bytesToSize(file.size)})`, title: `${file.name} (${$A.bytesToSize(file.size)})`,
titleFixed: true, titleFixed: true,
width: Math.min(window.screen.availWidth, 1440),
height: Math.min(window.screen.availHeight, 900),
userAgent: "/hideenOfficeTitle/", userAgent: "/hideenOfficeTitle/",
}); });
} else if (this.$isEEUIApp) { } else if (this.$isEEUIApp) {

View File

@ -1525,8 +1525,6 @@ export default {
path: path, path: path,
title: $A.getFileName(item), title: $A.getFileName(item),
titleFixed: true, titleFixed: true,
width: Math.min(window.screen.availWidth, 1440),
height: Math.min(window.screen.availHeight, 900),
userAgent: "/hideenOfficeTitle/", userAgent: "/hideenOfficeTitle/",
}); });
} else if (this.$isEEUIApp) { } else if (this.$isEEUIApp) {

View File

@ -60,8 +60,6 @@ export function openFileInClient(vm, item, options = {}) {
title: finalTitle, title: finalTitle,
titleFixed: true, titleFixed: true,
parent: null, parent: null,
width: Math.min(window.screen.availWidth, 1440),
height: Math.min(window.screen.availHeight, 900),
}, options.windowConfig || {}); }, options.windowConfig || {});
if (vm.$Electron) { if (vm.$Electron) {