summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorAndrew Knight <andrew.knight@digia.com>2014-02-10 10:11:18 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-02-12 20:12:17 +0100
commit2eda13c965497e41bb2d031f7890979a819d6438 (patch)
tree0a1335f9345a2c95af030fea5aa767e31af29d2c /src/corelib/kernel
parent2b66a37a3e9b6528d5e398a2c1dad4611a38e1b4 (diff)
WinRT: move most of GUI event dispatcher logic into core
The native event dispatcher is responsible for delivering callbacks to non-GUI handlers, such as network socket listeners. So, the non-GUI logic is moved into the core dispatcher so that the event loop works better for apps (and test cases) which use QCoreApplication. Change-Id: Ic5f7d939cf164198fd39aa5880e265ae560b39b4 Reviewed-by: Oliver Wolff <oliver.wolff@digia.com>
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt.cpp69
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt_p.h1
2 files changed, 62 insertions, 8 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp
index cd843a4986..8b2dd2ef6d 100644
--- a/src/corelib/kernel/qeventdispatcher_winrt.cpp
+++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp
@@ -44,18 +44,19 @@
#include <QtCore/QCoreApplication>
#include <QtCore/QThread>
#include <QtCore/QHash>
-
-#include <private/qcoreapplication_p.h>
-#include <private/qthread_p.h>
#include <private/qabstracteventdispatcher_p.h>
#include <wrl.h>
#include <windows.foundation.h>
#include <windows.system.threading.h>
+#include <windows.ui.core.h>
+#include <windows.applicationmodel.core.h>
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::System::Threading;
using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::UI::Core;
+using namespace ABI::Windows::ApplicationModel::Core;
QT_BEGIN_NAMESPACE
@@ -92,7 +93,6 @@ public:
void unregisterTimer(WinRTTimerInfo *t);
void sendTimerEvent(int timerId);
-
private:
static HRESULT timerExpiredCallback(IThreadPoolTimer *timer);
@@ -100,11 +100,33 @@ private:
QHash<IThreadPoolTimer *, int> timerIds;
ComPtr<IThreadPoolTimerStatics> timerFactory;
+ ComPtr<ICoreDispatcher> coreDispatcher;
+
+ bool interrupt;
};
QEventDispatcherWinRT::QEventDispatcherWinRT(QObject *parent)
: QAbstractEventDispatcher(*new QEventDispatcherWinRTPrivate, parent)
{
+ Q_D(QEventDispatcherWinRT);
+ ComPtr<ICoreApplication> application;
+ HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
+ IID_PPV_ARGS(&application));
+ if (SUCCEEDED(hr)) {
+ ComPtr<ICoreApplicationView> view;
+ hr = application->GetCurrentView(&view);
+ if (SUCCEEDED(hr)) {
+ ComPtr<ICoreWindow> window;
+ hr = view->get_CoreWindow(&window);
+ if (SUCCEEDED(hr)) {
+ hr = window->get_Dispatcher(&d->coreDispatcher);
+ if (SUCCEEDED(hr))
+ return;
+ }
+ }
+ }
+ qCritical("QEventDispatcherWinRT: Unable to capture the core dispatcher. %s",
+ qPrintable(qt_error_string(hr)));
}
QEventDispatcherWinRT::QEventDispatcherWinRT(QEventDispatcherWinRTPrivate &dd, QObject *parent)
@@ -117,12 +139,40 @@ QEventDispatcherWinRT::~QEventDispatcherWinRT()
bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
{
- Q_UNUSED(flags);
+ Q_D(QEventDispatcherWinRT);
- // we are awake, broadcast it
- emit awake();
- QCoreApplicationPrivate::sendPostedEvents(0, 0, QThreadData::current());
+ bool didProcess = false;
+ forever {
+ // Process native events
+ if (d->coreDispatcher)
+ d->coreDispatcher->ProcessEvents(CoreProcessEventsOption_ProcessAllIfPresent);
+
+ // Dispatch accumulated user events
+ didProcess = sendPostedEvents(flags);
+ if (didProcess)
+ break;
+
+ if (d->interrupt)
+ break;
+
+ // Short sleep if there is nothing to do
+ if (flags & QEventLoop::WaitForMoreEvents) {
+ emit aboutToBlock();
+ WaitForSingleObjectEx(GetCurrentThread(), 1, FALSE);
+ emit awake();
+ }
+ }
+ d->interrupt = false;
+ return didProcess;
+}
+bool QEventDispatcherWinRT::sendPostedEvents(QEventLoop::ProcessEventsFlags flags)
+{
+ Q_UNUSED(flags);
+ if (hasPendingEvents()) {
+ QCoreApplication::sendPostedEvents();
+ return true;
+ }
return false;
}
@@ -268,6 +318,8 @@ void QEventDispatcherWinRT::wakeUp()
void QEventDispatcherWinRT::interrupt()
{
+ Q_D(QEventDispatcherWinRT);
+ d->interrupt = true;
}
void QEventDispatcherWinRT::flush()
@@ -318,6 +370,7 @@ bool QEventDispatcherWinRT::event(QEvent *e)
}
QEventDispatcherWinRTPrivate::QEventDispatcherWinRTPrivate()
+ : interrupt(false)
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_System_Threading_ThreadPoolTimer).Get(), &timerFactory);
diff --git a/src/corelib/kernel/qeventdispatcher_winrt_p.h b/src/corelib/kernel/qeventdispatcher_winrt_p.h
index 0631b2ea33..5cc37fb538 100644
--- a/src/corelib/kernel/qeventdispatcher_winrt_p.h
+++ b/src/corelib/kernel/qeventdispatcher_winrt_p.h
@@ -99,6 +99,7 @@ public:
protected:
QEventDispatcherWinRT(QEventDispatcherWinRTPrivate &dd, QObject *parent = 0);
+ virtual bool sendPostedEvents(QEventLoop::ProcessEventsFlags flags);
bool event(QEvent *);
int activateTimers();
};