fix: miniWindow not sync with theme change (#3643)

* fix: miniWindow not sync theme change

* fix: mac: miniWindow theme display incorrect

* fix: mac: miniWindow display error when system dark+ app light
This commit is contained in:
fullex 2025-03-21 13:11:21 +08:00 committed by GitHub
parent 707e713e73
commit d0ddfce280
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 42 additions and 7 deletions

View File

@ -84,8 +84,21 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) {
})
// theme
ipcMain.handle('app:set-theme', (_, theme: ThemeMode) => {
ipcMain.handle('app:set-theme', (event, theme: ThemeMode) => {
if (theme === configManager.getTheme()) return
configManager.setTheme(theme)
// should sync theme change to all windows
const senderWindowId = event.sender.id
const windows = BrowserWindow.getAllWindows()
// 向其他窗口广播主题变化
windows.forEach((win) => {
if (win.webContents.id !== senderWindowId) {
win.webContents.send('theme:change', theme)
}
})
mainWindow?.setTitleBarOverlay &&
mainWindow.setTitleBarOverlay(theme === 'dark' ? titleBarOverlayDark : titleBarOverlayLight)
})

View File

@ -45,7 +45,15 @@ export const ThemeProvider: React.FC<ThemeProviderProps> = ({ children, defaultT
useEffect(() => {
document.body.setAttribute('os', isMac ? 'mac' : 'windows')
}, [])
// listen theme change from main process from other windows
const themeChangeListenerRemover = window.electron.ipcRenderer.on('theme:change', (_, newTheme) => {
setTheme(newTheme)
})
return () => {
themeChangeListenerRemover()
}
})
return <ThemeContext.Provider value={{ theme: _theme, toggleTheme }}>{children}</ThemeContext.Provider>
}

View File

@ -29,7 +29,7 @@ const HomeWindow: FC = () => {
const textChange = useState(() => {})[1]
const { defaultAssistant } = useDefaultAssistant()
const { defaultModel: model } = useDefaultModel()
const { language, readClipboardAtStartup } = useSettings()
const { language, readClipboardAtStartup, windowStyle, theme } = useSettings()
const { t } = useTranslation()
const inputBarRef = useRef<HTMLDivElement>(null)
const featureMenusRef = useRef<FeatureMenusRef>(null)
@ -201,9 +201,24 @@ const HomeWindow: FC = () => {
}
}, [route])
const backgroundColor = () => {
// ONLY MAC: when transparent style + light theme: use vibrancy effect
// because the dark style under mac's vibrancy effect has not been implemented
if (
isMac &&
windowStyle === 'transparent' &&
theme === 'light' &&
!window.matchMedia('(prefers-color-scheme: dark)').matches
) {
return 'transparent'
}
return 'var(--color-background)'
}
if (['chat', 'summary', 'explanation'].includes(route)) {
return (
<Container>
<Container style={{ backgroundColor: backgroundColor() }}>
{route === 'chat' && (
<>
<InputBar
@ -232,7 +247,7 @@ const HomeWindow: FC = () => {
if (route === 'translate') {
return (
<Container>
<Container style={{ backgroundColor: backgroundColor() }}>
<TranslateWindow text={referenceText} />
<Divider style={{ margin: '10px 0' }} />
<Footer route={route} onExit={() => setRoute('home')} />
@ -241,7 +256,7 @@ const HomeWindow: FC = () => {
}
return (
<Container>
<Container style={{ backgroundColor: backgroundColor() }}>
<InputBar
text={text}
model={model}
@ -280,7 +295,6 @@ const Container = styled.div`
flex-direction: column;
-webkit-app-region: drag;
padding: 8px 10px;
background-color: ${isMac ? 'transparent' : 'var(--color-background)'};
`
const Main = styled.main`