From: Vadim Zeitlin Date: Tue, 16 Jun 2009 23:04:42 +0000 (+0000) Subject: introduce wxBG_STYLE_{ERASE,PAINT} and implement their documented semantics in wxGTK X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/9c61c5b04b0b023eb9592bde5633c2111f1940fb introduce wxBG_STYLE_{ERASE,PAINT} and implement their documented semantics in wxGTK git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61084 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/changes.txt b/docs/changes.txt index 3fc631a4de..b0be3a6447 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -124,6 +124,10 @@ Changes in behaviour not resulting in compilation errors, please read this! - wxLoadFileSelector() now allows the user to select existing files only. +- Erase background events are now not generated at all when background style is + changed. See the updated wxWindow::SetBackgroundStyle() description in the + manual for more details. + Changes in behaviour which may result in compilation errors ----------------------------------------------------------- diff --git a/include/wx/dcbuffer.h b/include/wx/dcbuffer.h index 7b54ecd7e8..383dfcb3ae 100644 --- a/include/wx/dcbuffer.h +++ b/include/wx/dcbuffer.h @@ -219,8 +219,8 @@ public: wxAutoBufferedPaintDC(wxWindow* win) : wxAutoBufferedPaintDCBase(win) { - wxASSERT_MSG( win->GetBackgroundStyle() == wxBG_STYLE_CUSTOM, - "You need to call SetBackgroundStyle(wxBG_STYLE_CUSTOM) in ctor, " + wxASSERT_MSG( win->GetBackgroundStyle() == wxBG_STYLE_PAINT, + "You need to call SetBackgroundStyle(wxBG_STYLE_PAINT) in ctor, " "and also, if needed, paint the background in wxEVT_PAINT handler." ); } diff --git a/include/wx/defs.h b/include/wx/defs.h index 963a4b3d13..75d36d81b3 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -1836,13 +1836,32 @@ enum wxBorder /* * Background styles. See wxWindow::SetBackgroundStyle */ - enum wxBackgroundStyle { - wxBG_STYLE_SYSTEM, - wxBG_STYLE_COLOUR, - wxBG_STYLE_CUSTOM, - wxBG_STYLE_TRANSPARENT + // background is erased in the EVT_ERASE_BACKGROUND handler or using the + // system default background if no such handler is defined (this is the + // default style) + wxBG_STYLE_ERASE, + + // background is erased by the system, no EVT_ERASE_BACKGROUND event is + // generated at all + wxBG_STYLE_SYSTEM, + + // background is erased in EVT_PAINT handler and not erased at all before + // it, this should be used if the paint handler paints over the entire + // window to avoid flicker + wxBG_STYLE_PAINT, + + + // this is a Mac-only style, don't use in portable code + wxBG_STYLE_TRANSPARENT, + + // this style is deprecated and doesn't do anything, don't use + wxBG_STYLE_COLOUR, + + // this style is deprecated and is synonymous with wxBG_STYLE_PAINT, use + // the new name + wxBG_STYLE_CUSTOM = wxBG_STYLE_PAINT }; /* diff --git a/include/wx/window.h b/include/wx/window.h index 31dbf9587c..913cd7d0aa 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -1032,9 +1032,10 @@ public: wxColour GetForegroundColour() const; // Set/get the background style. - // Pass one of wxBG_STYLE_SYSTEM, wxBG_STYLE_COLOUR, wxBG_STYLE_CUSTOM - virtual bool SetBackgroundStyle(wxBackgroundStyle style) { m_backgroundStyle = style; return true; } - virtual wxBackgroundStyle GetBackgroundStyle() const { return m_backgroundStyle; } + virtual bool SetBackgroundStyle(wxBackgroundStyle style) + { m_backgroundStyle = style; return true; } + wxBackgroundStyle GetBackgroundStyle() const + { return m_backgroundStyle; } // returns true if the control has "transparent" areas such as a // wxStaticText and wxCheckBox and the background should be adapted diff --git a/interface/wx/defs.h b/interface/wx/defs.h index 2b2afd8f16..21948b99ff 100644 --- a/interface/wx/defs.h +++ b/interface/wx/defs.h @@ -136,28 +136,54 @@ enum wxBorder /** - Background styles. See wxWindow::SetBackgroundStyle(). + Background styles. + + @see wxWindow::SetBackgroundStyle() */ enum wxBackgroundStyle { - /// Use the default background, as determined by - /// the system or the current theme. + /** + Default background style value indicating that the background may be + erased in the user-defined EVT_ERASE_BACKGROUND handler. + + If no such handler is defined (or if it skips the event), the effect of + this style is the same as wxBG_STYLE_SYSTEM. If an empty handler (@em + not skipping the event) is defined, the effect is the same as + wxBG_STYLE_PAINT, i.e. the background is not erased at all until + EVT_PAINT handler is executed. + + This is the only background style value for which erase background + events are generated at all. + */ + wxBG_STYLE_ERASE, + + /** + Use the default background, as determined by the system or the current + theme. + + If the window has been assigned a non-default background colour, it + will be used for erasing its background. Otherwise the default + background (which might be a gradient or a pattern) will be used. + + EVT_ERASE_BACKGROUND event will not be generated at all for windows + with this style. + */ wxBG_STYLE_SYSTEM, - /// Use a solid colour for the background, this style is set automatically if you call - /// SetBackgroundColour() so you only need to set it explicitly if you had - /// changed the background style to something else before. - wxBG_STYLE_COLOUR, + /** + Indicates that the background is only erased in the user-defined + EVT_PAINT handler. - /// Don't draw the background at all, it's supposed that it is drawn by - /// the user-defined erase background event handler. - /// This style should be used to avoid flicker when the background is entirely - /// custom-drawn. - wxBG_STYLE_CUSTOM, + Using this style avoids flicker which would result from redrawing the + background twice if the EVT_PAINT handler entirely overwrites it. It + must not be used however if the paint handler leaves any parts of the + window unpainted as their contents is then undetermined. Only use it if + you repaint the whole window in your handler. - /// The background is (partially) transparent,this style is automatically set if you call - /// SetTransparent() which is used to set the transparency level. - wxBG_STYLE_TRANSPARENT + EVT_ERASE_BACKGROUND event will not be generated at all for windows + with this style. + */ + wxBG_STYLE_PAINT }; diff --git a/interface/wx/window.h b/interface/wx/window.h index 962d193a0c..73b300c789 100644 --- a/interface/wx/window.h +++ b/interface/wx/window.h @@ -1418,12 +1418,12 @@ public: /** Returns the background style of the window. - The background style can be one of the wxBackgroundStyle. @see SetBackgroundColour(), GetForegroundColour(), SetBackgroundStyle(), SetTransparent() */ virtual wxBackgroundStyle GetBackgroundStyle() const; + /** Returns the character height for this window. */ @@ -1583,8 +1583,28 @@ public: virtual bool SetBackgroundColour(const wxColour& colour); /** - Sets the background style of the window. see GetBackgroundStyle() for - the description of the possible style values. + Sets the background style of the window. + + The default background style is wxBG_STYLE_ERASE which indicates that + the window background may be erased in EVT_ERASE_BACKGROUND handler. + This is a safe compatibility default however you may want to change it + to wxBG_STYLE_SYSTEM if you don't define any erase background event + handlers at all to avoid unnecessary generation of erase background + events and always let system erase the background. And you should + change the background style to wxBG_STYLE_PAINT if you define an + EVT_PAINT handler which completely overwrites the window background as + in this case erasing it previously, either in EVT_ERASE_BACKGROUND + handler or in the system default handler, would result in flicker as + the background pixels will be repainted twice every time the window is + redrawn. Do ensure that the background is entirely erased by your + EVT_PAINT handler in this case however as otherwise garbage may be left + on screen. + + Notice that in previous versions of wxWidgets a common way to work + around the above mentioned flickering problem was to define an empty + EVT_ERASE_BACKGROUND handler. Setting background style to + wxBG_STYLE_PAINT is a simpler and more efficient solution to the same + problem. @see SetBackgroundColour(), GetForegroundColour(), SetTransparent() diff --git a/samples/erase/erase.cpp b/samples/erase/erase.cpp index 94dd570ec4..cc6ca65d4f 100644 --- a/samples/erase/erase.cpp +++ b/samples/erase/erase.cpp @@ -1,11 +1,11 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: erase.cpp +// Name: samples/erase/erase.cpp // Purpose: Erase wxWidgets sample -// Author: Robert Roebling -// Modified by: +// Author: Robert Roebling, Vadim Zeitlin // Created: 04/01/98 // RCS-ID: $Id$ -// Copyright: (c) Robert Roebling +// Copyright: (c) 1998 Robert Roebling +// (c) 2009 Vadim Zeitlin // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -30,6 +30,8 @@ #include "wx/wx.h" #endif +#include "wx/dcbuffer.h" + // ---------------------------------------------------------------------------- // resources // ---------------------------------------------------------------------------- @@ -52,10 +54,10 @@ public: class MyCanvas : public wxScrolledWindow { public: - MyCanvas( wxFrame *parent ); + MyCanvas(wxFrame *parent); void UseBuffer(bool useBuffer) { m_useBuffer = useBuffer; Refresh(); } - void EraseBg(bool eraseBg) { m_eraseBg = eraseBg; Refresh(); } + bool UsesBuffer() const { return m_useBuffer; } private: void OnPaint( wxPaintEvent &event ); @@ -71,9 +73,6 @@ private: // use wxMemoryDC in OnPaint()? bool m_useBuffer; - // paint custom background in OnEraseBackground()? - bool m_eraseBg; - DECLARE_EVENT_TABLE() }; @@ -83,12 +82,23 @@ class MyFrame : public wxFrame public: MyFrame(); +private: void OnUseBuffer(wxCommandEvent& event); - void OnEraseBg(wxCommandEvent& event); + void OnChangeBgStyle(wxCommandEvent& event); void OnQuit(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); -private: + // we can only use double-buffering with wxBG_STYLE_PAINT + void OnUpdateUIUseBuffer(wxUpdateUIEvent& event) + { + event.Enable( m_canvas->GetBackgroundStyle() == wxBG_STYLE_PAINT ); + } + + void OnUpdateUIChangeBgStyle(wxUpdateUIEvent& event) + { + event.Enable( !m_canvas->UsesBuffer() ); + } + MyCanvas *m_canvas; DECLARE_EVENT_TABLE() @@ -103,7 +113,9 @@ enum { // menu items Erase_Menu_UseBuffer = 100, - Erase_Menu_EraseBg, + Erase_Menu_BgStyleErase, + Erase_Menu_BgStyleSystem, + Erase_Menu_BgStylePaint, Erase_Menu_Exit = wxID_EXIT, Erase_Menu_About = wxID_ABOUT }; @@ -133,40 +145,46 @@ bool MyApp::OnInit() BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(Erase_Menu_UseBuffer, MyFrame::OnUseBuffer) - EVT_MENU(Erase_Menu_EraseBg, MyFrame::OnEraseBg) + EVT_MENU_RANGE(Erase_Menu_BgStyleErase, Erase_Menu_BgStylePaint, + MyFrame::OnChangeBgStyle) + EVT_MENU(Erase_Menu_Exit, MyFrame::OnQuit) EVT_MENU(Erase_Menu_About, MyFrame::OnAbout) + + EVT_UPDATE_UI(Erase_Menu_UseBuffer, MyFrame::OnUpdateUIUseBuffer) + EVT_UPDATE_UI_RANGE(Erase_Menu_BgStyleErase, Erase_Menu_BgStylePaint, + MyFrame::OnUpdateUIChangeBgStyle) END_EVENT_TABLE() // frame constructor MyFrame::MyFrame() - : wxFrame(NULL, wxID_ANY, _T("Erase sample"), + : wxFrame(NULL, wxID_ANY, "Erase sample", wxPoint(50, 50), wxSize(450, 340)) { SetIcon(wxICON(mondrian)); - wxMenu *menuFile = new wxMenu(_T(""), wxMENU_TEAROFF); - menuFile->AppendCheckItem(Erase_Menu_UseBuffer, _T("&Use memory DC\tCtrl-M")); - menuFile->AppendCheckItem(Erase_Menu_EraseBg, _T("Custom &background\tCtrl-B")); + wxMenu *menuFile = new wxMenu("", wxMENU_TEAROFF); + menuFile->AppendCheckItem(Erase_Menu_UseBuffer, "&Use memory DC\tCtrl-M"); + menuFile->AppendSeparator(); + menuFile->AppendRadioItem(Erase_Menu_BgStyleErase, + "Use wxBG_STYLE_&ERASE\tCtrl-E"); + menuFile->AppendRadioItem(Erase_Menu_BgStyleSystem, + "Use wxBG_STYLE_&SYSTEM\tCtrl-S"); + menuFile->AppendRadioItem(Erase_Menu_BgStylePaint, + "Use wxBG_STYLE_&PAINT\tCtrl-P"); menuFile->AppendSeparator(); - menuFile->Append(Erase_Menu_Exit, _T("E&xit\tAlt-X"), _T("Quit this program")); + menuFile->Append(Erase_Menu_Exit, "E&xit\tAlt-X", "Quit this program"); wxMenu *helpMenu = new wxMenu; - helpMenu->Append(Erase_Menu_About, _T("&About...\tCtrl-A"), _T("Show about dialog")); + helpMenu->Append(Erase_Menu_About, "&About...\tCtrl-A", "Show about dialog"); wxMenuBar *menuBar = new wxMenuBar(); - menuBar->Append(menuFile, _T("&File")); - menuBar->Append(helpMenu, _T("&Help")); + menuBar->Append(menuFile, "&File"); + menuBar->Append(helpMenu, "&Help"); SetMenuBar(menuBar); -#if wxUSE_STATUSBAR - // create a status bar just for fun (by default with 1 pane only) - CreateStatusBar(2); - SetStatusText(_T("Welcome to wxWidgets erase sample!")); -#endif // wxUSE_STATUSBAR - m_canvas = new MyCanvas( this ); } @@ -176,9 +194,12 @@ void MyFrame::OnUseBuffer(wxCommandEvent& event) m_canvas->UseBuffer(event.IsChecked()); } -void MyFrame::OnEraseBg(wxCommandEvent& event) +void MyFrame::OnChangeBgStyle(wxCommandEvent& event) { - m_canvas->EraseBg(event.IsChecked()); + int style = wxBG_STYLE_ERASE + event.GetId() - Erase_Menu_BgStyleErase; + m_canvas->SetBackgroundStyle(static_cast(style)); + + m_canvas->Refresh(); } void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) @@ -188,22 +209,29 @@ void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) { - wxMessageBox(_T("This sample shows how you can draw custom background."), - _T("About Erase Sample"), wxOK | wxICON_INFORMATION, this); + wxMessageBox + ( + "This sample shows differences between different background styles " + "and how you may draw custom background.\n" + "\n" + "(c) 1998 Robert Roebling\n" + "(c) 2009 Vadim Zeitlin\n", + "About Erase Sample", + wxOK | wxICON_INFORMATION, + this + ); } BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow) - EVT_PAINT( MyCanvas::OnPaint) - EVT_CHAR( MyCanvas::OnChar) - EVT_ERASE_BACKGROUND( MyCanvas::OnEraseBackground) + EVT_PAINT(MyCanvas::OnPaint) + EVT_CHAR(MyCanvas::OnChar) + EVT_ERASE_BACKGROUND(MyCanvas::OnEraseBackground) END_EVENT_TABLE() -MyCanvas::MyCanvas( wxFrame *parent ) - : wxScrolledWindow( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, - wxScrolledWindowStyle | wxSUNKEN_BORDER ) +MyCanvas::MyCanvas(wxFrame *parent) + : wxScrolledWindow(parent, wxID_ANY) { - m_eraseBg = m_useBuffer = false; SetScrollbars( 10, 10, 40, 100, 0, 0 ); @@ -213,6 +241,7 @@ MyCanvas::MyCanvas( wxFrame *parent ) new wxStaticBitmap( this, wxID_ANY, m_bitmap, wxPoint(80,20) ); SetFocusIgnoringChildren(); + SetBackgroundColour(*wxBLUE); } void MyCanvas::OnChar( wxKeyEvent &event ) @@ -241,99 +270,47 @@ void MyCanvas::OnChar( wxKeyEvent &event ) void MyCanvas::DoPaint(wxDC& dc) { dc.SetBrush( *wxBLACK_BRUSH ); - dc.DrawRectangle( 10,10,200,50 ); + dc.DrawRectangle( 10,10,60,50 ); - dc.DrawBitmap( m_bitmap, 10, 20, true ); + dc.DrawBitmap( m_bitmap, 20, 20, true ); - dc.SetTextForeground(*wxBLUE); - dc.DrawText(_T("This text is drawn from OnPaint"), 65, 65); + dc.SetTextForeground(*wxWHITE); + dc.DrawText("This text is drawn from OnPaint", 65, 65); wxString tmp; - tmp.Printf( _T("Hit any key to display more text: %s"), m_text.c_str() ); + tmp.Printf("Hit any key to display more text: %s", m_text); + int w,h; dc.GetTextExtent( tmp, &w, &h ); - dc.SetBrush( *wxWHITE_BRUSH ); dc.DrawRectangle( 65, 85, w, h ); dc.DrawText( tmp, 65, 85 ); - -#if 0 - wxRegionIterator upd( GetUpdateRegion() ); - while (upd) - { - wxLogDebug( _T("Paint: %d %d %d %d"), upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() ); - upd ++; - } -#endif - -#if 0 - wxSize size = GetSize(); - wxSize client_size = GetClientSize(); - wxLogDebug( _T("size %d %d client_size %d %d"), size.x, size.y, client_size.x, client_size.y ); -#endif - -#if 0 - int i; - dc.SetPen( *wxWHITE_PEN ); - for (i = 0; i < 20; i += 2) - dc.DrawLine( i,i, i+100,i ); - - dc.SetPen( *wxWHITE_PEN ); - for (i = 200; i < 220; i += 2) - dc.DrawLine( i-200,i, i-100,i ); - - wxRegion region( 110, 110, 80, 80 ); - wxRegion hole( 130, 130, 40, 1 ); - region.Intersect( hole ); - dc.SetClippingRegion( region ); - - dc.SetBrush( *wxRED_BRUSH ); - dc.DrawRectangle( 100, 100, 200, 200 ); - - dc.DestroyClippingRegion(); - - dc.SetPen( *wxTRANSPARENT_PEN ); - - wxRegion strip( 110, 200, 30, 1 ); - wxRegionIterator it( strip ); - while (it) - { - dc.DrawRectangle( it.GetX(), it.GetY(), it.GetWidth(), it.GetHeight() ); - it ++; - } -#endif // 0 } void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) ) { - wxPaintDC dcWin(this); - PrepareDC( dcWin ); - if ( m_useBuffer ) { - const wxSize size = GetClientSize(); - wxMemoryDC dc; - wxBitmap bmp(size.x, size.y); - dc.SelectObject(bmp); - dc.Blit(0, 0, size.x, size.y, &dcWin, 0, 0); - dc.DrawText(_T("(copy of background)"), 5, 120 ); + wxAutoBufferedPaintDC dc(this); + PrepareDC(dc); DoPaint(dc); - - dcWin.Blit(0, 0, size.x, size.y, &dc, 0, 0); } else { - DoPaint(dcWin); + wxPaintDC dc(this); + PrepareDC(dc); + + DoPaint(dc); } } void MyCanvas::OnEraseBackground( wxEraseEvent& event ) { - if ( !m_eraseBg ) - { - event.Skip(); - return; - } + wxASSERT_MSG + ( + GetBackgroundStyle() == wxBG_STYLE_ERASE, + "shouldn't be called unless background style is \"erase\"" + ); wxDC& dc = *event.GetDC(); dc.SetPen(*wxGREEN_PEN); @@ -355,6 +332,7 @@ void MyCanvas::OnEraseBackground( wxEraseEvent& event ) } dc.SetTextForeground(*wxRED); - dc.DrawText(_T("This text is drawn from OnEraseBackground"), 60, 160); + dc.SetBackgroundMode(wxSOLID); + dc.DrawText("This text is drawn from OnEraseBackground", 60, 160); } diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 8d3fa0af2c..8a0ae4f54f 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -154,7 +154,7 @@ wxWindowBase::wxWindowBase() m_exStyle = m_windowStyle = 0; - m_backgroundStyle = wxBG_STYLE_SYSTEM; + m_backgroundStyle = wxBG_STYLE_ERASE; #if wxUSE_CONSTRAINTS // no constraints whatsoever @@ -1333,8 +1333,6 @@ bool wxWindowBase::SetBackgroundColour( const wxColour &colour ) return false; m_hasBgCol = colour.IsOk(); - if ( m_backgroundStyle != wxBG_STYLE_CUSTOM ) - m_backgroundStyle = m_hasBgCol ? wxBG_STYLE_COLOUR : wxBG_STYLE_SYSTEM; m_inheritBgCol = m_hasBgCol; m_backgroundColour = colour; diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index b5d5d18bfe..b72018c1df 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -2586,8 +2586,8 @@ void wxWindowGTK::OnInternalIdle() RealizeTabOrder(); } - // Update style if the window was not yet realized - // and SetBackgroundStyle(wxBG_STYLE_CUSTOM) was called + // Update style if the window was not yet realized when + // SetBackgroundStyle() was called if (m_needsStyleChange) { SetBackgroundStyle(GetBackgroundStyle()); @@ -3655,54 +3655,74 @@ void wxWindowGTK::GtkSendPaintEvents() } } - if (GetThemeEnabled() && (GetBackgroundStyle() == wxBG_STYLE_SYSTEM)) + switch ( GetBackgroundStyle() ) { - // find ancestor from which to steal background - wxWindow *parent = wxGetTopLevelParent((wxWindow *)this); - if (!parent) - parent = (wxWindow*)this; - - if (GTK_WIDGET_MAPPED(parent->m_widget)) - { - wxRegionIterator upd( m_nativeUpdateRegion ); - while (upd) + case wxBG_STYLE_ERASE: { - GdkRectangle rect; - rect.x = upd.GetX(); - rect.y = upd.GetY(); - rect.width = upd.GetWidth(); - rect.height = upd.GetHeight(); - - gtk_paint_flat_box( parent->m_widget->style, - m_wxwindow->window, - (GtkStateType)GTK_WIDGET_STATE(m_wxwindow), - GTK_SHADOW_NONE, - &rect, - parent->m_widget, - (char *)"base", - 0, 0, -1, -1 ); - - ++upd; + wxWindowDC dc( (wxWindow*)this ); + dc.SetDeviceClippingRegion( m_updateRegion ); + + // Work around gtk-qt <= 0.60 bug whereby the window colour + // remains grey + if ( UseBgCol() && + wxSystemOptions:: + GetOptionInt("gtk.window.force-background-colour") ) + { + dc.SetBackground(GetBackgroundColour()); + dc.Clear(); + } + + wxEraseEvent erase_event( GetId(), &dc ); + erase_event.SetEventObject( this ); + + if ( HandleWindowEvent(erase_event) ) + { + // background erased, don't do it again + break; + } } - } - } - else - { - wxWindowDC dc( (wxWindow*)this ); - dc.SetDeviceClippingRegion( m_updateRegion ); + // fall through - // Work around gtk-qt <= 0.60 bug whereby the window colour - // remains grey - if (GetBackgroundStyle() == wxBG_STYLE_COLOUR && GetBackgroundColour().Ok() && wxSystemOptions::GetOptionInt(wxT("gtk.window.force-background-colour")) == 1) - { - dc.SetBackground(wxBrush(GetBackgroundColour())); - dc.Clear(); - } + case wxBG_STYLE_SYSTEM: + if ( GetThemeEnabled() ) + { + // find ancestor from which to steal background + wxWindow *parent = wxGetTopLevelParent((wxWindow *)this); + if (!parent) + parent = (wxWindow*)this; + + if (GTK_WIDGET_MAPPED(parent->m_widget)) + { + wxRegionIterator upd( m_nativeUpdateRegion ); + while (upd) + { + GdkRectangle rect; + rect.x = upd.GetX(); + rect.y = upd.GetY(); + rect.width = upd.GetWidth(); + rect.height = upd.GetHeight(); + + gtk_paint_flat_box( parent->m_widget->style, + m_wxwindow->window, + (GtkStateType)GTK_WIDGET_STATE(m_wxwindow), + GTK_SHADOW_NONE, + &rect, + parent->m_widget, + (char *)"base", + 0, 0, -1, -1 ); + + ++upd; + } + } + } + break; - wxEraseEvent erase_event( GetId(), &dc ); - erase_event.SetEventObject( this ); + case wxBG_STYLE_PAINT: + // nothing to do: window will be painted over in EVT_PAINT + break; - HandleWindowEvent(erase_event); + default: + wxFAIL_MSG( "unsupported background style" ); } wxNcPaintEvent nc_paint_event( GetId() ); @@ -3767,8 +3787,7 @@ bool wxWindowGTK::SetBackgroundColour( const wxColour &colour ) // apply style change (forceStyle=true so that new style is applied // even if the bg colour changed from valid to wxNullColour) - if (GetBackgroundStyle() != wxBG_STYLE_CUSTOM) - GTKApplyWidgetStyle(true); + GTKApplyWidgetStyle(true); return true; } @@ -3896,7 +3915,7 @@ bool wxWindowGTK::SetBackgroundStyle(wxBackgroundStyle style) { wxWindowBase::SetBackgroundStyle(style); - if (style == wxBG_STYLE_CUSTOM) + if ( style == wxBG_STYLE_PAINT ) { GdkWindow *window; if ( m_wxwindow ) @@ -3934,6 +3953,7 @@ bool wxWindowGTK::SetBackgroundStyle(wxBackgroundStyle style) // even if the bg colour changed from valid to wxNullColour): GTKApplyWidgetStyle(true); } + return true; }