Skip to content

Moving a menu item past the last row throws TypeError: menu.box.add is not a function #649

Description

@bittner

Opening a menu whose items are reordered while its rows are still being created throws a TypeError, and the moved row disappears from the menu:

Exception in callback for signal: child-moved: TypeError: menu.box.add is not a function

Stack trace:
  moveItemInMenu@/dbusMenu.js:838:30
  _onRootChildMoved@/dbusMenu.js:956:19
  
  set active@/dbusMenu.js:474:22
  _onMenuOpenStateChanged@/dbusMenu.js:963:9

Every menu opening that takes this path drops another row, so the menu keeps shrinking the more it is used.

MenuUtils.moveItemInMenu() appends a row with menu.box.add() when its new position is past the last row the menu currently has. menu.box is an St.BoxLayout, and add() went away with Clutter.Containerjs/ui/popupMenu.js appends with add_child(). The row has already been removed from the box at that point, so the exception leaves it out of the menu altogether.

Cause

menu.box.remove_child(family[i]);

// and add it again somewhere else
if (newpos < family.length && family[newpos] !== family[i])
    menu.box.insert_child_below(family[i], family[newpos]);
else
    menu.box.add(family[i]);

The else is taken when newpos >= family.length, that is when the children of a DbusMenuItem are ahead of the rows in the menu. _onRootChildAdded() creates rows from an idle callback and keeps them in _itemsBeingAdded in the meantime, so a layout update that adds and moves items in one pass gets here while some rows are still queued.

The call dates back to 2014, but the branch was unreachable while moveItemInMenu() was looking up the root item instead of the moved one; correcting that in v65 exposed it.

Suggested fix

    menu.box.add_child(family[i]);

Reproduction

Any application that refills part of its menu while the menu is being opened, so that the additions are still queued when the moves of the surrounding items are processed.

indicator-test-tool/reorderTool.js does not get there: rotating a fixed set of items only ever moves items towards the front, and all of its rows exist by the time the moves arrive.

Environment

  • Extension version 65 and current master, GNOME Shell 50.2 and 50.3

Related

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions