summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2020-07-27 08:16:14 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2020-07-29 08:22:18 +0200
commited114b728d9dc5265333c593254d9f6527464a60 (patch)
treeb883567bb0d6e3518060b12434048dd0b467fe56 /src
parent44d4bc6d90442e1f82b8f921165360fecf3bed67 (diff)
Windows: Prevent event processing during QDesktopServices::openUrl()
The platform implementation uses the Win32 API ShellExecute(), which may spin an event loop to do COM processing, causing things like QMetaCallEvent being processed. Run it in a thread to suppress this. Pick-to: 5.15 Fixes: QTBUG-85676 Change-Id: I240ca78b41b39ded22e466662ffce8e9b03c10a2 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/windows/qwindowsservices.cpp28
1 files changed, 24 insertions, 4 deletions
diff --git a/src/plugins/platforms/windows/qwindowsservices.cpp b/src/plugins/platforms/windows/qwindowsservices.cpp
index 09ae55cd99..8a95cc53a8 100644
--- a/src/plugins/platforms/windows/qwindowsservices.cpp
+++ b/src/plugins/platforms/windows/qwindowsservices.cpp
@@ -44,6 +44,8 @@
#include <QtCore/qurl.h>
#include <QtCore/qdebug.h>
#include <QtCore/qdir.h>
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qthread.h>
#include <QtCore/private/qwinregistry_p.h>
@@ -54,15 +56,33 @@ QT_BEGIN_NAMESPACE
enum { debug = 0 };
+static quintptr runShellExecute(const wchar_t *path)
+{
+ HINSTANCE result = nullptr;
+ if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE))) {
+ result = ShellExecute(nullptr, nullptr, path, nullptr, nullptr, SW_SHOWNORMAL);
+ CoUninitialize();
+ }
+ return reinterpret_cast<quintptr>(result);
+}
+
static inline bool shellExecute(const QUrl &url)
{
const QString nativeFilePath = url.isLocalFile() && !url.hasFragment() && !url.hasQuery()
? QDir::toNativeSeparators(url.toLocalFile())
: url.toString(QUrl::FullyEncoded);
- const auto result =
- reinterpret_cast<quintptr>(ShellExecute(nullptr, nullptr,
- reinterpret_cast<const wchar_t *>(nativeFilePath.utf16()),
- nullptr, nullptr, SW_SHOWNORMAL));
+
+
+ // Run ShellExecute() in a thread since it may spin the event loop.
+ // Prevent it from interfering with processing of posted events (QTBUG-85676).
+ quintptr result = 0;
+ quintptr *resultPtr = &result;
+ const auto path = reinterpret_cast<const wchar_t *>(nativeFilePath.utf16());
+ QScopedPointer<QThread> thread(QThread::create([path, resultPtr]
+ () { *resultPtr = runShellExecute(path); }));
+ thread->start();
+ thread->wait();
+
// ShellExecute returns a value greater than 32 if successful
if (result <= 32) {
qWarning("ShellExecute '%ls' failed (error %zu).", qUtf16Printable(url.toString()), result);