@@ -5,10 +5,10 @@ const fs = require('fs');
55const { registerAppIpcHandlers, terminateAllProcesses, filterCliArgs } = require ( './main-app-ipc' ) ;
66const { registerFsIpcHandlers, getAppDataDir } = require ( './main-fs-ipc' ) ;
77const { registerCredIpcHandlers } = require ( './main-cred-ipc' ) ;
8- const { registerWindowIpcHandlers, registerWindow } = require ( './main-window-ipc' ) ;
8+ const { registerWindowIpcHandlers, registerWindow, setOnAllWindowsClosed } = require ( './main-window-ipc' ) ;
99const { assertTrusted } = require ( './ipc-security' ) ;
1010const { getWindowOptions, trackWindowState, DEFAULTS } = require ( './window-state' ) ;
11- const { phoenixLoadURL } = require ( './config' ) ;
11+ const { phoenixLoadURL, gaMetricsURL } = require ( './config' ) ;
1212
1313// Request single instance lock - only one instance of the app should run at a time
1414const gotTheLock = app . requestSingleInstanceLock ( ) ;
@@ -22,6 +22,25 @@ if (!gotTheLock) {
2222// Used for multi-window storage synchronization
2323const sharedStorageMap = new Map ( ) ;
2424
25+ // Hidden metrics window for Google Analytics
26+ let metricsWindow = null ;
27+
28+ async function createMetricsWindow ( ) {
29+ metricsWindow = new BrowserWindow ( {
30+ show : false ,
31+ width : 400 ,
32+ height : 300 ,
33+ webPreferences : {
34+ preload : path . join ( __dirname , 'preload.js' ) ,
35+ contextIsolation : true ,
36+ nodeIntegration : false
37+ }
38+ } ) ;
39+ metricsWindow . loadURL ( gaMetricsURL ) ;
40+ // uncomment line below if you want to open dev tools at app start
41+ metricsWindow . webContents . openDevTools ( ) ;
42+ }
43+
2544async function createWindow ( ) {
2645 // Get window options with restored state or defaults
2746 const windowOptions = getWindowOptions ( ) ;
@@ -71,6 +90,11 @@ registerFsIpcHandlers();
7190registerCredIpcHandlers ( ) ;
7291registerWindowIpcHandlers ( ) ;
7392
93+ // Quit when all registered Phoenix windows are closed (metrics window doesn't count)
94+ setOnAllWindowsClosed ( ( ) => {
95+ gracefulShutdown ( 0 ) ;
96+ } ) ;
97+
7498/**
7599 * IPC handlers for electronAPI
76100 * Preload location: contextBridge.exposeInMainWorld('electronAPI', { ... })
@@ -119,6 +143,13 @@ ipcMain.handle('get-src-node-path', (event) => {
119143 return srcNodePath ;
120144} ) ;
121145
146+ // Health metrics forwarding to hidden metrics window (no assertTrusted needed - metrics come from Phoenix windows)
147+ ipcMain . on ( 'send-health-metric' , ( event , payload ) => {
148+ if ( metricsWindow && ! metricsWindow . isDestroyed ( ) ) {
149+ metricsWindow . webContents . send ( 'health-metric' , payload ) ;
150+ }
151+ } ) ;
152+
122153// Handle quit request from renderer
123154app . on ( 'quit-requested' , ( exitCode ) => {
124155 gracefulShutdown ( exitCode ) ;
@@ -170,6 +201,7 @@ app.whenReady().then(async () => {
170201 }
171202 } ) ;
172203
204+ await createMetricsWindow ( ) ;
173205 await createWindow ( ) ;
174206} ) ;
175207
0 commit comments