linuxmint / linuxmint/cinnamon

PopupMenuBase retains destroyed items and disconnects sibling state handlers

Open
#13,956 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
5.6k
Forks
915
Avg merge
5d 22h
Merged PRs (30d)
3

Description

Distribution

Fedora Linux 44 (Cinnamon), X11

Package version

Cinnamon 6.6.7. The same faulty source pattern is present on current master at commit dc924304ff2f4aa5d972ff54dd933a9358ee1faa.

Graphics hardware in use

Intel Alder Lake-UP3 GT2 (Iris Xe Graphics), i915, Mesa 26.1.7.

Frequency

Always. The code-level reproduction is deterministic.

Bug description

PopupMenuBase retains destroyed menu items in its parent SignalManager.
Destroying a PopupSubMenuMenuItem can additionally disconnect unrelated
open-state-changed handlers belonging to sibling submenus and separators.

On unmodified Cinnamon 6.6.7, 1000 add/destroy cycles changed the parent
menu's managed signal count from 6 to 1006 while menu.length correctly
returned to 0.

The item destroy cleanup disconnects selected signal names but leaves its own
managed destroy record behind. The submenu cleanup also calls:

this._signals.disconnect('open-state-changed', this);

That removes all managed parent handlers with the same signal/object pair,
not only state associated with the destroyed submenu. Remaining submenus can
then stay open when their parent closes, and separators can stop updating.

Steps to reproduce

  1. Create a PopupMenu.
  2. Record menu._signals._storage.length.
  3. Repeat 1000 times:
    • create a PopupMenuItem,
    • add it with menu.addMenuItem(item),
    • destroy it with item.destroy().
  4. Check menu.length and menu._signals._storage.length again.

For the behavioral side effect:

  1. Add two submenu items to one parent menu.
  2. Destroy the first submenu item.
  3. Open the second submenu and close the parent menu.
  4. The second submenu's close handler has been removed by destruction of the
    first item. The equivalent issue affects separator visibility handlers.

Expected behavior

  • Destroyed items and child menus are no longer referenced by the parent
    SignalManager.
  • Managed signal count returns to its baseline after every add/destroy cycle.
  • Destroying one submenu does not affect sibling submenu or separator
    behavior.

Additional information

Root cause is the mismatch between signal-name-based cleanup and actual
object ownership. A focused fix is to:

  • disconnect all parent-managed signals owned by the destroyed item and its
    child menu,
  • replace per-item parent handlers with one menu-lifetime
    open-state-changed handler,
  • traverse current items recursively through PopupMenuSection.

I have a focused patch and an isolated regression runner ready. Verification
covers:

  • 1000 add/destroy cycles each for normal items, separators, submenu items,
    and sections,
  • sibling submenu close behavior,
  • separator updates after submenu destruction,
  • nested sections,
  • non-animated parent close,
  • animated deferred close through the real mapped/unmapped path,
  • the current master source file,
  • an exact source port to the 6.6.9 maintenance branch.

Searches for popupMenu SignalManager leak, PopupSubMenuMenuItem destroy,
open-state-changed popupMenu, and popup menu memory leak found no specific
duplicate. #6850 is a broad long-term memory-growth report without this
reproduction or root cause.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing PopupMenuBase, SignalManager cleanup, PopupSubMenuMenuItem destruction, and PopupMenuSection recursion, then run the isolated regression runner described in the issue. Done means destroyed items no longer remain parent-managed, signal counts return to baseline, sibling submenu close behavior and separator updates remain intact, and both animated and non-animated closes pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.