summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntónio Fernandes <antoniof@gnome.org>2022-12-09 18:59:53 +0000
committerAntónio Fernandes <antoniof@gnome.org>2023-01-06 19:34:10 +0000
commit4fea54d8c74370078c07c2de512d9f56f64f4049 (patch)
tree973c1c3da04fa3808282dd16fb5ecb638e844161
parent71c7770823fe4c6c26debbb05bcb60b3eca08f33 (diff)
downloadnautilus-4fea54d8c74370078c07c2de512d9f56f64f4049.tar.gz
window: Avoid crash when closing window
We remove the pad controller before calling gtk_window_destroy() to break a dependency cycle. However, if for some reason the controller has already been removed by the time we reach that part of our code, we access a pointer to and already destroyed object. Try to avoid this with a weak pointer, such that we skip the step if the pointer is already NULL. Presumably fixes https://gitlab.gnome.org/GNOME/nautilus/-/issues/2572
-rw-r--r--src/nautilus-window.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/nautilus-window.c b/src/nautilus-window.c
index 5e251f095..1d927b622 100644
--- a/src/nautilus-window.c
+++ b/src/nautilus-window.c
@@ -1672,8 +1672,12 @@ nautilus_window_close (NautilusWindow *window)
* Usually, reference cycles are resolved in dispose(), but GTK removes the
* controllers in finalize(), so our only option is to manually remove it
* here before starting the destruction of the window. */
- gtk_widget_remove_controller (GTK_WIDGET (window),
- GTK_EVENT_CONTROLLER (window->pad_controller));
+ if (window->pad_controller != NULL)
+ {
+ gtk_widget_remove_controller (GTK_WIDGET (window),
+ GTK_EVENT_CONTROLLER (window->pad_controller));
+ g_clear_weak_pointer (&window->pad_controller);
+ }
gtk_window_destroy (GTK_WINDOW (window));
}
@@ -2064,6 +2068,7 @@ nautilus_window_init (NautilusWindow *window)
{
GtkWindowGroup *window_group;
GtkEventController *controller;
+ GtkPadController *pad_controller;
g_type_ensure (NAUTILUS_TYPE_TOOLBAR);
g_type_ensure (NAUTILUS_TYPE_GTK_PLACES_SIDEBAR);
@@ -2098,8 +2103,11 @@ nautilus_window_init (NautilusWindow *window)
/* Attention: this creates a reference cycle: the pad controller owns a
* reference to the window (as an action group) and the window (as a widget)
* owns a reference to the pad controller. To break this, we must remove
- * the controller from the window before destroying the window. */
- window->pad_controller = gtk_pad_controller_new (G_ACTION_GROUP (window), NULL);
+ * the controller from the window before destroying the window. But we need
+ * to know the controller is still alive before trying to remove it, so a
+ * weak reference is added. */
+ pad_controller = gtk_pad_controller_new (G_ACTION_GROUP (window), NULL);
+ g_set_weak_pointer (&window->pad_controller, pad_controller);
gtk_pad_controller_set_action_entries (window->pad_controller,
pad_actions, G_N_ELEMENTS (pad_actions));
gtk_widget_add_controller (GTK_WIDGET (window),