Share a single idle timer for all event loops in wxQT

This commit is contained in:
Graham Dawes
2019-01-23 13:55:20 +00:00
parent 0c28952ff6
commit 6aecaa8845

View File

@@ -21,33 +21,48 @@
#include <QtWidgets/QApplication>
class wxQtIdleTimer : public QTimer
class wxQtIdleTimer : public QTimer, public wxRefCounter
{
public:
wxQtIdleTimer( wxQtEventLoopBase *eventLoop );
wxQtIdleTimer();
~wxQtIdleTimer();
virtual bool eventFilter( QObject * watched, QEvent * event );
private:
void idle();
private:
wxQtEventLoopBase *m_eventLoop;
void ScheduleIdleCheck();
};
wxQtIdleTimer::wxQtIdleTimer( wxQtEventLoopBase *eventLoop )
wxQtIdleTimer::wxQtIdleTimer()
{
m_eventLoop = eventLoop;
// We need a QCoreApplication for event loops, create it here if it doesn't
// already exist as we can't modify wxAppConsole
if ( !QCoreApplication::instance() )
{
new QApplication(wxAppConsole::GetInstance()->argc, wxAppConsole::GetInstance()->argv);
}
// Pass all events to the idle timer, so it can be restarted each time
// an event is received
qApp->installEventFilter(this);
connect(this, &QTimer::timeout, this, &wxQtIdleTimer::idle);
setSingleShot(true);
}
wxQtIdleTimer::~wxQtIdleTimer()
{
qApp->removeEventFilter(this);
}
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() )
m_eventLoop->ScheduleIdleCheck();
ScheduleIdleCheck();
return false; // Continue handling the event
}
@@ -59,35 +74,45 @@ void wxQtIdleTimer::idle()
wxTheApp->ProcessPendingEvents();
// Send idle event
if ( m_eventLoop->ProcessIdle() )
m_eventLoop->ScheduleIdleCheck();
if (wxTheApp->ProcessIdle())
ScheduleIdleCheck();
}
namespace
{
wxQtIdleTimer *gs_idleTimer = NULL;
}
void wxQtIdleTimer::ScheduleIdleCheck()
{
wxQtEventLoopBase *eventLoop = static_cast<wxQtEventLoopBase*>(wxEventLoop::GetActive());
if ( eventLoop )
eventLoop->ScheduleIdleCheck();
}
wxQtEventLoopBase::wxQtEventLoopBase()
{
// We need a QCoreApplication for event loops, create it here if it doesn't
// already exist as we can't modify wxAppConsole
if ( !QCoreApplication::instance() )
// Create an idle timer to run each time there are no events (timeout = 0)
if ( !gs_idleTimer )
{
new QApplication( wxAppConsole::GetInstance()->argc, wxAppConsole::GetInstance()->argv );
gs_idleTimer = new wxQtIdleTimer();
}
else
{
gs_idleTimer->IncRef();
}
// Create an idle timer to run each time there are no events (timeout = 0)
m_qtIdleTimer = new wxQtIdleTimer( this );
// Pass all events to the idle timer, so it can be restarted each time
// an event is received
qApp->installEventFilter( m_qtIdleTimer );
m_qtIdleTimer = gs_idleTimer;
m_qtEventLoop = new QEventLoop;
}
wxQtEventLoopBase::~wxQtEventLoopBase()
{
qApp->removeEventFilter(m_qtIdleTimer);
if ( gs_idleTimer->GetRefCount() <= 1 )
gs_idleTimer = NULL;
delete m_qtEventLoop;
delete m_qtIdleTimer;
}
void wxQtEventLoopBase::ScheduleExit(int rc)