diff --git a/packages/shared/IpcChannel.ts b/packages/shared/IpcChannel.ts index bae5c54a7e..20bc852e7e 100644 --- a/packages/shared/IpcChannel.ts +++ b/packages/shared/IpcChannel.ts @@ -35,6 +35,7 @@ export enum IpcChannel { App_InstallBunBinary = 'app:install-bun-binary', App_LogToMain = 'app:log-to-main', App_SaveData = 'app:save-data', + App_SetFullScreen = 'app:set-full-screen', App_MacIsProcessTrusted = 'app:mac-is-process-trusted', App_MacRequestProcessTrust = 'app:mac-request-process-trust', diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 98d384c7cc..f094e8d580 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -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) => { configManager.set(key, value, isNotify) }) diff --git a/src/main/services/WindowService.ts b/src/main/services/WindowService.ts index 185901322f..e2c2dc4866 100644 --- a/src/main/services/WindowService.ts +++ b/src/main/services/WindowService.ts @@ -223,26 +223,26 @@ export class WindowService { }) // 添加Escape键退出全屏的支持 - mainWindow.webContents.on('before-input-event', (event, input) => { - // 当按下Escape键且窗口处于全屏状态时退出全屏 - if (input.key === 'Escape' && !input.alt && !input.control && !input.meta && !input.shift) { - if (mainWindow.isFullScreen()) { - // 获取 shortcuts 配置 - const shortcuts = configManager.getShortcuts() - const exitFullscreenShortcut = shortcuts.find((s) => s.key === 'exit_fullscreen') - if (exitFullscreenShortcut == undefined) { - mainWindow.setFullScreen(false) - return - } - if (exitFullscreenShortcut?.enabled) { - event.preventDefault() - mainWindow.setFullScreen(false) - return - } - } - } - return - }) + // mainWindow.webContents.on('before-input-event', (event, input) => { + // // 当按下Escape键且窗口处于全屏状态时退出全屏 + // if (input.key === 'Escape' && !input.alt && !input.control && !input.meta && !input.shift) { + // if (mainWindow.isFullScreen()) { + // // 获取 shortcuts 配置 + // const shortcuts = configManager.getShortcuts() + // const exitFullscreenShortcut = shortcuts.find((s) => s.key === 'exit_fullscreen') + // if (exitFullscreenShortcut == undefined) { + // mainWindow.setFullScreen(false) + // return + // } + // if (exitFullscreenShortcut?.enabled) { + // event.preventDefault() + // mainWindow.setFullScreen(false) + // return + // } + // } + // } + // return + // }) } private setupWebContentsHandlers(mainWindow: BrowserWindow) { diff --git a/src/preload/index.ts b/src/preload/index.ts index 9b46576476..594bade1db 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -76,6 +76,7 @@ const api = { clearCache: () => ipcRenderer.invoke(IpcChannel.App_ClearCache), logToMain: (source: LogSourceWithContext, level: LogLevel, message: string, data: any[]) => ipcRenderer.invoke(IpcChannel.App_LogToMain, source, level, message, data), + setFullScreen: (value: boolean): Promise => ipcRenderer.invoke(IpcChannel.App_SetFullScreen, value), mac: { isProcessTrusted: (): Promise => ipcRenderer.invoke(IpcChannel.App_MacIsProcessTrusted), requestProcessTrust: (): Promise => ipcRenderer.invoke(IpcChannel.App_MacRequestProcessTrust) diff --git a/src/renderer/src/components/CollapsibleSearchBar.tsx b/src/renderer/src/components/CollapsibleSearchBar.tsx index 0b7c038a68..3ce3b436be 100644 --- a/src/renderer/src/components/CollapsibleSearchBar.tsx +++ b/src/renderer/src/components/CollapsibleSearchBar.tsx @@ -62,6 +62,7 @@ const CollapsibleSearchBar: React.FC = ({ onSearch, i onChange={(e) => handleTextChange(e.target.value)} onKeyDown={(e) => { if (e.key === 'Escape') { + e.stopPropagation() handleTextChange('') if (!searchText) setSearchVisible(false) } diff --git a/src/renderer/src/components/ContentSearch.tsx b/src/renderer/src/components/ContentSearch.tsx index 6842312137..637af96de4 100644 --- a/src/renderer/src/components/ContentSearch.tsx +++ b/src/renderer/src/components/ContentSearch.tsx @@ -282,6 +282,7 @@ export const ContentSearch = React.forwardRef( implementation.searchNext() } } else if (event.key === 'Escape') { + event.stopPropagation() implementation.disable() } }, diff --git a/src/renderer/src/components/EditableNumber/index.tsx b/src/renderer/src/components/EditableNumber/index.tsx index 3cc0f09507..220cf5fb57 100644 --- a/src/renderer/src/components/EditableNumber/index.tsx +++ b/src/renderer/src/components/EditableNumber/index.tsx @@ -63,6 +63,7 @@ const EditableNumber: FC = ({ if (e.key === 'Enter') { handleBlur() } else if (e.key === 'Escape') { + e.stopPropagation() setInputValue(value) setIsEditing(false) } diff --git a/src/renderer/src/components/Popups/SelectModelPopup/popup.tsx b/src/renderer/src/components/Popups/SelectModelPopup/popup.tsx index e7557f5e5e..3ea309f6a0 100644 --- a/src/renderer/src/components/Popups/SelectModelPopup/popup.tsx +++ b/src/renderer/src/components/Popups/SelectModelPopup/popup.tsx @@ -256,6 +256,7 @@ const PopupContainer: React.FC = ({ model, resolve, modelFilter }) => { break case 'Escape': e.preventDefault() + e.stopPropagation() setOpen(false) resolve(undefined) break diff --git a/src/renderer/src/components/QuickPanel/view.tsx b/src/renderer/src/components/QuickPanel/view.tsx index c955453903..a129477599 100644 --- a/src/renderer/src/components/QuickPanel/view.tsx +++ b/src/renderer/src/components/QuickPanel/view.tsx @@ -456,6 +456,7 @@ export const QuickPanelView: React.FC = ({ setInputText }) => { } break case 'Escape': + e.stopPropagation() handleClose('esc') break } diff --git a/src/renderer/src/components/TopView/index.tsx b/src/renderer/src/components/TopView/index.tsx index 91d5cc42cd..8c8b48a22c 100644 --- a/src/renderer/src/components/TopView/index.tsx +++ b/src/renderer/src/components/TopView/index.tsx @@ -1,5 +1,7 @@ +import { loggerService } from '@logger' import TopViewMinappContainer from '@renderer/components/MinApp/TopViewMinappContainer' import { useAppInit } from '@renderer/hooks/useAppInit' +import { useShortcuts } from '@renderer/hooks/useShortcuts' import { message, Modal } from 'antd' import React, { PropsWithChildren, useCallback, useEffect, useRef, useState } from 'react' @@ -24,6 +26,8 @@ type ElementItem = { element: React.FC | React.ReactNode } +const logger = loggerService.withContext('TopView') + const TopViewContainer: React.FC = ({ children }) => { const [elements, setElements] = useState([]) const elementsRef = useRef([]) @@ -31,6 +35,8 @@ const TopViewContainer: React.FC = ({ children }) => { const [messageApi, messageContextHolder] = message.useMessage() const [modal, modalContextHolder] = Modal.useModal() + const { shortcuts } = useShortcuts() + const enableQuitFullScreen = shortcuts.find((item) => item.key === 'exit_fullscreen')?.enabled useAppInit() @@ -72,8 +78,20 @@ const TopViewContainer: React.FC = ({ children }) => { ) }, []) + const handleKeyDown = useCallback( + (e: React.KeyboardEvent) => { + 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 ( - <> +
{children} {messageContextHolder} {modalContextHolder} @@ -83,7 +101,7 @@ const TopViewContainer: React.FC = ({ children }) => { {typeof Element === 'function' ? : Element} ))} - +
) } diff --git a/src/renderer/src/hooks/useInPlaceEdit.ts b/src/renderer/src/hooks/useInPlaceEdit.ts index 3af085f99a..077b6d21cb 100644 --- a/src/renderer/src/hooks/useInPlaceEdit.ts +++ b/src/renderer/src/hooks/useInPlaceEdit.ts @@ -66,6 +66,7 @@ export function useInPlaceEdit(options: UseInPlaceEditOptions): UseInPlaceEditRe saveEdit() } else if (e.key === 'Escape') { e.preventDefault() + e.stopPropagation() cancelEdit() } }, diff --git a/src/renderer/src/pages/home/Inputbar/Inputbar.tsx b/src/renderer/src/pages/home/Inputbar/Inputbar.tsx index c31d5579fa..bb16201a22 100644 --- a/src/renderer/src/pages/home/Inputbar/Inputbar.tsx +++ b/src/renderer/src/pages/home/Inputbar/Inputbar.tsx @@ -400,6 +400,7 @@ const Inputbar: FC = ({ assistant: _assistant, setActiveTopic, topic }) = if (expanded) { if (event.key === 'Escape') { + event.stopPropagation() return onToggleExpanded() } } diff --git a/src/renderer/src/pages/settings/ProviderSettings/index.tsx b/src/renderer/src/pages/settings/ProviderSettings/index.tsx index 98d8120557..5fdfaecd64 100644 --- a/src/renderer/src/pages/settings/ProviderSettings/index.tsx +++ b/src/renderer/src/pages/settings/ProviderSettings/index.tsx @@ -466,6 +466,7 @@ const ProvidersList: FC = () => { onChange={(e) => setSearchText(e.target.value)} onKeyDown={(e) => { if (e.key === 'Escape') { + e.stopPropagation() setSearchText('') } }}