feat: 新增界面整体缩放与字体超大档,修复设置页溢出

- 界面缩放:Electron webContents.setZoomFactor,档位 90%/100%/110%/125%/150%
  - 主进程新增 set-zoom-factor IPC,启动时从 window-state.json 恢复 zoomFactor
  - 窗口尺寸保存与退出前均持久化当前 zoom
  - displaySettings 新增 UiScaleOption + initUiScale,App.vue 启动恢复
  - SettingsModal 新增「界面缩放」卡片,实时经 IPC 应用并持久化
- 字体大小新增「超大」档(html font-size 20px),共 5 档
- 修复设置模态框在字体/界面放大后内容超出视口:面板限制
  max-h-[calc(100vh-2rem)],内容区 flex-1 overflow-y-auto 滚动
This commit is contained in:
xiyidaiwa
2026-08-17 23:40:23 +08:00
parent 7b658e9dd1
commit e25a3c9d8f
5 changed files with 191 additions and 7 deletions
+34 -1
View File
@@ -170,6 +170,18 @@ ipcMain.handle("save-window-bounds", (): boolean => {
return true;
});
// 渲染端(设置页)切换界面整体缩放系数,经此实时应用到主窗口。
// factor 限定在 0.5~3 之间,避免极端值导致界面不可用。
ipcMain.handle("set-zoom-factor", (_event, factor: unknown): boolean => {
if (typeof factor !== "number" || !Number.isFinite(factor)) return false;
const clamped = Math.min(3, Math.max(0.5, factor));
if (win && !win.isDestroyed()) {
win.webContents.setZoomFactor(clamped);
return true;
}
return false;
});
ipcMain.handle("get-app-version", (): string => getAppVersion());
ipcMain.handle("get-system-info", (): { distro: string } => getSystemInfo());
@@ -307,6 +319,8 @@ interface WindowState {
x?: number;
y?: number;
maximized?: boolean;
/** 界面整体缩放系数(Electron webContents.setZoomFactor),默认 1 */
zoomFactor?: number;
}
function getWindowStatePath(): string {
@@ -375,7 +389,14 @@ function flushSaveBounds(): void {
}
if (win && !win.isDestroyed()) {
const { width, height, x, y } = win.getBounds();
saveWindowState({ width, height, x, y, maximized: win.isMaximized() });
saveWindowState({
width,
height,
x,
y,
maximized: win.isMaximized(),
zoomFactor: win.webContents.getZoomFactor(),
});
}
}
function scheduleSaveBounds(winInstance: BrowserWindow): void {
@@ -389,6 +410,7 @@ function scheduleSaveBounds(winInstance: BrowserWindow): void {
x,
y,
maximized: winInstance.isMaximized(),
zoomFactor: winInstance.webContents.getZoomFactor(),
});
}, 400);
}
@@ -438,6 +460,17 @@ async function createWindow() {
});
win = mainWindow;
// 启动即应用持久化的界面缩放系数(默认 1 = 100%)。
// 必须在 loadURL/loadFile 前设置,使首帧即按目标缩放渲染,避免闪烁。
const savedZoom =
typeof saved.zoomFactor === "number" &&
saved.zoomFactor >= 0.5 &&
saved.zoomFactor <= 3
? saved.zoomFactor
: 1;
mainWindow.webContents.setZoomFactor(savedZoom);
logger.info({ zoomFactor: savedZoom }, "已应用界面缩放系数");
// 设计意图(非缺陷,勿改为自动恢复 maximized):
// 启动时不自动恢复最大化状态。原因——最大化窗口在多数屏幕上 bounds 会超过
// OVERSIZED_WINDOW_THRESHOLD(1600x900),若强行恢复最大化会导致「启动即全屏、