From 7d6d514984e3fe4f03f301cc2156747f9f36d8f6 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 17 Oct 2019 17:07:00 +0200 Subject: [PATCH] Improve WaitForPaint helper used in window unit tests Unbind the event handler referencing a local variable, as leaving it bound could result in a crash later if another paint event was generated for the window for whatever reason. Doing it like this requires using 2 different objects, but the complexity can be still hidden inside WaitForPaint class, with the 2nd object being just a member of it, and, in fact, makes the code using it simpler as it doesn't need to use a boolean variable with it. --- tests/window/setsize.cpp | 51 +++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/tests/window/setsize.cpp b/tests/window/setsize.cpp index 81b3eeb8d5..8728413336 100644 --- a/tests/window/setsize.cpp +++ b/tests/window/setsize.cpp @@ -51,23 +51,48 @@ protected: class WaitForPaint { public: - // Note that we have to use a pointer here, i.e. we can't just store the - // flag inside the class itself because it's going to be cloned inside wx - // and querying the flag of the original copy is not going to work. - explicit WaitForPaint(bool* painted) - : m_painted(*painted) + explicit WaitForPaint(wxWindow* win) + : m_win(*win), + m_painted(false), + m_handler(&m_painted) { - m_painted = false; + m_win.Bind(wxEVT_PAINT, m_handler); } - void operator()(wxPaintEvent& event) + bool GotPaintEvent() const { - event.Skip(); - m_painted = true; + return m_painted; + } + + ~WaitForPaint() + { + m_win.Unbind(wxEVT_PAINT, m_handler); } private: - bool& m_painted; + wxWindow& m_win; + bool m_painted; + + class PaintHandler + { + public: + // Note that we have to use a pointer here, i.e. we can't just store + // the flag inside the class itself because it's going to be cloned + // inside wx and querying the flag of the original copy wouldtn' work. + explicit PaintHandler(bool* painted) + : m_painted(*painted) + { + } + + void operator()(wxPaintEvent& event) + { + event.Skip(); + m_painted = true; + } + + private: + bool& m_painted; + } m_handler; }; // This function should be used to show the window and wait until we can get @@ -79,14 +104,12 @@ void ShowAndWaitForPaint(wxWindow* w) // geometry. And it's not clear how long should we wait, so we do it until // we get the first paint event -- by then the window really should have // its final size. - bool painted; - WaitForPaint waitForPaint(&painted); - w->Bind(wxEVT_PAINT, waitForPaint); + WaitForPaint waitForPaint(w); w->Show(); wxStopWatch sw; - while ( !painted ) + while ( !waitForPaint.GotPaintEvent() ) { wxYield();