[gtk/gtk-3-24: 2/3] gtksettings: Remove display from cache on closing
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/gtk-3-24: 2/3] gtksettings: Remove display from cache on closing
- Date: Fri, 24 Jan 2020 16:36:07 +0000 (UTC)
commit b1d55f2c85203d92cecd0bc4112a78e7d8abc3a3
Author: Olivier Fourdan <ofourdan redhat com>
Date: Thu Jan 23 14:25:29 2020 +0100
gtksettings: Remove display from cache on closing
GTK caches the settings per display in a static `GArray`, keeping a
reference to the `GdkDisplay` as the key.
However, when closing the display, the corresponding entry is not
removed from the cache in `GtkSettings`.
So when reopening again a `GdkDisplay`, if the new address matches one
of the previously closed display, the cache will return the existing
`GtkSettings` from the cache, which still holds a reference to the old
`GdkScreen` which was freed along the `GdkDisplay`.
To avoid the issue, make sure to remove the `GdkDisplay` and
corresponding `GdkSettings` when closing the `GdkDisplay`.
Also, care must be taken not to recreate the `GdkSettings` and re-add
the `GdkDisplay` to the cache once the display is closed, and make sure
callers of `gtk_settings_get_for_display()` can deal with a returned
value being `NULL` if the display is closed.
Fixes: commit 360a3c16902 - "Use a cheaper way to store settings per
display"
gtk/gtkicontheme.c | 7 ++++---
gtk/gtkmodules.c | 8 ++++----
gtk/gtksettings.c | 31 ++++++++++++++++++++++++++++++-
3 files changed, 38 insertions(+), 8 deletions(-)
---
diff --git a/gtk/gtkicontheme.c b/gtk/gtkicontheme.c
index 33634254a2..179078eec8 100644
--- a/gtk/gtkicontheme.c
+++ b/gtk/gtkicontheme.c
@@ -608,9 +608,10 @@ unset_screen (GtkIconTheme *icon_theme)
g_signal_handlers_disconnect_by_func (display,
(gpointer) display_closed,
icon_theme);
- g_signal_handlers_disconnect_by_func (settings,
- (gpointer) theme_changed,
- icon_theme);
+ if (settings)
+ g_signal_handlers_disconnect_by_func (settings,
+ (gpointer) theme_changed,
+ icon_theme);
priv->screen = NULL;
}
diff --git a/gtk/gtkmodules.c b/gtk/gtkmodules.c
index 0aaedae581..704e412aeb 100644
--- a/gtk/gtkmodules.c
+++ b/gtk/gtkmodules.c
@@ -463,10 +463,10 @@ display_closed_cb (GdkDisplay *display,
screen = gdk_display_get_default_screen (display);
settings = gtk_settings_get_for_screen (screen);
-
- g_object_set_data_full (G_OBJECT (settings),
- I_("gtk-modules"),
- NULL, NULL);
+ if (settings)
+ g_object_set_data_full (G_OBJECT (settings),
+ I_("gtk-modules"),
+ NULL, NULL);
}
diff --git a/gtk/gtksettings.c b/gtk/gtksettings.c
index b786385127..71a1c29902 100644
--- a/gtk/gtksettings.c
+++ b/gtk/gtksettings.c
@@ -1900,6 +1900,29 @@ settings_init_style (GtkSettings *settings)
settings_update_key_theme (settings);
}
+static void
+settings_display_closed (GdkDisplay *display,
+ gboolean is_error,
+ gpointer data)
+{
+ DisplaySettings *ds;
+ int i;
+
+ if (G_UNLIKELY (display_settings == NULL))
+ return;
+
+ ds = (DisplaySettings *)display_settings->data;
+ for (i = 0; i < display_settings->len; i++)
+ {
+ if (ds[i].display == display)
+ {
+ g_clear_object (&ds[i].settings);
+ display_settings = g_array_remove_index_fast (display_settings, i);
+ break;
+ }
+ }
+}
+
static GtkSettings *
gtk_settings_create_for_display (GdkDisplay *display)
{
@@ -1955,7 +1978,9 @@ gtk_settings_create_for_display (GdkDisplay *display)
v.display = display;
v.settings = settings;
- g_array_append_val (display_settings, v);
+ display_settings = g_array_append_val (display_settings, v);
+ g_signal_connect (display, "closed",
+ G_CALLBACK (settings_display_closed), NULL);
settings_init_style (settings);
settings_update_xsettings (settings);
@@ -1975,6 +2000,10 @@ gtk_settings_get_for_display (GdkDisplay *display)
DisplaySettings *ds;
int i;
+ /* If the display is closed, we don't want to recreate the settings! */
+ if G_UNLIKELY (gdk_display_is_closed (display))
+ return NULL;
+
if G_UNLIKELY (display_settings == NULL)
display_settings = g_array_new (FALSE, TRUE, sizeof (DisplaySettings));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]