Skip to content

[BUG] power@cinnamon.org repeatedly re-adds contentSection in _updateProfile, causing Clutter-WARNING loop and compositor frame drops #13998

Description

@RainbowXie

Distribution

Linux Mint 22.3 (Zena) (also reproducible on any distribution running Cinnamon with power-profiles-daemon)

Package version

Cinnamon 6.6.9 (verified present on master at files/usr/share/cinnamon/applets/power@cinnamon.org/applet.js)

Graphics hardware in use

NVIDIA GeForce GTX 1660 Ti (Driver 595.84) / Intel / AMD (hardware agnostic)

Frequency

Quite often (triggers whenever power-profiles-daemon / UPower signals a property change, e.g. switching AC/battery or power profile)

Bug description

In files/usr/share/cinnamon/applets/power@cinnamon.org/applet.js, this._proxyId listens to g-properties-changed on org.freedesktop.UPower.PowerProfiles:

this._proxyId = this._profilesProxy.connect("g-properties-changed", (proxy, changed, invalidated) => {
    for (let [changedProperty, changedValue] of Object.entries(changed.deepUnpack())) {
        if (["ActiveProfile", "Profiles"].includes(changedProperty))
            this[changedProperty] = changedValue.deepUnpack();
        this._updateProfile();
    }
});

Inside _updateProfile() (line 553 on master / line 621 on 6.6.9):

_updateProfile() {
    this.contentSection.removeAll();
    // ... items added to contentSection ...
    this.menu.addMenuItem(this.contentSection); // <-- BUG: re-adds contentSection unconditionally
}

Because this.contentSection has already been added to this.menu (and its underlying St.BoxLayout container), calling this.menu.addMenuItem(this.contentSection) again on every property change violates Clutter actor parenting rules:

  1. It spams ~/.xsession-errors with thousands of Clutter warnings:
    Clutter-WARNING **: Attempting to add actor of type 'StBoxLayout' to a container of type 'StBoxLayout', but the actor has already a parent of type 'StBoxLayout'.
  2. It breaks PopupMenuBase bookkeeping: every addMenuItem() calls this.length++, leading to internal length drift.
  3. Every invalid reparenting attempt invalidates the panel's layout and queues stage redraws, which can cause compositor frame drops and high GPU utilization on systems with multi-monitor / high-resolution setups.

Note: This appears to explain the root cause of the log spam previously reported in #12916.

Steps to reproduce

  1. Ensure power-profiles-daemon is running and the power applet (power@cinnamon.org) is enabled on the panel.
  2. In a terminal, trigger _updateProfile() directly via Cinnamon's DBus interface (or switch power profile via command line powerprofilesctl set performance && powerprofilesctl set balanced):
gdbus call --session --dest org.Cinnamon --object-path /org/Cinnamon --method org.Cinnamon.Eval '
(() => {
    let defs = imports.ui.main.AppletManager.getDefinitions();
    let power = defs.find(d => d.uuid === "power@cinnamon.org").applet;
    power._updateProfile();
    return "triggered";
})()
'
  1. Inspect ~/.xsession-errors:
tail -n 10 ~/.xsession-errors

Observed behavior

Each call prints the following warning to ~/.xsession-errors:

(cinnamon:<PID>): Clutter-WARNING **: Attempting to add actor of type 'StBoxLayout' to a container of type 'StBoxLayout', but the actor has already a parent of type 'StBoxLayout'.

The captured GJS stack trace shows:

St.BoxLayout.prototype.add_actor
_patchContainerClass/containerClass.prototype.add@/usr/share/cinnamon/js/ui/environment.js:46
addMenuItem@/usr/share/cinnamon/js/ui/popupMenu.js:1996
_updateProfile@/usr/share/cinnamon/applets/power@cinnamon.org/applet.js:573
CinnamonPowerApplet/this._proxyId<@/usr/share/cinnamon/applets/power@cinnamon.org/applet.js:349

In long desktop sessions with dynamic power states, thousands of these warnings accumulate (over 3,000 instances recorded in a single session).

Expected behavior

this.contentSection should be added to this.menu only once during construction (consistent with user@cinnamon.org and removable-drives@cinnamon.org), or guarded with if (!this.contentSection.actor.get_parent()) before calling this.menu.addMenuItem(this.contentSection).

Calling _updateProfile() repeatedly should cleanly refresh the items within this.contentSection without emitting Clutter warnings or mutating the menu container structure.

Additional information

  • Tested locally by placing the patched applet in ~/.local/share/cinnamon/applets/power@cinnamon.org/: after running for 3+ days with multiple profile switches, zero warnings were logged and desktop compositor performance remained stable.
  • PR with the clean fix will be submitted shortly.

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