Gtk will temporarily unset my backing pixmap for a GtkDrawingArea when it is packed into a GtkScrolledWindow, is this a necessary behavior?
- From: Yueh-Wei Hu <r88052 ms csie ntu edu tw>
- To: gtk-devel-list gnome org
- Subject: Gtk will temporarily unset my backing pixmap for a GtkDrawingArea when it is packed into a GtkScrolledWindow, is this a necessary behavior?
- Date: Fri, 09 Apr 2004 15:08:37 +0800
I have posted a message about using GdkDrawingArea with backing pixmap to gtk-app-devel-list mailing list yesterday.
After tracing into gtk and gdk for several hours, I think I find where the problem is.
However, I don't know whether this problem is an undocumented feature or a bug in gtk.
My attempt is to redraw parts of the contents of the GtkDrawingArea without using an expose_event signal handler.
That is to say, I want the X Window System to recover the old contents of the GtkDrawingArea by using the backing pixmap.
Because I want to acquire the max preformance without causing a round trip between the X Window Server and my own program.
Following is my original question:
==============================================================
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?
============================================================
And I find the problem is:
When I click the scrollbar (vertical or horizontal) in the GtkScrolledWindow,
the GtkAdjustment will send a change signal to trigger many side effects.
These side effects include moving the GtkViewport and invalidating the previous obscure portion in
GtkDrawingArea to trigger the X Window Server to send an expose event to the GtkDrawingArea.
But the problem is,
before the above side effect occurs, Gtk will first unset the background pixmap of the GtkDrawingArea
by using XSetWindowBackgroundPixmap(..., ..., NONE). Following are the calling sequences:
... -> _gdk_window_move_resize_child() -> gdk_window_clip_changed() -> gdk_window_tmp_unset_bg() -> XSetWindowBackgroundPixmap()
After that, gdk_window_clip_changed() will call gdk_window_invalidate_region() to trigger the X Window
to send an expose event to the GtkDrawingArea.
However, because of the absence of the background pixmap for the GtkDrawingArea,
the X Window Server will not redraw the background pixmap for the GtkDrawingArea.
After that, _gdk_window_move_resize_child() will call gdk_window_postmove() to reset the background pixmap
for the GtkDrawingArea.
Thus the previous obscure portions of the GtkDrawingArea will not be covered automatically by the backing pixmap I offered,
and the old contents of that part of the GtkDrawingArea will still be showed on the screen.
This is not what most programmers want in most situation.
The method to solve this problem is setting up an expose_event signal handler for the GtkDrawingArea,
and calls some clear_area function or draw_pixmap function to manually recover the backing pixmap for the GtkDrawingArea.
Thus my question is is this behavour (gdk_window_tmp_unset_bg() & gdk_window_tmp_reset_bg()) necessary in gtk & gdk?
And can I use a backing pixmap for the GtkDrawingArea when it is packed into a GtkScrolledWindow or I must to set up an expose_event
signal handler and unset the backing pixmap of the GtkDrawingArea.
Thanks for your help.
============================================================
#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]