From: Robert Roebling Date: Mon, 4 Feb 2002 14:05:28 +0000 (+0000) Subject: Now updating and clearing are done in a delayed fashion. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/3bcc8d15815a0c3d8c515083561e296cac242bf0 Now updating and clearing are done in a delayed fashion. The m_updateRegion gets updated and the (often much smaller) m_clearRegion gets cleared. This removes the flicker introduced by having delayed updates and immediate clearings. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13994 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h index 9c9bb4d739..a0d1a66f2e 100644 --- a/include/wx/gtk/window.h +++ b/include/wx/gtk/window.h @@ -183,6 +183,9 @@ public: GdkICAttr *m_icattr; #endif + // The area to be cleared (and not just refreshed) + wxRegion m_clearRegion; + // scrolling stuff GtkAdjustment *m_hAdjust,*m_vAdjust; float m_oldHorizontalPos; diff --git a/include/wx/gtk1/window.h b/include/wx/gtk1/window.h index 9c9bb4d739..a0d1a66f2e 100644 --- a/include/wx/gtk1/window.h +++ b/include/wx/gtk1/window.h @@ -183,6 +183,9 @@ public: GdkICAttr *m_icattr; #endif + // The area to be cleared (and not just refreshed) + wxRegion m_clearRegion; + // scrolling stuff GtkAdjustment *m_hAdjust,*m_vAdjust; float m_oldHorizontalPos; diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 016b47c69b..688d7399cd 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -3320,8 +3320,8 @@ void wxWindowGTK::WarpPointer( int x, int y ) { wxCHECK_RET( (m_widget != NULL), wxT("invalid window") ); - /* we provide this function ourselves as it is - missing in GDK (top of this file) */ + // We provide this function ourselves as it is + // missing in GDK (top of this file). GdkWindow *window = (GdkWindow*) NULL; if (m_wxwindow) @@ -3348,95 +3348,45 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect ) { if (rect) { - gdk_window_clear_area( GTK_PIZZA(m_wxwindow)->bin_window, - rect->x, rect->y, - rect->width, rect->height ); + // Schedule for later Updating in ::Update() or ::OnInternalIdle(). + m_clearRegion.Union( rect->x, rect->y, rect->width, rect->height ); } else { - gdk_window_clear( GTK_PIZZA(m_wxwindow)->bin_window ); + // Schedule for later Updating in ::Update() or ::OnInternalIdle(). + m_clearRegion.Clear(); + m_clearRegion.Union( 0, 0, m_wxwindow->allocation.width, m_wxwindow->allocation.height ); } } - /* there is no GTK equivalent of "draw only, don't clear" so we - invent our own in the GtkPizza widget */ - - if (!rect) + if (rect) { if (m_wxwindow) { -#if 0 - GtkPizza *pizza = GTK_PIZZA(m_wxwindow); - gboolean old_clear = pizza->clear_on_draw; - gtk_pizza_set_clear( pizza, FALSE ); - gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL ); - gtk_pizza_set_clear( pizza, old_clear ); -#endif - -#if 1 // Schedule for later Updating in ::Update() or ::OnInternalIdle(). - m_updateRegion.Union( 0, 0, m_wxwindow->allocation.width, m_wxwindow->allocation.height ); -#else - GdkEventExpose gdk_event; - gdk_event.type = GDK_EXPOSE; - gdk_event.window = GTK_PIZZA(m_wxwindow)->bin_window; - gdk_event.count = 0; - gdk_event.area.x = 0; - gdk_event.area.y = 0; - gdk_event.area.width = m_wxwindow->allocation.width; - gdk_event.area.height = m_wxwindow->allocation.height; - gtk_window_expose_callback( m_wxwindow, &gdk_event, (wxWindow *)this ); -#endif + m_updateRegion.Union( rect->x, rect->y, rect->width, rect->height ); } else { - gtk_widget_draw( m_widget, (GdkRectangle*) NULL ); + GdkRectangle gdk_rect; + gdk_rect.x = rect->x; + gdk_rect.y = rect->y; + gdk_rect.width = rect->width; + gdk_rect.height = rect->height; + gtk_widget_draw( m_widget, &gdk_rect ); } } else { - if (m_wxwindow) { -#if 0 - GtkPizza *pizza = GTK_PIZZA(m_wxwindow); - gboolean old_clear = pizza->clear_on_draw; - gtk_pizza_set_clear( pizza, FALSE ); - - GdkRectangle gdk_rect; - gdk_rect.x = rect->x; - gdk_rect.y = rect->y; - gdk_rect.width = rect->width; - gdk_rect.height = rect->height; - gtk_widget_draw( m_wxwindow, &gdk_rect ); - gtk_window_draw_callback( m_wxwindow, &gdk_rect, this ); - - gtk_pizza_set_clear( pizza, old_clear ); -#endif - -#if 1 // Schedule for later Updating in ::Update() or ::OnInternalIdle(). - m_updateRegion.Union( rect->x, rect->y, rect->width, rect->height ); -#else - GdkEventExpose gdk_event; - gdk_event.type = GDK_EXPOSE; - gdk_event.window = GTK_PIZZA(m_wxwindow)->bin_window; - gdk_event.count = 0; - gdk_event.area.x = rect->x; - gdk_event.area.y = rect->y; - gdk_event.area.width = rect->width; - gdk_event.area.height = rect->height; - gtk_window_expose_callback( m_wxwindow, &gdk_event, (wxWindow *)this ); -#endif + m_updateRegion.Clear(); + m_updateRegion.Union( 0, 0, m_wxwindow->allocation.width, m_wxwindow->allocation.height ); } else { - GdkRectangle gdk_rect; - gdk_rect.x = rect->x; - gdk_rect.y = rect->y; - gdk_rect.width = rect->width; - gdk_rect.height = rect->height; - gtk_widget_draw( m_widget, &gdk_rect ); + gtk_widget_draw( m_widget, (GdkRectangle*) NULL ); } } } @@ -3451,33 +3401,35 @@ void wxWindowGTK::Update() void wxWindowGTK::GtkSendPaintEvents() { - m_clipPaintRegion = TRUE; + if (!m_wxwindow) + { + m_clearRegion.Clear(); + m_updateRegion.Clear(); + return; + } - wxWindowDC dc( (wxWindow*)this ); - dc.SetClippingRegion( m_updateRegion ); - wxEraseEvent erase_event( GetId(), &dc ); - erase_event.SetEventObject( this ); + m_clipPaintRegion = TRUE; -#if 1 - GetEventHandler()->ProcessEvent( erase_event ); -#else - if (!GetEventHandler()->ProcessEvent(erase_event)) + if (!m_clearRegion.IsEmpty()) { + wxWindowDC dc( (wxWindow*)this ); + dc.SetClippingRegion( m_clearRegion ); + + wxEraseEvent erase_event( GetId(), &dc ); + erase_event.SetEventObject( this ); + if (!GetEventHandler()->ProcessEvent(erase_event)) { - wxClientDC dc( this ); - dc.SetBrush( wxBrush( GetBackgroundColour(), wxSOLID ) ); - dc.SetPen( *wxTRANSPARENT_PEN ); - - wxRegionIterator upd( m_updateRegion ); + wxRegionIterator upd( m_clearRegion ); while (upd) { - dc.DrawRectangle( upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() ); + gdk_window_clear_area( GTK_PIZZA(m_wxwindow)->bin_window, + upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() ); upd ++; } } + m_clearRegion.Clear(); } -#endif wxNcPaintEvent nc_paint_event( GetId() ); nc_paint_event.SetEventObject( this ); @@ -4101,6 +4053,16 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) m_updateRegion.Intersect( 0, 0, cw, ch ); } + if (!m_clearRegion.IsEmpty()) + { + m_clearRegion.Offset( dx, dy ); + + int cw = 0; + int ch = 0; + GetClientSize( &cw, &ch ); + m_clearRegion.Intersect( 0, 0, cw, ch ); + } + #if 1 m_clipPaintRegion = TRUE; diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index 016b47c69b..688d7399cd 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/window.cpp @@ -3320,8 +3320,8 @@ void wxWindowGTK::WarpPointer( int x, int y ) { wxCHECK_RET( (m_widget != NULL), wxT("invalid window") ); - /* we provide this function ourselves as it is - missing in GDK (top of this file) */ + // We provide this function ourselves as it is + // missing in GDK (top of this file). GdkWindow *window = (GdkWindow*) NULL; if (m_wxwindow) @@ -3348,95 +3348,45 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect ) { if (rect) { - gdk_window_clear_area( GTK_PIZZA(m_wxwindow)->bin_window, - rect->x, rect->y, - rect->width, rect->height ); + // Schedule for later Updating in ::Update() or ::OnInternalIdle(). + m_clearRegion.Union( rect->x, rect->y, rect->width, rect->height ); } else { - gdk_window_clear( GTK_PIZZA(m_wxwindow)->bin_window ); + // Schedule for later Updating in ::Update() or ::OnInternalIdle(). + m_clearRegion.Clear(); + m_clearRegion.Union( 0, 0, m_wxwindow->allocation.width, m_wxwindow->allocation.height ); } } - /* there is no GTK equivalent of "draw only, don't clear" so we - invent our own in the GtkPizza widget */ - - if (!rect) + if (rect) { if (m_wxwindow) { -#if 0 - GtkPizza *pizza = GTK_PIZZA(m_wxwindow); - gboolean old_clear = pizza->clear_on_draw; - gtk_pizza_set_clear( pizza, FALSE ); - gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL ); - gtk_pizza_set_clear( pizza, old_clear ); -#endif - -#if 1 // Schedule for later Updating in ::Update() or ::OnInternalIdle(). - m_updateRegion.Union( 0, 0, m_wxwindow->allocation.width, m_wxwindow->allocation.height ); -#else - GdkEventExpose gdk_event; - gdk_event.type = GDK_EXPOSE; - gdk_event.window = GTK_PIZZA(m_wxwindow)->bin_window; - gdk_event.count = 0; - gdk_event.area.x = 0; - gdk_event.area.y = 0; - gdk_event.area.width = m_wxwindow->allocation.width; - gdk_event.area.height = m_wxwindow->allocation.height; - gtk_window_expose_callback( m_wxwindow, &gdk_event, (wxWindow *)this ); -#endif + m_updateRegion.Union( rect->x, rect->y, rect->width, rect->height ); } else { - gtk_widget_draw( m_widget, (GdkRectangle*) NULL ); + GdkRectangle gdk_rect; + gdk_rect.x = rect->x; + gdk_rect.y = rect->y; + gdk_rect.width = rect->width; + gdk_rect.height = rect->height; + gtk_widget_draw( m_widget, &gdk_rect ); } } else { - if (m_wxwindow) { -#if 0 - GtkPizza *pizza = GTK_PIZZA(m_wxwindow); - gboolean old_clear = pizza->clear_on_draw; - gtk_pizza_set_clear( pizza, FALSE ); - - GdkRectangle gdk_rect; - gdk_rect.x = rect->x; - gdk_rect.y = rect->y; - gdk_rect.width = rect->width; - gdk_rect.height = rect->height; - gtk_widget_draw( m_wxwindow, &gdk_rect ); - gtk_window_draw_callback( m_wxwindow, &gdk_rect, this ); - - gtk_pizza_set_clear( pizza, old_clear ); -#endif - -#if 1 // Schedule for later Updating in ::Update() or ::OnInternalIdle(). - m_updateRegion.Union( rect->x, rect->y, rect->width, rect->height ); -#else - GdkEventExpose gdk_event; - gdk_event.type = GDK_EXPOSE; - gdk_event.window = GTK_PIZZA(m_wxwindow)->bin_window; - gdk_event.count = 0; - gdk_event.area.x = rect->x; - gdk_event.area.y = rect->y; - gdk_event.area.width = rect->width; - gdk_event.area.height = rect->height; - gtk_window_expose_callback( m_wxwindow, &gdk_event, (wxWindow *)this ); -#endif + m_updateRegion.Clear(); + m_updateRegion.Union( 0, 0, m_wxwindow->allocation.width, m_wxwindow->allocation.height ); } else { - GdkRectangle gdk_rect; - gdk_rect.x = rect->x; - gdk_rect.y = rect->y; - gdk_rect.width = rect->width; - gdk_rect.height = rect->height; - gtk_widget_draw( m_widget, &gdk_rect ); + gtk_widget_draw( m_widget, (GdkRectangle*) NULL ); } } } @@ -3451,33 +3401,35 @@ void wxWindowGTK::Update() void wxWindowGTK::GtkSendPaintEvents() { - m_clipPaintRegion = TRUE; + if (!m_wxwindow) + { + m_clearRegion.Clear(); + m_updateRegion.Clear(); + return; + } - wxWindowDC dc( (wxWindow*)this ); - dc.SetClippingRegion( m_updateRegion ); - wxEraseEvent erase_event( GetId(), &dc ); - erase_event.SetEventObject( this ); + m_clipPaintRegion = TRUE; -#if 1 - GetEventHandler()->ProcessEvent( erase_event ); -#else - if (!GetEventHandler()->ProcessEvent(erase_event)) + if (!m_clearRegion.IsEmpty()) { + wxWindowDC dc( (wxWindow*)this ); + dc.SetClippingRegion( m_clearRegion ); + + wxEraseEvent erase_event( GetId(), &dc ); + erase_event.SetEventObject( this ); + if (!GetEventHandler()->ProcessEvent(erase_event)) { - wxClientDC dc( this ); - dc.SetBrush( wxBrush( GetBackgroundColour(), wxSOLID ) ); - dc.SetPen( *wxTRANSPARENT_PEN ); - - wxRegionIterator upd( m_updateRegion ); + wxRegionIterator upd( m_clearRegion ); while (upd) { - dc.DrawRectangle( upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() ); + gdk_window_clear_area( GTK_PIZZA(m_wxwindow)->bin_window, + upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() ); upd ++; } } + m_clearRegion.Clear(); } -#endif wxNcPaintEvent nc_paint_event( GetId() ); nc_paint_event.SetEventObject( this ); @@ -4101,6 +4053,16 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) m_updateRegion.Intersect( 0, 0, cw, ch ); } + if (!m_clearRegion.IsEmpty()) + { + m_clearRegion.Offset( dx, dy ); + + int cw = 0; + int ch = 0; + GetClientSize( &cw, &ch ); + m_clearRegion.Intersect( 0, 0, cw, ch ); + } + #if 1 m_clipPaintRegion = TRUE;