From dd62c82d304588bbbf0fe75a955aa38915049f76 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Mon, 21 Jan 2019 14:42:07 +0000 Subject: [PATCH 1/4] Remove event filter on destruction --- src/qt/evtloop.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/evtloop.cpp b/src/qt/evtloop.cpp index 2cb13ba0f6..ce99d051d0 100644 --- a/src/qt/evtloop.cpp +++ b/src/qt/evtloop.cpp @@ -82,6 +82,7 @@ wxQtEventLoopBase::wxQtEventLoopBase() wxQtEventLoopBase::~wxQtEventLoopBase() { + qApp->removeEventFilter(m_qtIdleTimer); delete m_qtIdleTimer; } From 278f4fa1d66640e6c3b61b46add30c68235646fd Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Mon, 21 Jan 2019 14:48:37 +0000 Subject: [PATCH 2/4] Add wxOVERRIDE to overriden methods --- include/wx/qt/evtloop.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/wx/qt/evtloop.h b/include/wx/qt/evtloop.h index 25ea24a8dc..d8d73576da 100644 --- a/include/wx/qt/evtloop.h +++ b/include/wx/qt/evtloop.h @@ -16,13 +16,13 @@ public: wxQtEventLoopBase(); ~wxQtEventLoopBase(); - virtual int DoRun(); - virtual void ScheduleExit(int rc = 0); - virtual bool Pending() const; - virtual bool Dispatch(); - virtual int DispatchTimeout(unsigned long timeout); - virtual void WakeUp(); - virtual void DoYieldFor(long eventsToProcess); + virtual int DoRun() wxOVERRIDE; + virtual void ScheduleExit(int rc = 0) wxOVERRIDE; + virtual bool Pending() const wxOVERRIDE; + virtual bool Dispatch() wxOVERRIDE; + virtual int DispatchTimeout(unsigned long timeout) wxOVERRIDE; + virtual void WakeUp() wxOVERRIDE; + virtual void DoYieldFor(long eventsToProcess) wxOVERRIDE; #if wxUSE_EVENTLOOP_SOURCE virtual wxEventLoopSource *AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags); From 7fa7fd1bebb681e3edb76e3042b52d303eae372c Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Mon, 21 Jan 2019 14:53:43 +0000 Subject: [PATCH 3/4] Don't generate idle events when the event loop is not running --- include/wx/qt/evtloop.h | 2 ++ src/qt/evtloop.cpp | 11 ++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/wx/qt/evtloop.h b/include/wx/qt/evtloop.h index d8d73576da..bb725e63d8 100644 --- a/include/wx/qt/evtloop.h +++ b/include/wx/qt/evtloop.h @@ -24,6 +24,8 @@ public: virtual void WakeUp() wxOVERRIDE; virtual void DoYieldFor(long eventsToProcess) wxOVERRIDE; + void ScheduleIdleCheck(); + #if wxUSE_EVENTLOOP_SOURCE virtual wxEventLoopSource *AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags); #endif // wxUSE_EVENTLOOP_SOURCE diff --git a/src/qt/evtloop.cpp b/src/qt/evtloop.cpp index ce99d051d0..3a6bd2e6b7 100644 --- a/src/qt/evtloop.cpp +++ b/src/qt/evtloop.cpp @@ -40,14 +40,13 @@ wxQtIdleTimer::wxQtIdleTimer( wxQtEventLoopBase *eventLoop ) connect( this, &QTimer::timeout, this, &wxQtIdleTimer::idle ); setSingleShot( true ); - start( 0 ); } bool wxQtIdleTimer::eventFilter( QObject *WXUNUSED( watched ), QEvent *WXUNUSED( event ) ) { // Called for each Qt event, start with timeout 0 (run as soon as idle) if ( !isActive() ) - start( 0 ); + m_eventLoop->ScheduleIdleCheck(); return false; // Continue handling the event } @@ -60,7 +59,7 @@ void wxQtIdleTimer::idle() // Send idle event if ( m_eventLoop->ProcessIdle() ) - start( 0 ); + m_eventLoop->ScheduleIdleCheck(); } wxQtEventLoopBase::wxQtEventLoopBase() @@ -147,6 +146,12 @@ void wxQtEventLoopBase::DoYieldFor(long eventsToProcess) wxEventLoopBase::DoYieldFor(eventsToProcess); } +void wxQtEventLoopBase::ScheduleIdleCheck() +{ + if ( IsInsideRun() ) + m_qtIdleTimer->start(0); +} + #if wxUSE_EVENTLOOP_SOURCE template From 8a73f652851178cb99ecc9d9bcdf6b226f9f7033 Mon Sep 17 00:00:00 2001 From: Graham Dawes Date: Mon, 21 Jan 2019 16:11:28 +0000 Subject: [PATCH 4/4] Use QEventLoop to implement wxEventLoop for wxQT --- include/wx/qt/evtloop.h | 2 ++ src/qt/evtloop.cpp | 32 ++++++++++++-------------------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/include/wx/qt/evtloop.h b/include/wx/qt/evtloop.h index bb725e63d8..dbdbd6a5a0 100644 --- a/include/wx/qt/evtloop.h +++ b/include/wx/qt/evtloop.h @@ -9,6 +9,7 @@ #define _WX_QT_EVTLOOP_H_ class QTimer; +class QEventLoop; class WXDLLIMPEXP_CORE wxQtEventLoopBase : public wxEventLoopBase { @@ -32,6 +33,7 @@ public: protected: private: + QEventLoop *m_qtEventLoop; QTimer *m_qtIdleTimer; wxDECLARE_NO_COPY_CLASS(wxQtEventLoopBase); diff --git a/src/qt/evtloop.cpp b/src/qt/evtloop.cpp index 3a6bd2e6b7..132d6533c2 100644 --- a/src/qt/evtloop.cpp +++ b/src/qt/evtloop.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -56,7 +57,7 @@ void wxQtIdleTimer::idle() // Process pending events if ( wxTheApp ) wxTheApp->ProcessPendingEvents(); - + // Send idle event if ( m_eventLoop->ProcessIdle() ) m_eventLoop->ScheduleIdleCheck(); @@ -77,11 +78,15 @@ wxQtEventLoopBase::wxQtEventLoopBase() // Pass all events to the idle timer, so it can be restarted each time // an event is received qApp->installEventFilter( m_qtIdleTimer ); + + + m_qtEventLoop = new QEventLoop; } wxQtEventLoopBase::~wxQtEventLoopBase() { qApp->removeEventFilter(m_qtIdleTimer); + delete m_qtEventLoop; delete m_qtIdleTimer; } @@ -89,44 +94,31 @@ void wxQtEventLoopBase::ScheduleExit(int rc) { wxCHECK_RET( IsInsideRun(), wxT("can't call ScheduleExit() if not started") ); m_shouldExit = true; - QCoreApplication::exit( rc ); + m_qtEventLoop->exit(rc); } int wxQtEventLoopBase::DoRun() { - int ret; - - // This is placed inside of a loop to take into account nested event loops - while ( !m_shouldExit ) - { - // This will print Qt warnins if app already started: - // "QCoreApplication::exec: The event loop is already running" - // TODO: check the loopLevel (nested) like in wxGTK - ret = QCoreApplication::exec(); - // process pending events (if exec was started previously) - // TODO: use a real new QEventLoop() ? - QCoreApplication::processEvents(); - } + const int ret = m_qtEventLoop->exec(); OnExit(); return ret; } bool wxQtEventLoopBase::Pending() const { - return QCoreApplication::hasPendingEvents(); + QAbstractEventDispatcher *instance = QAbstractEventDispatcher::instance(); + return instance->hasPendingEvents(); } bool wxQtEventLoopBase::Dispatch() { - QCoreApplication::processEvents(); - + m_qtEventLoop->processEvents(); return true; } int wxQtEventLoopBase::DispatchTimeout(unsigned long timeout) { - QCoreApplication::processEvents( QEventLoop::AllEvents, timeout ); - + m_qtEventLoop->processEvents(QEventLoop::AllEvents, timeout); return true; }