Gnome Shell聚合菜单中如何整体上移PopupSubMenuMenuItem
问题原因
子菜单未随主项同步移位是两个写法错误导致的:
- 位置计算传入对象错误:
Main.panel.statusArea.aggregateMenu._power.menu是电源选项的子菜单实例,不属于聚合菜单根菜单的直属菜单项,_findMenuItemPosition找不到该对象时会返回-1,最终算出的position值完全不符合预期。 - 操作时序触发渲染bug:先把菜单项追加到菜单末尾、再调用
moveMenuItem移动时,子菜单的弹出锚点会绑定在初次插入的位置,不会随后续move操作同步更新。
修复方案
PopupSubMenuMenuItem的子菜单完全绑定在主菜单项上,只要主菜单项插入位置正确,子菜单会自动跟随主项定位,不需要单独调整子菜单位置,按两点修改即可:
- 计算插入位置时,直接传入聚合菜单下的电源主菜单项
_power,不要传入它的子菜单属性_power.menu - 调用
addMenuItem时直接传入目标位置参数,省略后续单独的moveMenuItem调用,从根源避免锚点错位问题
修复后的完整代码:
enable() { this._item = new PopupMenu.PopupSubMenuMenuItem('Thermal Management', true); this._item.icon.icon_name = 'applications-system-symbolic'; // 传入根菜单直属的电源主菜单项计算目标位置 let position = this._findMenuItemPosition(Main.panel.statusArea.aggregateMenu._power) + 1; this._optimizedOption = this._createOptimizedOption(); this._item.menu.addMenuItem(this._optimizedOption); this._quietOption = this._createQuietOption(); this._item.menu.addMenuItem(this._quietOption); this._coolOption = this._createCoolOption(); this._item.menu.addMenuItem(this._coolOption); this._ultraPerformanceOption = this._createUltraPerformanceOption(); this._item.menu.addMenuItem(this._ultraPerformanceOption); // 添加菜单项时直接指定位置,无需先追加再移动 Main.panel.statusArea.aggregateMenu.menu.addMenuItem(this._item, position); }
兼容提示:GNOME 42及以上版本中
aggregateMenu._power的访问路径未发生变化,上述写法可直接兼容,不会出现API调用错误。
内容的提问来源于stack exchange,提问作者dolszewski97
相关产品推荐
相关产品推荐

