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:
@@ -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');
|
||||
|
Reference in New Issue
Block a user