From d3cd68f11dace98bc04f16d9e958cbb2f0d25b09 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 26 Sep 2020 20:38:36 -0400 Subject: [PATCH] scrolledwindow: Fix critical when unsetting scroll cursor When installing the scroll cursor, add a weak ref to scrolled_window that clears it if finalised. Unset the weak ref when the uninstalling the cursor, and when the widget is destroyed. Patch by Michael James Gratton Fixes: #749 --- gtk/gtkscrolledwindow.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c index 95c910f50e..f17863d805 100644 --- a/gtk/gtkscrolledwindow.c +++ b/gtk/gtkscrolledwindow.c @@ -412,6 +412,7 @@ static void indicator_start_fade (Indicator *indicator, gdouble pos); static void indicator_set_over (Indicator *indicator, gboolean over); +static void uninstall_scroll_cursor (GtkScrolledWindow *scrolled_window); static guint signals[LAST_SIGNAL] = {0}; @@ -2806,6 +2807,7 @@ gtk_scrolled_window_destroy (GtkWidget *widget) remove_indicator (scrolled_window, &priv->hindicator); remove_indicator (scrolled_window, &priv->vindicator); + uninstall_scroll_cursor (scrolled_window); if (priv->hscrollbar) { @@ -3407,6 +3409,21 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget, gtk_widget_set_clip (widget, &clip); } +static void +clear_scroll_window (GtkScrolledWindow *scrolled_window) +{ + GtkScrolledWindowPrivate *priv = scrolled_window->priv; + priv->scroll_window = NULL; + g_clear_object (&priv->scroll_cursor); +} + +static void +finalize_scroll_window (gpointer data, + GObject *where_the_object_was) +{ + clear_scroll_window ((GtkScrolledWindow *) data); +} + static void install_scroll_cursor (GtkScrolledWindow *scrolled_window, GdkWindow *window) @@ -3419,6 +3436,8 @@ install_scroll_cursor (GtkScrolledWindow *scrolled_window, return; priv->scroll_window = window; + g_object_weak_ref (G_OBJECT (priv->scroll_window), finalize_scroll_window, scrolled_window); + priv->scroll_cursor = gdk_window_get_cursor (priv->scroll_window); if (priv->scroll_cursor) g_object_ref (priv->scroll_cursor); @@ -3437,8 +3456,8 @@ uninstall_scroll_cursor (GtkScrolledWindow *scrolled_window) if (priv->scroll_window) { gdk_window_set_cursor (priv->scroll_window, priv->scroll_cursor); - priv->scroll_window = NULL; - g_clear_object (&priv->scroll_cursor); + g_object_weak_unref (G_OBJECT (priv->scroll_window), finalize_scroll_window, scrolled_window); + clear_scroll_window (scrolled_window); } }