mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-26 03:31:24 +08:00
* feat(SelectionAssistant): add macOS support and process trust handling - Updated the selection assistant to support macOS, including new IPC channels for process trust verification. - Enhanced the SelectionService to check for accessibility permissions on macOS before starting the service. - Added user interface elements to guide macOS users in granting necessary permissions. - Updated localization files to reflect macOS support and provide relevant user instructions. - Refactored selection-related configurations to accommodate both Windows and macOS environments. * feat(SelectionService): update toolbar window settings for macOS and Windows - Set the toolbar window to be hidden in Mission Control and accept the first mouse click on macOS. - Adjusted visibility settings for the toolbar window to ensure it appears correctly on all workspaces, including full-screen mode. - Refactored the MacProcessTrustHintModal component to improve layout and styling of buttons in the modal footer. * feat(SelectionToolbar): enhance styling and layout of selection toolbar components * feat(SelectionService): enhance toolbar window settings and refactor position calculation * feat(SelectionToolbar): update button padding and add last button padding for improved layout * chore(dependencies): update selection-hook to version 1.0.2 and refine build file exclusions in electron-builder.yml * feat(SelectionService): center action window on screen when not following toolbar * fix(SelectionService): implement workaround to prevent other windows from bringing the app to front on macOS when action window is closed * fix(SelectionService): refine macOS workaround to prevent other windows from bringing the app to front when action window is closed; update selection-toolbar logo padding in styles * fix(SelectionService): implement macOS toolbar reload to clear hover status; optimize display retrieval logic * fix(SelectionService): update macOS toolbar hover status handling by sending mouseMove event instead of reloading the window * chore: update selection-hook dependency to version 1.0.3 in package.json and yarn.lock * fix(SelectionService): improve toolbar visibility handling on macOS and ensure focusability of other windows when hiding the toolbar --------- Co-authored-by: Teo <cheesen.xu@gmail.com>
142 lines
3.8 KiB
TypeScript
142 lines
3.8 KiB
TypeScript
import { isLinux, isMac, isWin } from '@main/constant'
|
|
import { locales } from '@main/utils/locales'
|
|
import { app, Menu, MenuItemConstructorOptions, nativeImage, nativeTheme, Tray } from 'electron'
|
|
|
|
import icon from '../../../build/tray_icon.png?asset'
|
|
import iconDark from '../../../build/tray_icon_dark.png?asset'
|
|
import iconLight from '../../../build/tray_icon_light.png?asset'
|
|
import { ConfigKeys, configManager } from './ConfigManager'
|
|
import selectionService from './SelectionService'
|
|
import { windowService } from './WindowService'
|
|
|
|
export class TrayService {
|
|
private static instance: TrayService
|
|
private tray: Tray | null = null
|
|
private contextMenu: Menu | null = null
|
|
|
|
constructor() {
|
|
this.watchConfigChanges()
|
|
this.updateTray()
|
|
TrayService.instance = this
|
|
}
|
|
|
|
public static getInstance() {
|
|
return TrayService.instance
|
|
}
|
|
|
|
private createTray() {
|
|
this.destroyTray()
|
|
|
|
const iconPath = isMac ? (nativeTheme.shouldUseDarkColors ? iconLight : iconDark) : icon
|
|
const tray = new Tray(iconPath)
|
|
|
|
if (isWin) {
|
|
tray.setImage(iconPath)
|
|
} else if (isMac) {
|
|
const image = nativeImage.createFromPath(iconPath)
|
|
const resizedImage = image.resize({ width: 16, height: 16 })
|
|
resizedImage.setTemplateImage(true)
|
|
tray.setImage(resizedImage)
|
|
} else if (isLinux) {
|
|
const image = nativeImage.createFromPath(iconPath)
|
|
const resizedImage = image.resize({ width: 16, height: 16 })
|
|
tray.setImage(resizedImage)
|
|
}
|
|
|
|
this.tray = tray
|
|
|
|
this.updateContextMenu()
|
|
|
|
if (isLinux) {
|
|
this.tray.setContextMenu(this.contextMenu)
|
|
}
|
|
|
|
this.tray.setToolTip('Cherry Studio')
|
|
|
|
this.tray.on('right-click', () => {
|
|
if (this.contextMenu) {
|
|
this.tray?.popUpContextMenu(this.contextMenu)
|
|
}
|
|
})
|
|
|
|
this.tray.on('click', () => {
|
|
if (configManager.getEnableQuickAssistant() && configManager.getClickTrayToShowQuickAssistant()) {
|
|
windowService.showMiniWindow()
|
|
} else {
|
|
windowService.showMainWindow()
|
|
}
|
|
})
|
|
}
|
|
|
|
private updateContextMenu() {
|
|
const locale = locales[configManager.getLanguage()]
|
|
const { tray: trayLocale, selection: selectionLocale } = locale.translation
|
|
|
|
const quickAssistantEnabled = configManager.getEnableQuickAssistant()
|
|
const selectionAssistantEnabled = configManager.getSelectionAssistantEnabled()
|
|
|
|
const template = [
|
|
{
|
|
label: trayLocale.show_window,
|
|
click: () => windowService.showMainWindow()
|
|
},
|
|
quickAssistantEnabled && {
|
|
label: trayLocale.show_mini_window,
|
|
click: () => windowService.showMiniWindow()
|
|
},
|
|
(isWin || isMac) && {
|
|
label: selectionLocale.name + (selectionAssistantEnabled ? ' - On' : ' - Off'),
|
|
click: () => {
|
|
if (selectionService) {
|
|
selectionService.toggleEnabled()
|
|
this.updateContextMenu()
|
|
}
|
|
}
|
|
},
|
|
{ type: 'separator' },
|
|
{
|
|
label: trayLocale.quit,
|
|
click: () => this.quit()
|
|
}
|
|
].filter(Boolean) as MenuItemConstructorOptions[]
|
|
|
|
this.contextMenu = Menu.buildFromTemplate(template)
|
|
}
|
|
|
|
private updateTray() {
|
|
const showTray = configManager.getTray()
|
|
if (showTray) {
|
|
this.createTray()
|
|
} else {
|
|
this.destroyTray()
|
|
}
|
|
}
|
|
|
|
private destroyTray() {
|
|
if (this.tray) {
|
|
this.tray.destroy()
|
|
this.tray = null
|
|
}
|
|
}
|
|
|
|
private watchConfigChanges() {
|
|
configManager.subscribe(ConfigKeys.Tray, () => this.updateTray())
|
|
|
|
configManager.subscribe(ConfigKeys.Language, () => {
|
|
this.updateContextMenu()
|
|
})
|
|
|
|
configManager.subscribe(ConfigKeys.EnableQuickAssistant, () => {
|
|
this.updateContextMenu()
|
|
})
|
|
|
|
configManager.subscribe(ConfigKeys.SelectionAssistantEnabled, () => {
|
|
this.updateContextMenu()
|
|
})
|
|
}
|
|
|
|
private quit() {
|
|
app.quit()
|
|
}
|
|
}
|