Skip to content
Merged
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
2 changes: 1 addition & 1 deletion src/main/presenter/shortcutPresenter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export class ShortcutPresenter implements IShortcutPresenter {
globalShortcut.register(this.shortcutKeys.GoSettings, () => {
const focusedWindow = presenter.windowPresenter.getFocusedWindow()
if (focusedWindow?.isFocused()) {
presenter.windowPresenter.sendToActiveTab(focusedWindow.id, SHORTCUT_EVENTS.GO_SETTINGS)
eventBus.sendToMain(SHORTCUT_EVENTS.GO_SETTINGS, focusedWindow.id)
}
})
}
Expand Down
42 changes: 42 additions & 0 deletions src/main/presenter/windowPresenter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,29 @@ export class WindowPresenter implements IWindowPresenter {
}
})

// Listen for shortcut event: go settings (from main shortcut or renderer IPC bridge)
eventBus.on(SHORTCUT_EVENTS.GO_SETTINGS, async (windowId?: number) => {
try {
const targetWindowId = windowId ?? this.getFocusedWindow()?.id ?? this.mainWindow?.id
if (!targetWindowId) return
await this.openOrFocusSettingsTab(targetWindowId)
} catch (err) {
console.error('Failed to open/focus settings tab via eventBus:', err)
}
})

// Allow renderer to request opening/focusing settings via IPC
ipcMain.on(SHORTCUT_EVENTS.GO_SETTINGS, async (event, maybeWindowId?: number) => {
try {
const senderWindow = BrowserWindow.fromWebContents(event.sender)
const targetWindowId = maybeWindowId ?? senderWindow?.id ?? this.mainWindow?.id
if (!targetWindowId) return
await this.openOrFocusSettingsTab(targetWindowId)
} catch (err) {
console.error('Failed to open/focus settings tab via IPC:', err)
}
})

// 监听系统主题更新事件,通知所有窗口 Renderer
eventBus.on(SYSTEM_EVENTS.SYSTEM_THEME_UPDATED, (isDark: boolean) => {
console.log('System theme updated, notifying all windows.')
Expand Down Expand Up @@ -159,6 +182,25 @@ export class WindowPresenter implements IWindowPresenter {
})
}

/**
* Open Settings tab if not exists, otherwise focus existing one in the given window.
*/
public async openOrFocusSettingsTab(windowId: number): Promise<void> {
const window = this.windows.get(windowId)
if (!window || window.isDestroyed()) return
const tabPresenterInstance = presenter.tabPresenter as TabPresenter
const tabsData = await tabPresenterInstance.getWindowTabsData(windowId)
const settingsTab = tabsData.find((t) => {
const url = t.url || ''
return url.startsWith('local://settings') || url.includes('#/settings')
})
if (settingsTab) {
await tabPresenterInstance.switchTab(settingsTab.id)
} else {
await tabPresenterInstance.createTab(windowId, 'local://settings', { active: true })
}
}

/**
* 获取当前主窗口 (优先返回焦点窗口,否则返回第一个有效窗口)。
*/
Expand Down
16 changes: 3 additions & 13 deletions src/renderer/shell/components/AppBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -516,19 +516,9 @@ const closeWindow = () => {
}

const openSettings = () => {
// 检查是否已经存在设置标签页
const existingSettingsTab = tabStore.tabs.find((tab) => tab.url.includes('#/settings'))

if (existingSettingsTab) {
// 如果已经存在设置标签页,切换到该标签页
tabStore.setCurrentTabId(existingSettingsTab.id)
} else {
// 如果不存在设置标签页,创建新的
tabStore.addTab({
name: 'Settings',
icon: 'lucide:settings',
viewType: 'settings'
})
const windowId = window.api.getWindowId()
if (windowId != null) {
windowPresenter.openOrFocusSettingsTab(windowId)
}
}
</script>
Expand Down
15 changes: 3 additions & 12 deletions src/renderer/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -164,14 +164,7 @@ const handleCreateNewConversation = () => {
}
}

// Handle going to settings page
const handleGoSettings = () => {
const currentRoute = router.currentRoute.value
// Check if current route or its parent route is already settings
if (!currentRoute.path.startsWith('/settings')) {
router.push({ name: 'settings' })
}
}
// Removed GO_SETTINGS handler; now handled in main via tab logic

// Handle ESC key - close floating chat window
const handleEscKey = (event: KeyboardEvent) => {
Expand Down Expand Up @@ -219,9 +212,7 @@ onMounted(() => {
handleCreateNewConversation()
})

window.electron.ipcRenderer.on(SHORTCUT_EVENTS.GO_SETTINGS, () => {
handleGoSettings()
})
// GO_SETTINGS is now handled in main process (open/focus Settings tab)

window.electron.ipcRenderer.on(NOTIFICATION_EVENTS.DATA_RESET_COMPLETE_DEV, () => {
toast({
Expand Down Expand Up @@ -307,7 +298,7 @@ onBeforeUnmount(() => {
window.electron.ipcRenderer.removeAllListeners(SHORTCUT_EVENTS.ZOOM_OUT)
window.electron.ipcRenderer.removeAllListeners(SHORTCUT_EVENTS.ZOOM_RESUME)
window.electron.ipcRenderer.removeAllListeners(SHORTCUT_EVENTS.CREATE_NEW_CONVERSATION)
window.electron.ipcRenderer.removeAllListeners(SHORTCUT_EVENTS.GO_SETTINGS)
// GO_SETTINGS listener removed; handled in main
window.electron.ipcRenderer.removeAllListeners(NOTIFICATION_EVENTS.SYS_NOTIFY_CLICKED)
window.electron.ipcRenderer.removeAllListeners(NOTIFICATION_EVENTS.DATA_RESET_COMPLETE_DEV)
})
Expand Down
1 change: 1 addition & 0 deletions src/shared/types/presenters/legacy.presenters.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ export interface IWindowPresenter {
sendToAllWindows(channel: string, ...args: unknown[]): void
sendToWindow(windowId: number, channel: string, ...args: unknown[]): boolean
sendToDefaultTab(channel: string, switchToTarget?: boolean, ...args: unknown[]): Promise<boolean>
openOrFocusSettingsTab(windowId: number): Promise<void>
closeWindow(windowId: number, forceClose?: boolean): Promise<void>
isApplicationQuitting(): boolean
setApplicationQuitting(isQuitting: boolean): void
Expand Down