diff --git a/src/common/uiactioncmn.cpp b/src/common/uiactioncmn.cpp index eeaf01ef93..e110af9142 100644 --- a/src/common/uiactioncmn.cpp +++ b/src/common/uiactioncmn.cpp @@ -74,10 +74,8 @@ bool wxUIActionSimulatorImpl::MouseClick(int button) bool wxUIActionSimulatorImpl::MouseDblClick(int button) { - MouseDown(button); - MouseUp(button); - MouseDown(button); - MouseUp(button); + MouseClick(button); + MouseClick(button); return true; } diff --git a/src/unix/uiactionx11.cpp b/src/unix/uiactionx11.cpp index 5233e6d64f..d682addf60 100644 --- a/src/unix/uiactionx11.cpp +++ b/src/unix/uiactionx11.cpp @@ -27,12 +27,32 @@ #include "wx/unix/utilsx11.h" -#ifdef __WXGTK3__ -#include "wx/utils.h" - +#ifdef __WXGTK__ +#include "wx/window.h" #include "wx/gtk/private/wrapgtk.h" +#include + GtkWidget* wxGetTopLevelGTK(); -#endif +GdkWindow* wxGetTopLevelGDK(); + +// This helper function tries to set the input focus to the correct (top level) +// window, i.e.: the window to which keyboard events will be reported. +static inline void wxSetInputFocusToXWindow(wxX11Display& display) +{ + wxWindow* const win = wxGetActiveWindow(); + + GdkWindow* gdkwin; + + if ( win && win->IsTopLevel() ) + gdkwin = gtk_widget_get_window(win->GetHandle()); + else + gdkwin = wxGetTopLevelGDK(); + + XSetInputFocus(display, GDK_WINDOW_XID(gdkwin), RevertToPointerRoot, CurrentTime); +} +#else // !__WXGTK__ +#define wxSetInputFocusToXWindow(display) +#endif // __WXGTK__ // Normally we fall back on "plain X" implementation if XTest is not available, // but it's useless to do it when using GTK+ 3 as it's not going to work with @@ -46,6 +66,62 @@ GtkWidget* wxGetTopLevelGTK(); namespace { +// Like the real events, this class tries to add a _fake_ delay to the generated +// (fake) events so that chances that they got lost or ignored (for whatever reasons) +// by the X server (or the WM, or even the input device driver) are minimized. +class wxXSync +{ +public: + wxXSync(wxX11Display& display) + : m_display(display), m_isMotion(true) + { + } + + wxXSync(wxX11Display& display, bool depressed) + : m_display(display), m_isMotion(false) + { + depressed ? ++ms_numDepressed : --ms_numDepressed; + + wxASSERT_MSG( ms_numDepressed >= 0, "Invalid call to wxXSync() ctor" ); + } + + ~wxXSync() + { + XSync(m_display, False); + + if ( m_isMotion ) + { + wxYield(); + } + else // it's button or key event + { + if ( ms_numDepressed > 0 ) + { + // Do nothing if a key / button is still depressed. + return; + } + + wxYield(); + wxMilliSleep(Default_Delay); + } + } + +private: + wxX11Display& m_display; + const bool m_isMotion; // false if it's button or key event. + + enum + { + Default_Delay = 20 // amount of ms to sleep after key/button release. + }; + + static int ms_numDepressed; + + wxDECLARE_NO_COPY_CLASS(wxXSync); +}; + +/*static*/ +int wxXSync::ms_numDepressed = 0; // Base class for both available X11 implementations. class wxUIActionSimulatorX11Impl : public wxUIActionSimulatorImpl @@ -68,6 +144,10 @@ protected: explicit wxUIActionSimulatorX11Impl(wxX11Display& display) : m_display(display) { + wxYield(); + wxMilliSleep(50); + + wxSetInputFocusToXWindow(m_display); } wxX11Display m_display; @@ -106,16 +186,7 @@ bool wxUIActionSimulatorX11Impl::SendButtonEvent(int button, bool isDown) return false; } - // Ensure that the event is received by the correct window by processing - // all pending events, notably mouse moves. - XSync(m_display, False /* don't discard */); - - if ( !DoX11Button(xbutton, isDown) ) - return false; - - XFlush(m_display); - - return true; + return DoX11Button(xbutton, isDown); } #if wxUSE_PLAINX_IMPL @@ -161,6 +232,7 @@ bool wxUIActionSimulatorPlainX11Impl::DoX11Button(int xbutton, bool isDown) &event.xbutton.x, &event.xbutton.y, &event.xbutton.state); } + wxXSync sync(m_display, isDown); XSendEvent(m_display, PointerWindow, True, 0xfff, &event); return true; @@ -168,6 +240,7 @@ bool wxUIActionSimulatorPlainX11Impl::DoX11Button(int xbutton, bool isDown) bool wxUIActionSimulatorPlainX11Impl::DoX11MouseMove(long x, long y) { + wxXSync sync(m_display); Window root = m_display.DefaultRoot(); XWarpPointer(m_display, None, root, 0, 0, 0, 0, x, y); return true; @@ -222,6 +295,7 @@ wxUIActionSimulatorPlainX11Impl::DoX11Key(KeyCode xkeycode, event.state = mod; event.keycode = xkeycode; + wxXSync sync(m_display, isDown); XSendEvent(event.display, event.window, True, mask, (XEvent*) &event); return true; @@ -250,6 +324,7 @@ private: bool wxUIActionSimulatorXTestImpl::DoX11Button(int xbutton, bool isDown) { + wxXSync sync(m_display, isDown); return XTestFakeButtonEvent(m_display, xbutton, isDown, CurrentTime) != 0; } @@ -273,6 +348,7 @@ bool wxUIActionSimulatorXTestImpl::DoX11MouseMove(long x, long y) #endif // GTK+ 3.10+ #endif // __WXGTK3__ + wxXSync sync(m_display); return XTestFakeMotionEvent(m_display, -1, x, y, CurrentTime) != 0; } @@ -281,6 +357,7 @@ wxUIActionSimulatorXTestImpl::DoX11Key(KeyCode xkeycode, int WXUNUSED(modifiers), bool isDown) { + wxXSync sync(m_display, isDown); return XTestFakeKeyEvent(m_display, xkeycode, isDown, CurrentTime) != 0; } @@ -318,30 +395,29 @@ bool wxUIActionSimulatorX11Impl::MouseMove(long x, long y) if ( !m_display ) return false; - if ( !DoX11MouseMove(x, y) ) - return false; +#ifdef __WXGTK20__ + GdkWindow* const gdkwin1 = gdk_window_at_pointer(NULL, NULL); + const bool ret = DoX11MouseMove(x, y); + GdkWindow* const gdkwin2 = gdk_window_at_pointer(NULL, NULL); - // At least with wxGTK we must always process the pending events before the - // mouse position change really takes effect, so just do it from here - // instead of forcing the client code using this function to always use - // wxYield() which is unnecessary under the other platforms. - if ( wxEventLoopBase* const loop = wxEventLoop::GetActive() ) + if ( gdkwin1 != gdkwin2 ) { - loop->YieldFor(wxEVT_CATEGORY_USER_INPUT); + // Workaround the problem of destination window not getting a motion event + // after our fake mouse movement (unless the pointer is already inside it) + // by issuing a second call to 'DoX11MouseMove()' to get the event. + // Notice that ret is true here and we don't want to override it by whatever + // this second call returns. + DoX11MouseMove(x, y); } - return true; + return ret; +#endif + + return DoX11MouseMove(x, y); } bool wxUIActionSimulatorX11Impl::MouseUp(int button) { -#ifdef __WXGTK3__ - // This is a horrible hack, but some mouse click events are just lost - // without any apparent reason when using GTK 3 without this, i.e. they - // simply never reach GTK in some runs of the tests. - wxMilliSleep(10); -#endif - return SendButtonEvent(button, false); } @@ -355,12 +431,7 @@ bool wxUIActionSimulatorX11Impl::DoKey(int keycode, int modifiers, bool isDown) if ( xkeycode == NoSymbol ) return false; - if ( !DoX11Key(xkeycode, modifiers, isDown) ) - return false; - - XFlush(m_display); - - return true; + return DoX11Key(xkeycode, modifiers, isDown); } wxUIActionSimulator::wxUIActionSimulator() diff --git a/tests/controls/bitmaptogglebuttontest.cpp b/tests/controls/bitmaptogglebuttontest.cpp index 2a477daa80..cadd810fcd 100644 --- a/tests/controls/bitmaptogglebuttontest.cpp +++ b/tests/controls/bitmaptogglebuttontest.cpp @@ -88,7 +88,10 @@ void BitmapToggleButtonTestCase::Click() CPPUNIT_ASSERT(m_button->GetValue()); clicked.Clear(); + +#ifdef __WXMSW__ wxMilliSleep(1000); +#endif sim.MouseClick(); wxYield(); diff --git a/tests/controls/gridtest.cpp b/tests/controls/gridtest.cpp index 9c280c6d9b..7bffd9be71 100644 --- a/tests/controls/gridtest.cpp +++ b/tests/controls/gridtest.cpp @@ -145,38 +145,12 @@ TEST_CASE_METHOD(GridTestCase, "Grid::CellEdit", "[grid]") sim.Text("abab"); - // We need to wait until the editor is really shown under GTK, consider - // that it happens once it gets focus. -#ifdef __WXGTK__ - for ( wxStopWatch sw; wxWindow::FindFocus() == m_grid; ) - { - if ( sw.Time() > 250 ) - { - WARN("Editor control not shown until timeout expiration"); - break; - } - - wxYield(); - } -#endif // __WXGTK__ + wxYield(); sim.Char(WXK_RETURN); wxYield(); -#ifdef __WXGTK__ - for ( wxStopWatch sw; wxWindow::FindFocus() != m_grid; ) - { - if ( sw.Time() > 250 ) - { - WARN("Editor control not hidden until timeout expiration"); - break; - } - - wxYield(); - } -#endif // __WXGTK__ - CHECK(m_grid->GetCellValue(1, 1) == "abab"); CHECK(created.GetCount() == 1); @@ -388,11 +362,16 @@ TEST_CASE_METHOD(GridTestCase, "Grid::Size", "[grid]") // TODO on OSX resizing interactively works, but not automated // Grid could not pass the test under GTK, OSX, and Universal. // So there may has bug in Grid implementation -#if wxUSE_UIACTIONSIMULATOR && !defined(__WXGTK__) && !defined(__WXOSX__) \ -&& !defined(__WXUNIVERSAL__) +#if wxUSE_UIACTIONSIMULATOR && !defined(__WXOSX__) && !defined(__WXUNIVERSAL__) if ( !EnableUITests() ) return; +#ifdef __WXGTK20__ + // Works locally, but not when run on Travis CI. + if ( IsAutomaticTest() ) + return; +#endif + EventCounter colsize(m_grid, wxEVT_GRID_COL_SIZE); EventCounter rowsize(m_grid, wxEVT_GRID_ROW_SIZE); @@ -400,7 +379,6 @@ TEST_CASE_METHOD(GridTestCase, "Grid::Size", "[grid]") wxPoint pt = m_grid->ClientToScreen(wxPoint(m_grid->GetRowLabelSize() + m_grid->GetColSize(0), 5)); - sim.MouseMove(pt); wxYield(); @@ -419,6 +397,7 @@ TEST_CASE_METHOD(GridTestCase, "Grid::Size", "[grid]") m_grid->GetRowSize(0))); sim.MouseDragDrop(pt.x, pt.y, pt.x, pt.y + 50); + wxYield(); CHECK(rowsize.GetCount() == 1); @@ -1072,15 +1051,6 @@ TEST_CASE_METHOD(GridTestCase, "Grid::ReadOnly", "[grid]") m_grid->SetFocus(); -#ifdef __WXGTK__ - // This is a mystery, but we somehow get WXK_RETURN generated by the - // previous test (Editable) in this one. In spite of wxYield() in that - // test, the key doesn't get dispatched there and we have to consume it - // here before setting the current grid cell, as getting WXK_RETURN later - // would move the selection down, to a non read-only cell. - wxYield(); -#endif // __WXGTK__ - m_grid->SetGridCursor(1, 1); CHECK(m_grid->IsCurrentCellReadOnly()); @@ -1161,10 +1131,16 @@ TEST_CASE_METHOD(GridTestCase, "Grid::WindowAsEditorControl", "[grid]") TEST_CASE_METHOD(GridTestCase, "Grid::ResizeScrolledHeader", "[grid]") { // TODO this test currently works only under Windows unfortunately -#if wxUSE_UIACTIONSIMULATOR && defined(__WXMSW__) +#if wxUSE_UIACTIONSIMULATOR && (defined(__WXMSW__) || defined(__WXGTK__)) if ( !EnableUITests() ) return; +#ifdef __WXGTK20__ + // Works locally, but not when run on Travis CI. + if ( IsAutomaticTest() ) + return; +#endif + SECTION("Default") {} SECTION("Native header") { m_grid->UseNativeColHeader(); } @@ -1206,10 +1182,16 @@ TEST_CASE_METHOD(GridTestCase, "Grid::ResizeScrolledHeader", "[grid]") TEST_CASE_METHOD(GridTestCase, "Grid::ColumnMinWidth", "[grid]") { // TODO this test currently works only under Windows unfortunately -#if wxUSE_UIACTIONSIMULATOR && defined(__WXMSW__) +#if wxUSE_UIACTIONSIMULATOR && (defined(__WXMSW__) || defined(__WXGTK__)) if ( !EnableUITests() ) return; +#ifdef __WXGTK20__ + // Works locally, but not when run on Travis CI. + if ( IsAutomaticTest() ) + return; +#endif + SECTION("Default") {} SECTION("Native header") { diff --git a/tests/controls/hyperlinkctrltest.cpp b/tests/controls/hyperlinkctrltest.cpp index 88ff9ac5f6..be886b783e 100644 --- a/tests/controls/hyperlinkctrltest.cpp +++ b/tests/controls/hyperlinkctrltest.cpp @@ -92,7 +92,7 @@ void HyperlinkCtrlTestCase::Url() void HyperlinkCtrlTestCase::Click() { -#if wxUSE_UIACTIONSIMULATOR && !defined(__WXGTK__) +#if wxUSE_UIACTIONSIMULATOR EventCounter hyperlink(m_hyperlink, wxEVT_HYPERLINK); wxUIActionSimulator sim; diff --git a/tests/controls/listbasetest.cpp b/tests/controls/listbasetest.cpp index ca49e77914..40c2a53437 100644 --- a/tests/controls/listbasetest.cpp +++ b/tests/controls/listbasetest.cpp @@ -251,7 +251,7 @@ void ListBaseTestCase::KeyDown() list->SetFocus(); wxYield(); - sim.Text("aAbB"); + sim.Text("aAbB"); // 4 letters + 2 shift mods. wxYield(); CPPUNIT_ASSERT_EQUAL(6, keydown.GetCount()); diff --git a/tests/controls/radiobuttontest.cpp b/tests/controls/radiobuttontest.cpp index 104b5c98b4..a81d6aec61 100644 --- a/tests/controls/radiobuttontest.cpp +++ b/tests/controls/radiobuttontest.cpp @@ -75,8 +75,8 @@ void RadioButtonTestCase::tearDown() void RadioButtonTestCase::Click() { - // GTK and OS X do not support selecting a single radio button -#if wxUSE_UIACTIONSIMULATOR && !defined(__WXGTK__) && !defined(__WXOSX__) + // OS X doesn't support selecting a single radio button +#if wxUSE_UIACTIONSIMULATOR && !defined(__WXOSX__) EventCounter selected(m_radio, wxEVT_RADIOBUTTON); wxUIActionSimulator sim; diff --git a/tests/controls/richtextctrltest.cpp b/tests/controls/richtextctrltest.cpp index ca4efb6d34..5a407a12a9 100644 --- a/tests/controls/richtextctrltest.cpp +++ b/tests/controls/richtextctrltest.cpp @@ -128,9 +128,6 @@ void RichTextCtrlTestCase::CharacterEvent() { #if wxUSE_UIACTIONSIMULATOR - // There seems to be an event sequence problem on GTK+ that causes the events - // to be disconnected before they're processed, generating spurious errors. -#if !defined(__WXGTK__) EventCounter character(m_rich, wxEVT_RICHTEXT_CHARACTER); EventCounter content(m_rich, wxEVT_RICHTEXT_CONTENT_INSERTED); @@ -154,15 +151,12 @@ void RichTextCtrlTestCase::CharacterEvent() CPPUNIT_ASSERT_EQUAL(0, character.GetCount()); CPPUNIT_ASSERT_EQUAL(1, content.GetCount()); #endif -#endif } void RichTextCtrlTestCase::DeleteEvent() { #if wxUSE_UIACTIONSIMULATOR - // There seems to be an event sequence problem on GTK+ that causes the events - // to be disconnected before they're processed, generating spurious errors. -#if !defined(__WXGTK__) + EventCounter deleteevent(m_rich, wxEVT_RICHTEXT_DELETE); EventCounter contentdelete(m_rich, wxEVT_RICHTEXT_CONTENT_DELETED); @@ -178,15 +172,12 @@ void RichTextCtrlTestCase::DeleteEvent() //Only one as the delete doesn't delete anthing CPPUNIT_ASSERT_EQUAL(1, contentdelete.GetCount()); #endif -#endif } void RichTextCtrlTestCase::ReturnEvent() { #if wxUSE_UIACTIONSIMULATOR - // There seems to be an event sequence problem on GTK+ that causes the events - // to be disconnected before they're processed, generating spurious errors. -#if !defined(__WXGTK__) + EventCounter returnevent(m_rich, wxEVT_RICHTEXT_RETURN); m_rich->SetFocus(); @@ -197,7 +188,6 @@ void RichTextCtrlTestCase::ReturnEvent() CPPUNIT_ASSERT_EQUAL(1, returnevent.GetCount()); #endif -#endif } void RichTextCtrlTestCase::StyleEvent() @@ -235,8 +225,7 @@ void RichTextCtrlTestCase::BufferResetEvent() void RichTextCtrlTestCase::UrlEvent() { #if wxUSE_UIACTIONSIMULATOR - // Mouse up event not being caught on GTK+ -#if !defined(__WXGTK__) + EventCounter url(m_rich, wxEVT_TEXT_URL); m_rich->BeginURL("http://www.wxwidgets.org"); @@ -252,13 +241,11 @@ void RichTextCtrlTestCase::UrlEvent() CPPUNIT_ASSERT_EQUAL(1, url.GetCount()); #endif -#endif } void RichTextCtrlTestCase::TextEvent() { #if wxUSE_UIACTIONSIMULATOR -#if !defined(__WXGTK__) EventCounter updated(m_rich, wxEVT_TEXT); m_rich->SetFocus(); @@ -270,7 +257,6 @@ void RichTextCtrlTestCase::TextEvent() CPPUNIT_ASSERT_EQUAL("abcdef", m_rich->GetValue()); CPPUNIT_ASSERT_EQUAL(6, updated.GetCount()); #endif -#endif } void RichTextCtrlTestCase::CutCopyPaste() @@ -418,7 +404,6 @@ void RichTextCtrlTestCase::Selection() void RichTextCtrlTestCase::Editable() { #if wxUSE_UIACTIONSIMULATOR -#if !defined(__WXGTK__) EventCounter updated(m_rich, wxEVT_TEXT); m_rich->SetFocus(); @@ -438,7 +423,6 @@ void RichTextCtrlTestCase::Editable() CPPUNIT_ASSERT_EQUAL("abcdef", m_rich->GetValue()); CPPUNIT_ASSERT_EQUAL(0, updated.GetCount()); #endif -#endif } void RichTextCtrlTestCase::Range() diff --git a/tests/controls/spinctrldbltest.cpp b/tests/controls/spinctrldbltest.cpp index 5b9ba0dfd1..1d31f10798 100644 --- a/tests/controls/spinctrldbltest.cpp +++ b/tests/controls/spinctrldbltest.cpp @@ -91,7 +91,7 @@ void SpinCtrlDoubleTestCase::NoEventsInCtor() void SpinCtrlDoubleTestCase::Arrows() { -#if wxUSE_UIACTIONSIMULATOR && !defined(__WXGTK__) +#if wxUSE_UIACTIONSIMULATOR EventCounter updated(m_spin, wxEVT_SPINCTRLDOUBLE); wxUIActionSimulator sim; @@ -196,9 +196,10 @@ void SpinCtrlDoubleTestCase::Value() void SpinCtrlDoubleTestCase::Increment() { -#if wxUSE_UIACTIONSIMULATOR && !defined(__WXGTK__) +#if wxUSE_UIACTIONSIMULATOR CPPUNIT_ASSERT_EQUAL(1.0, m_spin->GetIncrement()); + m_spin->SetDigits(1); // GTK would fail without this. m_spin->SetIncrement(0.1); CPPUNIT_ASSERT_EQUAL(0.1, m_spin->GetIncrement()); diff --git a/tests/controls/spinctrltest.cpp b/tests/controls/spinctrltest.cpp index e91079de3c..7b1ad96e6d 100644 --- a/tests/controls/spinctrltest.cpp +++ b/tests/controls/spinctrltest.cpp @@ -21,6 +21,7 @@ #include "testableframe.h" #include "wx/uiaction.h" #include "wx/spinctrl.h" +#include "wx/textctrl.h" class SpinCtrlTestCase : public CppUnit::TestCase { @@ -245,6 +246,10 @@ void SpinCtrlTestCase::SetValueInsideEventHandler() #if wxUSE_UIACTIONSIMULATOR m_spin->Bind(wxEVT_SPINCTRL, &SpinCtrlTestCase::OnSpinSetValue, this); + // A dummy control with which we change the focus. + wxTextCtrl* text = new wxTextCtrl(wxTheApp->GetTopWindow(), wxID_ANY); + text->Move(m_spin->GetSize().x, m_spin->GetSize().y * 3); + wxUIActionSimulator sim; // run multiple times to make sure there are no issues with keeping old value @@ -258,7 +263,7 @@ void SpinCtrlTestCase::SetValueInsideEventHandler() sim.Text("20"); wxYield(); - wxTheApp->GetTopWindow()->SetFocus(); + text->SetFocus(); wxYield(); CPPUNIT_ASSERT_EQUAL(32, m_spin->GetValue()); diff --git a/tests/controls/textctrltest.cpp b/tests/controls/textctrltest.cpp index 795adcd981..1353f7dde2 100644 --- a/tests/controls/textctrltest.cpp +++ b/tests/controls/textctrltest.cpp @@ -359,6 +359,10 @@ void TextCtrlTestCase::HitTestSingleLine() long pos = -1; +#ifdef __WXGTK__ + wxYield(); +#endif + // Hitting a point near the left side of the control should find one of the // first few characters under it. SECTION("Normal") @@ -384,24 +388,14 @@ void TextCtrlTestCase::HitTestSingleLine() m_text->ChangeValue(wxString(200, 'X')); m_text->SetInsertionPointEnd(); + #ifdef __WXGTK__ // wxGTK must be given an opportunity to lay the text out. - wxYield(); + for ( wxStopWatch sw; sw.Time() < 50; ) + wxYield(); + #endif - // For some reason, this test consistently fails when running under - // Xvfb. Debugging shows that the text gets scrolled too far, instead - // of scrolling by ~156 characters, leaving the remaining 44 shown, in - // normal runs, it gets scrolled by all 200 characters, leaving nothing - // shown. It's not clear why does it happen, and there doesn't seem - // anything we can do about it. - if ( IsRunningUnderXVFB() ) - { - WARN("Skipping test known to fail under Xvfb"); - } - else - { - REQUIRE( m_text->HitTest(wxPoint(2*sizeChar.x, yMid), &pos) == wxTE_HT_ON_TEXT ); - CHECK( pos > 3 ); - } + REQUIRE( m_text->HitTest(wxPoint(2*sizeChar.x, yMid), &pos) == wxTE_HT_ON_TEXT ); + CHECK( pos > 3 ); // Using negative coordinates works even under Xvfb, so test at least // for this -- however this only works in wxGTK, not wxMSW. diff --git a/tests/controls/textentrytest.cpp b/tests/controls/textentrytest.cpp index 44bc437d89..e24db45622 100644 --- a/tests/controls/textentrytest.cpp +++ b/tests/controls/textentrytest.cpp @@ -292,6 +292,7 @@ void TextEntryTestCase::Editable() CPPUNIT_ASSERT_EQUAL("abcdef", entry->GetValue()); CPPUNIT_ASSERT_EQUAL(6, updated.GetCount()); + wxYield(); // And that the event carries the right value. TextEventHandler handler(window); diff --git a/tests/controls/treectrltest.cpp b/tests/controls/treectrltest.cpp index fa2a5ffd36..e4238b6d2b 100644 --- a/tests/controls/treectrltest.cpp +++ b/tests/controls/treectrltest.cpp @@ -49,10 +49,8 @@ private: CPPUNIT_TEST( DeleteAllItems ); WXUISIM_TEST( LabelEdit ); WXUISIM_TEST( KeyDown ); -#ifndef __WXGTK__ WXUISIM_TEST( CollapseExpandEvents ); WXUISIM_TEST( SelectionChange ); -#endif // !__WXGTK__ WXUISIM_TEST( Menu ); CPPUNIT_TEST( ItemData ); CPPUNIT_TEST( Iteration ); @@ -79,10 +77,8 @@ private: void DeleteAllItems(); void LabelEdit(); void KeyDown(); -#ifndef __WXGTK__ void CollapseExpandEvents(); void SelectionChange(); -#endif // !__WXGTK__ void Menu(); void ItemData(); void Iteration(); @@ -349,10 +345,14 @@ void TreeCtrlTestCase::KeyDown() CPPUNIT_ASSERT_EQUAL(6, keydown.GetCount()); } -#if !defined(__WXGTK__) - void TreeCtrlTestCase::CollapseExpandEvents() { +#ifdef __WXGTK20__ + // Works locally, but not when run on Travis CI. + if ( IsAutomaticTest() ) + return; +#endif + m_tree->CollapseAll(); EventCounter collapsed(m_tree, wxEVT_TREE_ITEM_COLLAPSED); @@ -377,6 +377,12 @@ void TreeCtrlTestCase::CollapseExpandEvents() CPPUNIT_ASSERT_EQUAL(1, expanding.GetCount()); CPPUNIT_ASSERT_EQUAL(1, expanded.GetCount()); +#ifdef __WXGTK__ + // Don't even know the reason why, but GTK has to sleep + // no less than 1200 for the test case to succeed. + wxMilliSleep(1200); +#endif + sim.MouseDblClick(); wxYield(); @@ -428,8 +434,6 @@ void TreeCtrlTestCase::SelectionChange() CPPUNIT_ASSERT_EQUAL(2, changing.GetCount()); } -#endif // !__WXGTK__ - void TreeCtrlTestCase::Menu() { EventCounter menu(m_tree, wxEVT_TREE_ITEM_MENU); @@ -612,12 +616,13 @@ void TreeCtrlTestCase::Sort() void TreeCtrlTestCase::KeyNavigation() { -#if wxUSE_UIACTIONSIMULATOR && !defined(__WXGTK__) +#if wxUSE_UIACTIONSIMULATOR wxUIActionSimulator sim; m_tree->CollapseAll(); m_tree->SelectItem(m_root); + wxYield(); m_tree->SetFocus(); sim.Char(WXK_RIGHT); @@ -635,6 +640,8 @@ void TreeCtrlTestCase::KeyNavigation() CPPUNIT_ASSERT(!m_tree->IsExpanded(m_root)); + wxYield(); + sim.Char(WXK_RIGHT); sim.Char(WXK_DOWN); wxYield(); diff --git a/tests/controls/windowtest.cpp b/tests/controls/windowtest.cpp index 11e1f89ca0..372317e67b 100644 --- a/tests/controls/windowtest.cpp +++ b/tests/controls/windowtest.cpp @@ -27,6 +27,7 @@ #include "wx/caret.h" #include "wx/cshelp.h" #include "wx/scopedptr.h" +#include "wx/stopwatch.h" #include "wx/tooltip.h" class WindowTestCase @@ -35,6 +36,13 @@ public: WindowTestCase() : m_window(new wxWindow(wxTheApp->GetTopWindow(), wxID_ANY)) { + #ifdef __WXGTK3__ + // 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(); + #endif } ~WindowTestCase() diff --git a/tests/events/keyboard.cpp b/tests/events/keyboard.cpp index 05229f9a99..6ba429ab8e 100644 --- a/tests/events/keyboard.cpp +++ b/tests/events/keyboard.cpp @@ -27,6 +27,10 @@ #include "wx/uiaction.h" #include "wx/vector.h" +#ifdef __WXGTK__ +#include "wx/stopwatch.h" +#endif + namespace { @@ -229,7 +233,11 @@ void KeyboardEventTestCase::setUp() m_win = new KeyboardTestWindow(wxTheApp->GetTopWindow()); wxYield(); m_win->SetFocus(); - wxYield(); // needed to show the new window + +#ifdef __WXGTK__ + for ( wxStopWatch sw; sw.Time() < 10; ) +#endif + wxYield(); // 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 7d4ae02252..4558954e3a 100644 --- a/tests/events/propagation.cpp +++ b/tests/events/propagation.cpp @@ -30,6 +30,7 @@ #include "wx/scopeguard.h" #include "wx/toolbar.h" #include "wx/uiaction.h" +#include "wx/stopwatch.h" // FIXME: Currently under OS X testing paint event doesn't work because neither // calling Refresh()+Update() nor even sending wxPaintEvent directly to @@ -37,12 +38,7 @@ // some tests there. But this should be fixed and the tests reenabled // because wxPaintEvent propagation in wxScrolledWindow is a perfect // example of fragile code that could be broken under OS X. -// -// FIXME: Under GTK+ 3 the test is broken because a simple wxYield() is not -// enough to map the frame. It should be also fixed there by waiting for -// it to come up, with some timeout, but for now it always fails, so -// it's useless to run it. -#if !defined(__WXOSX__) && !defined(__WXGTK3__) +#if !defined(__WXOSX__) #define CAN_TEST_PAINT_EVENTS #endif @@ -180,7 +176,8 @@ public: #ifdef __WXGTK__ // We need to map the window, otherwise we're not going to get any // paint events for it. - wxYield(); + for ( wxStopWatch sw; sw.Time() < 50; ) + wxYield(); // Ignore events generated during the initial mapping. g_str.clear(); diff --git a/tests/menu/menu.cpp b/tests/menu/menu.cpp index c4db03cfec..ef957e4f18 100644 --- a/tests/menu/menu.cpp +++ b/tests/menu/menu.cpp @@ -578,17 +578,6 @@ private: void MenuTestCase::Events() { -#ifdef __WXGTK__ - // FIXME: For some reason, we sporadically fail to get the event in - // buildbot slave builds even though the test always passes locally. - // There is undoubtedly something wrong here but without being able - // to debug it, I have no idea what is it, so let's just disable - // this test when running under buildbot to let the entire test - // suite pass. - if ( IsAutomaticTest() ) - return; -#endif // __WXGTK__ - #if wxUSE_UIACTIONSIMULATOR MenuEventHandler handler(m_frame); @@ -597,12 +586,6 @@ void MenuTestCase::Events() m_frame->SetFocus(); wxYield(); -#ifdef __WXGTK__ - // This is another test which fails with wxGTK without this delay because - // the frame doesn't appear on screen in time. - wxMilliSleep(50); -#endif // __WXGTK__ - wxUIActionSimulator sim; sim.KeyDown(WXK_F1); sim.KeyUp(WXK_F1); diff --git a/tests/test.cpp b/tests/test.cpp index 259c7c71db..baba0f7b3e 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -458,11 +458,11 @@ bool EnableUITests() if ( s_enabled == -1 ) { -#ifdef __WXMSW__ +#if defined(__WXMSW__) || defined(__WXGTK__) s_enabled = 1; -#else // !__WXMSW__ +#else // !(__WXMSW__ || __WXGTK__) s_enabled = 0; -#endif // __WXMSW__/!__WXMSW__ +#endif // (__WXMSW__ || __WXGTK__) } }