Re: Flickering with Socket and Plug



Hey Eric,

> I looked at this a little more and can get the flicker. Testing on
> Ubuntu16.04 with GTK3.18 it works without flicker and on Ubuntu16.04
> with a jhbuild of GTK3.22 it does flicker. I tweaked your code a little
> so that I could test it a little easier.

Good, that you can reproduce it!

So what is your suggestion, how can we procceed with this issue? This is very likely a bug in GTK, right?

Many thanks for our effort!
René

On 27.09.2017 22:00, cecashon aol com wrote:

Hi Rene,

I looked at this a little more and can get the flicker. Testing on Ubuntu16.04 with GTK3.18 it works without flicker and on Ubuntu16.04 with a jhbuild of GTK3.22 it does flicker. I tweaked your code a little so that I could test it a little easier.

Eric


/*
    gcc -Wall socket_plug1.c -o socket_plug1 `pkg-config --cflags --libs gtk+-3.0`
     Tested on Ubuntu16.04 and GTK3.18 and GTK3.22
     Flickers with 3.22
*/

#include <cairo.h>
#include <gtk/gtkx.h>

//cairo_surface_t * image = NULL;
GdkPixbuf *image=NULL;
static GTimer *timer=NULL;
static guint timer_id=0;

gboolean timeout(gpointer data)
{
   gtk_widget_queue_draw(GTK_WIDGET(data));
   return TRUE;
}

gboolean draw_callback (GtkWidget *widget, cairo_t *cr, gpointer data)
{
   g_timer_start(timer);
   gint width=gtk_widget_get_allocated_width(widget);
   gint height=gtk_widget_get_allocated_height(widget);
   gint rect_x=width/10;
   gint rect_y=height/10;
   gint i=0;
   gint j=0;
   gint move_x=0;
   gint move_y=0;
   static gint overlap=0;

   //Set some limits to draw with.
   if(rect_x>20&&rect_y>20)
     {
      GdkPixbuf *pixbuf=gdk_pixbuf_scale_simple(image, rect_x, rect_y, GDK_INTERP_BILINEAR);
       for(i=0;i<10;i++)
         {
           for(j=0;j<10;j++)
             {
               gdk_cairo_set_source_pixbuf(cr, pixbuf, move_x, move_y);
               cairo_paint(cr);
               move_x+=rect_x-overlap;
             }
           move_x=0;
           move_y+=rect_y;
         }
       g_object_unref(pixbuf);

       if(overlap==20) overlap=0;
       else overlap++;
     }
   else
     {
       //Just draw white if below the limit.
       cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
       cairo_paint(cr);
     }

   g_print("Timer %f\n", g_timer_elapsed(timer, NULL));
   return FALSE;
}
static void quit_program(GtkWidget *widget, gpointer data)
   {
     g_source_remove(timer_id);
     gtk_main_quit();
   }
//-------------------------------------------------------------------------
int main(int argc, char** argv)
{
   gtk_init (&argc, &argv);

  //image = cairo_image_surface_create_from_png("1200px-GTK+_logo.svg.png");
   GError *error=NULL;
   image = gdk_pixbuf_new_from_file("1200px-GTK+_logo.svg.png", &error);
   if(error!=NULL) g_print("%s\n", error->message);

   GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   gtk_window_set_default_size(GTK_WINDOW(window), 400, 400);
   g_signal_connect(window, "destroy", G_CALLBACK(quit_program), NULL);

   timer=g_timer_new();

   GtkWidget* socket = gtk_socket_new();
   gtk_widget_set_hexpand(socket, TRUE);
   gtk_widget_set_vexpand(socket, TRUE);
   gtk_container_add(GTK_CONTAINER(window), socket);

   Window socket_id = gtk_socket_get_id(GTK_SOCKET(socket));
   GtkWidget* plug = gtk_plug_new(socket_id);
   gtk_widget_set_hexpand(plug, TRUE);
   gtk_widget_set_vexpand(plug, TRUE);

   GtkWidget* drawing_area = gtk_drawing_area_new ();
   gtk_widget_set_hexpand(drawing_area, TRUE);
   gtk_widget_set_vexpand(drawing_area, TRUE);
   gtk_container_add(GTK_CONTAINER(plug), drawing_area);
  g_signal_connect (G_OBJECT (drawing_area), "draw", G_CALLBACK (draw_callback), NULL);

   timer_id=g_timeout_add(16, timeout, drawing_area);
   gtk_widget_show_all(plug);
   gtk_widget_show_all (window);

   gtk_main ();
   return 0;
}


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