@@ -374,3 +374,140 @@ function restart() {
374374 forceQuit = true ;
375375 app . quit ( ) ;
376376}
377+
378+ const pluginWindows = new Map ( ) ;
379+
380+ function createPluginWindow ( pluginId , htmlPath , options = { } ) {
381+ const defaultOptions = {
382+ width : 800 ,
383+ height : 600 ,
384+ webPreferences : {
385+ nodeIntegration : true ,
386+ contextIsolation : false ,
387+ backgroundThrottling : false ,
388+ } ,
389+ } ;
390+
391+ const windowOptions = { ...defaultOptions , ...options } ;
392+ const pluginWindow = new BrowserWindow ( windowOptions ) ;
393+
394+ require ( '@electron/remote/main' ) . enable ( pluginWindow . webContents ) ;
395+
396+ if ( path . isAbsolute ( htmlPath ) ) {
397+ pluginWindow . loadFile ( htmlPath ) ;
398+ }
399+ else {
400+ const absolutePath = path . join ( pluginDir , htmlPath ) ;
401+ pluginWindow . loadFile ( absolutePath ) ;
402+ }
403+
404+ pluginWindow . setMenu ( null ) ;
405+
406+ const windowInfo = {
407+ window : pluginWindow ,
408+ pluginId,
409+ htmlPath,
410+ options,
411+ } ;
412+
413+ pluginWindows . set ( pluginWindow . id , windowInfo ) ;
414+
415+ pluginWindow . on ( 'closed' , ( ) => {
416+ pluginWindows . delete ( pluginWindow . id ) ;
417+ if ( win ) {
418+ win . webContents . send ( 'plugin-window-closed' , {
419+ windowId : pluginWindow . id ,
420+ pluginId,
421+ } ) ;
422+ }
423+ } ) ;
424+
425+ return pluginWindow ;
426+ }
427+
428+ ipcMain . on ( 'open-plugin-window' , ( event , data ) => {
429+ const { pluginId, htmlPath, options } = data ;
430+
431+ for ( const [ windowId , windowInfo ] of pluginWindows . entries ( ) ) {
432+ if ( windowInfo . pluginId === pluginId ) {
433+ if ( ! windowInfo . window . isDestroyed ( ) ) {
434+ windowInfo . window . close ( ) ;
435+ }
436+ pluginWindows . delete ( windowId ) ;
437+ }
438+ }
439+
440+ try {
441+ const pluginWindow = createPluginWindow ( pluginId , htmlPath , options ) ;
442+
443+ event . reply ( 'plugin-window-opened' , {
444+ success : true ,
445+ windowId : pluginWindow . id ,
446+ pluginId,
447+ } ) ;
448+ }
449+ catch ( error ) {
450+ console . error ( 'Error opening plugin window:' , error ) ;
451+ event . reply ( 'plugin-window-opened' , {
452+ success : false ,
453+ error : error . message ,
454+ pluginId,
455+ } ) ;
456+ }
457+ } ) ;
458+
459+ ipcMain . on ( 'close-plugin-window' , ( event , windowId ) => {
460+ const windowInfo = pluginWindows . get ( windowId ) ;
461+ if ( windowInfo ) {
462+ windowInfo . window . close ( ) ;
463+ event . reply ( 'plugin-window-closed' , {
464+ success : true ,
465+ windowId,
466+ pluginId : windowInfo . pluginId ,
467+ } ) ;
468+ }
469+ } ) ;
470+
471+ ipcMain . on ( 'close-plugin-windows' , ( event , pluginId ) => {
472+ for ( const [ windowId , windowInfo ] of pluginWindows . entries ( ) ) {
473+ if ( windowInfo . pluginId === pluginId ) {
474+ windowInfo . window . close ( ) ;
475+ }
476+ }
477+ event . reply ( 'plugin-windows-closed' , {
478+ success : true ,
479+ pluginId,
480+ } ) ;
481+ } ) ;
482+
483+ ipcMain . on ( 'get-plugin-windows' , ( event , pluginId ) => {
484+ const windows = Array . from ( pluginWindows . entries ( ) )
485+ . filter ( ( [ _ , info ] ) => info . pluginId === pluginId )
486+ . map ( ( [ windowId , info ] ) => ( {
487+ windowId,
488+ htmlPath : info . htmlPath ,
489+ options : info . options ,
490+ } ) ) ;
491+
492+ event . reply ( 'plugin-windows-list' , {
493+ pluginId,
494+ windows,
495+ } ) ;
496+ } ) ;
497+
498+ ipcMain . on ( 'send-to-plugin-window' , ( event , data ) => {
499+ const { windowId, channel, payload } = data ;
500+ const windowInfo = pluginWindows . get ( windowId ) ;
501+ if ( windowInfo ) {
502+ windowInfo . window . webContents . send ( channel , payload ) ;
503+ }
504+ } ) ;
505+
506+ ipcMain . on ( 'broadcast-to-plugin-windows' , ( event , data ) => {
507+ const { pluginId, channel, payload } = data ;
508+ for ( const windowInfo of pluginWindows . values ( ) ) {
509+ if ( windowInfo . pluginId === pluginId ) {
510+ windowInfo . window . webContents . send ( channel , payload ) ;
511+ }
512+ }
513+ } ) ;
0 commit comments