Electron 中上下文菜单的堆叠

Stacking of Context Menus in Electron

我正在构建一个基于 Electron 的应用程序,其中包含一个包含唯一行的网格。我想要一个特定于每一行的上下文菜单。这是一个例子:

虽然此屏幕截图被裁剪了,但您可以看到有多行并且每行包含单独的数据。因为我想右键单击一行并获得一个独特的上下文菜单,所以我实现了 electron-context-menu,它在第一次右键单击时起作用,但随后的右键单击会导致上下文菜单的堆叠效果.

具体来说,是这样的:

  1. 我右键单击第 1 行,显示了正确的上下文菜单
  2. 我右键单击第 2 行,然后出现第 1 行的重复上​​下文菜单,然后出现第 2 行的上下文菜单。 (注意屏幕截图中显示的上下文菜单与我鼠标悬停的行不对应)
  3. 这会重复。

在React.JS中,这是我的监听器,它根据electron-context-menu模块的需要收集contextmenu对象:

  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: '---',
      }]
    })
  };

其中 this.props.contextMenu(...) 向上渗透 React.JS 个要馈入的组件:

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

我进行了大量调试,但我认为问题不在于模块。我正在使用的模块本质上是组织有关上下文菜单的信息,然后使用 electron.remote 函数和来自电子内部的 menu.popup 函数。这里有一个link到specific line in github.

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

menu.popup 的调用导致 line in electron

  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)
    }

}

所以我看到了对 ipcRender.sendSync 的调用——但是当我在 ipcMainreceiver of those calls 中添加调试语句时,我没有看到任何输出!

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)
  }
})

当我向上述函数添加调试语句时,我没有看到任何输出。这就是我搜索他的墙的地方。

我正在使用 electron 1.4.15。我知道这个问题应该是可以解决的,毕竟 Atom IDE(基于电子的)即使有多个上下文菜单也没有这个问题。

我想我需要在某处清除一些内存,我只是不知道如何清除以前的上下文菜单堆栈!

我首先使用 e.target 获取点击目标来解决这个问题。然后,据此,我调用相应的上下文菜单。如果目标命中不在我的应用程序的目标列表中,我会使用默认的上下文菜单。

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
);