power applet: debounce device menu rebuilds - #13949
Open
rumours86 wants to merge 1 commit into
Open
Conversation
_devicesChanged() is connected to the csd-power proxy's g-properties-changed and rebuilt the whole device menu (destroying and recreating every DeviceItem) on each signal. With a flapping AC adapter (loose plug or failing cable) csd-power emits a storm of signals - 126 in 3 minutes measured against ~18 at idle - and the flood of destroyed and recreated actors drives GJS into high-frequency incremental GC. While that GC runs, GJS blocks JS callbacks from C, including the shell's paint vfunc, so the entire screen freezes or goes black for seconds every time the charger blinks; destroy callbacks of notification banners get blocked too, leaving stuck banners floating over all windows. Debounce the rebuild: handle the first signal immediately and fold the rest of a burst into a single trailing rebuild 500ms later. An A/B test with a deliberately flapped charger went from 200 unpainted frames over 9s to under 30, and with this fix applied the blackouts are gone. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug.
_devicesChanged()is connected to the csd-power proxy'sg-properties-changedand rebuilds the whole device menu — destroying and recreating everyDeviceItem— on each signal. With a flapping AC adapter (loose plug / failing cable) csd-power emits a storm of signals: measured 126 in 3 minutes against ~18 at idle. The flood of destroyed/recreated actors drives GJS into high-frequency incremental GC; while it runs, GJS blocks JS callbacks from C — including the shell's own paint vfunc (UiActor.vfunc_paintinlayout.js, which paints everything). Result: every time the charger blinks, the entire screen freezes or goes black for seconds (Attempting to run a JS callback during garbage collection ... The offending callback was paint(), a vfuncat exactly the frame rate in.xsession-errors), and blocked destroy callbacks leave zombie notification banners floating over all windows.Measurements (Cinnamon 6.6.9, 3000x2000 eDP): deliberately flapping the charger produced 200 unpainted frames over 9s with the stock applet; removing the applet from the panel dropped it to 29; with this debounce the blackouts are gone entirely (user-confirmed over many plug/unplug cycles).
The fix. Coalesce bursts into one rebuild per 500ms: the first signal is handled immediately (icon still reacts instantly), the rest of a burst is folded into a single trailing rebuild.
🤖 Generated with Claude Code