@@ -17,6 +17,7 @@ import macOSTrayIcon from '../../resources/tray-icon-macos.png?asset'
1717import { openDebugger , setupDebugger } from './app/debugger'
1818import { emitAppBeforeQuit , emitAppReady , emitAppWindowAllClosed , onAppBeforeQuit } from './libs/bootkit/lifecycle'
1919import { setElectronMainDirname } from './libs/electron/location'
20+ import { setupCaptionWindowManager } from './windows/caption'
2021import { setupInlayWindow } from './windows/inlay'
2122import { setupMainWindow } from './windows/main'
2223import { setupSettingsWindowReusableFunc } from './windows/settings'
@@ -49,16 +50,27 @@ electronApp.setAppUserModelId('ai.moeru.airi')
4950function setupTray ( params : {
5051 mainWindow : BrowserWindow
5152 settingsWindow : ( ) => Promise < BrowserWindow >
53+ captionWindow : ReturnType < typeof setupCaptionWindowManager >
5254} ) : void {
5355 once ( ( ) => {
5456 const appTray = new Tray ( nativeImage . createFromPath ( macOSTrayIcon ) . resize ( { width : 16 } ) )
5557 onAppBeforeQuit ( ( ) => appTray . destroy ( ) )
5658
5759 const contextMenu = Menu . buildFromTemplate ( [
5860 { label : 'Show' , click : ( ) => toggleWindowShow ( params . mainWindow ) } ,
59- { label : 'Inlay' , click : ( ) => setupInlayWindow ( ) } ,
6061 { type : 'separator' } ,
61- { label : 'Settings' , click : ( ) => params . settingsWindow ( ) . then ( window => toggleWindowShow ( window ) ) } ,
62+ { label : 'Settings...' , click : ( ) => params . settingsWindow ( ) . then ( window => toggleWindowShow ( window ) ) } ,
63+ { type : 'separator' } ,
64+ { label : 'Open Inlay...' , click : ( ) => setupInlayWindow ( ) } ,
65+ { label : 'Open Caption...' , click : ( ) => params . captionWindow . getWindow ( ) . then ( window => toggleWindowShow ( window ) ) } ,
66+ {
67+ type : 'submenu' ,
68+ label : 'Caption Overlay' ,
69+ submenu : Menu . buildFromTemplate ( [
70+ { type : 'checkbox' , label : 'Follow window' , checked : params . captionWindow . getIsFollowingWindow ( ) , click : async menuItem => await params . captionWindow . setFollowWindow ( Boolean ( menuItem . checked ) ) } ,
71+ { label : 'Reset position' , click : async ( ) => await params . captionWindow . resetToSide ( ) } ,
72+ ] ) ,
73+ } ,
6274 { type : 'separator' } ,
6375 { label : 'Quit' , click : ( ) => app . quit ( ) } ,
6476 ] )
@@ -117,9 +129,13 @@ app.whenReady().then(async () => {
117129 dependsOn : { settingsWindow } ,
118130 build : async ( { dependsOn } ) => setupMainWindow ( dependsOn ) ,
119131 } )
132+ const captionWindow = injecta . provide ( 'windows:caption' , {
133+ dependsOn : { mainWindow } ,
134+ build : async ( { dependsOn } ) => setupCaptionWindowManager ( { mainWindow : dependsOn . mainWindow } ) ,
135+ } )
120136 const tray = injecta . provide ( 'app:tray' , {
121- dependsOn : { mainWindow, settingsWindow } ,
122- build : async ( { dependsOn } ) => setupTray ( dependsOn ) ,
137+ dependsOn : { mainWindow, settingsWindow, captionWindow } ,
138+ build : async ( { dependsOn } ) => setupTray ( dependsOn as any ) ,
123139 } )
124140 injecta . invoke ( {
125141 dependsOn : { mainWindow, tray } ,
0 commit comments