WinRT: Improve event dispatcher
- Sleep when there are no events to process. Otherwise, CPU usage remains high all the time. - Reorder processing so window events are processed after being collected by the native event loop. - Provide basic interrupt and WaitForMoreEvents flag support. Task-number: QTBUG-35327 Change-Id: I8a5545cba5f3e65eafd0bb40695bf6ffde68bb04 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com> Reviewed-by: Oliver Wolff <oliver.wolff@digia.com>bb10
parent
ae56140b50
commit
153f82390d
|
|
@ -52,12 +52,14 @@
|
|||
using namespace ABI::Windows::ApplicationModel::Core;
|
||||
using namespace ABI::Windows::UI::Core;
|
||||
using namespace ABI::Windows::Foundation;
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QWinRTEventDispatcher::QWinRTEventDispatcher(ICoreDispatcher *dispatcher, QObject *parent)
|
||||
: QEventDispatcherWinRT(parent)
|
||||
, m_dispatcher(dispatcher)
|
||||
, m_interrupt(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -66,14 +68,38 @@ bool QWinRTEventDispatcher::hasPendingEvents()
|
|||
return QEventDispatcherWinRT::hasPendingEvents() || QWindowSystemInterface::windowSystemEventsQueued();
|
||||
}
|
||||
|
||||
void QWinRTEventDispatcher::interrupt()
|
||||
{
|
||||
m_interrupt = true;
|
||||
}
|
||||
|
||||
bool QWinRTEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
|
||||
{
|
||||
if (m_dispatcher)
|
||||
m_dispatcher->ProcessEvents(CoreProcessEventsOption_ProcessAllIfPresent);
|
||||
bool canWait = flags & QEventLoop::WaitForMoreEvents;
|
||||
bool didProcess;
|
||||
m_interrupt = false;
|
||||
do {
|
||||
// Send Qt events
|
||||
didProcess = QEventDispatcherWinRT::processEvents(flags);
|
||||
|
||||
const bool didProcess = QWindowSystemInterface::sendWindowSystemEvents(flags);
|
||||
// Process system events
|
||||
emit aboutToBlock();
|
||||
if (m_dispatcher)
|
||||
m_dispatcher->ProcessEvents(CoreProcessEventsOption_ProcessAllIfPresent);
|
||||
emit awake();
|
||||
|
||||
return QEventDispatcherWinRT::processEvents(flags & ~QEventLoop::WaitForMoreEvents) || didProcess;
|
||||
// Dispatch accumulated user events
|
||||
didProcess |= QWindowSystemInterface::sendWindowSystemEvents(flags);
|
||||
canWait = canWait && !didProcess && !m_interrupt;
|
||||
|
||||
// Short sleep if there is nothing to do
|
||||
if (canWait) {
|
||||
emit aboutToBlock();
|
||||
WaitForSingleObjectEx(GetCurrentThread(), 1, true);
|
||||
emit awake();
|
||||
}
|
||||
} while (canWait);
|
||||
return didProcess;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -42,11 +42,10 @@
|
|||
#ifndef QWINRTEVENTDISPATCHER_H
|
||||
#define QWINRTEVENTDISPATCHER_H
|
||||
|
||||
#include <QtCore/QAbstractEventDispatcher>
|
||||
#include <QtCore/QEvent>
|
||||
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <wrl.h>
|
||||
|
||||
namespace ABI {
|
||||
namespace Windows {
|
||||
namespace UI {
|
||||
|
|
@ -66,11 +65,13 @@ public:
|
|||
explicit QWinRTEventDispatcher(ABI::Windows::UI::Core::ICoreDispatcher *dispatcher, QObject *parent = 0);
|
||||
|
||||
protected:
|
||||
void interrupt();
|
||||
bool hasPendingEvents();
|
||||
bool processEvents(QEventLoop::ProcessEventsFlags flags);
|
||||
|
||||
private:
|
||||
ABI::Windows::UI::Core::ICoreDispatcher *m_dispatcher;
|
||||
Microsoft::WRL::ComPtr<ABI::Windows::UI::Core::ICoreDispatcher> m_dispatcher;
|
||||
bool m_interrupt;
|
||||
|
||||
friend class QWinRTIntegration;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue