]> git.saurik.com Git - wxWidgets.git/commitdiff
ensure that ProcessEvent() is called for all the event handlers, not just the first...
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 16 Jan 2009 16:07:16 +0000 (16:07 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 16 Jan 2009 16:07:16 +0000 (16:07 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58144 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/event.h
src/common/event.cpp

index 369c0b9da975b82b78de9a3e9fe6606f34d57512..e88450a8a28fe2b03f9b5f8e332fe1b9fa3249d5 100644 (file)
@@ -718,7 +718,7 @@ public:
     void Skip(bool skip = true) { m_skipped = skip; }
     bool GetSkipped() const { return m_skipped; }
 
     void Skip(bool skip = true) { m_skipped = skip; }
     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()
     // for them wouldn't work (it needs to do a copy of the event)
     virtual wxEvent *Clone() const = 0;
     // all derived classes must implement it because otherwise wxPostEvent()
     // for them wouldn't work (it needs to do a copy of the event)
     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:
     wxObject*         m_eventObject;
     wxEventType       m_eventType;
 protected:
     wxObject*         m_eventObject;
     wxEventType       m_eventType;
@@ -768,6 +782,12 @@ protected:
     bool              m_skipped;
     bool              m_isCommandEvent;
 
     bool              m_skipped;
     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:
     wxEvent(const wxEvent&);            // for implementing Clone()
     wxEvent& operator=(const wxEvent&); // for derived classes operator=()
 protected:
     wxEvent(const wxEvent&);            // for implementing Clone()
     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
-    // 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.
+    // The method tries to process the event in this event handler.
     //
     // It is meant to be called from ProcessEvent() only and is not virtual,
     // additional event handlers can be hooked into the normal event processing
     //
     // It is meant to be called from ProcessEvent() only and is not virtual,
     // additional event handlers can be hooked into the normal event processing
index 700084e9ccad7f0d2b4689c06c5345fe1a4e989f..3ee0d136ed3fc7652352054dbaee41f82c2f7304 100644 (file)
@@ -352,6 +352,7 @@ wxEvent::wxEvent(int theId, wxEventType commandType )
     m_callbackUserData = NULL;
     m_isCommandEvent = false;
     m_propagationLevel = wxEVENT_PROPAGATE_NONE;
     m_callbackUserData = NULL;
     m_isCommandEvent = false;
     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_skipped(src.m_skipped)
     , m_isCommandEvent(src.m_isCommandEvent)
     , m_propagationLevel(src.m_propagationLevel)
     , m_skipped(src.m_skipped)
     , m_isCommandEvent(src.m_isCommandEvent)
+    , m_wasProcessed(false)
 {
 }
 
 {
 }
 
@@ -380,6 +382,8 @@ wxEvent& wxEvent::operator=(const wxEvent& src)
     m_skipped = src.m_skipped;
     m_isCommandEvent = src.m_isCommandEvent;
 
     m_skipped = src.m_skipped;
     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)
 {
     // allow the application to hook into event processing
 bool wxEvtHandler::ProcessEvent(wxEvent& event)
 {
     // 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 ( rc != -1 )
+        if ( wxTheApp )
         {
         {
-            wxASSERT_MSG( rc == 1 || rc == 0,
-                          _T("unexpected wxApp::FilterEvent return value") );
+            int rc = wxTheApp->FilterEvent(event);
+            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) )
         return true;
 
     }
 
     if ( ProcessEventHere(event) )
         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
     // object if it wasn't processed at this level
     return TryParent(event);
     // propagate the event upwards the window chain and/or to the application
     // object if it wasn't processed at this level
     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 ( GetEvtHandlerEnabled() )
-    {
-        // if we have a validator, it has higher priority than our own event
-        // table
-        if ( TryValidator(event) )
-            return true;
+    // If the event handler is disabled it doesn't process any events
+    if ( !GetEvtHandlerEnabled() )
+        return false;
 
 
-        // Handle per-instance dynamic event tables first
-        if ( m_dynamicEvents && SearchDynamicEventTable(event) )
-            return true;
+    // If we have a validator, it has higher priority than our own event
+    // handlers
+    if ( TryValidator(event) )
+        return true;
 
 
-        // Then static per-class event tables
-        if ( GetEventHashTable().HandleEvent(event, this) )
-            return true;
-    }
+    // Handle per-instance dynamic event tables first
+    if ( m_dynamicEvents && SearchDynamicEventTable(event) )
+        return true;
 
 
-    // Try going down the event handler chain
-    if ( GetNextHandler() && GetNextHandler()->ProcessEventHere(event) )
+    // Then static per-class event tables
+    if ( GetEventHashTable().HandleEvent(event, this) )
         return true;
 
     // We don't have a handler for this event.
         return true;
 
     // We don't have a handler for this event.