CSS provider memory problem

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

CSS provider memory problem

Michal Koranda
Hello,

I have in aplication many widget which some times change color (as atention of working device). I stil use gtk_widget_override_color() function. I rewrite code to CSS-like styling for widgets. There is problem with memmory.
I write simpy demonstration code:


int blink(GtkWidget *widget)
{
   static int flag=0;
       
   GtkStyleContext *style_context = gtk_widget_get_style_context(GTK_WIDGET(widget));
   GtkCssProvider *provider = gtk_css_provider_new();
   gtk_style_context_add_provider(style_context, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
   g_object_unref(provider);
       
   if(flag){
      gtk_css_provider_load_from_data(provider, "*{background: red;}", -1, NULL);
      flag = 0;
   }else{
      gtk_css_provider_load_from_data(provider, "*{background: white;}", -1, NULL);
      flag = 1;
   }
       
        return(TRUE);
}

int main
{
.........

        g_timeout_add(50, (GSourceFunc)blink, button);

...........
}

After starting this code, constantly rise amount of alocated memory. It seems that every use of gtk_style_context_add_provider() add new provider, but the old one is not remove. Is there any way to remove the old provider or get pointer to old provider from widget and reuse this one? Or any other solution?

Thanks much.
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: CSS provider memory problem

Gtk+ - General mailing list

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




_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list