mirror of
https://github.com/zhayujie/chatgpt-on-wechat.git
synced 2026-07-21 06:07:13 +08:00
feat(desktop): native desktop enhancements
- Add a minimal application menu with common items and shortcuts: New Chat (Cmd+N), Settings (Cmd+,), Reload, etc. - Add system tray with show window, new chat, and quit; click icon to restore - Add single-instance lock so relaunching focuses the existing window - Implement close-to-tray: closing the window hides it; only a real quit destroys it - Explicitly define Window menu's Close Window bound to Cmd+W / Ctrl+W to reliably trigger hide-to-tray - Listen for menu-action in the renderer to handle menu-triggered new chat / open settings
This commit is contained in:
59
desktop/src/main/tray.ts
Normal file
59
desktop/src/main/tray.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { app, Tray, Menu, BrowserWindow, nativeImage } from 'electron'
|
||||
|
||||
let tray: Tray | null = null
|
||||
|
||||
interface TrayDeps {
|
||||
getWindow: () => BrowserWindow | null
|
||||
iconPath?: string
|
||||
// Called when the user picks "Quit" so the app can fully exit.
|
||||
onQuit: () => void
|
||||
}
|
||||
|
||||
// Build a system tray icon with a minimal menu. The tray lets users restore the
|
||||
// window after closing it to the background and start a new chat quickly.
|
||||
export function createTray({ getWindow, iconPath, onQuit }: TrayDeps): Tray | null {
|
||||
if (tray) return tray
|
||||
if (!iconPath) return null
|
||||
|
||||
let image = nativeImage.createFromPath(iconPath)
|
||||
if (image.isEmpty()) return null
|
||||
// Tray icons render small; resize to avoid an oversized image on some platforms.
|
||||
image = image.resize({ width: 18, height: 18 })
|
||||
// macOS renders template images correctly in both light/dark menubars.
|
||||
if (process.platform === 'darwin') image.setTemplateImage(false)
|
||||
|
||||
tray = new Tray(image)
|
||||
tray.setToolTip(app.name)
|
||||
|
||||
const showWindow = () => {
|
||||
const win = getWindow()
|
||||
if (!win) return
|
||||
if (win.isMinimized()) win.restore()
|
||||
win.show()
|
||||
win.focus()
|
||||
}
|
||||
|
||||
const contextMenu = Menu.buildFromTemplate([
|
||||
{ label: 'Show CowAgent', click: showWindow },
|
||||
{
|
||||
label: 'New Chat',
|
||||
click: () => {
|
||||
showWindow()
|
||||
getWindow()?.webContents.send('menu-action', 'new-chat')
|
||||
},
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{ label: 'Quit', click: onQuit },
|
||||
])
|
||||
tray.setContextMenu(contextMenu)
|
||||
|
||||
// Single click restores the window (common Windows/Linux behavior).
|
||||
tray.on('click', showWindow)
|
||||
|
||||
return tray
|
||||
}
|
||||
|
||||
export function destroyTray() {
|
||||
tray?.destroy()
|
||||
tray = null
|
||||
}
|
||||
Reference in New Issue
Block a user