Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions apps/electron/src/main/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,29 @@ export function registerIpcHandlers(): void {
})
})

// 设置 Electron 原生缩放因子(全局模式)
ipcMain.handle(
SETTINGS_IPC_CHANNELS.SET_ZOOM_FACTOR,
async (event, zoomFactor: number): Promise<void> => {
const win = BrowserWindow.fromWebContents(event.sender)
if (win) {
win.webContents.setZoomFactor(zoomFactor)
}
}
)

// 获取当前 Electron 原生缩放因子
ipcMain.handle(
SETTINGS_IPC_CHANNELS.GET_ZOOM_FACTOR,
async (event): Promise<number> => {
const win = BrowserWindow.fromWebContents(event.sender)
if (win) {
return win.webContents.getZoomFactor()
}
return 1.0
}
)

// ===== 环境检测相关 =====

// 执行环境检测
Expand Down
10 changes: 9 additions & 1 deletion apps/electron/src/main/lib/settings-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { readFileSync, writeFileSync, existsSync } from 'node:fs'
import { getSettingsPath } from './config-paths'
import { DEFAULT_THEME_MODE } from '../../types'
import { DEFAULT_THEME_MODE, DEFAULT_ZOOM_MODE, DEFAULT_MESSAGE_AREA_ZOOM_LEVEL, DEFAULT_GLOBAL_ZOOM_LEVEL } from '../../types'
import type { AppSettings } from '../../types'

/**
Expand All @@ -21,6 +21,9 @@ export function getSettings(): AppSettings {
if (!existsSync(filePath)) {
return {
themeMode: DEFAULT_THEME_MODE,
zoomMode: DEFAULT_ZOOM_MODE,
messageAreaZoomLevel: DEFAULT_MESSAGE_AREA_ZOOM_LEVEL,
globalZoomLevel: DEFAULT_GLOBAL_ZOOM_LEVEL,
onboardingCompleted: false,
environmentCheckSkipped: false,
notificationsEnabled: true,
Expand All @@ -32,6 +35,9 @@ export function getSettings(): AppSettings {
const data = JSON.parse(raw) as Partial<AppSettings>
return {
themeMode: data.themeMode || DEFAULT_THEME_MODE,
zoomMode: data.zoomMode || DEFAULT_ZOOM_MODE,
messageAreaZoomLevel: data.messageAreaZoomLevel ?? DEFAULT_MESSAGE_AREA_ZOOM_LEVEL,
globalZoomLevel: data.globalZoomLevel ?? DEFAULT_GLOBAL_ZOOM_LEVEL,
agentChannelId: data.agentChannelId,
agentModelId: data.agentModelId,
agentWorkspaceId: data.agentWorkspaceId,
Expand All @@ -44,6 +50,8 @@ export function getSettings(): AppSettings {
console.error('[设置] 读取失败:', error)
return {
themeMode: DEFAULT_THEME_MODE,
zoomMode: DEFAULT_ZOOM_MODE,
messageAreaZoomLevel: DEFAULT_MESSAGE_AREA_ZOOM_LEVEL,
onboardingCompleted: false,
environmentCheckSkipped: false,
notificationsEnabled: true,
Expand Down
33 changes: 29 additions & 4 deletions apps/electron/src/main/menu.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Menu, shell } from 'electron'
import { Menu, shell, BrowserWindow } from 'electron'
import { getSettings } from './lib/settings-service'

export function createApplicationMenu(): Menu {
const isMac = process.platform === 'darwin'
Expand Down Expand Up @@ -58,9 +59,33 @@ export function createApplicationMenu(): Menu {
{ role: 'forceReload' as const, label: '强制重新加载' },
{ role: 'toggleDevTools' as const, label: '切换开发者工具' },
{ type: 'separator' as const },
{ role: 'resetZoom' as const, label: '重置缩放' },
{ role: 'zoomIn' as const, label: '放大' },
{ role: 'zoomOut' as const, label: '缩小' },
{
label: '重置缩放',
accelerator: 'CommandOrControl+0',
click: (_menuItem, browserWindow) => {
if (!browserWindow || !(browserWindow instanceof BrowserWindow)) return
// 统一发送 IPC 事件,由渲染进程根据模式处理
browserWindow.webContents.send('zoom:reset')
},
},
{
label: '放大',
accelerator: 'CommandOrControl+Plus',
click: (_menuItem, browserWindow) => {
if (!browserWindow || !(browserWindow instanceof BrowserWindow)) return
// 统一发送 IPC 事件,由渲染进程根据模式处理
browserWindow.webContents.send('zoom:in')
},
},
{
label: '缩小',
accelerator: 'CommandOrControl+-',
click: (_menuItem, browserWindow) => {
if (!browserWindow || !(browserWindow instanceof BrowserWindow)) return
// 统一发送 IPC 事件,由渲染进程根据模式处理
browserWindow.webContents.send('zoom:out')
},
},
{ type: 'separator' as const },
{ role: 'togglefullscreen' as const, label: '切换全屏' },
],
Expand Down
45 changes: 45 additions & 0 deletions apps/electron/src/preload/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,12 @@ export interface ElectronAPI {
/** 订阅系统主题变化事件(返回清理函数) */
onSystemThemeChanged: (callback: (isDark: boolean) => void) => () => void

/** 设置 Electron 原生缩放因子(全局模式) */
setZoomFactor: (zoomFactor: number) => Promise<void>

/** 获取当前 Electron 原生缩放因子 */
getZoomFactor: () => Promise<number>

// ===== 环境检测相关 =====

/** 执行环境检测 */
Expand Down Expand Up @@ -421,6 +427,17 @@ export interface ElectronAPI {
// 工作区文件变化通知
onCapabilitiesChanged: (callback: () => void) => () => void
onWorkspaceFilesChanged: (callback: () => void) => () => void

// ===== 缩放事件订阅(返回清理函数) =====

/** 订阅放大事件 */
onZoomIn: (callback: () => void) => () => void

/** 订阅缩小事件 */
onZoomOut: (callback: () => void) => () => void

/** 订阅重置缩放事件 */
onZoomReset: (callback: () => void) => () => void
}

/**
Expand Down Expand Up @@ -590,6 +607,14 @@ const electronAPI: ElectronAPI = {
return () => { ipcRenderer.removeListener(SETTINGS_IPC_CHANNELS.ON_SYSTEM_THEME_CHANGED, listener) }
},

setZoomFactor: (zoomFactor: number) => {
return ipcRenderer.invoke(SETTINGS_IPC_CHANNELS.SET_ZOOM_FACTOR, zoomFactor)
},

getZoomFactor: () => {
return ipcRenderer.invoke(SETTINGS_IPC_CHANNELS.GET_ZOOM_FACTOR)
},

// 环境检测
checkEnvironment: () => {
return ipcRenderer.invoke(ENVIRONMENT_IPC_CHANNELS.CHECK)
Expand Down Expand Up @@ -875,6 +900,26 @@ const electronAPI: ElectronAPI = {
getReleaseByTag: (tag) => {
return ipcRenderer.invoke(GITHUB_RELEASE_IPC_CHANNELS.GET_RELEASE_BY_TAG, tag)
},

// ===== 缩放事件订阅 =====

onZoomIn: (callback) => {
const listener = (): void => callback()
ipcRenderer.on('zoom:in', listener)
return () => { ipcRenderer.removeListener('zoom:in', listener) }
},

onZoomOut: (callback) => {
const listener = (): void => callback()
ipcRenderer.on('zoom:out', listener)
return () => { ipcRenderer.removeListener('zoom:out', listener) }
},

onZoomReset: (callback) => {
const listener = (): void => callback()
ipcRenderer.on('zoom:reset', listener)
return () => { ipcRenderer.removeListener('zoom:reset', listener) }
},
}

// 将 API 暴露到渲染进程的 window 对象上
Expand Down
1 change: 1 addition & 0 deletions apps/electron/src/renderer/atoms/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export * from './settings-tab'
export * from './chat-atoms'
export * from './user-profile'
export * from './theme'
export * from './zoom-atoms'
Loading