From b0ed71658dd4ec39094e1ff2990d0e6bc88311b6 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 17 Oct 2022 17:22:43 +0100 Subject: [PATCH] Document WS_EX_COMPOSITED impact on wxClientDC This is a big and incompatible change but, arguably, is still worth making because it makes wxMSW behaviour similar to that of wxOSX and wxGTK when using Wayland. Do document it prominently and also document MSWDisableComposited() as it will probably end up being used in quite a lot of existing code. --- docs/changes.txt | 8 ++++++++ interface/wx/dcclient.h | 14 ++++++++------ interface/wx/window.h | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 08ab794d42..3486cc6c03 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -11,6 +11,14 @@ INCOMPATIBLE CHANGES SINCE 3.2.x: Changes in behaviour not resulting in compilation errors -------------------------------------------------------- +- wxMSW now uses double buffering by default, meaning that updating the + windows using wxClientDC doesn't work any longer, which is consistent with + the behaviour of wxGTK with Wayland backend and of wxOSX, but not with the + traditional historic behaviour of wxMSW (or wxGTK/X11). You may call + MSWDisableComposited() to restore the previous behaviour, however it is + strongly recommended to change your redrawing logic to avoid using wxClientDC + instead, as the code using it still won't work with wxGTK/wxOSX. + - As first mentioned in 3.0 release notes, the value of wxTHREAD_WAIT_DEFAULT, used by wxThread::Delete() and Wait() by default, has changed from wxTHREAD_WAIT_YIELD to wxTHREAD_WAIT_BLOCK for safety and consistency. diff --git a/interface/wx/dcclient.h b/interface/wx/dcclient.h index 4777da851b..05058d016a 100644 --- a/interface/wx/dcclient.h +++ b/interface/wx/dcclient.h @@ -61,12 +61,14 @@ public: @note While wxClientDC may also be used for drawing on the client area of a window from outside an EVT_PAINT() handler in some ports, this does @em not - work on all platforms (neither wxOSX nor wxGTK with GTK 3 Wayland backend - support this, so drawing using wxClientDC simply doesn't have any effect - there) and the only portable way of drawing is via wxPaintDC. To redraw a - small part of the window, use wxWindow::RefreshRect() to invalidate just - this part and check wxWindow::GetUpdateRegion() in the paint event handler - to redraw this part only. + work on most of the platforms: neither wxOSX nor wxGTK with GTK 3 Wayland + backend support this at all, so drawing using wxClientDC simply doesn't + have any effect there, while wxMSW doesn't support using it for composited + windows, so wxWindow::MSWDisableComposited() must be called to allow it to + work. The only supported way of drawing on a window is via wxPaintDC. To + redraw a small part of the window, use wxWindow::RefreshRect() to + invalidate just this part and check wxWindow::GetUpdateRegion() in the + paint event handler to redraw this part only. wxClientDC objects should normally be constructed as temporary stack objects, i.e. don't store a wxClientDC object. diff --git a/interface/wx/window.h b/interface/wx/window.h index cd39e1d75a..481f458de2 100644 --- a/interface/wx/window.h +++ b/interface/wx/window.h @@ -4173,6 +4173,39 @@ public: ///@} + /** + Disable the use native double buffering in wxMSW. + + This MSW-specific function can be used to disable the use of + `WS_EX_COMPOSITED` for this window and all of its parents and so allow + using wxClientDC with it. + + `WS_EX_COMPOSITED` style is turned on by default when creating the + windows and it is strongly recommended @e not to use this functions to + remove it, but to instead change the drawing code to avoid using + wxClientDC. + + If you do need to use it, please note that this function doesn't exist + in the other ports and has to be explicitly bracketed by the checks for + wxMSW, e.g. + @code + MyFrame::MyFrame(...) + { + auto p = new wxPanel(this); + #ifdef __WXMSW__ + p->MSWDisableComposited(); + #endif + + // Using wxClientDC will work now with this panel in wxMSW -- + // although it still won't with wxOSX nor wxGTK under Wayland. + } + @endcode + + @see wxClientDC + + @since 3.3.0 + */ + void MSWDisableComposited(); protected: