import * as Electron from 'electron'; import log from 'electron-log'; import * as windowStateKeeper from 'electron-window-state'; import { BrowserWindowChannel, AppChannel } from '@ucap/electron-core'; import { AppApi, BrowserWindowApi, IpcMainApi } from '@ucap/electron-common'; import { WindowState } from '@ucap/native'; import { WindowChannel } from '@ucap/electron-native'; import { AppLoggerService } from '../services/app-logger.service'; const MIN_WIDTH = 420; const MIN_HEIGHT = 640; const DEFAULT_WIDTH = 820; const DEFAULT_HEIGHT = 650; let savedWindowState: windowStateKeeper.State; @BrowserWindowApi.BrowserWindowSettings({ constructorOptions: (appConfiguration: AppApi.AppConfiguration) => { savedWindowState = windowStateKeeper({ defaultWidth: DEFAULT_WIDTH, defaultHeight: DEFAULT_HEIGHT }); return { x: savedWindowState.x, y: savedWindowState.y, width: savedWindowState.width, height: savedWindowState.height, minWidth: MIN_WIDTH, minHeight: MIN_HEIGHT, center: true, backgroundColor: '#fff', webPreferences: { // Disable auxclick event // See https://developers.google.com/web/updates/2016/10/auxclick disableBlinkFeatures: 'Auxclick', // Enable, among other things, the ResizeObserver experimentalFeatures: true, nodeIntegration: true }, acceptFirstMouse: true, icon: appConfiguration.assets.appIcon, titleBarStyle: __DARWIN__ ? 'hidden' : 'default', frame: __WIN32__ || __LINUX__ ? false : true }; } }) export class AppWindow implements BrowserWindowApi.ElectronBrowserWindow { static readonly ucapClassName: string = 'appWindow'; appLoggerService: AppLoggerService; constructor( private configuration: BrowserWindowApi.BrowserWindowConfiguration, public native: Electron.BrowserWindow ) { savedWindowState.manage(native); } @BrowserWindowApi.On(BrowserWindowChannel.readyToShow) onReadyToShow() { log.info('BrowserWindowChannel.ReadyToShow'); } @BrowserWindowApi.On(BrowserWindowChannel.close) onClose() { log.info('BrowserWindowChannel.Close'); } @BrowserWindowApi.On(BrowserWindowChannel.closed) onClosed() { log.info('BrowserWindowChannel.Closed'); } @BrowserWindowApi.On(BrowserWindowChannel.focus) onFocus() { this.sendWindowFocus(true); } @BrowserWindowApi.On(BrowserWindowChannel.blur) onBlur() { this.sendWindowFocus(false); } @BrowserWindowApi.On(BrowserWindowChannel.enterFullScreen) onEnterFullScreen() { this.sendWindowState(WindowState.FullScreen); } @BrowserWindowApi.On(BrowserWindowChannel.leaveFullScreen) onLeaveFullScreen() { this.sendWindowState(this.windowState()); } @BrowserWindowApi.On(BrowserWindowChannel.minimize) onMinimize() { this.sendWindowState(WindowState.Minimized); } @BrowserWindowApi.On(BrowserWindowChannel.maximize) onMaximize() { this.sendWindowState(WindowState.Maximized); } @BrowserWindowApi.On(BrowserWindowChannel.unmaximize) onUnmaximize() { this.sendWindowState(WindowState.Normal); } @BrowserWindowApi.On(BrowserWindowChannel.restore) onRestore() { this.sendWindowState(WindowState.Normal); } @BrowserWindowApi.On(BrowserWindowChannel.hide) onHide() { this.sendWindowState(WindowState.Hidden); } @BrowserWindowApi.On(BrowserWindowChannel.show) onShow() { this.sendWindowState(this.windowState()); } @IpcMainApi.Handle(WindowChannel.state) async handleState(event: Electron.IpcMainEvent): Promise { this.appLoggerService.debug('handleState'); return this.windowState(); } @IpcMainApi.Handle(WindowChannel.focused) async handleFocused(event: Electron.IpcMainEvent): Promise { this.appLoggerService.debug('handleFocused'); return this.native.isFocused(); } private attachHandlers() { this.attachAppHandlers(); } private attachAppHandlers() { Electron.app.on(AppChannel.beforeQuit, (event: Electron.Event) => { log.info('AppChannel.BeforeQuit'); }); } private sendWindowFocus(focus: boolean) { this.native.webContents.send(WindowChannel.onFocus$, focus); } private sendWindowState(windowState: WindowState) { this.native.webContents.send(WindowChannel.onState$, windowState); } private windowState(): WindowState { if (this.native.isFullScreen()) { return WindowState.FullScreen; } else if (this.native.isMaximized()) { return WindowState.Maximized; } else if (this.native.isMinimized()) { return WindowState.Minimized; } else if (!this.native.isVisible()) { return WindowState.Hidden; } else { return WindowState.Normal; } } }