ensure that ProcessEvent() is called for all the event handlers, not just the first one in event handlers list
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58144 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -718,7 +718,7 @@ public:
|
|||||||
void Skip(bool skip = true) { m_skipped = skip; }
|
void Skip(bool skip = true) { m_skipped = skip; }
|
||||||
bool GetSkipped() const { return m_skipped; }
|
bool GetSkipped() const { return m_skipped; }
|
||||||
|
|
||||||
// this function is used to create a copy of the event polymorphically and
|
// This function is used to create a copy of the event polymorphically and
|
||||||
// all derived classes must implement it because otherwise wxPostEvent()
|
// all derived classes must implement it because otherwise wxPostEvent()
|
||||||
// for them wouldn't work (it needs to do a copy of the event)
|
// for them wouldn't work (it needs to do a copy of the event)
|
||||||
virtual wxEvent *Clone() const = 0;
|
virtual wxEvent *Clone() const = 0;
|
||||||
@@ -747,6 +747,20 @@ public:
|
|||||||
m_propagationLevel = propagationLevel;
|
m_propagationLevel = propagationLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This is for internal use only and is only called by
|
||||||
|
// wxEvtHandler::ProcessEvent() to check whether it's the first time this
|
||||||
|
// event is being processed
|
||||||
|
bool WasProcessed()
|
||||||
|
{
|
||||||
|
if ( m_wasProcessed )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
m_wasProcessed = true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
wxObject* m_eventObject;
|
wxObject* m_eventObject;
|
||||||
wxEventType m_eventType;
|
wxEventType m_eventType;
|
||||||
@@ -768,6 +782,12 @@ protected:
|
|||||||
bool m_skipped;
|
bool m_skipped;
|
||||||
bool m_isCommandEvent;
|
bool m_isCommandEvent;
|
||||||
|
|
||||||
|
// initially false but becomes true as soon as WasProcessed() is called for
|
||||||
|
// the first time, as this is done only by ProcessEvent() it explains the
|
||||||
|
// variable name: it becomes true after ProcessEvent() was called at least
|
||||||
|
// once for this event
|
||||||
|
bool m_wasProcessed;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
wxEvent(const wxEvent&); // for implementing Clone()
|
wxEvent(const wxEvent&); // for implementing Clone()
|
||||||
wxEvent& operator=(const wxEvent&); // for derived classes operator=()
|
wxEvent& operator=(const wxEvent&); // for derived classes operator=()
|
||||||
@@ -3081,12 +3101,7 @@ public:
|
|||||||
void OnSinkDestroyed( wxEvtHandler *sink );
|
void OnSinkDestroyed( wxEvtHandler *sink );
|
||||||
|
|
||||||
|
|
||||||
// The method processing the event in this event handler (or rather in this
|
// The method tries to process the event in this event handler.
|
||||||
// event handler chain as it also tries the next handler and so on), i.e.
|
|
||||||
// it returns true if we processed this event or false if we didn't but
|
|
||||||
// does not call TryParent() in the latter case. It also doesn't call
|
|
||||||
// wxApp::FilterEvent() before processing it, this is supposed to be done
|
|
||||||
// by the public ProcessEvent() only once for every event we handle.
|
|
||||||
//
|
//
|
||||||
// It is meant to be called from ProcessEvent() only and is not virtual,
|
// It is meant to be called from ProcessEvent() only and is not virtual,
|
||||||
// additional event handlers can be hooked into the normal event processing
|
// additional event handlers can be hooked into the normal event processing
|
||||||
|
@@ -352,6 +352,7 @@ wxEvent::wxEvent(int theId, wxEventType commandType )
|
|||||||
m_callbackUserData = NULL;
|
m_callbackUserData = NULL;
|
||||||
m_isCommandEvent = false;
|
m_isCommandEvent = false;
|
||||||
m_propagationLevel = wxEVENT_PROPAGATE_NONE;
|
m_propagationLevel = wxEVENT_PROPAGATE_NONE;
|
||||||
|
m_wasProcessed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxEvent::wxEvent(const wxEvent& src)
|
wxEvent::wxEvent(const wxEvent& src)
|
||||||
@@ -364,6 +365,7 @@ wxEvent::wxEvent(const wxEvent& src)
|
|||||||
, m_propagationLevel(src.m_propagationLevel)
|
, m_propagationLevel(src.m_propagationLevel)
|
||||||
, m_skipped(src.m_skipped)
|
, m_skipped(src.m_skipped)
|
||||||
, m_isCommandEvent(src.m_isCommandEvent)
|
, m_isCommandEvent(src.m_isCommandEvent)
|
||||||
|
, m_wasProcessed(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,6 +382,8 @@ wxEvent& wxEvent::operator=(const wxEvent& src)
|
|||||||
m_skipped = src.m_skipped;
|
m_skipped = src.m_skipped;
|
||||||
m_isCommandEvent = src.m_isCommandEvent;
|
m_isCommandEvent = src.m_isCommandEvent;
|
||||||
|
|
||||||
|
// don't change m_wasProcessed
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1263,22 +1267,35 @@ bool wxEvtHandler::TryParent(wxEvent& event)
|
|||||||
bool wxEvtHandler::ProcessEvent(wxEvent& event)
|
bool wxEvtHandler::ProcessEvent(wxEvent& event)
|
||||||
{
|
{
|
||||||
// allow the application to hook into event processing
|
// allow the application to hook into event processing
|
||||||
if ( wxTheApp )
|
//
|
||||||
|
// note that we should only do it if we're the first event handler called
|
||||||
|
// to avoid calling FilterEvent() multiple times as the event goes through
|
||||||
|
// the event handler chain and possibly upwards the window hierarchy
|
||||||
|
if ( !event.WasProcessed() )
|
||||||
{
|
{
|
||||||
int rc = wxTheApp->FilterEvent(event);
|
if ( wxTheApp )
|
||||||
if ( rc != -1 )
|
|
||||||
{
|
{
|
||||||
wxASSERT_MSG( rc == 1 || rc == 0,
|
int rc = wxTheApp->FilterEvent(event);
|
||||||
_T("unexpected wxApp::FilterEvent return value") );
|
if ( rc != -1 )
|
||||||
|
{
|
||||||
|
wxASSERT_MSG( rc == 1 || rc == 0,
|
||||||
|
"unexpected wxApp::FilterEvent return value" );
|
||||||
|
|
||||||
return rc != 0;
|
return rc != 0;
|
||||||
|
}
|
||||||
|
//else: proceed normally
|
||||||
}
|
}
|
||||||
//else: proceed normally
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ProcessEventHere(event) )
|
if ( ProcessEventHere(event) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// pass the event to the next handler, notice that we shouldn't call
|
||||||
|
// TryParent() even if it doesn't handle the event as the last handler in
|
||||||
|
// the chain will do it
|
||||||
|
if ( GetNextHandler() )
|
||||||
|
return GetNextHandler()->ProcessEvent(event);
|
||||||
|
|
||||||
// propagate the event upwards the window chain and/or to the application
|
// propagate the event upwards the window chain and/or to the application
|
||||||
// object if it wasn't processed at this level
|
// object if it wasn't processed at this level
|
||||||
return TryParent(event);
|
return TryParent(event);
|
||||||
@@ -1286,25 +1303,21 @@ bool wxEvtHandler::ProcessEvent(wxEvent& event)
|
|||||||
|
|
||||||
bool wxEvtHandler::ProcessEventHere(wxEvent& event)
|
bool wxEvtHandler::ProcessEventHere(wxEvent& event)
|
||||||
{
|
{
|
||||||
// An event handler can be enabled or disabled
|
// If the event handler is disabled it doesn't process any events
|
||||||
if ( GetEvtHandlerEnabled() )
|
if ( !GetEvtHandlerEnabled() )
|
||||||
{
|
return false;
|
||||||
// if we have a validator, it has higher priority than our own event
|
|
||||||
// table
|
|
||||||
if ( TryValidator(event) )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Handle per-instance dynamic event tables first
|
// If we have a validator, it has higher priority than our own event
|
||||||
if ( m_dynamicEvents && SearchDynamicEventTable(event) )
|
// handlers
|
||||||
return true;
|
if ( TryValidator(event) )
|
||||||
|
return true;
|
||||||
|
|
||||||
// Then static per-class event tables
|
// Handle per-instance dynamic event tables first
|
||||||
if ( GetEventHashTable().HandleEvent(event, this) )
|
if ( m_dynamicEvents && SearchDynamicEventTable(event) )
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
// Try going down the event handler chain
|
// Then static per-class event tables
|
||||||
if ( GetNextHandler() && GetNextHandler()->ProcessEventHere(event) )
|
if ( GetEventHashTable().HandleEvent(event, this) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// We don't have a handler for this event.
|
// We don't have a handler for this event.
|
||||||
|
Reference in New Issue
Block a user