Skip to content

Hide the entry before detaching it in _release_ui (shell crash on GNOME 50) - #164

Open
daniel-g-carrasco wants to merge 2 commits into
icedman:mainfrom
daniel-g-carrasco:fix/release-ui-unrealize-crash
Open

daniel-g-carrasco wants to merge 2 commits into
icedman:mainfrom
daniel-g-carrasco:fix/release-ui-unrealize-crash

Conversation

@daniel-g-carrasco

Copy link
Copy Markdown

Launching an app from the overlay on GNOME 50 sometimes aborts the whole shell (on Wayland that means losing the session, and GNOME's crash protection then disables all extensions):

Clutter:ERROR:../clutter/clutter/clutter-actor.c:1989:clutter_actor_real_unrealize:
  assertion failed: (!clutter_actor_is_mapped (self))
== Stack trace for context ==
#0  extension.js:755 (_release_ui)
#1  extension.js:495 (hide)
#2  extension.js:1012

Caught it with a coredump on Fedora 44 / gnome-shell 50.2 / Wayland. _release_ui() calls remove_child() on the entry while the overlay is still mapped, and clutter 18's stricter unrealize assertions abort on that.

Hiding the entry first unmaps it so the detach is safe. There's no visible difference since the whole overlay is fading out at that point anyway.

This is probably what #82 and #133 have been hitting too.

On GNOME 50 (mutter/clutter 18) launching an app from the overlay can
abort the whole shell:

    Clutter:ERROR:../clutter/clutter/clutter-actor.c:1989:clutter_actor_real_unrealize:
      assertion failed: (!clutter_actor_is_mapped (self))
    JS stack: extension.js:755 (_release_ui) -> 495 (hide) -> 1012

_release_ui() removes the entry from its parent while the overlay is
still mapped, and clutter 18's stricter unrealize assertions abort on
that. On Wayland this takes down the session and trips GNOME's
extension crash protection.

Hiding the entry first unmaps it, so the detach is safe. No visible
difference since the whole overlay is fading out at that point.

Probably related to icedman#82 and icedman#133.
@oameye

oameye commented Jun 12, 2026

Copy link
Copy Markdown

oeoeoeo exactly the fix I am looking for!

Hiding the entry in _release_ui() flips the stage key-focus, which fires
_onKeyFocusChanged -> this.hide() again, re-entering teardown while the
first pass is still mid-unmap:

  clutter_actor_set_mapped: assertion '!CLUTTER_ACTOR_IN_MAP_UNMAP' failed
  Clutter:ERROR clutter_actor_real_unrealize: (!clutter_actor_is_mapped)

Reproduced from the keyboard accelerator (Super+Space) on GNOME 50;
coredump-confirmed. A small re-entrancy guard makes the recursive hide()
a no-op so the actor teardown runs exactly once.
@daniel-g-carrasco

Copy link
Copy Markdown
Author

Pushed a follow-up commit: a re-entrancy guard on hide().

While validating this fix on GNOME 50 I hit a second instance of the same abort, reached from the keyboard accelerator (Super+Space) rather than a click:

clutter_actor_set_mapped: assertion '!CLUTTER_ACTOR_IN_MAP_UNMAP' failed
Clutter:ERROR clutter_actor_real_unrealize: assertion (!clutter_actor_is_mapped (self))

Root cause (coredump JS stack): the this._entry.hide() this PR adds flips the stage key-focus → _onKeyFocusChangedthis.hide() again → re-enters _release_ui() while the first teardown is still mid-unmap. The guard (this._hiding) makes the recursive hide() a no-op so teardown runs exactly once. With both changes, click and keyboard paths are stable here.

@daniel-g-carrasco

Copy link
Copy Markdown
Author

Folded the full root-cause writeup + the remaining crash sites into #166 — this PR is the _release_ui hide-before-detach + hide() re-entrancy part of it.

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.

2 participants