Re: CSS provider memory problem




When you first start your program and setup the CSS to style with, keep the pointer to the provider around so that you can reuse it. That way the program won't leak memory by getting a new provider each time that a CSS change is made in the program.

I tried to put some CSS differences in the following test code that I have run into. Hopefully it is of some help.

Eric

/*
   gcc -Wall css_button1.c -o css_button1 `pkg-config --cflags --libs gtk+-3.0`
   Tested with GTK3.18 and GTK3.22 on Ubuntu16.04
*/
#include<gtk/gtk.h>

static gboolean blink(gpointer *data)
  {
    static gint flag=0;
    GError *error=NULL;
 
    if(flag)
      {
        gtk_css_provider_load_from_data((GtkCssProvider*)data[0], (gchar*)data[1], -1, &error);
        flag=0;
      }
    else
      {
        gtk_css_provider_load_from_data((GtkCssProvider*)data[0], (gchar*)data[2], -1, &error);
        flag=1;
      }

    if(error!=NULL)
      {
        g_print("%s\n", error->message);
        g_error_free(error);
      }

    return TRUE;
  }
int main(int argc, char *argv[])
  {
    gtk_init (&argc, &argv);

    GtkWidget *window=gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "CSS Button");
    gtk_window_set_default_size(GTK_WINDOW(window), 200, 100);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    GtkWidget *button1=gtk_button_new_with_label("button1");
    gtk_widget_set_hexpand(button1, TRUE);
    gtk_widget_set_vexpand(button1, TRUE); 
 
    GtkWidget *grid=gtk_grid_new();
    gtk_grid_attach(GTK_GRID(grid), button1, 0, 0, 1, 1);

    gtk_container_add(GTK_CONTAINER(window), grid);

    gtk_widget_show_all(window);

    //Setup CSS for the program.
    GError *css_error=NULL;
    gint minor_version=gtk_get_minor_version();
    gchar *css_string1=NULL;
    gchar *css_string2=NULL;
    //GTK CSS changed in 3.20.
    if(minor_version>20)
      {
        css_string1=g_strdup("button{background: red;}");
        css_string2=g_strdup("button{background: white;}");
      }
    else
      {
        css_string1=g_strdup("GtkButton{background: red;}");
        css_string2=g_strdup("GtkButton{background: white;}");
      }
    GtkCssProvider *provider=gtk_css_provider_new();
    GdkDisplay *display=gdk_display_get_default();
    GdkScreen *screen=gdk_display_get_default_screen(display);
    gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
    gtk_css_provider_load_from_data(provider, css_string1, -1, &css_error);
    //Print out the provider to see what is there.
    if(css_error==NULL)
      {
        gchar *string=gtk_css_provider_to_string(provider);
        g_print("%s\n", string);
        g_free(string);
      }
    else
      {
        g_print("CSS loader error %s\n", css_error->message);
        g_error_free(css_error);
      }
    g_object_unref(provider);

    gpointer data[]={provider, css_string1, css_string2};
    g_timeout_add(500, (GSourceFunc)blink, data);

    gtk_main();

    if(css_string1!=NULL) g_free(css_string1);
    if(css_string2!=NULL) g_free(css_string2);

    return 0;
  } 





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]