From 26bacb82ff3191f5807b0602036899bf13f1ed36 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin <vadim@wxwidgets.org> Date: Mon, 20 Jul 2009 12:14:42 +0000 Subject: [PATCH] Dispatch pending events without waiting for idle time (closes #10994). git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61470 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/evtloop.h | 6 ++++++ src/common/appbase.cpp | 3 --- src/common/evtloopcmn.cpp | 28 ++++++++++++++++++++++------ src/gtk/app.cpp | 2 ++ 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/include/wx/evtloop.h b/include/wx/evtloop.h index ad58b1482c..7bef1f38dd 100644 --- a/include/wx/evtloop.h +++ b/include/wx/evtloop.h @@ -197,6 +197,12 @@ protected: bool m_shouldExit; private: + // process all already pending events and dispatch a new one (blocking + // until it appears in the event queue if necessary) + // + // returns the return value of Dispatch() + bool ProcessEvents(); + wxDECLARE_NO_COPY_CLASS(wxEventLoopManual); }; diff --git a/src/common/appbase.cpp b/src/common/appbase.cpp index 936d8d21b5..888c6828f7 100644 --- a/src/common/appbase.cpp +++ b/src/common/appbase.cpp @@ -333,9 +333,6 @@ void wxAppConsoleBase::WakeUpIdle() bool wxAppConsoleBase::ProcessIdle() { - // process pending wx events before sending idle events - ProcessPendingEvents(); - // synthesize an idle event and check if more of them are needed wxIdleEvent event; event.SetEventObject(this); diff --git a/src/common/evtloopcmn.cpp b/src/common/evtloopcmn.cpp index f4adbbed10..a7ce28dc6c 100644 --- a/src/common/evtloopcmn.cpp +++ b/src/common/evtloopcmn.cpp @@ -94,18 +94,33 @@ wxEventLoopManual::wxEventLoopManual() m_shouldExit = false; } +bool wxEventLoopManual::ProcessEvents() +{ + // process pending wx events first as they correspond to low-level events + // which happened before, i.e. typically pending events were queued by a + // previous call to Dispatch() and if we didn't process them now the next + // call to it might enqueue them again (as happens with e.g. socket events + // which would be generated as long as there is input available on socket + // and this input is only removed from it when pending event handlers are + // executed) + if ( wxTheApp ) + wxTheApp->ProcessPendingEvents(); + + return Dispatch(); +} + int wxEventLoopManual::Run() { // event loops are not recursive, you need to create another loop! wxCHECK_MSG( !IsRunning(), -1, _T("can't reenter a message loop") ); - // ProcessIdle() and Dispatch() below may throw so the code here should + // ProcessIdle() and ProcessEvents() below may throw so the code here should // be exception-safe, hence we must use local objects for all actions we // should undo wxEventLoopActivator activate(this); // we must ensure that OnExit() is called even if an exception is thrown - // from inside Dispatch() but we must call it from Exit() in normal + // from inside ProcessEvents() but we must call it from Exit() in normal // situations because it is supposed to be called synchronously, // wxModalEventLoop depends on this (so we can't just use ON_BLOCK_EXIT or // something similar here) @@ -133,14 +148,15 @@ int wxEventLoopManual::Run() if ( m_shouldExit ) { while ( Pending() ) - Dispatch(); + ProcessEvents(); break; } - // a message came or no more idle processing to do, sit in - // Dispatch() waiting for the next message - if ( !Dispatch() ) + // a message came or no more idle processing to do, dispatch + // all the pending events and call Dispatch() to wait for the + // next message + if ( !ProcessEvents() ) { // we got WM_QUIT break; diff --git a/src/gtk/app.cpp b/src/gtk/app.cpp index c349227bce..c510079d6e 100644 --- a/src/gtk/app.cpp +++ b/src/gtk/app.cpp @@ -127,6 +127,8 @@ bool wxApp::DoIdle() gdk_threads_enter(); bool needMore; do { + ProcessPendingEvents(); + needMore = ProcessIdle(); } while (needMore && gtk_events_pending() == 0); gdk_threads_leave(); -- 2.47.2