From 3f2b7f6bdbc3067b3dc777ca9071e4b338ecca4f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 1 Oct 2023 21:14:00 +0200 Subject: [PATCH 1/5] Try changing BitmapToggleButtonTestCase to avoid wxMSW failures This test sporadically fails under AppVeyor, perhaps due to a hard-coded sleep in it which may somehow misbehave there -- try changing it not to rely on this sleep. This has a nice side effect of making the test run faster, too. --- tests/controls/bitmaptogglebuttontest.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/controls/bitmaptogglebuttontest.cpp b/tests/controls/bitmaptogglebuttontest.cpp index 2f91dc29f3..e3843f8fa4 100644 --- a/tests/controls/bitmaptogglebuttontest.cpp +++ b/tests/controls/bitmaptogglebuttontest.cpp @@ -74,8 +74,10 @@ void BitmapToggleButtonTestCase::Click() wxUIActionSimulator sim; + const wxPoint pos = m_button->GetScreenPosition(); + //We move in slightly to account for window decorations - sim.MouseMove(m_button->GetScreenPosition() + wxPoint(10, 10)); + sim.MouseMove(pos + wxPoint(10, 10)); wxYield(); sim.MouseClick(); @@ -86,9 +88,10 @@ void BitmapToggleButtonTestCase::Click() clicked.Clear(); -#ifdef __WXMSW__ - wxMilliSleep(1000); -#endif + // Change the mouse position to prevent the second click from being + // recognized as double click. + sim.MouseMove(pos + wxPoint(20, 20)); + wxYield(); sim.MouseClick(); wxYield(); From 55e074f5bcffa6cbfee3301e3c926db367eef080 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 1 Oct 2023 21:25:46 +0200 Subject: [PATCH 2/5] Rename tests/waitforpaint.h into just waitfor.h No changes yet, just prepare for adding more "waiting" helpers. --- tests/controls/gridtest.cpp | 2 +- tests/graphics/clipper.cpp | 2 +- tests/graphics/clippingbox.cpp | 2 +- tests/{waitforpaint.h => waitfor.h} | 8 ++++---- tests/window/clientsize.cpp | 2 +- tests/window/setsize.cpp | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) rename tests/{waitforpaint.h => waitfor.h} (94%) diff --git a/tests/controls/gridtest.cpp b/tests/controls/gridtest.cpp index 9077e02726..5921793b82 100644 --- a/tests/controls/gridtest.cpp +++ b/tests/controls/gridtest.cpp @@ -26,7 +26,7 @@ #include "wx/stopwatch.h" #endif // __WXGTK__ -#include "waitforpaint.h" +#include "waitfor.h" // To disable tests which work locally, but not when run on GitHub CI. #if defined(__WXGTK__) && !defined(__WXGTK3__) diff --git a/tests/graphics/clipper.cpp b/tests/graphics/clipper.cpp index 0ab95b3f19..697169c446 100644 --- a/tests/graphics/clipper.cpp +++ b/tests/graphics/clipper.cpp @@ -23,7 +23,7 @@ #include "wx/window.h" #include "testfile.h" -#include "waitforpaint.h" +#include "waitfor.h" static const wxSize s_dcSize(260, 300); diff --git a/tests/graphics/clippingbox.cpp b/tests/graphics/clippingbox.cpp index d5da29af1a..249f4d85a2 100644 --- a/tests/graphics/clippingbox.cpp +++ b/tests/graphics/clippingbox.cpp @@ -22,7 +22,7 @@ #include "wx/dcclient.h" #include "testfile.h" -#include "waitforpaint.h" +#include "waitfor.h" #include diff --git a/tests/waitforpaint.h b/tests/waitfor.h similarity index 94% rename from tests/waitforpaint.h rename to tests/waitfor.h index 0a1891901b..88a95ab838 100644 --- a/tests/waitforpaint.h +++ b/tests/waitfor.h @@ -1,13 +1,13 @@ /////////////////////////////////////////////////////////////////////////////// -// Name: tests/waitforpaint.h +// Name: tests/waitfor.h // Purpose: Helper WaitForPaint class // Author: Vadim Zeitlin // Created: 2019-10-17 (extracted from tests/window/setsize.cpp) // Copyright: (c) 2019 Vadim Zeitlin /////////////////////////////////////////////////////////////////////////////// -#ifndef _WX_TESTS_WAITFORPAINT_H_ -#define _WX_TESTS_WAITFORPAINT_H_ +#ifndef _WX_TESTS_WAITFOR_H_ +#define _WX_TESTS_WAITFOR_H_ #include "wx/stopwatch.h" #include "wx/window.h" @@ -99,4 +99,4 @@ public: #endif // __WXGTK__/!__WXGTK__ -#endif // _WX_TESTS_WAITFORPAINT_H_ +#endif // _WX_TESTS_WAITFOR_H_ diff --git a/tests/window/clientsize.cpp b/tests/window/clientsize.cpp index 61f2b87cec..9d2da0380d 100644 --- a/tests/window/clientsize.cpp +++ b/tests/window/clientsize.cpp @@ -21,7 +21,7 @@ #include #include "asserthelper.h" -#include "waitforpaint.h" +#include "waitfor.h" // ---------------------------------------------------------------------------- // tests themselves diff --git a/tests/window/setsize.cpp b/tests/window/setsize.cpp index d30fb22fdb..e89516fa05 100644 --- a/tests/window/setsize.cpp +++ b/tests/window/setsize.cpp @@ -22,7 +22,7 @@ #include #include "asserthelper.h" -#include "waitforpaint.h" +#include "waitfor.h" // ---------------------------------------------------------------------------- // tests helpers From 1237322404b0e060ee6a40a343a4462d5ca7bf90 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 1 Oct 2023 21:30:00 +0200 Subject: [PATCH 3/5] Add WaitFor() helper and use it in Button::Click unit test This test also sporadically happens under AppVeyor, check if it happens because we need to wait for some time before the event is processed. --- tests/controls/buttontest.cpp | 6 +++++- tests/waitfor.h | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/tests/controls/buttontest.cpp b/tests/controls/buttontest.cpp index ce958bc5e9..2a5570b354 100644 --- a/tests/controls/buttontest.cpp +++ b/tests/controls/buttontest.cpp @@ -23,6 +23,7 @@ // Get operator<<(wxSize) so that wxSize values are shown correctly in case of // a failure of a CHECK() involving them. #include "asserthelper.h" +#include "waitfor.h" class ButtonTestCase { @@ -64,7 +65,10 @@ TEST_CASE_METHOD(ButtonTestCase, "Button::Click", "[button]") wxYield(); sim.MouseClick(); - wxYield(); + + // At least under wxMSW calling wxYield() just once doesn't always work, so + // try for a while. + WaitFor("button to be clicked", [&]() { return clicked.GetCount() != 0; }); CHECK( clicked.GetCount() == 1 ); } diff --git a/tests/waitfor.h b/tests/waitfor.h index 88a95ab838..35b1c161ca 100644 --- a/tests/waitfor.h +++ b/tests/waitfor.h @@ -12,6 +12,31 @@ #include "wx/stopwatch.h" #include "wx/window.h" +#include + +// Function used to wait until the given predicate becomes true or timeout +// expires. +inline bool +WaitFor(const char* what, const std::function& pred, int timeout = 500) +{ + wxStopWatch sw; + for ( ;; ) + { + wxYield(); + + if ( pred() ) + break; + + if ( sw.Time() > timeout ) + { + WARN("Timed out waiting for " << what); + return false; + } + } + + return true; +} + // Class used to check if we received the (first) paint event: this is // currently used under GTK only, as MSW doesn't seem to need to wait for the // things to work, while under Mac nothing works anyhow. From dc6085a808fcc689eb72bbdb77fff6cfbc4eab19 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 1 Oct 2023 21:32:09 +0200 Subject: [PATCH 4/5] Use WaitFor() in WaitForPaint::YieldUntilPainted() No real changes, just refactor the existing code to call the new function instead of duplicating it. --- tests/waitfor.h | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/tests/waitfor.h b/tests/waitfor.h index 35b1c161ca..37be4595cf 100644 --- a/tests/waitfor.h +++ b/tests/waitfor.h @@ -57,23 +57,10 @@ public: // event to come and logs a warning if we didn't get it. void YieldUntilPainted(int timeoutInMS = 250) { - wxStopWatch sw; - for ( ;; ) + if ( WaitFor("repaint", [this]() { return m_painted; }, timeoutInMS) ) { - wxYield(); - - if ( m_painted ) - { - // Reset it in case YieldUntilPainted() is called again. - m_painted = false; - break; - } - - if ( sw.Time() > timeoutInMS ) - { - WARN("Didn't get a paint event until timeout expiration"); - break; - } + // Reset it in case YieldUntilPainted() is called again. + m_painted = false; } } From fa5964c10041dd77a3f92ff4d30c18e7dae261e1 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 1 Oct 2023 21:47:44 +0200 Subject: [PATCH 5/5] Use WaitFor() and new YieldForAWhile() helpers in the tests Reuse the existing function (and another new one, which is even simpler) instead of duplicating its code in many places in the tests. No real changes. --- tests/controls/dataviewctrltest.cpp | 46 ++++++++--------------------- tests/controls/propgridtest.cpp | 15 +++------- tests/controls/textctrltest.cpp | 21 ++++--------- tests/controls/webtest.cpp | 5 ++-- tests/controls/windowtest.cpp | 13 ++------ tests/events/keyboard.cpp | 9 ++---- tests/events/propagation.cpp | 8 +++-- tests/graphics/clipper.cpp | 6 +--- tests/graphics/clippingbox.cpp | 6 +--- tests/persistence/dataview.cpp | 22 +++++--------- tests/persistence/tlw.cpp | 35 +++++++--------------- tests/waitfor.h | 15 ++++++++++ 12 files changed, 69 insertions(+), 132 deletions(-) diff --git a/tests/controls/dataviewctrltest.cpp b/tests/controls/dataviewctrltest.cpp index b460195a43..bfb849b14d 100644 --- a/tests/controls/dataviewctrltest.cpp +++ b/tests/controls/dataviewctrltest.cpp @@ -20,7 +20,7 @@ #include "wx/uiaction.h" #ifdef __WXGTK__ - #include "wx/stopwatch.h" + #include "waitfor.h" #endif // __WXGTK__ #include "testableframe.h" @@ -366,31 +366,23 @@ protected: #ifdef __WXGTK__ // Unfortunately it's not enough to call wxYield() once, so wait up to // 0.5 sec. - wxStopWatch sw; - while ( true ) - { - wxYield(); - + WaitFor("wxDataViewCtrl upder", [this, item, existence]() { const bool isItemRectEmpty = m_dvc->GetItemRect(item).IsEmpty(); switch ( existence ) { case wxITEM_APPEAR: if ( !isItemRectEmpty ) - return; + return true; break; case wxITEM_DISAPPEAR: if ( isItemRectEmpty ) - return; + return true; break; } - if ( sw.Time() > 500 ) - { - WARN("Timed out waiting for wxDataViewCtrl"); - break; - } - } + return false; + }); #else // !__WXGTK__ wxUnusedVar(item); wxUnusedVar(existence); @@ -810,16 +802,9 @@ TEST_CASE_METHOD(SingleSelectDataViewCtrlTestCase, #ifdef __WXGTK__ // Wait for the list control to be relaid out. - wxStopWatch sw; - while ( m_dvc->GetTopItem() == m_root ) - { - if ( sw.Time() > 500 ) - { - WARN("Timed out waiting for wxDataViewCtrl layout"); - break; - } - wxYield(); - } + WaitFor("wxDataViewCtrl layout", [this]() { + return m_dvc->GetTopItem() != m_root; + }); #endif // __WXGTK__ // Check that this was indeed the case. @@ -858,16 +843,9 @@ TEST_CASE_METHOD(MultiColumnsDataViewCtrlTestCase, { #ifdef __WXGTK__ // Wait for the list control to be realized. - wxStopWatch sw; - while ( m_firstColumn->GetWidth() == 0 ) - { - if ( sw.Time() > 500 ) - { - WARN("Timed out waiting for wxDataViewListCtrl to be realized"); - break; - } - wxYield(); - } + WaitFor("wxDataViewCtrl to be realized", [this]() { + return m_firstColumn->GetWidth() != 0; + }); #endif // Check the width of the first column. diff --git a/tests/controls/propgridtest.cpp b/tests/controls/propgridtest.cpp index 675a8524e7..0c21b04751 100644 --- a/tests/controls/propgridtest.cpp +++ b/tests/controls/propgridtest.cpp @@ -16,12 +16,13 @@ #if wxUSE_DATEPICKCTRL #include "wx/datectrl.h" #endif -#include "wx/stopwatch.h" #include "wx/propgrid/propgrid.h" #include "wx/propgrid/manager.h" #include "wx/propgrid/advprops.h" +#include "waitfor.h" + #include #include @@ -450,11 +451,7 @@ static wxPropertyGridManager* CreateGrid(int style, int extraStyle) pgManager->Refresh(); pgManager->Update(); // Wait for update to be done - wxStopWatch sw; - while ( sw.Time() < 100 ) - { - wxYield(); - } + YieldForAWhile(100); return pgManager; } @@ -722,11 +719,7 @@ TEST_CASE("PropertyGridTestCase", "[propgrid]") pgManager->Refresh(); pgManager->Update(); // Wait for update to be done - wxStopWatch sw; - while ( sw.Time() < 100 ) - { - wxYield(); - } + YieldForAWhile(100); } SECTION("Default_Values") diff --git a/tests/controls/textctrltest.cpp b/tests/controls/textctrltest.cpp index 4137487d48..a0c9991d0c 100644 --- a/tests/controls/textctrltest.cpp +++ b/tests/controls/textctrltest.cpp @@ -29,7 +29,7 @@ #endif // wxUSE_CLIPBOARD #ifdef __WXGTK__ - #include "wx/stopwatch.h" + #include "waitfor.h" #endif #include "wx/private/localeset.h" @@ -397,8 +397,7 @@ void TextCtrlTestCase::HitTestSingleLine() #ifdef __WXGTK__ // wxGTK must be given an opportunity to lay the text out. - for ( wxStopWatch sw; sw.Time() < 50; ) - wxYield(); + YieldForAWhile(); #endif REQUIRE( m_text->HitTest(wxPoint(2*sizeChar.x, yMid), &pos) == wxTE_HT_ON_TEXT ); @@ -757,18 +756,10 @@ void TextCtrlTestCase::DoPositionToCoordsTestWithStyle(long style) // wxGTK needs to yield here to update the text control. #ifdef __WXGTK__ - wxStopWatch sw; - while ( m_text->PositionToCoords(0).y == 0 || - m_text->PositionToCoords(pos).y > TEXT_HEIGHT ) - { - if ( sw.Time() > 1000 ) - { - FAIL("Timed out waiting for wxTextCtrl update."); - break; - } - - wxYield(); - } + WaitFor("wxTextCtrl update", [this, pos]() { + return m_text->PositionToCoords(0).y != 0 && + m_text->PositionToCoords(pos).y <= TEXT_HEIGHT; + }, 1000); #endif // __WXGTK__ wxPoint coords = m_text->PositionToCoords(0); diff --git a/tests/controls/webtest.cpp b/tests/controls/webtest.cpp index 98a817c997..c7055d895f 100644 --- a/tests/controls/webtest.cpp +++ b/tests/controls/webtest.cpp @@ -22,7 +22,7 @@ #include "wx/msw/webview_ie.h" #endif #if wxUSE_WEBVIEW_WEBKIT2 - #include "wx/stopwatch.h" + #include "waitfor.h" #endif //Convenience macro @@ -235,8 +235,7 @@ TEST_CASE_METHOD(WebViewTestCase, "WebView", "[wxWebView]") // bit before giving up. Avoid calling HasSelection() right away // without wxYielding a bit because this seems to cause the extension // to hang with webkit 2.40.0+. - for ( wxStopWatch sw; sw.Time() < 50; ) - wxYield(); + YieldForAWhile(); #endif // wxUSE_WEBVIEW_WEBKIT2 CHECK(m_browser->HasSelection()); diff --git a/tests/controls/windowtest.cpp b/tests/controls/windowtest.cpp index 6041bcb2fa..648fb6eacb 100644 --- a/tests/controls/windowtest.cpp +++ b/tests/controls/windowtest.cpp @@ -19,12 +19,12 @@ #include "asserthelper.h" #include "testableframe.h" #include "testwindow.h" +#include "waitfor.h" #include "wx/uiaction.h" #include "wx/caret.h" #include "wx/cshelp.h" #include "wx/dcclient.h" -#include "wx/stopwatch.h" #include "wx/tooltip.h" #include "wx/wupdlock.h" @@ -40,8 +40,7 @@ public: // Without this, when running this test suite solo it succeeds, // but not when running it together with the other tests !! // Not needed when run under Xvfb display. - for ( wxStopWatch sw; sw.Time() < 50; ) - wxYield(); + YieldForAWhile(); #endif } @@ -510,13 +509,7 @@ TEST_CASE_METHOD(WindowTestCase, "Window::Refresh", "[window]") parent->RefreshRect(wxRect(150, 10, 300, 80)); - for ( wxStopWatch sw; sw.Time() < 100; ) - { - if ( isParentPainted ) - break; - - wxYield(); - } + WaitFor("parent repaint", [&]() { return isParentPainted; }, 100); // child1 should be the only window not to receive the wxEVT_PAINT event // because it does not intersect with the refreshed rectangle. diff --git a/tests/events/keyboard.cpp b/tests/events/keyboard.cpp index 0b66a58bfb..9bf8f3a261 100644 --- a/tests/events/keyboard.cpp +++ b/tests/events/keyboard.cpp @@ -24,9 +24,7 @@ #include "wx/uiaction.h" #include "wx/vector.h" -#ifdef __WXGTK__ -#include "wx/stopwatch.h" -#endif +#include "waitfor.h" namespace { @@ -229,10 +227,7 @@ void KeyboardEventTestCase::setUp() wxYield(); m_win->SetFocus(); -#ifdef __WXGTK__ - for ( wxStopWatch sw; sw.Time() < 10; ) -#endif - wxYield(); // needed to show the new window + YieldForAWhile(10); // needed to show the new window // The window might get some key up events when it's being shown if the key // was pressed when the program was started and released after the window diff --git a/tests/events/propagation.cpp b/tests/events/propagation.cpp index 771e0e5bb2..37f2fc90aa 100644 --- a/tests/events/propagation.cpp +++ b/tests/events/propagation.cpp @@ -26,10 +26,13 @@ #include "wx/scopeguard.h" #include "wx/toolbar.h" #include "wx/uiaction.h" -#include "wx/stopwatch.h" #include +#ifdef __WXGTK__ + #include "waitfor.h" +#endif + // FIXME: Currently under OS X testing paint event doesn't work because neither // calling Refresh()+Update() nor even sending wxPaintEvent directly to // the window doesn't result in calls to its event handlers, so disable @@ -174,8 +177,7 @@ public: #ifdef __WXGTK__ // We need to map the window, otherwise we're not going to get any // paint events for it. - for ( wxStopWatch sw; sw.Time() < 50; ) - wxYield(); + YieldForAWhile(); // Ignore events generated during the initial mapping. g_str.clear(); diff --git a/tests/graphics/clipper.cpp b/tests/graphics/clipper.cpp index 697169c446..676a2e1270 100644 --- a/tests/graphics/clipper.cpp +++ b/tests/graphics/clipper.cpp @@ -751,11 +751,7 @@ TEST_CASE("ClipperTestCase::wxPaintDC", "[clipper][dc][paintdc]") testWin->Refresh(); testWin->Update(); // Wait for update to be done - wxStopWatch sw; - while( sw.Time() < 50 ) - { - wxYield(); - } + YieldForAWhile(); CHECK(paintExecuted == true); } diff --git a/tests/graphics/clippingbox.cpp b/tests/graphics/clippingbox.cpp index 249f4d85a2..cf0f409468 100644 --- a/tests/graphics/clippingbox.cpp +++ b/tests/graphics/clippingbox.cpp @@ -4322,11 +4322,7 @@ TEST_CASE("ClippingBoxTestCase::wxPaintDC", "[clip][dc][paintdc]") testWin->Refresh(); testWin->Update(); // Wait for update to be done - wxStopWatch sw; - while( sw.Time() < 50 ) - { - wxYield(); - } + YieldForAWhile(); CHECK(paintExecuted == true); } diff --git a/tests/persistence/dataview.cpp b/tests/persistence/dataview.cpp index 686cbec6a6..0cfa99c527 100644 --- a/tests/persistence/dataview.cpp +++ b/tests/persistence/dataview.cpp @@ -19,14 +19,14 @@ #ifndef WX_PRECOMP #include "wx/dataview.h" - - #ifdef __WXGTK__ - #include "wx/stopwatch.h" - #endif // __WXGTK__ #endif // WX_PRECOMP #include "wx/persist/dataview.h" +#ifdef __WXGTK__ + #include "waitfor.h" +#endif // __WXGTK__ + // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -90,17 +90,9 @@ static wxDataViewCtrl* CreatePersistenceTestDVC() void GTKWaitRealized(wxDataViewCtrl* list) { #ifdef __WXGTK__ - wxStopWatch sw; - while ( list->GetColumn(0)->GetWidth() == 0 ) - { - if ( sw.Time() > 500 ) - { - WARN("Timed out waiting for wxDataViewCtrl to be realized"); - break; - } - - wxYield(); - } + WaitFor("wxDataViewCtrl to be realized", [list]() { + return list->GetColumn(0)->GetWidth() != 0; + }); #else // !__WXGTK__ wxUnusedVar(list); #endif // __WXGTK__/!__WXGTK__ diff --git a/tests/persistence/tlw.cpp b/tests/persistence/tlw.cpp index 1de89b5756..34b43cc1fd 100644 --- a/tests/persistence/tlw.cpp +++ b/tests/persistence/tlw.cpp @@ -17,14 +17,14 @@ #ifndef WX_PRECOMP #include "wx/frame.h" - - #ifdef __WXGTK__ - #include "wx/stopwatch.h" - #endif // __WXGTK__ #endif // WX_PRECOMP #include "wx/persist/toplevel.h" +#ifdef __WXGTK__ + #include "waitfor.h" +#endif // __WXGTK__ + // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -117,17 +117,11 @@ TEST_CASE_METHOD(PersistenceTests, "wxPersistTLW", "[persist][tlw]") } else { - wxStopWatch sw; - while ( !frame->IsIconized() ) + if ( !WaitFor("frame to be iconized", [frame]() { + return frame->IsIconized(); + }) ) { - wxYield(); - if ( sw.Time() > 500 ) - { - // 500ms should be enough for the window to end up iconized. - WARN("Frame wasn't iconized as expected"); - checkIconized = false; - break; - } + checkIconized = false; } } #endif // __WXGTK__ @@ -148,16 +142,9 @@ TEST_CASE_METHOD(PersistenceTests, "wxPersistTLW", "[persist][tlw]") if ( checkIconized ) { #ifdef __WXGTK__ - wxStopWatch sw; - while ( !frame->IsIconized() ) - { - wxYield(); - if ( sw.Time() > 500 ) - { - INFO("Abandoning wait after " << sw.Time() << "ms"); - break; - } - } + WaitFor("frame to be iconized", [frame]() { + return frame->IsIconized(); + }); #endif // __WXGTK__ CHECK(frame->IsIconized()); diff --git a/tests/waitfor.h b/tests/waitfor.h index 37be4595cf..b3d0f6cc33 100644 --- a/tests/waitfor.h +++ b/tests/waitfor.h @@ -37,6 +37,21 @@ WaitFor(const char* what, const std::function& pred, int timeout = 500) return true; } +// An even simpler version which doesn't wait for anything but just calls +// wxYield() until the given timeout expires. +inline void +YieldForAWhile(int timeout = 50) +{ + wxStopWatch sw; + for ( ;; ) + { + wxYield(); + + if ( sw.Time() > timeout ) + break; + } +} + // Class used to check if we received the (first) paint event: this is // currently used under GTK only, as MSW doesn't seem to need to wait for the // things to work, while under Mac nothing works anyhow.