Skip to content

Main menu open/close animation not rendered when triggered via toggle() — closing via outside click works #13833

Description

@Avalonia-0

Bug Description

The main menu (mintMenu / start menu) fails to render its open/close animation in certain scenarios. Instead of playing the expected slide+fade transition, the menu simply appears or disappears instantly.

Reproduction Steps

  1. Ensure animations are enabled: System Settings → Effects → "Enable animations" ON, "Menus" effect ON
  2. Click the main menu applet icon to open → the menu appears instantly, no open animation
  3. Click the menu icon again to close → the menu disappears instantly, no close animation
  4. Press Super/Meta key to open → same as step 2, no animation
  5. Press Super/Meta key again to close → same as step 3, no animation
  6. Click the menu open, then click anywhere outside the menu to close → close animation renders correctly
  7. Compare with other panel menus (volume, network, calendar) — their animations always render correctly in all scenarios ✅

Observations

Trigger Open animation Close animation
Click menu icon ❌ Skipped ❌ Skipped
Press Super/Meta ❌ Skipped ❌ Skipped
Click outside menu N/A ✅ Renders correctly
Other panel menus (any trigger) ✅ Always ✅ Always
  • The bug is consistent, not intermittent — it reproduces every time
  • The menu still opens and functions correctly; only the transition animation is missing
  • Disabling and re-enabling animations in settings does not change behavior
  • The bug persists across Cinnamon restarts (Ctrl+Alt+Esc)

Technical Analysis (Speculative)

After examining the Cinnamon source code, here is my understanding of the likely root cause:

Code paths involved

All triggers ultimately call the same animation methods in js/ui/popupMenu.js:

  • Click icon / Super keymenu@cinnamon.org on_applet_clicked() or overlay-key binding → menu.toggle_with_options(true)open(true) / close(true)
  • Click outsidePopupMenuManager._onEventCapture()_closeMenu()close(true)

What I think is happening

The open(true) method (popupMenu.js line 2329) does:

this.actor.show();           // triggers layout of the entire menu tree
this.actor.opacity = 0;      // animation start state
// set initial position with offset ...
this.actor.ease(easeParams); // start Clutter implicit transition

The main menu is unique among panel menus because:

  1. Large actor tree — It builds 100+ St actors (sidebar, search box, apps list, categories, favorites, recents, system buttons) all as children of this.actor
  2. Heavy _onOpenStateChanged callback — Immediately after open() emits open-state-changed (line 2419), the applet's handler (applet.js line 1418) does synchronous work: set_key_focus(this.searchEntry), shows 30 app buttons, and queues an idle callback to show the rest
  3. First-time layout cost — When show() is called, Clutter must map, allocate, and apply CSS to the entire complex tree. On a system with hundreds of installed apps, this can be expensive

My hypothesis: when show() triggers the initial layout of the heavy tree, the actor may not yet be fully "realized" (backing texture ready) by the time ease() is called. Clutter's implicit transition system may not properly capture the initial property delta if the actor isn't in a fully ready rendering state, causing the transition to complete instantly (snap to final state).

This would explain why:

  • Close via outside click works — the actor is already fully mapped and visible when close(true) is called, so the transition starts from a clean state
  • Other menus are unaffected — their actor trees are much smaller, so show() completes before ease() starts
  • The bug is consistent — it's a timing issue, not a race condition

An alternative hypothesis

The _onOpenStateChanged callback calls global.stage.set_key_focus(this.searchEntry) synchronously right after the animation starts. Changing keyboard focus can trigger Clutter stage focus processing, which might flush or abort pending transitions on the actor.

Environment

  • Cinnamon 6.6.7
  • Linux Mint 22.3 Zena
  • Kernel 6.17.0-35-generic

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions