GDK双缓冲区的大小

时间:2014-06-16 08:57:26

标签: c buffer cairo clip

当(重新)在expose_event之后绘制CAIRO矩形时,我发现双缓冲可以防止屏幕闪烁。不幸的是,当调整窗口框架大小时,双缓冲区似乎在屏幕上“悬挂”为阴影。将双缓冲设置为FALSE,删除阴影但会使复杂的绘图闪烁。

如果我将“无效”整个新调整大小的窗口区域(在公开事件中),问题就解决了,但是曝光事件不断激发新的重绘请求。

如何在双缓冲上下文中调整GDK剪辑区域的大小?

非常感谢

我使用的程序代码检测问题的原因:

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

static gboolean on_expose_event (GtkWidget *widget,
                                 GdkEventExpose *event ,
                                 gpointer data)
{
  cairo_t *cr;
  int width, height, kwadrant;

  cr = gdk_cairo_create (widget->window);

  gtk_window_get_size(GTK_WINDOW(widget), &width, &height);

  cairo_rectangle(cr, 0.0, 0.0, width, height);
  cairo_set_source_rgb(cr, 0.0, 0.0, 0.5);
  cairo_fill(cr);

  if (width < height)
      kwadrant = 0.8 * width;
  else
      kwadrant = 0.8 * height;

  cairo_set_line_width(cr, 1);
  cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);

  cairo_rectangle(cr, (width - kwadrant)/2, (height - kwadrant)/2, kwadrant, kwadrant);  
  cairo_stroke(cr);

  cairo_destroy(cr);

  return TRUE;
}

void frame_callback(GtkWindow *window,  
                    GdkEvent *event, 
                    gpointer data)
{

   char buff [50];
   sprintf (buff, "%i X %i", event->configure.width, 
                             event->configure.height);

   gtk_window_set_title(window, buff);
   return;
}

int main (int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *darea;  

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    darea = gtk_drawing_area_new();
    gtk_container_add(GTK_CONTAINER (window), darea);

    gtk_widget_set_app_paintable(window, TRUE);     
    gtk_widget_set_double_buffered(window, TRUE);

    g_signal_connect(G_OBJECT(window), "expose-event",
                     G_CALLBACK(on_expose_event), NULL);

    g_signal_connect(G_OBJECT(window), "configure-event",
                     G_CALLBACK(frame_callback), NULL);

    g_signal_connect_swapped(G_OBJECT(window), "destroy",  
                             G_CALLBACK(gtk_main_quit), G_OBJECT(window));

    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_widget_add_events(GTK_WIDGET(window), GDK_CONFIGURE);

    gtk_widget_show (window);    
    gtk_main();    

    return 0;
}

=========稍后补充:

经常发生: 在搜索有效解决方案的天数后,我发布了此消息。过了一会儿,我试图在EXPOSE事件之外隔离“触发剪辑”并替换所有

gtk_widget_queue_draw (widget);

使用

进行调用
void request_redraw (GtkWidget *widget)
{
    GdkRectangle rect;
    int width, height;

    gtk_window_get_size (GTK_WINDOW(window), &width, &height);

    rect.x      = 0;
    rect.y      = 0;
    rect.width  = width;    
    rect.height = height;   

    gdk_window_invalidate_rect (gtk_widget_get_window(widget), &rect, TRUE);
    gtk_widget_queue_draw (widget);

    return;
}

这允许我保持双缓冲,避免屏幕闪烁并重新绘制与调整大小的帧/窗口对应的整个区域。

这是一个正确的解决方案还是有更好的方法?

抱歉提出了不必要的问题

0 个答案:

没有答案