Fix recently broken forwarding of events between event handlers.

After the recent changes to the event processing logic, forwarding an event
from one event handler to another one stopped working correctly because the
per-event "process here only" flag prevented it from following the event
handler chain after forwarding. This notably broke keyboard navigation in
wxComboCtrl under MSW in wx itself and probably quite a few of other things in
user code.

Fix this by replacing the boolean flag with a pointer to the handler to which
the processing of this event should be restricted. This allows the full
processing to still take place if an event is forwarded to another handler.
So wxEvent::ShouldProcessHereOnly() is now called ShouldProcessOnlyIn() and
takes a wxEvtHandler parameter.

This made appear a problem in wxScrollHelperEvtHandler code that was hidden by
the bug above: the events were still processed multiple times in it. To fix
this, also add wxEvent::DidntHonourProcessOnlyIn() and take it into account in
the base class code. Did I mention that wxScrollHelperEvtHandler must die?

Add another unit test checking that forwarding works correctly.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64464 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2010-06-02 11:58:31 +00:00
parent ce6b1014bf
commit bbdee10d5f
4 changed files with 107 additions and 37 deletions

View File

@@ -178,6 +178,7 @@ private:
CPPUNIT_TEST( TwoHandlers );
CPPUNIT_TEST( WindowWithoutHandler );
CPPUNIT_TEST( WindowWithHandler );
CPPUNIT_TEST( ForwardEvent );
CPPUNIT_TEST( ScrollWindowWithoutHandler );
CPPUNIT_TEST( ScrollWindowWithHandler );
CPPUNIT_TEST_SUITE_END();
@@ -186,6 +187,7 @@ private:
void TwoHandlers();
void WindowWithoutHandler();
void WindowWithHandler();
void ForwardEvent();
void ScrollWindowWithoutHandler();
void ScrollWindowWithHandler();
@@ -262,6 +264,48 @@ void EventPropagationTestCase::WindowWithHandler()
CPPUNIT_ASSERT_EQUAL( "oa2o1cpA", g_str );
}
void EventPropagationTestCase::ForwardEvent()
{
// The idea of this test is to check that the events explicitly forwarded
// to another event handler still get pre/post-processed as usual as this
// used to be broken by the fixes trying to avoid duplicate processing.
TestWindow * const win = new TestWindow(wxTheApp->GetTopWindow(), 'w');
wxON_BLOCK_EXIT_OBJ0( *win, wxWindow::Destroy );
TestEvtHandler h1('1');
win->PushEventHandler(&h1);
wxON_BLOCK_EXIT_OBJ1( *win, wxWindow::PopEventHandler, false );
class ForwardEvtHandler : public wxEvtHandler
{
public:
ForwardEvtHandler(wxEvtHandler& h) : m_h(&h) { }
virtual bool ProcessEvent(wxEvent& event)
{
g_str += 'f';
return m_h->ProcessEvent(event);
}
private:
wxEvtHandler *m_h;
} f(h1);
// First send the event directly to f.
wxCommandEvent event1(TEST_EVT);
f.ProcessEvent(event1);
CPPUNIT_ASSERT_EQUAL( "foa1wA", g_str );
g_str.clear();
// And then also test sending it to f indirectly.
wxCommandEvent event2(TEST_EVT);
TestEvtHandler h2('2');
h2.SetNextHandler(&f);
h2.ProcessEvent(event2);
CPPUNIT_ASSERT_EQUAL( "oa2fo1wAA", g_str );
}
void EventPropagationTestCase::ScrollWindowWithoutHandler()
{
TestWindow * const parent = new TestWindow(wxTheApp->GetTopWindow(), 'p');