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
This commit is contained in:
Matthias Clasen 2020-09-26 20:38:36 -04:00
parent 96f403d608
commit d3cd68f11d

View File

@ -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);
}
}