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
- Create a
PopupMenu.
- Record
menu._signals._storage.length.
- Repeat 1000 times:
- create a
PopupMenuItem,
- add it with
menu.addMenuItem(item),
- destroy it with
item.destroy().
- Check
menu.length and menu._signals._storage.length again.
For the behavioral side effect:
- Add two submenu items to one parent menu.
- Destroy the first submenu item.
- Open the second submenu and close the parent menu.
- 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.
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
PopupMenuBaseretains destroyed menu items in its parentSignalManager.Destroying a
PopupSubMenuMenuItemcan additionally disconnect unrelatedopen-state-changedhandlers 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.lengthcorrectlyreturned to 0.
The item destroy cleanup disconnects selected signal names but leaves its own
managed
destroyrecord behind. The submenu cleanup also calls: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
PopupMenu.menu._signals._storage.length.PopupMenuItem,menu.addMenuItem(item),item.destroy().menu.lengthandmenu._signals._storage.lengthagain.For the behavioral side effect:
first item. The equivalent issue affects separator visibility handlers.
Expected behavior
SignalManager.behavior.
Additional information
Root cause is the mismatch between signal-name-based cleanup and actual
object ownership. A focused fix is to:
child menu,
open-state-changedhandler,PopupMenuSection.I have a focused patch and an isolated regression runner ready. Verification
covers:
and sections,
Searches for
popupMenu SignalManager leak,PopupSubMenuMenuItem destroy,open-state-changed popupMenu, andpopup menu memory leakfound no specificduplicate. #6850 is a broad long-term memory-growth report without this
reproduction or root cause.