From ab0c8488e27201dd17442141f7fe1b511d9a91a8 Mon Sep 17 00:00:00 2001 From: Leonhard Kargl Date: Thu, 3 Sep 2026 14:20:25 +0200 Subject: [PATCH 1/2] TransitionBuilder: Add return value to run Inform the caller about whether the transitions have finished or whether they were somehow interrupted. --- lib/TransitionBuilder.vala | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/TransitionBuilder.vala b/lib/TransitionBuilder.vala index 58e632f83..453eff3a7 100644 --- a/lib/TransitionBuilder.vala +++ b/lib/TransitionBuilder.vala @@ -48,17 +48,28 @@ public class Gala.TransitionBuilder : Object { group.add_transition (property_transition); } - public async void run () { + /** + * Runs the transitions added to #this. Returns true if the transitions + * fully completed and false if they were somehow interrupted (e.g. + * the actor was destroyed or remove all transitions was called). + */ + public async bool run () { if (!Meta.Prefs.get_gnome_animations ()) { - return; + return true; } - var stopped_handler_id = group.stopped.connect (() => run.callback ()); + bool is_finished = false; + var stopped_handler_id = group.stopped.connect ((_is_finished) => { + is_finished = _is_finished; + run.callback (); + }); actor.add_transition (Uuid.string_random (), group); yield; group.disconnect (stopped_handler_id); + + return is_finished; } } From 48aa08b59b2c26868ca59696123a38fa62f9195a Mon Sep 17 00:00:00 2001 From: Leonhard Kargl Date: Thu, 3 Sep 2026 14:21:16 +0200 Subject: [PATCH 2/2] Fix crash when destroying notifications --- src/Misc/NotificationStack.vala | 4 ++-- src/WindowManager.vala | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Misc/NotificationStack.vala b/src/Misc/NotificationStack.vala index 1f2a668f1..20e3ba1a1 100644 --- a/src/Misc/NotificationStack.vala +++ b/src/Misc/NotificationStack.vala @@ -163,7 +163,7 @@ public class Gala.NotificationStack : Object { } } - public async void destroy_notification (Meta.WindowActor notification) { + public async bool destroy_notification (Meta.WindowActor notification) { notifications.remove (notification); update_positions (); @@ -171,7 +171,7 @@ public class Gala.NotificationStack : Object { builder.add_property ("opacity", 0u); builder.add_property ("x", notification.x + stack_width); - yield builder.run (); + return yield builder.run (); } /** diff --git a/src/WindowManager.vala b/src/WindowManager.vala index 52b6af966..5543b36ae 100644 --- a/src/WindowManager.vala +++ b/src/WindowManager.vala @@ -1155,7 +1155,15 @@ namespace Gala { default: if (NotificationStack.is_notification (window)) { - yield notification_stack.destroy_notification (actor); + if (!(yield notification_stack.destroy_notification (actor)) && window.window_type == NOTIFICATION) { + /* This is a workaround for X11. On X11 notifications actually get the window type + notification which is according to mutter not allowed to have any destroy animations. + Therefore if the destroy animation didn't finish this means it was interrupted probably + because mutter destroyed the actor already so don't call destroy_completed + because that would lead to a use after free. */ + destroying.remove (actor); + return; + } } break; }