Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions src/components/dock/dock_launch_feedback.vala
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,22 @@ namespace Singularity {
bin.scale_x = 1.0;
Singularity.Motion.spring_to(bin, "scale-x", STRETCH, Singularity.Motion.Spring.SNAPPY);
}
unowned Gtk.Widget wrapper_weak = wrapper;
unowned Singularity.Animation.MotionBin bin_weak = bin;
// The give-up timer can outlive the dock item it was armed for: a
// dock rebuild, an app-grid change or session teardown frees
// `wrapper` well inside GIVE_UP_SECONDS (10 s). The captures MUST
// therefore be owned references. With `unowned` captures the
// callback later called g_object_get_data() on a freed GtkWidget
// and the shell died with SIGSEGV in
// g_type_check_instance_is_fundamentally_a (O6N, 2026-10-11).
// Owning both objects keeps them valid until the source is
// removed; the closure drops the references when it is finalized.
Gtk.Widget wrapper_ref = wrapper;
Singularity.Animation.MotionBin bin_ref = bin;
GLib.Timeout.add_seconds(GIVE_UP_SECONDS, () => {
if (wrapper_weak.get_data<Singularity.Animation.MotionBin>("launch_dot") == bin_weak) {
wrapper_weak.set_data<Singularity.Animation.MotionBin?>("launch_dot", null);
var parent = bin_weak.get_parent() as Gtk.Box;
if (parent != null) parent.remove(bin_weak);
if (wrapper_ref.get_data<Singularity.Animation.MotionBin>("launch_dot") == bin_ref) {
wrapper_ref.set_data<Singularity.Animation.MotionBin?>("launch_dot", null);
var parent = bin_ref.get_parent() as Gtk.Box;
if (parent != null) parent.remove(bin_ref);
}
return GLib.Source.REMOVE;
});
Expand Down
Loading