diff --git a/src/gui/gtk.c b/src/gui/gtk.c index 7ccadb27c898..00f4ab2e4136 100644 --- a/src/gui/gtk.c +++ b/src/gui/gtk.c @@ -3686,9 +3686,20 @@ void dt_gui_load_theme(const char *theme) GError *error = NULL; - GtkStyleProvider *themes_style_provider = GTK_STYLE_PROVIDER(gtk_css_provider_new()); - gtk_style_context_add_provider_for_screen - (gdk_screen_get_default(), themes_style_provider, GTK_STYLE_PROVIDER_PRIORITY_USER + 1); + // Reuse a single provider across calls. Adding a fresh one each time + // leaked the previous theme onto the screen -- gtk keeps its own + // reference, so the unref below never removed it -- and with every + // provider sitting at the same priority the oldest one still won the + // @define-color lookups. The result was a theme change only taking + // effect one load later. + static GtkCssProvider *themes_style_provider = NULL; + if(!themes_style_provider) + { + themes_style_provider = gtk_css_provider_new(); + gtk_style_context_add_provider_for_screen + (gdk_screen_get_default(), GTK_STYLE_PROVIDER(themes_style_provider), + GTK_STYLE_PROVIDER_PRIORITY_USER + 1); + } // We load the themes in this specific order: // 1. The main darktable-*.css @@ -3739,7 +3750,7 @@ void dt_gui_load_theme(const char *theme) themecss = newcss; } - if(!gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(themes_style_provider), + if(!gtk_css_provider_load_from_data(themes_style_provider, themecss, -1, &error)) { dt_print(DT_DEBUG_ALWAYS, @@ -3749,8 +3760,7 @@ void dt_gui_load_theme(const char *theme) } g_free(themecss); - - g_object_unref(themes_style_provider); + // provider is kept alive on purpose, see above } void dt_gui_apply_theme() diff --git a/src/gui/preferences.c b/src/gui/preferences.c index ef3f89ab8ecd..112756fdae06 100644 --- a/src/gui/preferences.c +++ b/src/gui/preferences.c @@ -393,7 +393,9 @@ static void init_tab_general(GtkWidget *dialog, // read all themes char *theme_name = dt_conf_get_string("ui_last/theme"); - int selected = 0; + const char *default_theme = dt_confgen_get("ui_last/theme", DT_DEFAULT); + int selected = -1; + int default_selected = -1; int k = 0; for(GList *iter = darktable.themes; iter; iter = g_list_next(iter)) { @@ -403,10 +405,17 @@ static void init_tab_general(GtkWidget *dialog, if(i) *i = '\0'; dt_bauhaus_combobox_add_aligned(widget, name, DT_BAUHAUS_COMBOBOX_ALIGN_LEFT); if(!g_strcmp0(name, theme_name)) selected = k; + if(!g_strcmp0(name, default_theme)) default_selected = k; k++; + g_free(name); } g_free(theme_name); + // a theme we don't know about must not silently read as whichever one + // happens to sort first -- show the configured default instead + if(selected < 0) + selected = (default_selected >= 0) ? default_selected : 0; + dt_bauhaus_combobox_set(widget, selected); g_signal_connect(G_OBJECT(widget), "value-changed",