import { BrowserWindow , BrowserWindowConstructorOptions , screen , Tray , Point } from 'electron' ; import * as isDev from 'electron-is-dev' ; import * as path from 'path' ; const assetsDirectory = path . join ( __dirname , '../assets' ) ; class TrayWindowManager { private _window : BrowserWindow ; private _tray : Tray ; get window ( ) : BrowserWindow { return this . _window ; } constructor ( windowConfig = { } ) { this . createWindow ( windowConfig ) ; this . createTray ( ) ; } private createWindow ( config ) { this . _window = new BrowserWindow ( { show : false , frame : false , fullscreenable : false , movable : false , maximizable : false , resizable : false , transparent : true , ... config , } ) ; this . _window . loadFile ( path . resolve ( __dirname , 'renderer' , 'main.html' ) ) ; this . _window . setVisibleOnAllWorkspaces ( true , { visibleOnFullScreen : true } ) ; if ( isDev ) { this . _window . webContents . openDevTools ( { mode : 'detach' } ) ; } this . _window . on ( 'blur' , ( ) => { if ( isDev && this . _window . webContents . isDevToolsOpened ( ) ) { return ; } this . _window . hide ( ) ; } ) ; } private createTray ( ) { this . _tray = new Tray ( path . join ( assetsDirectory , 'menu_iconTemplate.png' ) ) ; this . _tray . on ( 'right-click' , ( ) => { this . toggleWindow ( ) ; } ) ; this . _tray . on ( 'click' , ( ) => { this . toggleWindow ( ) ; } ) ; } get visible ( ) : boolean { return this . _window . isVisible ( ) ; } setWindowPosition ( ) { const position = this . getWindowPosition ( ) ; this . _window . setPosition ( position . x , position . y , false ) ; } ipcSend ( channel , ... args ) { this . _window . webContents . send ( channel , ... args ) ; } getWindowPosition ( ) { const windowBounds = this . _window . getBounds ( ) ; const trayBounds = this . _tray . getBounds ( ) ; const activeDisplay = screen . getDisplayMatching ( trayBounds ) ; let yOffset = 0 ; if ( activeDisplay . bounds . y < 0 ) { yOffset = activeDisplay . bounds . y ; } return { x : Math . round ( trayBounds . x + trayBounds . width / 2 - windowBounds . width / 2 ) , y : Math . round ( yOffset + trayBounds . height ) , } ; } showWindow ( ) { this . setWindowPosition ( ) ; this . _window . show ( ) ; this . _window . focus ( ) ; } closeWindow ( ) { this . _window . getChildWindows ( ) . forEach ( ( childWindow ) => { childWindow . close ( ) ; } ) ; this . _window . close ( ) ; } toggleWindow ( ) { if ( this . _window . isVisible ( ) ) { this . _window . hide ( ) ; } else { this . showWindow ( ) ; } } updateTray ( { title = '' , tooltip = '' , } = { } ) { this . _tray . setTitle ( title , { fontType : 'monospacedDigit' } ) ; this . _tray . setToolTip ( tooltip ) ; this . setWindowPosition ( ) ; } clearTray ( ) { this . updateTray ( ) ; } } export default TrayWindowManager ;