mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-03 19:30:04 +08:00
fix: 修复Escape键事件冒泡问题并改进全屏处理
修复多个组件中Escape键事件未阻止冒泡的问题 添加全屏控制IPC通道 将全屏退出逻辑移至渲染进程处理 移除主进程中冗余的全屏退出处理代码
This commit is contained in:
parent
fc174ba4ac
commit
f92edadb61
@ -35,6 +35,7 @@ export enum IpcChannel {
|
|||||||
App_InstallBunBinary = 'app:install-bun-binary',
|
App_InstallBunBinary = 'app:install-bun-binary',
|
||||||
App_LogToMain = 'app:log-to-main',
|
App_LogToMain = 'app:log-to-main',
|
||||||
App_SaveData = 'app:save-data',
|
App_SaveData = 'app:save-data',
|
||||||
|
App_SetFullScreen = 'app:set-full-screen',
|
||||||
|
|
||||||
App_MacIsProcessTrusted = 'app:mac-is-process-trusted',
|
App_MacIsProcessTrusted = 'app:mac-is-process-trusted',
|
||||||
App_MacRequestProcessTrust = 'app:mac-request-process-trust',
|
App_MacRequestProcessTrust = 'app:mac-request-process-trust',
|
||||||
|
|||||||
@ -191,6 +191,10 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ipcMain.handle(IpcChannel.App_SetFullScreen, (_, value: boolean): void => {
|
||||||
|
mainWindow.setFullScreen(value)
|
||||||
|
})
|
||||||
|
|
||||||
ipcMain.handle(IpcChannel.Config_Set, (_, key: string, value: any, isNotify: boolean = false) => {
|
ipcMain.handle(IpcChannel.Config_Set, (_, key: string, value: any, isNotify: boolean = false) => {
|
||||||
configManager.set(key, value, isNotify)
|
configManager.set(key, value, isNotify)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -223,26 +223,26 @@ export class WindowService {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 添加Escape键退出全屏的支持
|
// 添加Escape键退出全屏的支持
|
||||||
mainWindow.webContents.on('before-input-event', (event, input) => {
|
// mainWindow.webContents.on('before-input-event', (event, input) => {
|
||||||
// 当按下Escape键且窗口处于全屏状态时退出全屏
|
// // 当按下Escape键且窗口处于全屏状态时退出全屏
|
||||||
if (input.key === 'Escape' && !input.alt && !input.control && !input.meta && !input.shift) {
|
// if (input.key === 'Escape' && !input.alt && !input.control && !input.meta && !input.shift) {
|
||||||
if (mainWindow.isFullScreen()) {
|
// if (mainWindow.isFullScreen()) {
|
||||||
// 获取 shortcuts 配置
|
// // 获取 shortcuts 配置
|
||||||
const shortcuts = configManager.getShortcuts()
|
// const shortcuts = configManager.getShortcuts()
|
||||||
const exitFullscreenShortcut = shortcuts.find((s) => s.key === 'exit_fullscreen')
|
// const exitFullscreenShortcut = shortcuts.find((s) => s.key === 'exit_fullscreen')
|
||||||
if (exitFullscreenShortcut == undefined) {
|
// if (exitFullscreenShortcut == undefined) {
|
||||||
mainWindow.setFullScreen(false)
|
// mainWindow.setFullScreen(false)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
if (exitFullscreenShortcut?.enabled) {
|
// if (exitFullscreenShortcut?.enabled) {
|
||||||
event.preventDefault()
|
// event.preventDefault()
|
||||||
mainWindow.setFullScreen(false)
|
// mainWindow.setFullScreen(false)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return
|
// return
|
||||||
})
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
private setupWebContentsHandlers(mainWindow: BrowserWindow) {
|
private setupWebContentsHandlers(mainWindow: BrowserWindow) {
|
||||||
|
|||||||
@ -76,6 +76,7 @@ const api = {
|
|||||||
clearCache: () => ipcRenderer.invoke(IpcChannel.App_ClearCache),
|
clearCache: () => ipcRenderer.invoke(IpcChannel.App_ClearCache),
|
||||||
logToMain: (source: LogSourceWithContext, level: LogLevel, message: string, data: any[]) =>
|
logToMain: (source: LogSourceWithContext, level: LogLevel, message: string, data: any[]) =>
|
||||||
ipcRenderer.invoke(IpcChannel.App_LogToMain, source, level, message, data),
|
ipcRenderer.invoke(IpcChannel.App_LogToMain, source, level, message, data),
|
||||||
|
setFullScreen: (value: boolean): Promise<void> => ipcRenderer.invoke(IpcChannel.App_SetFullScreen, value),
|
||||||
mac: {
|
mac: {
|
||||||
isProcessTrusted: (): Promise<boolean> => ipcRenderer.invoke(IpcChannel.App_MacIsProcessTrusted),
|
isProcessTrusted: (): Promise<boolean> => ipcRenderer.invoke(IpcChannel.App_MacIsProcessTrusted),
|
||||||
requestProcessTrust: (): Promise<boolean> => ipcRenderer.invoke(IpcChannel.App_MacRequestProcessTrust)
|
requestProcessTrust: (): Promise<boolean> => ipcRenderer.invoke(IpcChannel.App_MacRequestProcessTrust)
|
||||||
|
|||||||
@ -62,6 +62,7 @@ const CollapsibleSearchBar: React.FC<CollapsibleSearchBarProps> = ({ onSearch, i
|
|||||||
onChange={(e) => handleTextChange(e.target.value)}
|
onChange={(e) => handleTextChange(e.target.value)}
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (e.key === 'Escape') {
|
if (e.key === 'Escape') {
|
||||||
|
e.stopPropagation()
|
||||||
handleTextChange('')
|
handleTextChange('')
|
||||||
if (!searchText) setSearchVisible(false)
|
if (!searchText) setSearchVisible(false)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -282,6 +282,7 @@ export const ContentSearch = React.forwardRef<ContentSearchRef, Props>(
|
|||||||
implementation.searchNext()
|
implementation.searchNext()
|
||||||
}
|
}
|
||||||
} else if (event.key === 'Escape') {
|
} else if (event.key === 'Escape') {
|
||||||
|
event.stopPropagation()
|
||||||
implementation.disable()
|
implementation.disable()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -63,6 +63,7 @@ const EditableNumber: FC<EditableNumberProps> = ({
|
|||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
handleBlur()
|
handleBlur()
|
||||||
} else if (e.key === 'Escape') {
|
} else if (e.key === 'Escape') {
|
||||||
|
e.stopPropagation()
|
||||||
setInputValue(value)
|
setInputValue(value)
|
||||||
setIsEditing(false)
|
setIsEditing(false)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -256,6 +256,7 @@ const PopupContainer: React.FC<Props> = ({ model, resolve, modelFilter }) => {
|
|||||||
break
|
break
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
setOpen(false)
|
setOpen(false)
|
||||||
resolve(undefined)
|
resolve(undefined)
|
||||||
break
|
break
|
||||||
|
|||||||
@ -456,6 +456,7 @@ export const QuickPanelView: React.FC<Props> = ({ setInputText }) => {
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
|
e.stopPropagation()
|
||||||
handleClose('esc')
|
handleClose('esc')
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
|
import { loggerService } from '@logger'
|
||||||
import TopViewMinappContainer from '@renderer/components/MinApp/TopViewMinappContainer'
|
import TopViewMinappContainer from '@renderer/components/MinApp/TopViewMinappContainer'
|
||||||
import { useAppInit } from '@renderer/hooks/useAppInit'
|
import { useAppInit } from '@renderer/hooks/useAppInit'
|
||||||
|
import { useShortcuts } from '@renderer/hooks/useShortcuts'
|
||||||
import { message, Modal } from 'antd'
|
import { message, Modal } from 'antd'
|
||||||
import React, { PropsWithChildren, useCallback, useEffect, useRef, useState } from 'react'
|
import React, { PropsWithChildren, useCallback, useEffect, useRef, useState } from 'react'
|
||||||
|
|
||||||
@ -24,6 +26,8 @@ type ElementItem = {
|
|||||||
element: React.FC | React.ReactNode
|
element: React.FC | React.ReactNode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const logger = loggerService.withContext('TopView')
|
||||||
|
|
||||||
const TopViewContainer: React.FC<Props> = ({ children }) => {
|
const TopViewContainer: React.FC<Props> = ({ children }) => {
|
||||||
const [elements, setElements] = useState<ElementItem[]>([])
|
const [elements, setElements] = useState<ElementItem[]>([])
|
||||||
const elementsRef = useRef<ElementItem[]>([])
|
const elementsRef = useRef<ElementItem[]>([])
|
||||||
@ -31,6 +35,8 @@ const TopViewContainer: React.FC<Props> = ({ children }) => {
|
|||||||
|
|
||||||
const [messageApi, messageContextHolder] = message.useMessage()
|
const [messageApi, messageContextHolder] = message.useMessage()
|
||||||
const [modal, modalContextHolder] = Modal.useModal()
|
const [modal, modalContextHolder] = Modal.useModal()
|
||||||
|
const { shortcuts } = useShortcuts()
|
||||||
|
const enableQuitFullScreen = shortcuts.find((item) => item.key === 'exit_fullscreen')?.enabled
|
||||||
|
|
||||||
useAppInit()
|
useAppInit()
|
||||||
|
|
||||||
@ -72,8 +78,20 @@ const TopViewContainer: React.FC<Props> = ({ children }) => {
|
|||||||
)
|
)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
const handleKeyDown = useCallback(
|
||||||
|
(e: React.KeyboardEvent<HTMLDivElement>) => {
|
||||||
|
logger.debug('keydown', e)
|
||||||
|
if (!enableQuitFullScreen) return
|
||||||
|
|
||||||
|
if (e.key === 'Escape' && !e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey) {
|
||||||
|
window.api.setFullScreen(false)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[enableQuitFullScreen]
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div onKeyDown={handleKeyDown}>
|
||||||
{children}
|
{children}
|
||||||
{messageContextHolder}
|
{messageContextHolder}
|
||||||
{modalContextHolder}
|
{modalContextHolder}
|
||||||
@ -83,7 +101,7 @@ const TopViewContainer: React.FC<Props> = ({ children }) => {
|
|||||||
{typeof Element === 'function' ? <Element /> : Element}
|
{typeof Element === 'function' ? <Element /> : Element}
|
||||||
</FullScreenContainer>
|
</FullScreenContainer>
|
||||||
))}
|
))}
|
||||||
</>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -66,6 +66,7 @@ export function useInPlaceEdit(options: UseInPlaceEditOptions): UseInPlaceEditRe
|
|||||||
saveEdit()
|
saveEdit()
|
||||||
} else if (e.key === 'Escape') {
|
} else if (e.key === 'Escape') {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
cancelEdit()
|
cancelEdit()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -400,6 +400,7 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
|
|||||||
|
|
||||||
if (expanded) {
|
if (expanded) {
|
||||||
if (event.key === 'Escape') {
|
if (event.key === 'Escape') {
|
||||||
|
event.stopPropagation()
|
||||||
return onToggleExpanded()
|
return onToggleExpanded()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -466,6 +466,7 @@ const ProvidersList: FC = () => {
|
|||||||
onChange={(e) => setSearchText(e.target.value)}
|
onChange={(e) => setSearchText(e.target.value)}
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (e.key === 'Escape') {
|
if (e.key === 'Escape') {
|
||||||
|
e.stopPropagation()
|
||||||
setSearchText('')
|
setSearchText('')
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user