]> git.saurik.com Git - wxWidgets.git/commitdiff
move pending event processing back to wxApp (these methods were moved into wxEventLoo...
authorFrancesco Montorsi <f18m_cpp217828@yahoo.it>
Mon, 2 Mar 2009 20:45:22 +0000 (20:45 +0000)
committerFrancesco Montorsi <f18m_cpp217828@yahoo.it>
Mon, 2 Mar 2009 20:45:22 +0000 (20:45 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59284 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/app.h
include/wx/evtloop.h
interface/wx/app.h
interface/wx/event.h
interface/wx/evtloop.h
src/common/appbase.cpp
src/common/event.cpp
src/common/evtloopcmn.cpp

index 10a99bf981e0f59e74b1117b0f899c0b1e86556c..1a9a083f5e6ffc979bd0f2efea2a505946875c26 100644 (file)
@@ -277,14 +277,46 @@ public:
 #endif // wxUSE_EXCEPTIONS
 
 
-    // wxEventLoop redirections
-    // ------------------------
-
-    virtual void SuspendProcessingOfPendingEvents();
-    virtual void ResumeProcessingOfPendingEvents();
+    // pending events
+    // --------------
+
+    // IMPORTANT: all these methods conceptually belong to wxEventLoopBase
+    //            but for many reasons we need to allow queuing of events
+    //            even when there's no event loop (e.g. in wxApp::OnInit);
+    //            this feature is used e.g. to queue events on secondary threads
+    //            or in wxPython to use wx.CallAfter before the GUI is initialized
+
+    // process all events in the m_handlersWithPendingEvents list -- it is necessary
+    // to call this function to process posted events. This happens during each
+    // event loop iteration in GUI mode but if there is no main loop, it may be
+    // also called directly.
     virtual void ProcessPendingEvents();
+
+    // check if there are pending events on global pending event list
     bool HasPendingEvents() const;
 
+    // temporary suspends processing of the pending events
+    void SuspendProcessingOfPendingEvents();
+
+    // resume processing of the pending events previously stopped because of a
+    // call to SuspendProcessingOfPendingEvents()
+    void ResumeProcessingOfPendingEvents();
+
+    // called by ~wxEvtHandler to (eventually) remove the handler from the list of
+    // the handlers with pending events
+    void RemovePendingEventHandler(wxEvtHandler* toRemove);
+
+    // adds an event handler to the list of the handlers with pending events
+    void AppendPendingEventHandler(wxEvtHandler* toAppend);
+
+    // moves the event handler from the list of the handlers with pending events
+    //to the list of the handlers with _delayed_ pending events
+    void DelayPendingEventHandler(wxEvtHandler* toDelay);
+
+
+    // wxEventLoop redirections
+    // ------------------------
+
     virtual bool Pending();
     virtual bool Dispatch();
 
@@ -388,6 +420,18 @@ protected:
     // been started yet or has already terminated)
     wxEventLoopBase *m_mainLoop;
 
+    // the array of the handlers with pending events which needs to be processed
+    // inside ProcessPendingEvents()
+    wxEvtHandlerArray m_handlersWithPendingEvents;
+
+    // helper array used by ProcessPendingEvents()
+    wxEvtHandlerArray m_handlersWithPendingDelayedEvents;
+
+#if wxUSE_THREADS
+    // this critical section protects both the lists above
+    wxCriticalSection m_handlersWithPendingEventsLocker;
+#endif
+
     friend class WXDLLIMPEXP_FWD_BASE wxEvtHandler;
 
     // the application object is a singleton anyhow, there is no sense in
index df144fb97aaf60452455f4f351f276844cf94368..8bea93090a5bb8bf4e00063858f4bf5de9fa6306 100644 (file)
@@ -96,37 +96,6 @@ public:
     virtual void WakeUp() = 0;
 
 
-    // pending events
-    // --------------
-
-    // process all events in the wxHandlersWithPendingEvents list -- it is necessary
-    // to call this function to process posted events. This happens during each
-    // event loop iteration in GUI mode but if there is no main loop, it may be
-    // also called directly.
-    virtual void ProcessPendingEvents();
-
-    // check if there are pending events on global pending event list
-    bool HasPendingEvents() const;
-
-    // temporary suspends processing of the pending events
-    void SuspendProcessingOfPendingEvents();
-
-    // resume processing of the pending events previously stopped because of a
-    // call to SuspendProcessingOfPendingEvents()
-    void ResumeProcessingOfPendingEvents();
-
-    // called by ~wxEvtHandler to (eventually) remove the handler from the list of
-    // the handlers with pending events
-    void RemovePendingEventHandler(wxEvtHandler* toRemove);
-
-    // adds an event handler to the list of the handlers with pending events
-    void AppendPendingEventHandler(wxEvtHandler* toAppend);
-
-    // moves the event handler from the list of the handlers with pending events
-    //to the list of the handlers with _delayed_ pending events
-    void DelayPendingEventHandler(wxEvtHandler* toDelay);
-
-
     // idle handling
     // -------------
 
@@ -188,19 +157,7 @@ protected:
     // the pointer to currently active loop
     static wxEventLoopBase *ms_activeLoop;
 
-    // the array of the handlers with pending events which needs to be processed
-    // inside ProcessPendingEvents()
-    wxEvtHandlerArray m_handlersWithPendingEvents;
-
-    // helper array used by ProcessPendingEvents()
-    wxEvtHandlerArray m_handlersWithPendingDelayedEvents;
-
-#if wxUSE_THREADS
-    // this critical section protects both the lists above
-    wxCriticalSection m_handlersWithPendingEventsLocker;
-#endif
-
-    // Yield() helpers:
+    // YieldFor() helpers:
     bool m_isInsideYield;
     long m_eventsToProcessInsideYield;
 
index 4652096e3fb427533cfb4520527cb097dd31072f..9d358c7473d131a69679b6dc12a19b17bf780ae8 100644 (file)
@@ -114,6 +114,45 @@ public:
     //@}
 
 
+    /**
+        @name Pending events
+
+        Pending events are handled by wxAppConsole rather than wxEventLoopBase
+        to allow queuing of events even when there's no event loop
+        (e.g. in wxAppConsole::OnInit).
+    */
+    //@{
+
+    /**
+        Process all pending events; it is necessary to call this function to
+        process posted events.
+
+        This happens during each event loop iteration in GUI mode but
+        it may be also called directly.
+    */
+    virtual void ProcessPendingEvents();
+
+    /**
+        Returns @true if there are pending events on the internal pending event list.
+    */
+    bool HasPendingEvents() const;
+
+    /**
+        Temporary suspends processing of the pending events.
+
+        @see ResumeProcessingOfPendingEvents()
+    */
+    void SuspendProcessingOfPendingEvents();
+
+    /**
+        Resume processing of the pending events previously stopped because of a
+        call to SuspendProcessingOfPendingEvents().
+    */
+    void ResumeProcessingOfPendingEvents();
+
+    //@}
+
+
     /**
         Allows external code to modify global ::wxTheApp, but you should really
         know what you're doing if you call it.
index d0ea624e1f468b5328eb93b6d7db1b043d2ddcf2..2e80f9c739d75460d2032c60e3961376d43d33db 100644 (file)
@@ -333,7 +333,7 @@ public:
     @library{wxbase}
     @category{events}
 
-    @see @ref overview_events_processing
+    @see @ref overview_events_processing, wxEventBlocker, wxEventLoopBase
 */
 class wxEvtHandler : public wxObject
 {
index 885ce458622afa68d18777bb1fb1fabb0471cd6a..4322ac08d0eefedd9fefac5cca88a34ef6734d79 100644 (file)
@@ -146,41 +146,6 @@ public:
     //@}
 
 
-    /**
-        @name Pending events
-    */
-    //@{
-
-    /**
-        Process all pending events; it is necessary to call this function to
-        process posted events.
-
-        This happens during each event loop iteration in GUI mode but
-        it may be also called directly.
-    */
-    virtual void ProcessPendingEvents();
-
-    /**
-        Returns @true if there are pending events on the internal pending event list.
-    */
-    bool HasPendingEvents() const;
-
-    /**
-        Temporary suspends processing of the pending events.
-
-        @see ResumeProcessingOfPendingEvents()
-    */
-    void SuspendProcessingOfPendingEvents();
-
-    /**
-        Resume processing of the pending events previously stopped because of a
-        call to SuspendProcessingOfPendingEvents().
-    */
-    void ResumeProcessingOfPendingEvents();
-
-    //@}
-
-
     /**
         @name Idle handling
     */
index 81dacee807aaf6c9d0190062ffc6762b9425cfbc..a78e93d1d47c42776f266653f4a0363e0f157c77 100644 (file)
@@ -313,34 +313,6 @@ bool wxAppConsoleBase::Dispatch()
     return loop && loop->Dispatch();
 }
 
-bool wxAppConsoleBase::HasPendingEvents() const
-{
-    wxEventLoopBase * const loop = wxEventLoopBase::GetActive();
-
-    return loop && loop->HasPendingEvents();
-}
-
-void wxAppConsoleBase::SuspendProcessingOfPendingEvents()
-{
-    wxEventLoopBase * const loop = wxEventLoopBase::GetActive();
-
-    if (loop) loop->SuspendProcessingOfPendingEvents();
-}
-
-void wxAppConsoleBase::ResumeProcessingOfPendingEvents()
-{
-    wxEventLoopBase * const loop = wxEventLoopBase::GetActive();
-
-    if (loop) loop->ResumeProcessingOfPendingEvents();
-}
-
-void wxAppConsoleBase::ProcessPendingEvents()
-{
-    wxEventLoopBase * const loop = wxEventLoopBase::GetActive();
-
-    if (loop) loop->ProcessPendingEvents();
-}
-
 bool wxAppConsoleBase::Yield(bool onlyIfNeeded)
 {
     wxEventLoopBase * const loop = wxEventLoopBase::GetActive();
@@ -379,6 +351,117 @@ int wxAppConsoleBase::FilterEvent(wxEvent& WXUNUSED(event))
     return -1;
 }
 
+void wxAppConsoleBase::DelayPendingEventHandler(wxEvtHandler* toDelay)
+{
+    wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker);
+
+    // move the handler from the list of handlers with processable pending events
+    // to the list of handlers with pending events which needs to be processed later
+    m_handlersWithPendingEvents.Remove(toDelay);
+
+    if (m_handlersWithPendingDelayedEvents.Index(toDelay) == wxNOT_FOUND)
+        m_handlersWithPendingDelayedEvents.Add(toDelay);
+
+    wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker);
+}
+
+void wxAppConsoleBase::RemovePendingEventHandler(wxEvtHandler* toRemove)
+{
+    wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker);
+
+    if (m_handlersWithPendingEvents.Index(toRemove) != wxNOT_FOUND)
+    {
+        m_handlersWithPendingEvents.Remove(toRemove);
+
+        // check that the handler was present only once in the list
+        wxASSERT_MSG( m_handlersWithPendingEvents.Index(toRemove) == wxNOT_FOUND,
+                        "Handler occurs twice in the m_handlersWithPendingEvents list!" );
+    }
+    //else: it wasn't in this list at all, it's ok
+
+    if (m_handlersWithPendingDelayedEvents.Index(toRemove) != wxNOT_FOUND)
+    {
+        m_handlersWithPendingDelayedEvents.Remove(toRemove);
+
+        // check that the handler was present only once in the list
+        wxASSERT_MSG( m_handlersWithPendingDelayedEvents.Index(toRemove) == wxNOT_FOUND,
+                        "Handler occurs twice in m_handlersWithPendingDelayedEvents list!" );
+    }
+    //else: it wasn't in this list at all, it's ok
+
+    wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker);
+}
+
+void wxAppConsoleBase::AppendPendingEventHandler(wxEvtHandler* toAppend)
+{
+    wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker);
+
+    if ( m_handlersWithPendingEvents.Index(toAppend) == wxNOT_FOUND )
+        m_handlersWithPendingEvents.Add(toAppend);
+
+    wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker);
+}
+
+bool wxAppConsoleBase::HasPendingEvents() const
+{
+    wxENTER_CRIT_SECT(const_cast<wxAppConsoleBase*>(this)->m_handlersWithPendingEventsLocker);
+
+    bool has = !m_handlersWithPendingEvents.IsEmpty();
+
+    wxLEAVE_CRIT_SECT(const_cast<wxAppConsoleBase*>(this)->m_handlersWithPendingEventsLocker);
+
+    return has;
+}
+
+void wxAppConsoleBase::SuspendProcessingOfPendingEvents()
+{
+    wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker);
+        // entering the critical section locks blocks calls to ProcessPendingEvents()
+}
+
+void wxAppConsoleBase::ResumeProcessingOfPendingEvents()
+{
+    wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker);
+}
+
+void wxAppConsoleBase::ProcessPendingEvents()
+{
+    wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker);
+
+    wxCHECK_RET( m_handlersWithPendingDelayedEvents.IsEmpty(),
+                 "this helper list should be empty" );
+
+    // iterate until the list becomes empty: the handlers remove themselves
+    // from it when they don't have any more pending events
+    while (!m_handlersWithPendingEvents.IsEmpty())
+    {
+        // In ProcessPendingEvents(), new handlers might be added
+        // and we can safely leave the critical section here.
+        wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker);
+
+        // NOTE: we always call ProcessPendingEvents() on the first event handler
+        //       with pending events because handlers auto-remove themselves
+        //       from this list (see RemovePendingEventHandler) if they have no
+        //       more pending events.
+        m_handlersWithPendingEvents[0]->ProcessPendingEvents();
+
+        wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker);
+    }
+
+    // now the wxHandlersWithPendingEvents is surely empty; however some event
+    // handlers may have moved themselves into wxHandlersWithPendingDelayedEvents
+    // because of a selective wxYield call in progress.
+    // Now we need to move them back to wxHandlersWithPendingEvents so the next
+    // call to this function has the chance of processing them:
+    if (!m_handlersWithPendingDelayedEvents.IsEmpty())
+    {
+        WX_APPEND_ARRAY(m_handlersWithPendingEvents, m_handlersWithPendingDelayedEvents);
+        m_handlersWithPendingDelayedEvents.Clear();
+    }
+
+    wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker);
+}
+
 // ----------------------------------------------------------------------------
 // exception handling
 // ----------------------------------------------------------------------------
index af8b2ac1b2038cf41c96e046f7cb407c0aa23d23..7118b7dbd9697166ea770f42424b775862e79f35 100644 (file)
@@ -402,10 +402,9 @@ wxEvent& wxEvent::operator=(const wxEvent& src)
 
 #if wxUSE_GUI
 
-/*
- * Command events
- *
- */
+// ----------------------------------------------------------------------------
+// wxCommandEvent
+// ----------------------------------------------------------------------------
 
 #ifdef __VISUALC__
     // 'this' : used in base member initializer list (for m_commandString)
@@ -447,9 +446,9 @@ wxString wxCommandEvent::GetString() const
     }
 }
 
-/*
- * UI update events
- */
+// ----------------------------------------------------------------------------
+// wxUpdateUIEvent
+// ----------------------------------------------------------------------------
 
 #if wxUSE_LONGLONG
 wxLongLong wxUpdateUIEvent::sm_lastUpdate = 0;
@@ -506,9 +505,9 @@ void wxUpdateUIEvent::ResetUpdateTime()
 #endif
 }
 
-/*
- * Scroll events
- */
+// ----------------------------------------------------------------------------
+// wxScrollEvent
+// ----------------------------------------------------------------------------
 
 wxScrollEvent::wxScrollEvent(wxEventType commandType,
                              int id,
@@ -520,9 +519,9 @@ wxScrollEvent::wxScrollEvent(wxEventType commandType,
     m_commandInt = pos;
 }
 
-/*
- * ScrollWin events
- */
+// ----------------------------------------------------------------------------
+// wxScrollWinEvent
+// ----------------------------------------------------------------------------
 
 wxScrollWinEvent::wxScrollWinEvent(wxEventType commandType,
                                    int pos,
@@ -533,10 +532,9 @@ wxScrollWinEvent::wxScrollWinEvent(wxEventType commandType,
     m_commandInt = pos;
 }
 
-/*
- * Mouse events
- *
- */
+// ----------------------------------------------------------------------------
+// wxMouseEvent
+// ----------------------------------------------------------------------------
 
 wxMouseEvent::wxMouseEvent(wxEventType commandType)
 {
@@ -751,11 +749,9 @@ wxPoint wxMouseEvent::GetLogicalPosition(const wxDC& dc) const
     return pt;
 }
 
-
-/*
- * Keyboard event
- *
- */
+// ----------------------------------------------------------------------------
+// wxKeyEvent
+// ----------------------------------------------------------------------------
 
 wxKeyEvent::wxKeyEvent(wxEventType type)
 {
@@ -782,18 +778,30 @@ wxKeyEvent::wxKeyEvent(const wxKeyEvent& evt)
 #endif
 }
 
+// ----------------------------------------------------------------------------
+// wxWindowCreateEvent
+// ----------------------------------------------------------------------------
+
 wxWindowCreateEvent::wxWindowCreateEvent(wxWindow *win)
 {
     SetEventType(wxEVT_CREATE);
     SetEventObject(win);
 }
 
+// ----------------------------------------------------------------------------
+// wxWindowDestroyEvent
+// ----------------------------------------------------------------------------
+
 wxWindowDestroyEvent::wxWindowDestroyEvent(wxWindow *win)
 {
     SetEventType(wxEVT_DESTROY);
     SetEventObject(win);
 }
 
+// ----------------------------------------------------------------------------
+// wxChildFocusEvent
+// ----------------------------------------------------------------------------
+
 wxChildFocusEvent::wxChildFocusEvent(wxWindow *win)
                  : wxCommandEvent(wxEVT_CHILD_FOCUS)
 {
@@ -1076,9 +1084,8 @@ wxEvtHandler::~wxEvtHandler()
     delete m_pendingEvents;
 
     // Remove us from the list of the pending events if necessary.
-    wxEventLoopBase *loop = wxEventLoopBase::GetActive();
-    if (loop)
-        loop->RemovePendingEventHandler(this);
+    if (wxTheApp)
+        wxTheApp->RemovePendingEventHandler(this);
 
     // we only delete object data, not untyped
     if ( m_clientDataType == wxClientData_Object )
@@ -1124,12 +1131,11 @@ void wxEvtHandler::QueueEvent(wxEvent *event)
 {
     wxCHECK_RET( event, "NULL event can't be posted" );
 
-    wxEventLoopBase* loop = wxEventLoopBase::GetActive();
-    if (!loop)
+    if (!wxTheApp)
     {
         // we need an event loop which manages the list of event handlers with
         // pending events... cannot proceed without it!
-        wxLogDebug("No event loop is running! Cannot queue this event!");
+        wxLogDebug("No application object! Cannot queue this event!");
 
         // anyway delete the given event to avoid memory leaks
         delete event;
@@ -1148,7 +1154,7 @@ void wxEvtHandler::QueueEvent(wxEvent *event)
     // 2) Add this event handler to list of event handlers that
     //    have pending events.
 
-    loop->AppendPendingEventHandler(this);
+    wxTheApp->AppendPendingEventHandler(this);
 
     // only release m_pendingEventsLock now because otherwise there is a race
     // condition as described in the ticket #9093: we could process the event
@@ -1165,12 +1171,11 @@ void wxEvtHandler::QueueEvent(wxEvent *event)
 
 void wxEvtHandler::ProcessPendingEvents()
 {
-    wxEventLoopBase* loop = wxEventLoopBase::GetActive();
-    if (!loop)
+    if (!wxTheApp)
     {
         // we need an event loop which manages the list of event handlers with
         // pending events... cannot proceed without it!
-        wxLogDebug("No event loop is running! Cannot process pending events!");
+        wxLogDebug("No application object! Cannot process pending events!");
         return;
     }
 
@@ -1201,7 +1206,7 @@ void wxEvtHandler::ProcessPendingEvents()
         if (!node)
         {
             // all our events are NOT processable now... signal this:
-            loop->DelayPendingEventHandler(this);
+            wxTheApp->DelayPendingEventHandler(this);
 
             // see the comment at the beginning of evtloop.h header for the
             // logic behind YieldFor() and behind DelayPendingEventHandler()
@@ -1223,7 +1228,7 @@ void wxEvtHandler::ProcessPendingEvents()
     {
         // if there are no more pending events left, we don't need to
         // stay in this list
-        loop->RemovePendingEventHandler(this);
+        wxTheApp->RemovePendingEventHandler(this);
     }
 
     wxLEAVE_CRIT_SECT( m_pendingEventsLock );
@@ -1235,13 +1240,10 @@ void wxEvtHandler::ProcessPendingEvents()
     // of this object any more
 }
 
-/*
- * Event table stuff
- */
-/* static */ bool
-wxEvtHandler::ProcessEventIfMatchesId(const wxEventTableEntryBase& entry,
-                                      wxEvtHandler *handler,
-                                      wxEvent& event)
+/* static */
+bool wxEvtHandler::ProcessEventIfMatchesId(const wxEventTableEntryBase& entry,
+                                           wxEvtHandler *handler,
+                                           wxEvent& event)
 {
     int tableId1 = entry.m_id,
         tableId2 = entry.m_lastId;
@@ -1412,7 +1414,6 @@ bool wxEvtHandler::SafelyProcessEvent(wxEvent& event)
 #endif // wxUSE_EXCEPTIONS
 }
 
-
 bool wxEvtHandler::SearchEventTable(wxEventTable& table, wxEvent& event)
 {
     const wxEventType eventType = event.GetEventType();
index 863946f59db59b75f87ae23331cded03f02e06ad..15813725a8843c9374f707529074942df0cc27a9 100644 (file)
@@ -56,116 +56,6 @@ void wxEventLoopBase::OnExit()
         wxTheApp->OnEventLoopExit(this);
 }
 
-void wxEventLoopBase::DelayPendingEventHandler(wxEvtHandler* toDelay)
-{
-    wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker);
-
-    // move the handler from the list of handlers with processable pending events
-    // to the list of handlers with pending events which needs to be processed later
-    m_handlersWithPendingEvents.Remove(toDelay);
-
-    if (m_handlersWithPendingDelayedEvents.Index(toDelay) == wxNOT_FOUND)
-        m_handlersWithPendingDelayedEvents.Add(toDelay);
-
-    wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker);
-}
-
-void wxEventLoopBase::RemovePendingEventHandler(wxEvtHandler* toRemove)
-{
-    wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker);
-
-    if (m_handlersWithPendingEvents.Index(toRemove) != wxNOT_FOUND)
-    {
-        m_handlersWithPendingEvents.Remove(toRemove);
-
-        // check that the handler was present only once in the list
-        wxASSERT_MSG( m_handlersWithPendingEvents.Index(toRemove) == wxNOT_FOUND,
-                        "Handler occurs twice in the m_handlersWithPendingEvents list!" );
-    }
-    //else: it wasn't in this list at all, it's ok
-
-    if (m_handlersWithPendingDelayedEvents.Index(toRemove) != wxNOT_FOUND)
-    {
-        m_handlersWithPendingDelayedEvents.Remove(toRemove);
-
-        // check that the handler was present only once in the list
-        wxASSERT_MSG( m_handlersWithPendingDelayedEvents.Index(toRemove) == wxNOT_FOUND,
-                        "Handler occurs twice in m_handlersWithPendingDelayedEvents list!" );
-    }
-    //else: it wasn't in this list at all, it's ok
-
-    wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker);
-}
-
-void wxEventLoopBase::AppendPendingEventHandler(wxEvtHandler* toAppend)
-{
-    wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker);
-
-    if ( m_handlersWithPendingEvents.Index(toAppend) == wxNOT_FOUND )
-        m_handlersWithPendingEvents.Add(toAppend);
-
-    wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker);
-}
-
-bool wxEventLoopBase::HasPendingEvents() const
-{
-    wxENTER_CRIT_SECT(const_cast<wxEventLoopBase*>(this)->m_handlersWithPendingEventsLocker);
-
-    bool has = !m_handlersWithPendingEvents.IsEmpty();
-
-    wxLEAVE_CRIT_SECT(const_cast<wxEventLoopBase*>(this)->m_handlersWithPendingEventsLocker);
-
-    return has;
-}
-
-void wxEventLoopBase::SuspendProcessingOfPendingEvents()
-{
-    wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker);
-}
-
-void wxEventLoopBase::ResumeProcessingOfPendingEvents()
-{
-    wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker);
-}
-
-void wxEventLoopBase::ProcessPendingEvents()
-{
-    wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker);
-
-    wxCHECK_RET( m_handlersWithPendingDelayedEvents.IsEmpty(),
-                 "this helper list should be empty" );
-
-    // iterate until the list becomes empty: the handlers remove themselves
-    // from it when they don't have any more pending events
-    while (!m_handlersWithPendingEvents.IsEmpty())
-    {
-        // In ProcessPendingEvents(), new handlers might be added
-        // and we can safely leave the critical section here.
-        wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker);
-
-        // NOTE: we always call ProcessPendingEvents() on the first event handler
-        //       with pending events because handlers auto-remove themselves
-        //       from this list (see RemovePendingEventHandler) if they have no
-        //       more pending events.
-        m_handlersWithPendingEvents[0]->ProcessPendingEvents();
-
-        wxENTER_CRIT_SECT(m_handlersWithPendingEventsLocker);
-    }
-
-    // now the wxHandlersWithPendingEvents is surely empty; however some event
-    // handlers may have moved themselves into wxHandlersWithPendingDelayedEvents
-    // because of a selective wxYield call in progress.
-    // Now we need to move them back to wxHandlersWithPendingEvents so the next
-    // call to this function has the chance of processing them:
-    if (!m_handlersWithPendingDelayedEvents.IsEmpty())
-    {
-        WX_APPEND_ARRAY(m_handlersWithPendingEvents, m_handlersWithPendingDelayedEvents);
-        m_handlersWithPendingDelayedEvents.Clear();
-    }
-
-    wxLEAVE_CRIT_SECT(m_handlersWithPendingEventsLocker);
-}
-
 void wxEventLoopBase::WakeUpIdle()
 {
     WakeUp();
@@ -173,13 +63,17 @@ void wxEventLoopBase::WakeUpIdle()
 
 bool wxEventLoopBase::ProcessIdle()
 {
+    if (!wxTheApp)
+        return false;
+
     // process pending wx events before sending idle events
-    ProcessPendingEvents();
+    wxTheApp->ProcessPendingEvents();
 
+    // synthetize an idle event and send it to wxApp
     wxIdleEvent event;
-
     event.SetEventObject(wxTheApp);
     wxTheApp->ProcessEvent(event);
+
     return event.MoreRequested();
 }