Strange behavior when using GtkDrawingArea with backing pixmap in a GtkScrolledWindow



Hi,

I have some problems about the usage of GtkDrawingArea with backing
pixmap when I use it in a GtkScrolledWindow.

You can copy the following code segment into a c++ file (ex: ddd.cpp),
and compile with

g++ 'pkg-config gtkmm-2.0 --cflags --libs' ddd.cpp

and see what will happen.

I have no idea whether this result is the misuse of GtkDrawingArea or a
bug in gtk.

Althought I've implemented the following code segment by using gtkmm
(i.e. C++), but I think it is eqivalent to using gtk (i.e. C).

The container hierarchy is:

GtkWindow -> GtkScrolledWindow -> GtkTable -> GtkDrawingArea

And I use a backing pixmap with GtkDrawingArea to avoid the flicker,
thus I disable the default double buffered behavior with the
GtkDrawingArea.

When I start the program and hit a keystoke, the DrawingArea will be
filled with red. This is OK.

However, when I try to resize the window by using the mouse, X window
seems
not to update the drawing area with its backing pixmap.

Is this  a bug in gtk or the misuse of GtkDrawingArea with backing
pixmap?

Thanks for any replies.
============================================================

#include <gtkmm.h>

struct MainWindow : public Gtk::Window
{
  Gtk::ScrolledWindow mScrolledWindow;
  Gtk::DrawingArea mDrawingArea;
  Gtk::Table mTable;
  
  Glib::RefPtr<Gdk::Pixbuf> mpPixbuf;
  Glib::RefPtr<Gdk::Pixmap> mpPixmap;
  
  MainWindow()
  {
    add(mScrolledWindow);
    mScrolledWindow.add(mTable);
    mTable.attach(mDrawingArea, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0,
0);
    
    mDrawingArea.set_double_buffered(false);
    
    mDrawingArea.signal_size_allocate().
      connect(SigC::slot(*this,
&MainWindow::OnDrawingAreaSizeAllocate));
    
    signal_key_press_event().connect_notify(SigC::slot(*this,
&MainWindow::OnKeyPressEvent));
    
    show_all_children();
  }
  
  void
  OnKeyPressEvent(GdkEventKey *event)
  {
    mDrawingArea.set_size_request(400, 500);
  }
  
  void
  OnDrawingAreaSizeAllocate(GtkAllocation *allocate)
  {
    if (true == mDrawingArea.is_realized())
    {
      int width = allocate->width;
      int height = allocate->height;
      
      if (false == mpPixmap.is_null())
      {
        mpPixmap.clear();
      }
      
      if (false == mpPixbuf.is_null())
      {
        mpPixbuf.clear();
      }
      
      mpPixbuf = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB,
                                     false, // has_alpha
                                     8, // bits_per_sample
                                     width,
                                     height);
      
      mpPixbuf->fill(0xFF000000);
      
      mpPixmap = Gdk::Pixmap::create(mDrawingArea.get_window(),
                                     width,
                                     height, -1);
      
      mpPixmap->draw_pixbuf(Glib::RefPtr<Gdk::GC>(), // an empty GC
                            mpPixbuf,
                            0, 0, // src
                            0, 0, // dest
                            static_cast<int>(width),
                            static_cast<int>(height),
                            Gdk::RGB_DITHER_NONE,
                            0, 0 // dither offset
                            );
      
      mDrawingArea.get_window()->set_back_pixmap(mpPixmap,
                                                 false //
parent_relative
                                                 );
      mDrawingArea.get_window()->clear();
    }
  }
};

int
main(int argc, char *argv[])
{
  Gtk::Main kit(argc, argv);
  
  MainWindow main_window;
  
  Gtk::Main::run(main_window);
  
  return 0;
}

=========================================================






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