Impilamento di menu contestuali in elettrone

Sto costruendo un’applicazione basata su Electron che contiene una griglia contenente righe univoche. Vorrei un menu di scelta rapida specifico per ogni riga. Ecco un esempio:

Immagine della GUI con menu contestuale

Sebbene questa schermata sia ritagliata, puoi vedere che ci sono più righe e ogni riga contiene dati separati. Poiché vorrei fare clic con il tasto destro su una riga e ottenere un menu di scelta rapida univoco, ho implementato electron-context-menu , che funziona con il primo clic con il tasto destro, ma successivamente i clic con il tasto destro causano un effetto di sovrapposizione dei menu contestuali .

In particolare, ecco cosa succede:

  1. Clicco con il tasto destro su Row-1 e compare il menu contestuale appropriato
  2. Faccio clic destro su Row-2 e una ripetizione del menu di scelta rapida per la riga 1 viene visualizzata, quindi viene visualizzato il menu di scelta rapida di Row-2. (Notare nella schermata che il menu contestuale mostra non corrisponde alla riga che il mio mouse è finito)
  3. Questo si ripete.

In React.JS, ecco il mio listener, che raccoglie l’object contextmenu come richiesto dal modulo electron-context-menu :

  handleContextMenu() { this.props.contextMenu({ window: electron.remote.BrowserWindow.getFocusedWindow(), prepend: (params, browserWindow) => [{ label: `Library Compare ${this.state.msn}`, click: () => this.runLibCompare() }], append: (params, browserWindow) => [{ label: '---', }] }) }; 

Dove this.props.contextMenu(...) percula i componenti React.JS da inserire in:

 const contextMenu = eRequire('electron-context-menu'); 

Ho fatto un grande debugging e non penso che il problema sia il modulo. Il modulo che sto usando essenzialmente organizza le informazioni sul menu di scelta rapida e quindi usa electron.remote funzioni electron.remote e una funzione menu.popup che proviene dagli interni di elettroni. Ecco un link alla linea specifica in github .

 const menu = (electron.Menu || electron.remote.Menu).buildFromTemplate(menuTpl); menu.popup(electron.remote ? electron.remote.getCurrentWindow() : win); 

Questa chiamata a menu.popup porta a questa linea in elettrone .

  const remoteMemberFunction = function (...args) { if (this && this.constructor === remoteMemberFunction) { // Constructor call. let ret = ipcRenderer.sendSync('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', metaId, member.name, wrapArgs(args)) return metaToValue(ret) } else { // Call member function. let ret = ipcRenderer.sendSync('ELECTRON_BROWSER_MEMBER_CALL', metaId, member.name, wrapArgs(args)) return metaToValue(ret) } 

}

Quindi vedo una chiamata a ipcRender.sendSync – tuttavia quando aggiungo istruzioni di debug nel ricevitore ipcMain di quelle chiamate , non vedo alcun output!

 ipcMain.on('ELECTRON_BROWSER_MEMBER_CALL', function (event, id, method, args) { try { args = unwrapArgs(event.sender, args) let obj = objectsRegistry.get(id) if (obj == null) { throwRPCError(`Cannot call function '${method}' on missing remote object ${id}`) } callFunction(event, obj[method], obj, args) } catch (error) { event.returnValue = exceptionToMeta(error) } }) 

Quando ho aggiunto le istruzioni di debug alla funzione sopra, non ho visto alcun output. Ed è qui che la mia ricerca è un muro.

Sto usando l’elettrone 1.4.15. So che questo problema dovrebbe essere risolvibile, dopotutto l’IDE Atom (che è basato su elettroni) non ha questo problema anche se ha più menu contestuali.

Penso che ci sia un po ‘di memoria che ho bisogno di cancellare da qualche parte, non riesco proprio a capire come cancellare lo stack dei precedenti menu contestuali!

Risolvo questo problema ottenendo il bersaglio del clic usando e.target. Quindi, a seconda di ciò, chiamo il corrispondente menu contestuale. Se il bersaglio colpito non è nella lista degli obiettivi per la mia app, utilizzo un menu contestuale predefinito.

 window.addEventListener( "contextmenu", e => { e.preventDefault(); if (e.target.id === 'fullscr'){ console.log(e && e.target); // e.preventDefault(); mymenu.popup(remote.getCurrentWindow()); }else{ editmenu.popup(remote.getCurrentWindow()); } console.log(e.which); }, false );