mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-19 14:41:24 +08:00
fix(SelectionAssistant): [macOS] show actionWindow on fullscreen app (#8004)
* feat(SelectionService): enhance action window handling for macOS fullscreen mode - Updated processAction and showActionWindow methods to support fullscreen mode on macOS. - Added isFullScreen parameter to manage action window visibility and positioning. - Improved action window positioning logic to ensure it remains within screen boundaries. - Adjusted IPC channel to pass fullscreen state from the renderer to the service. - Updated SelectionToolbar to track fullscreen state and pass it to the action processing function. * chore(deps): update selection-hook to version 1.0.6 in package.json and yarn.lock * fix(SelectionService): improve macOS fullscreen handling and action window focus - Added app import to manage dock visibility on macOS. - Enhanced fullscreen handling logic to ensure the dock icon is restored correctly. - Updated action window focus behavior to prevent unintended hiding when blurred. - Refactored SelectionActionApp to streamline auto pinning logic and remove redundant useEffect. - Cleaned up SelectionToolbar by removing unnecessary window size updates when demo is false. * refactor(SelectionService): remove commented-out code for clarity * refactor(SelectionService): streamline macOS handling and improve code clarity
This commit is contained in:
parent
855499681f
commit
7c6db809bb
@ -71,7 +71,7 @@
|
|||||||
"notion-helper": "^1.3.22",
|
"notion-helper": "^1.3.22",
|
||||||
"os-proxy-config": "^1.1.2",
|
"os-proxy-config": "^1.1.2",
|
||||||
"pdfjs-dist": "4.10.38",
|
"pdfjs-dist": "4.10.38",
|
||||||
"selection-hook": "^1.0.5",
|
"selection-hook": "^1.0.6",
|
||||||
"turndown": "7.2.0"
|
"turndown": "7.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { SELECTION_FINETUNED_LIST, SELECTION_PREDEFINED_BLACKLIST } from '@main/configs/SelectionConfig'
|
import { SELECTION_FINETUNED_LIST, SELECTION_PREDEFINED_BLACKLIST } from '@main/configs/SelectionConfig'
|
||||||
import { isDev, isMac, isWin } from '@main/constant'
|
import { isDev, isMac, isWin } from '@main/constant'
|
||||||
import { IpcChannel } from '@shared/IpcChannel'
|
import { IpcChannel } from '@shared/IpcChannel'
|
||||||
import { BrowserWindow, ipcMain, screen, systemPreferences } from 'electron'
|
import { app, BrowserWindow, ipcMain, screen, systemPreferences } from 'electron'
|
||||||
import Logger from 'electron-log'
|
import Logger from 'electron-log'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import type {
|
import type {
|
||||||
@ -509,54 +509,55 @@ export class SelectionService {
|
|||||||
//should set every time the window is shown
|
//should set every time the window is shown
|
||||||
this.toolbarWindow!.setAlwaysOnTop(true, 'screen-saver')
|
this.toolbarWindow!.setAlwaysOnTop(true, 'screen-saver')
|
||||||
|
|
||||||
// [macOS] a series of hacky ways only for macOS
|
if (!isMac) {
|
||||||
if (isMac) {
|
this.toolbarWindow!.show()
|
||||||
// [macOS] a hacky way
|
/**
|
||||||
// when set `skipTransformProcessType: true`, if the selection is in self app, it will make the selection canceled after toolbar showing
|
* [Windows]
|
||||||
// so we just don't set `skipTransformProcessType: true` when in self app
|
* In Windows 10, setOpacity(1) will make the window completely transparent
|
||||||
const isSelf = ['com.github.Electron', 'com.kangfenmao.CherryStudio'].includes(programName)
|
* It's a strange behavior, so we don't use it for compatibility
|
||||||
|
*/
|
||||||
if (!isSelf) {
|
// this.toolbarWindow!.setOpacity(1)
|
||||||
// [macOS] an ugly hacky way
|
|
||||||
// `focusable: true` will make mainWindow disappeared when `setVisibleOnAllWorkspaces`
|
|
||||||
// so we set `focusable: true` before showing, and then set false after showing
|
|
||||||
this.toolbarWindow!.setFocusable(false)
|
|
||||||
|
|
||||||
// [macOS]
|
|
||||||
// force `setVisibleOnAllWorkspaces: true` to let toolbar show in all workspaces. And we MUST not set it to false again
|
|
||||||
// set `skipTransformProcessType: true` to avoid dock icon spinning when `setVisibleOnAllWorkspaces`
|
|
||||||
this.toolbarWindow!.setVisibleOnAllWorkspaces(true, {
|
|
||||||
visibleOnFullScreen: true,
|
|
||||||
skipTransformProcessType: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// [macOS] MUST use `showInactive()` to prevent other windows bring to front together
|
|
||||||
// [Windows] is OK for both `show()` and `showInactive()` because of `focusable: false`
|
|
||||||
this.toolbarWindow!.showInactive()
|
|
||||||
|
|
||||||
// [macOS] restore the focusable status
|
|
||||||
this.toolbarWindow!.setFocusable(true)
|
|
||||||
|
|
||||||
this.startHideByMouseKeyListener()
|
this.startHideByMouseKeyListener()
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/************************************************
|
||||||
* The following is for Windows
|
* [macOS] the following code is only for macOS
|
||||||
*/
|
*
|
||||||
|
* WARNING:
|
||||||
|
* DO NOT MODIFY THESE CODES, UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!!!!
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
this.toolbarWindow!.show()
|
// [macOS] a hacky way
|
||||||
|
// when set `skipTransformProcessType: true`, if the selection is in self app, it will make the selection canceled after toolbar showing
|
||||||
|
// so we just don't set `skipTransformProcessType: true` when in self app
|
||||||
|
const isSelf = ['com.github.Electron', 'com.kangfenmao.CherryStudio'].includes(programName)
|
||||||
|
|
||||||
/**
|
if (!isSelf) {
|
||||||
* [Windows]
|
// [macOS] an ugly hacky way
|
||||||
* In Windows 10, setOpacity(1) will make the window completely transparent
|
// `focusable: true` will make mainWindow disappeared when `setVisibleOnAllWorkspaces`
|
||||||
* It's a strange behavior, so we don't use it for compatibility
|
// so we set `focusable: true` before showing, and then set false after showing
|
||||||
*/
|
this.toolbarWindow!.setFocusable(false)
|
||||||
// this.toolbarWindow!.setOpacity(1)
|
|
||||||
|
// [macOS]
|
||||||
|
// force `setVisibleOnAllWorkspaces: true` to let toolbar show in all workspaces. And we MUST not set it to false again
|
||||||
|
// set `skipTransformProcessType: true` to avoid dock icon spinning when `setVisibleOnAllWorkspaces`
|
||||||
|
this.toolbarWindow!.setVisibleOnAllWorkspaces(true, {
|
||||||
|
visibleOnFullScreen: true,
|
||||||
|
skipTransformProcessType: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// [macOS] MUST use `showInactive()` to prevent other windows bring to front together
|
||||||
|
// [Windows] is OK for both `show()` and `showInactive()` because of `focusable: false`
|
||||||
|
this.toolbarWindow!.showInactive()
|
||||||
|
|
||||||
|
// [macOS] restore the focusable status
|
||||||
|
this.toolbarWindow!.setFocusable(true)
|
||||||
|
|
||||||
this.startHideByMouseKeyListener()
|
this.startHideByMouseKeyListener()
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -911,6 +912,7 @@ export class SelectionService {
|
|||||||
refPoint = { x: Math.round(refPoint.x), y: Math.round(refPoint.y) }
|
refPoint = { x: Math.round(refPoint.x), y: Math.round(refPoint.y) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [macOS] isFullscreen is only available on macOS
|
||||||
this.showToolbarAtPosition(refPoint, refOrientation, selectionData.programName)
|
this.showToolbarAtPosition(refPoint, refOrientation, selectionData.programName)
|
||||||
this.toolbarWindow!.webContents.send(IpcChannel.Selection_TextSelected, selectionData)
|
this.toolbarWindow!.webContents.send(IpcChannel.Selection_TextSelected, selectionData)
|
||||||
}
|
}
|
||||||
@ -1218,20 +1220,26 @@ export class SelectionService {
|
|||||||
return actionWindow
|
return actionWindow
|
||||||
}
|
}
|
||||||
|
|
||||||
public processAction(actionItem: ActionItem): void {
|
/**
|
||||||
|
* Process action item
|
||||||
|
* @param actionItem Action item to process
|
||||||
|
* @param isFullScreen [macOS] only macOS has the available isFullscreen mode
|
||||||
|
*/
|
||||||
|
public processAction(actionItem: ActionItem, isFullScreen: boolean = false): void {
|
||||||
const actionWindow = this.popActionWindow()
|
const actionWindow = this.popActionWindow()
|
||||||
|
|
||||||
actionWindow.webContents.send(IpcChannel.Selection_UpdateActionData, actionItem)
|
actionWindow.webContents.send(IpcChannel.Selection_UpdateActionData, actionItem)
|
||||||
|
|
||||||
this.showActionWindow(actionWindow)
|
this.showActionWindow(actionWindow, isFullScreen)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show action window with proper positioning relative to toolbar
|
* Show action window with proper positioning relative to toolbar
|
||||||
* Ensures window stays within screen boundaries
|
* Ensures window stays within screen boundaries
|
||||||
* @param actionWindow Window to position and show
|
* @param actionWindow Window to position and show
|
||||||
|
* @param isFullScreen [macOS] only macOS has the available isFullscreen mode
|
||||||
*/
|
*/
|
||||||
private showActionWindow(actionWindow: BrowserWindow): void {
|
private showActionWindow(actionWindow: BrowserWindow, isFullScreen: boolean = false): void {
|
||||||
let actionWindowWidth = this.ACTION_WINDOW_WIDTH
|
let actionWindowWidth = this.ACTION_WINDOW_WIDTH
|
||||||
let actionWindowHeight = this.ACTION_WINDOW_HEIGHT
|
let actionWindowHeight = this.ACTION_WINDOW_HEIGHT
|
||||||
|
|
||||||
@ -1241,11 +1249,14 @@ export class SelectionService {
|
|||||||
actionWindowHeight = this.lastActionWindowSize.height
|
actionWindowHeight = this.lastActionWindowSize.height
|
||||||
}
|
}
|
||||||
|
|
||||||
//center way
|
/********************************************
|
||||||
if (!this.isFollowToolbar || !this.toolbarWindow) {
|
* Setting the position of the action window
|
||||||
const display = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
|
********************************************/
|
||||||
const workArea = display.workArea
|
const display = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
|
||||||
|
const workArea = display.workArea
|
||||||
|
|
||||||
|
// Center of the screen
|
||||||
|
if (!this.isFollowToolbar || !this.toolbarWindow) {
|
||||||
const centerX = workArea.x + (workArea.width - actionWindowWidth) / 2
|
const centerX = workArea.x + (workArea.width - actionWindowWidth) / 2
|
||||||
const centerY = workArea.y + (workArea.height - actionWindowHeight) / 2
|
const centerY = workArea.y + (workArea.height - actionWindowHeight) / 2
|
||||||
|
|
||||||
@ -1255,54 +1266,107 @@ export class SelectionService {
|
|||||||
x: Math.round(centerX),
|
x: Math.round(centerX),
|
||||||
y: Math.round(centerY)
|
y: Math.round(centerY)
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
// Follow toolbar position
|
||||||
|
const toolbarBounds = this.toolbarWindow!.getBounds()
|
||||||
|
const GAP = 6 // 6px gap from screen edges
|
||||||
|
|
||||||
|
//make sure action window is inside screen
|
||||||
|
if (actionWindowWidth > workArea.width - 2 * GAP) {
|
||||||
|
actionWindowWidth = workArea.width - 2 * GAP
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actionWindowHeight > workArea.height - 2 * GAP) {
|
||||||
|
actionWindowHeight = workArea.height - 2 * GAP
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate initial position to center action window horizontally below toolbar
|
||||||
|
let posX = Math.round(toolbarBounds.x + (toolbarBounds.width - actionWindowWidth) / 2)
|
||||||
|
let posY = Math.round(toolbarBounds.y)
|
||||||
|
|
||||||
|
// Ensure action window stays within screen boundaries with a small gap
|
||||||
|
if (posX + actionWindowWidth > workArea.x + workArea.width) {
|
||||||
|
posX = workArea.x + workArea.width - actionWindowWidth - GAP
|
||||||
|
} else if (posX < workArea.x) {
|
||||||
|
posX = workArea.x + GAP
|
||||||
|
}
|
||||||
|
if (posY + actionWindowHeight > workArea.y + workArea.height) {
|
||||||
|
// If window would go below screen, try to position it above toolbar
|
||||||
|
posY = workArea.y + workArea.height - actionWindowHeight - GAP
|
||||||
|
} else if (posY < workArea.y) {
|
||||||
|
posY = workArea.y + GAP
|
||||||
|
}
|
||||||
|
|
||||||
|
actionWindow.setPosition(posX, posY, false)
|
||||||
|
//KEY to make window not resize
|
||||||
|
actionWindow.setBounds({
|
||||||
|
width: actionWindowWidth,
|
||||||
|
height: actionWindowHeight,
|
||||||
|
x: posX,
|
||||||
|
y: posY
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isMac) {
|
||||||
actionWindow.show()
|
actionWindow.show()
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//follow toolbar
|
/************************************************
|
||||||
const toolbarBounds = this.toolbarWindow!.getBounds()
|
* [macOS] the following code is only for macOS
|
||||||
const display = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
|
*
|
||||||
const workArea = display.workArea
|
* WARNING:
|
||||||
const GAP = 6 // 6px gap from screen edges
|
* DO NOT MODIFY THESE CODES, UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!!!!
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
//make sure action window is inside screen
|
// act normally when the app is not in fullscreen mode
|
||||||
if (actionWindowWidth > workArea.width - 2 * GAP) {
|
if (!isFullScreen) {
|
||||||
actionWindowWidth = workArea.width - 2 * GAP
|
actionWindow.show()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionWindowHeight > workArea.height - 2 * GAP) {
|
// [macOS] an UGLY HACKY way for fullscreen override settings
|
||||||
actionWindowHeight = workArea.height - 2 * GAP
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate initial position to center action window horizontally below toolbar
|
// FIXME sometimes the dock will be shown when the action window is shown
|
||||||
let posX = Math.round(toolbarBounds.x + (toolbarBounds.width - actionWindowWidth) / 2)
|
// FIXME if actionWindow show on the fullscreen app, switch to other space will cause the mainWindow to be shown
|
||||||
let posY = Math.round(toolbarBounds.y)
|
// FIXME When setVisibleOnAllWorkspaces is true, docker icon disappeared when the first action window is shown on the fullscreen app
|
||||||
|
// use app.dock.show() to show the dock again will cause the action window to be closed when auto hide on blur is enabled
|
||||||
|
|
||||||
// Ensure action window stays within screen boundaries with a small gap
|
// setFocusable(false) to prevent the action window hide when blur (if auto hide on blur is enabled)
|
||||||
if (posX + actionWindowWidth > workArea.x + workArea.width) {
|
actionWindow.setFocusable(false)
|
||||||
posX = workArea.x + workArea.width - actionWindowWidth - GAP
|
actionWindow.setAlwaysOnTop(true, 'floating')
|
||||||
} else if (posX < workArea.x) {
|
|
||||||
posX = workArea.x + GAP
|
|
||||||
}
|
|
||||||
if (posY + actionWindowHeight > workArea.y + workArea.height) {
|
|
||||||
// If window would go below screen, try to position it above toolbar
|
|
||||||
posY = workArea.y + workArea.height - actionWindowHeight - GAP
|
|
||||||
} else if (posY < workArea.y) {
|
|
||||||
posY = workArea.y + GAP
|
|
||||||
}
|
|
||||||
|
|
||||||
actionWindow.setPosition(posX, posY, false)
|
// `setVisibleOnAllWorkspaces(true)` will cause the dock icon disappeared
|
||||||
//KEY to make window not resize
|
// just store the dock icon status, and show it again
|
||||||
actionWindow.setBounds({
|
const isDockShown = app.dock?.isVisible()
|
||||||
width: actionWindowWidth,
|
|
||||||
height: actionWindowHeight,
|
// DO NOT set `skipTransformProcessType: true`,
|
||||||
x: posX,
|
// it will cause the action window to be shown on other space
|
||||||
y: posY
|
actionWindow.setVisibleOnAllWorkspaces(true, {
|
||||||
|
visibleOnFullScreen: true
|
||||||
})
|
})
|
||||||
|
|
||||||
actionWindow.show()
|
actionWindow.showInactive()
|
||||||
|
|
||||||
|
// show the dock again if last time it was shown
|
||||||
|
// do not put it after `actionWindow.focus()`, will cause the action window to be closed when auto hide on blur is enabled
|
||||||
|
if (!app.dock?.isVisible() && isDockShown) {
|
||||||
|
app.dock?.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
// unset everything
|
||||||
|
setTimeout(() => {
|
||||||
|
actionWindow.setVisibleOnAllWorkspaces(false, {
|
||||||
|
visibleOnFullScreen: true,
|
||||||
|
skipTransformProcessType: true
|
||||||
|
})
|
||||||
|
actionWindow.setAlwaysOnTop(false)
|
||||||
|
|
||||||
|
actionWindow.setFocusable(true)
|
||||||
|
|
||||||
|
// regain the focus when all the works done
|
||||||
|
actionWindow.focus()
|
||||||
|
}, 50)
|
||||||
}
|
}
|
||||||
|
|
||||||
public closeActionWindow(actionWindow: BrowserWindow): void {
|
public closeActionWindow(actionWindow: BrowserWindow): void {
|
||||||
@ -1408,8 +1472,9 @@ export class SelectionService {
|
|||||||
configManager.setSelectionAssistantFilterList(filterList)
|
configManager.setSelectionAssistantFilterList(filterList)
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.handle(IpcChannel.Selection_ProcessAction, (_, actionItem: ActionItem) => {
|
// [macOS] only macOS has the available isFullscreen mode
|
||||||
selectionService?.processAction(actionItem)
|
ipcMain.handle(IpcChannel.Selection_ProcessAction, (_, actionItem: ActionItem, isFullScreen: boolean = false) => {
|
||||||
|
selectionService?.processAction(actionItem, isFullScreen)
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.handle(IpcChannel.Selection_ActionWindowClose, (event) => {
|
ipcMain.handle(IpcChannel.Selection_ActionWindowClose, (event) => {
|
||||||
|
|||||||
@ -309,7 +309,8 @@ const api = {
|
|||||||
ipcRenderer.invoke(IpcChannel.Selection_SetRemeberWinSize, isRemeberWinSize),
|
ipcRenderer.invoke(IpcChannel.Selection_SetRemeberWinSize, isRemeberWinSize),
|
||||||
setFilterMode: (filterMode: string) => ipcRenderer.invoke(IpcChannel.Selection_SetFilterMode, filterMode),
|
setFilterMode: (filterMode: string) => ipcRenderer.invoke(IpcChannel.Selection_SetFilterMode, filterMode),
|
||||||
setFilterList: (filterList: string[]) => ipcRenderer.invoke(IpcChannel.Selection_SetFilterList, filterList),
|
setFilterList: (filterList: string[]) => ipcRenderer.invoke(IpcChannel.Selection_SetFilterList, filterList),
|
||||||
processAction: (actionItem: ActionItem) => ipcRenderer.invoke(IpcChannel.Selection_ProcessAction, actionItem),
|
processAction: (actionItem: ActionItem, isFullScreen: boolean = false) =>
|
||||||
|
ipcRenderer.invoke(IpcChannel.Selection_ProcessAction, actionItem, isFullScreen),
|
||||||
closeActionWindow: () => ipcRenderer.invoke(IpcChannel.Selection_ActionWindowClose),
|
closeActionWindow: () => ipcRenderer.invoke(IpcChannel.Selection_ActionWindowClose),
|
||||||
minimizeActionWindow: () => ipcRenderer.invoke(IpcChannel.Selection_ActionWindowMinimize),
|
minimizeActionWindow: () => ipcRenderer.invoke(IpcChannel.Selection_ActionWindowMinimize),
|
||||||
pinActionWindow: (isPinned: boolean) => ipcRenderer.invoke(IpcChannel.Selection_ActionWindowPin, isPinned)
|
pinActionWindow: (isPinned: boolean) => ipcRenderer.invoke(IpcChannel.Selection_ActionWindowPin, isPinned)
|
||||||
|
|||||||
@ -36,10 +36,6 @@ const SelectionActionApp: FC = () => {
|
|||||||
const lastScrollHeight = useRef(0)
|
const lastScrollHeight = useRef(0)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isAutoPin) {
|
|
||||||
window.api.selection.pinActionWindow(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
const actionListenRemover = window.electron?.ipcRenderer.on(
|
const actionListenRemover = window.electron?.ipcRenderer.on(
|
||||||
IpcChannel.Selection_UpdateActionData,
|
IpcChannel.Selection_UpdateActionData,
|
||||||
(_, actionItem: ActionItem) => {
|
(_, actionItem: ActionItem) => {
|
||||||
@ -60,6 +56,20 @@ const SelectionActionApp: FC = () => {
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isAutoPin) {
|
||||||
|
window.api.selection.pinActionWindow(true)
|
||||||
|
setIsPinned(true)
|
||||||
|
} else if (!isActionLoaded.current) {
|
||||||
|
window.api.selection.pinActionWindow(false)
|
||||||
|
setIsPinned(false)
|
||||||
|
}
|
||||||
|
}, [isAutoPin])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
shouldCloseWhenBlur.current = isAutoClose && !isPinned
|
||||||
|
}, [isAutoClose, isPinned])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
i18n.changeLanguage(language || navigator.language || defaultLanguage)
|
i18n.changeLanguage(language || navigator.language || defaultLanguage)
|
||||||
}, [language])
|
}, [language])
|
||||||
@ -100,10 +110,6 @@ const SelectionActionApp: FC = () => {
|
|||||||
}
|
}
|
||||||
}, [action, t])
|
}, [action, t])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
shouldCloseWhenBlur.current = isAutoClose && !isPinned
|
|
||||||
}, [isAutoClose, isPinned])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
//if the action is loaded, we should not set the opacity update from settings
|
//if the action is loaded, we should not set the opacity update from settings
|
||||||
if (!isActionLoaded.current) {
|
if (!isActionLoaded.current) {
|
||||||
|
|||||||
@ -107,6 +107,8 @@ const SelectionToolbar: FC<{ demo?: boolean }> = ({ demo = false }) => {
|
|||||||
}, [actionItems])
|
}, [actionItems])
|
||||||
|
|
||||||
const selectedText = useRef('')
|
const selectedText = useRef('')
|
||||||
|
// [macOS] only macOS has the fullscreen mode
|
||||||
|
const isFullScreen = useRef(false)
|
||||||
|
|
||||||
// listen to selectionService events
|
// listen to selectionService events
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -115,6 +117,7 @@ const SelectionToolbar: FC<{ demo?: boolean }> = ({ demo = false }) => {
|
|||||||
IpcChannel.Selection_TextSelected,
|
IpcChannel.Selection_TextSelected,
|
||||||
(_, selectionData: TextSelectionData) => {
|
(_, selectionData: TextSelectionData) => {
|
||||||
selectedText.current = selectionData.text
|
selectedText.current = selectionData.text
|
||||||
|
isFullScreen.current = selectionData.isFullscreen ?? false
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
//make sure the animation is active
|
//make sure the animation is active
|
||||||
setAnimateKey((prev) => prev + 1)
|
setAnimateKey((prev) => prev + 1)
|
||||||
@ -133,8 +136,6 @@ const SelectionToolbar: FC<{ demo?: boolean }> = ({ demo = false }) => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!demo) updateWindowSize()
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
textSelectionListenRemover()
|
textSelectionListenRemover()
|
||||||
toolbarVisibilityChangeListenRemover()
|
toolbarVisibilityChangeListenRemover()
|
||||||
@ -234,7 +235,8 @@ const SelectionToolbar: FC<{ demo?: boolean }> = ({ demo = false }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleDefaultAction = (action: ActionItem) => {
|
const handleDefaultAction = (action: ActionItem) => {
|
||||||
window.api?.selection.processAction(action)
|
// [macOS] only macOS has the available isFullscreen mode
|
||||||
|
window.api?.selection.processAction(action, isFullScreen.current)
|
||||||
window.api?.selection.hideToolbar()
|
window.api?.selection.hideToolbar()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
10
yarn.lock
10
yarn.lock
@ -7235,7 +7235,7 @@ __metadata:
|
|||||||
remove-markdown: "npm:^0.6.2"
|
remove-markdown: "npm:^0.6.2"
|
||||||
rollup-plugin-visualizer: "npm:^5.12.0"
|
rollup-plugin-visualizer: "npm:^5.12.0"
|
||||||
sass: "npm:^1.88.0"
|
sass: "npm:^1.88.0"
|
||||||
selection-hook: "npm:^1.0.5"
|
selection-hook: "npm:^1.0.6"
|
||||||
shiki: "npm:^3.7.0"
|
shiki: "npm:^3.7.0"
|
||||||
string-width: "npm:^7.2.0"
|
string-width: "npm:^7.2.0"
|
||||||
styled-components: "npm:^6.1.11"
|
styled-components: "npm:^6.1.11"
|
||||||
@ -18229,14 +18229,14 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"selection-hook@npm:^1.0.5":
|
"selection-hook@npm:^1.0.6":
|
||||||
version: 1.0.5
|
version: 1.0.6
|
||||||
resolution: "selection-hook@npm:1.0.5"
|
resolution: "selection-hook@npm:1.0.6"
|
||||||
dependencies:
|
dependencies:
|
||||||
node-addon-api: "npm:^8.4.0"
|
node-addon-api: "npm:^8.4.0"
|
||||||
node-gyp: "npm:latest"
|
node-gyp: "npm:latest"
|
||||||
node-gyp-build: "npm:^4.8.4"
|
node-gyp-build: "npm:^4.8.4"
|
||||||
checksum: 10c0/d188e2bafa6d820779e57a721bd2480dc1fde3f9daa2e3f92f1b69712637079e5fd9443575bc8624c98a057608f867d82fb2abf2d0796777db1f18ea50ea0028
|
checksum: 10c0/c7d28db51fc16b5648530344cbe1d5b72a7469cfb7edbb9c56d7be4bea2d93ddd01993fb27b344e44865f9eb0f3211b1be638caaacd0f9165b2bc03bada7c360
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user