winrt: Handle dispatcher thread change
If the calling thread changes when processing events, the dispatcher will no longer have thread access and event processing will fail. This can e.g. prevent new threads from being created. To remedy this, the dispatcher object is re-fetched if the thread is changed. Change-Id: I519cff521f9b84211db3f28a7a28b532de44a6a4 Reviewed-by: Oliver Wolff <oliver.wolff@digia.com>
This commit is contained in:
parent
c7abf81786
commit
ed7894dd77
@ -133,6 +133,7 @@ private:
|
|||||||
|
|
||||||
ComPtr<IThreadPoolTimerStatics> timerFactory;
|
ComPtr<IThreadPoolTimerStatics> timerFactory;
|
||||||
ComPtr<ICoreDispatcher> coreDispatcher;
|
ComPtr<ICoreDispatcher> coreDispatcher;
|
||||||
|
QPointer<QThread> thread;
|
||||||
|
|
||||||
bool interrupt;
|
bool interrupt;
|
||||||
};
|
};
|
||||||
@ -140,24 +141,6 @@ private:
|
|||||||
QEventDispatcherWinRT::QEventDispatcherWinRT(QObject *parent)
|
QEventDispatcherWinRT::QEventDispatcherWinRT(QObject *parent)
|
||||||
: QAbstractEventDispatcher(*new QEventDispatcherWinRTPrivate, parent)
|
: QAbstractEventDispatcher(*new QEventDispatcherWinRTPrivate, parent)
|
||||||
{
|
{
|
||||||
Q_D(QEventDispatcherWinRT);
|
|
||||||
|
|
||||||
// Obtain the WinRT Application, view, and window
|
|
||||||
ComPtr<ICoreImmersiveApplication> application;
|
|
||||||
HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
|
|
||||||
IID_PPV_ARGS(&application));
|
|
||||||
RETURN_VOID_IF_FAILED("Failed to activate the application factory");
|
|
||||||
|
|
||||||
ComPtr<ICoreApplicationView> view;
|
|
||||||
hr = application->get_MainView(&view);
|
|
||||||
RETURN_VOID_IF_FAILED("Failed to get the main view");
|
|
||||||
|
|
||||||
ComPtr<ICoreWindow> window;
|
|
||||||
hr = view->get_CoreWindow(&window);
|
|
||||||
RETURN_VOID_IF_FAILED("Failed to get the core window");
|
|
||||||
|
|
||||||
hr = window->get_Dispatcher(&d->coreDispatcher);
|
|
||||||
RETURN_VOID_IF_FAILED("Failed to get the core dispatcher");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QEventDispatcherWinRT::QEventDispatcherWinRT(QEventDispatcherWinRTPrivate &dd, QObject *parent)
|
QEventDispatcherWinRT::QEventDispatcherWinRT(QEventDispatcherWinRTPrivate &dd, QObject *parent)
|
||||||
@ -172,6 +155,26 @@ bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
|
|||||||
{
|
{
|
||||||
Q_D(QEventDispatcherWinRT);
|
Q_D(QEventDispatcherWinRT);
|
||||||
|
|
||||||
|
if (d->thread != QThread::currentThread()) {
|
||||||
|
ComPtr<ICoreImmersiveApplication> application;
|
||||||
|
HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
|
||||||
|
IID_PPV_ARGS(&application));
|
||||||
|
RETURN_FALSE_IF_FAILED("Failed to get the application factory");
|
||||||
|
|
||||||
|
ComPtr<ICoreApplicationView> view;
|
||||||
|
hr = application->get_MainView(&view);
|
||||||
|
RETURN_FALSE_IF_FAILED("Failed to get the main view");
|
||||||
|
|
||||||
|
ComPtr<ICoreWindow> window;
|
||||||
|
hr = view->get_CoreWindow(&window);
|
||||||
|
RETURN_FALSE_IF_FAILED("Failed to get the core window");
|
||||||
|
|
||||||
|
hr = window->get_Dispatcher(&d->coreDispatcher);
|
||||||
|
RETURN_FALSE_IF_FAILED("Failed to get the core dispatcher");
|
||||||
|
|
||||||
|
d->thread = QThread::currentThread();
|
||||||
|
}
|
||||||
|
|
||||||
bool didProcess = false;
|
bool didProcess = false;
|
||||||
forever {
|
forever {
|
||||||
// Process native events
|
// Process native events
|
||||||
|
Loading…
Reference in New Issue
Block a user