allow disable tray icon while floating window is open

This commit is contained in:
pompurin404 2024-10-06 21:08:24 +08:00
parent f49850ae8a
commit 558b9e7c30
No known key found for this signature in database
9 changed files with 67 additions and 11 deletions

View File

@ -1,3 +1,7 @@
### New Features
- 允许在开启悬浮窗的情况下禁用托盘图标
### Bug Fixes ### Bug Fixes
- 修复开启轻量模式后 TrafficMonitor 重复启动的问题 - 修复开启轻量模式后 TrafficMonitor 重复启动的问题

View File

@ -150,13 +150,15 @@ app.whenReady().then(async () => {
app.on('browser-window-created', (_, window) => { app.on('browser-window-created', (_, window) => {
optimizer.watchWindowShortcuts(window) optimizer.watchWindowShortcuts(window)
}) })
const { showFloatingWindow: showFloating = false } = await getAppConfig() const { showFloatingWindow: showFloating = false, disableTray = false } = await getAppConfig()
registerIpcMainHandlers() registerIpcMainHandlers()
await createWindow() await createWindow()
if (showFloating) { if (showFloating) {
showFloatingWindow() showFloatingWindow()
} }
if (!disableTray) {
await createTray() await createTray()
}
await initShortcut() await initShortcut()
app.on('activate', function () { app.on('activate', function () {
// On macOS it's common to re-create a window in the app when the // On macOS it's common to re-create a window in the app when the

View File

@ -4,7 +4,7 @@ import windowStateKeeper from 'electron-window-state'
import { join } from 'path' import { join } from 'path'
import { getAppConfig, patchAppConfig } from '../config' import { getAppConfig, patchAppConfig } from '../config'
import { applyTheme } from './theme' import { applyTheme } from './theme'
import { buildContextMenu } from './tray' import { buildContextMenu, showTrayIcon } from './tray'
export let floatingWindow: BrowserWindow | null = null export let floatingWindow: BrowserWindow | null = null
@ -55,7 +55,7 @@ async function createFloatingWindow(): Promise<void> {
} }
} }
export function showFloatingWindow(): void { export async function showFloatingWindow(): Promise<void> {
if (floatingWindow) { if (floatingWindow) {
floatingWindow.show() floatingWindow.show()
} else { } else {
@ -66,19 +66,21 @@ export function showFloatingWindow(): void {
export async function triggerFloatingWindow(): Promise<void> { export async function triggerFloatingWindow(): Promise<void> {
if (floatingWindow?.isVisible()) { if (floatingWindow?.isVisible()) {
await patchAppConfig({ showFloatingWindow: false }) await patchAppConfig({ showFloatingWindow: false })
closeFloatingWindow() await closeFloatingWindow()
} else { } else {
await patchAppConfig({ showFloatingWindow: true }) await patchAppConfig({ showFloatingWindow: true })
showFloatingWindow() await showFloatingWindow()
} }
} }
export function closeFloatingWindow(): void { export async function closeFloatingWindow(): Promise<void> {
if (floatingWindow) { if (floatingWindow) {
floatingWindow.close() floatingWindow.close()
floatingWindow.destroy() floatingWindow.destroy()
floatingWindow = null floatingWindow = null
} }
await showTrayIcon()
await patchAppConfig({ disableTray: false })
} }
export async function showContextMenu(): Promise<void> { export async function showContextMenu(): Promise<void> {

View File

@ -365,3 +365,16 @@ export async function copyEnv(type: 'bash' | 'cmd' | 'powershell'): Promise<void
} }
} }
} }
export async function showTrayIcon(): Promise<void> {
if (!tray) {
await createTray()
}
}
export async function closeTrayIcon(): Promise<void> {
if (tray) {
tray.destroy()
}
tray = null
}

View File

@ -148,7 +148,9 @@ async function migration(): Promise<void> {
], ],
appTheme = 'system', appTheme = 'system',
envType = [process.platform === 'win32' ? 'powershell' : 'bash'], envType = [process.platform === 'win32' ? 'powershell' : 'bash'],
useSubStore = true useSubStore = true,
showFloatingWindow = false,
disableTray = false
} = await getAppConfig() } = await getAppConfig()
const { const {
'external-controller-pipe': externalControllerPipe, 'external-controller-pipe': externalControllerPipe,
@ -208,6 +210,9 @@ async function migration(): Promise<void> {
if (externalController === undefined) { if (externalController === undefined) {
await patchControledMihomoConfig({ 'external-controller': '' }) await patchControledMihomoConfig({ 'external-controller': '' })
} }
if (!showFloatingWindow && disableTray) {
await patchAppConfig({ disableTray: false })
}
} }
function initDeeplink(): void { function initDeeplink(): void {

View File

@ -63,7 +63,7 @@ import {
import { getRuntimeConfig, getRuntimeConfigStr } from '../core/factory' import { getRuntimeConfig, getRuntimeConfigStr } from '../core/factory'
import { listWebdavBackups, webdavBackup, webdavDelete, webdavRestore } from '../resolve/backup' import { listWebdavBackups, webdavBackup, webdavDelete, webdavRestore } from '../resolve/backup'
import { getInterfaces } from '../sys/interface' import { getInterfaces } from '../sys/interface'
import { copyEnv } from '../resolve/tray' import { closeTrayIcon, copyEnv, showTrayIcon } from '../resolve/tray'
import { registerShortcut } from '../resolve/shortcut' import { registerShortcut } from '../resolve/shortcut'
import { closeMainWindow, mainWindow, showMainWindow, triggerMainWindow } from '..' import { closeMainWindow, mainWindow, showMainWindow, triggerMainWindow } from '..'
import { import {
@ -210,11 +210,13 @@ export function registerIpcMainHandlers(): void {
ipcMain.handle('isAlwaysOnTop', () => { ipcMain.handle('isAlwaysOnTop', () => {
return mainWindow?.isAlwaysOnTop() return mainWindow?.isAlwaysOnTop()
}) })
ipcMain.handle('showTrayIcon', () => ipcErrorWrapper(showTrayIcon)())
ipcMain.handle('closeTrayIcon', () => ipcErrorWrapper(closeTrayIcon)())
ipcMain.handle('showMainWindow', showMainWindow) ipcMain.handle('showMainWindow', showMainWindow)
ipcMain.handle('closeMainWindow', closeMainWindow) ipcMain.handle('closeMainWindow', closeMainWindow)
ipcMain.handle('triggerMainWindow', triggerMainWindow) ipcMain.handle('triggerMainWindow', triggerMainWindow)
ipcMain.handle('showFloatingWindow', showFloatingWindow) ipcMain.handle('showFloatingWindow', () => ipcErrorWrapper(showFloatingWindow)())
ipcMain.handle('closeFloatingWindow', closeFloatingWindow) ipcMain.handle('closeFloatingWindow', () => ipcErrorWrapper(closeFloatingWindow)())
ipcMain.handle('showContextMenu', () => ipcErrorWrapper(showContextMenu)()) ipcMain.handle('showContextMenu', () => ipcErrorWrapper(showContextMenu)())
ipcMain.handle('openFile', (_e, type, id, ext) => openFile(type, id, ext)) ipcMain.handle('openFile', (_e, type, id, ext) => openFile(type, id, ext))
ipcMain.handle('openDevTools', () => { ipcMain.handle('openDevTools', () => {

View File

@ -8,6 +8,7 @@ import {
applyTheme, applyTheme,
checkAutoRun, checkAutoRun,
closeFloatingWindow, closeFloatingWindow,
closeTrayIcon,
copyEnv, copyEnv,
disableAutoRun, disableAutoRun,
enableAutoRun, enableAutoRun,
@ -17,6 +18,7 @@ import {
relaunchApp, relaunchApp,
resolveThemes, resolveThemes,
showFloatingWindow, showFloatingWindow,
showTrayIcon,
startMonitor, startMonitor,
writeTheme writeTheme
} from '@renderer/utils/ipc' } from '@renderer/utils/ipc'
@ -39,6 +41,7 @@ const GeneralConfig: React.FC = () => {
useDockIcon = true, useDockIcon = true,
showTraffic = true, showTraffic = true,
proxyInTray = true, proxyInTray = true,
disableTray = false,
showFloatingWindow: showFloating = false, showFloatingWindow: showFloating = false,
useWindowFrame = false, useWindowFrame = false,
autoQuitWithoutCore = false, autoQuitWithoutCore = false,
@ -192,6 +195,22 @@ const GeneralConfig: React.FC = () => {
}} }}
/> />
</SettingItem> </SettingItem>
{showFloating && (
<SettingItem title="禁用托盘图标" divider>
<Switch
size="sm"
isSelected={disableTray}
onValueChange={async (v) => {
await patchAppConfig({ disableTray: v })
if (v) {
closeTrayIcon()
} else {
showTrayIcon()
}
}}
/>
</SettingItem>
)}
{platform !== 'linux' && ( {platform !== 'linux' && (
<> <>
<SettingItem title="托盘菜单显示节点信息" divider> <SettingItem title="托盘菜单显示节点信息" divider>

View File

@ -327,6 +327,14 @@ export async function subStoreCollections(): Promise<ISubStoreSub[]> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('subStoreCollections')) return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('subStoreCollections'))
} }
export async function showTrayIcon(): Promise<void> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('showTrayIcon'))
}
export async function closeTrayIcon(): Promise<void> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('closeTrayIcon'))
}
export async function showMainWindow(): Promise<void> { export async function showMainWindow(): Promise<void> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('showMainWindow')) return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('showMainWindow'))
} }

View File

@ -212,6 +212,7 @@ interface IAppConfig {
proxyCols: 'auto' | '1' | '2' | '3' | '4' proxyCols: 'auto' | '1' | '2' | '3' | '4'
connectionDirection: 'asc' | 'desc' connectionDirection: 'asc' | 'desc'
connectionOrderBy: 'time' | 'upload' | 'download' | 'uploadSpeed' | 'downloadSpeed' connectionOrderBy: 'time' | 'upload' | 'download' | 'uploadSpeed' | 'downloadSpeed'
disableTray?: boolean
showFloatingWindow?: boolean showFloatingWindow?: boolean
connectionCardStatus?: CardStatus connectionCardStatus?: CardStatus
dnsCardStatus?: CardStatus dnsCardStatus?: CardStatus