在 Electron 中堆叠上下文菜单

Posted

技术标签:

【中文标题】在 Electron 中堆叠上下文菜单【英文标题】:Stacking of Context Menus in Electron 【发布时间】:2017-06-28 03:22:21 【问题描述】:

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

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

具体来说,会发生以下情况:

    我右键单击第 1 行,然后显示正确的上下文菜单 我右键单击第 2 行,重复显示第 1 行的上下文菜单,然后显示第 2 行的上下文菜单。 (请注意屏幕截图中显示的上下文菜单与我的鼠标所在的行不对应) 如此反复。

在 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 函数。这是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 的调用——但是当我在ipcMain 的receiver 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)
  
)

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

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

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

【问题讨论】:

【参考方案1】:

我首先使用 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
);  

【讨论】:

以上是关于在 Electron 中堆叠上下文菜单的主要内容,如果未能解决你的问题,请参考以下文章

08.《Electron 跨平台开发实战》- chapter08-深入集成(shell模块)动态启动菜单项

电子中的上下文菜单

堆叠上下文

Webkit - 修复定位元素似乎具有固有的堆叠上下文

堆叠上下文z-index

z-index和嵌套DOM元素(堆叠上下文)覆盖