Skip to content

grouped-window-list: guard against null close button in thumbnailCloseButtonOffset handler - #13917

Open
mrbeandev wants to merge 1 commit into
linuxmint:masterfrom
mrbeandev:fix-grouped-window-list-null-close-button
Open

grouped-window-list: guard against null close button in thumbnailCloseButtonOffset handler#13917
mrbeandev wants to merge 1 commit into
linuxmint:masterfrom
mrbeandev:fix-grouped-window-list-null-close-button

Conversation

@mrbeandev

Copy link
Copy Markdown

Problem

WindowThumbnail's constructor registers a thumbnailCloseButtonOffset state listener at menus.js:464, but this.button is not assigned until menus.js:529, and it is gone again once the thumbnail is destroyed. The listener dereferences it unconditionally:

thumbnailCloseButtonOffset: ({thumbnailCloseButtonOffset}) => {
    this.button.style = CLOSED_BUTTON_STYLE + `position: ${thumbnailCloseButtonOffset}px -2px;`;
}

GroupedWindowListApplet.onUIScaleChange() calls state.set({thumbnailCloseButtonOffset: ...}), which dispatches to every registered WindowThumbnail — including any that are still mid-construction or already torn down. Those throw:

JS ERROR: TypeError: this.button is null
thumbnailCloseButtonOffset@/usr/share/cinnamon/applets/grouped-window-list@cinnamon.org/menus.js:466:72
dispatch@/usr/share/cinnamon/applets/grouped-window-list@cinnamon.org/state.js:170:30
set@/usr/share/cinnamon/applets/grouped-window-list@cinnamon.org/state.js:212:21
onUIScaleChange@/usr/share/cinnamon/applets/grouped-window-list@cinnamon.org/applet.js:1029:20
GroupedWindowListApplet/<@/usr/share/cinnamon/applets/grouped-window-list@cinnamon.org/applet.js:286:73

How I hit it

Laptop panel plus an external monitor at different fractional scales (1.25 and 1.0), with scale-monitor-framebuffer and x11-randr-fractional-scaling enabled. Closing and reopening the lid re-detects the outputs, which changes the global UI scale and fires onUIScaleChange while thumbnails are being rebuilt.

The exception left the applet's actor tree inconsistent. Orphaned actors then accumulated:

Clutter-WARNING **: Attempting to remove actor of type 'StIcon' from group of
class 'ClutterBox', but the container is not the actor's parent.

About 80 minutes later Cinnamon's main thread went to 100% CPU and stopped responding entirely — the session froze with only the mouse cursor still moving, since that is drawn on the hardware cursor plane. Xorg itself stayed at 0% CPU and healthy throughout, and cinnamon-killer-daemon eventually dropped the session to the metacity/mate-panel fallback.

Any monitor hotplug that changes the global scale should reach this — unplugging an external display or a monitor going to sleep, not just the lid.

Fix

Return early when there is no button to style. Same approach as #13633.

Environment

Cinnamon 6.6.4, muffin 6.6.1, Linux Mint 22.3, X11, two monitors at scales 1.25 / 1.0.

WindowThumbnail registers a thumbnailCloseButtonOffset listener in its
constructor, but this.button is not created until later in setup and is
gone once the thumbnail has been destroyed. onUIScaleChange() dispatches
the new offset to every registered thumbnail, so any that are still being
constructed or already torn down raise "TypeError: this.button is null".

This is reachable on any monitor hotplug that changes the global UI scale
(lid close/open, unplugging an external display) when monitors are running
at different fractional scales. The exception leaves the applet's actor
tree inconsistent, which can end with Cinnamon spinning on its main thread.

Skip the style update when there is no button to style.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant