summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2018-07-03 08:24:42 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2018-09-28 14:04:20 +0000
commitecfa33e751115919ddb47a6f641a2b1842c96788 (patch)
treef6f872d7c36b285ceda8125528a3e079983cea0c
parent76c4a7049957a0497530e06cccb92cebf3f1477d (diff)
Windows QPA: Work around intermittent clipboard copy failures
Repeatedly attempt to open the clipboard in case it is opened by other applications. Task-number: QTBUG-27097 Change-Id: Ic1cfec0bb17e34f8c7f744add21a4431dae4f5b7 Reviewed-by: Andy Shaw <andy.shaw@qt.io>
-rw-r--r--src/plugins/platforms/windows/qwindowsclipboard.cpp11
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp32
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h2
-rw-r--r--src/plugins/platforms/windows/windows.pri2
4 files changed, 45 insertions, 2 deletions
diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp
index 53f329422c..8b386da9f7 100644
--- a/src/plugins/platforms/windows/qwindowsclipboard.cpp
+++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp
@@ -50,6 +50,7 @@
#include <QtCore/qdebug.h>
#include <QtCore/qmimedata.h>
#include <QtCore/qstringlist.h>
+#include <QtCore/qthread.h>
#include <QtCore/qvariant.h>
#include <QtCore/qurl.h>
@@ -318,7 +319,15 @@ void QWindowsClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode)
m_data = new QWindowsOleDataObject(mimeData);
}
- const HRESULT src = OleSetClipboard(m_data);
+ HRESULT src = S_FALSE;
+ int attempts = 0;
+ for (; attempts < 3; ++attempts) {
+ src = OleSetClipboard(m_data);
+ if (src != CLIPBRD_E_CANT_OPEN || QWindowsContext::isSessionLocked())
+ break;
+ QThread::msleep(100);
+ }
+
if (src != S_OK) {
QString mimeDataFormats = mimeData ?
mimeData->formats().join(QLatin1String(", ")) : QString(QStringLiteral("NULL"));
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 373758b49e..9bce72d853 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -86,6 +86,7 @@
#include <windowsx.h>
#include <comdef.h>
#include <dbt.h>
+#include <wtsapi32.h>
QT_BEGIN_NAMESPACE
@@ -754,6 +755,37 @@ QWindowsWindow *QWindowsContext::findPlatformWindowAt(HWND parent,
return result;
}
+bool QWindowsContext::isSessionLocked()
+{
+ bool result = false;
+ const DWORD sessionId = WTSGetActiveConsoleSessionId();
+ if (sessionId != 0xFFFFFFFF) {
+ LPTSTR buffer = nullptr;
+ DWORD size = 0;
+#if !defined(Q_CC_MINGW)
+ if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId,
+ WTSSessionInfoEx, &buffer, &size) == TRUE
+ && size > 0) {
+ const WTSINFOEXW *info = reinterpret_cast<WTSINFOEXW *>(buffer);
+ result = info->Level == 1 && info->Data.WTSInfoExLevel1.SessionFlags == WTS_SESSIONSTATE_LOCK;
+ WTSFreeMemory(buffer);
+ }
+#else // MinGW as of 7.3 does not have WTSINFOEXW in wtsapi32.h
+ // Retrieve the flags which are at offset 16 due to padding for 32/64bit alike.
+ if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId,
+ WTS_INFO_CLASS(25), &buffer, &size) == TRUE
+ && size >= 20) {
+ const DWORD *p = reinterpret_cast<DWORD *>(buffer);
+ const DWORD level = *p;
+ const DWORD sessionFlags = *(p + 4);
+ result = level == 1 && sessionFlags == 1;
+ WTSFreeMemory(buffer);
+ }
+#endif // Q_CC_MINGW
+ }
+ return result;
+}
+
QWindowsMimeConverter &QWindowsContext::mimeConverter() const
{
return d->m_mimeConverter;
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 622c729a10..19e9c26130 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -224,6 +224,8 @@ public:
bool useRTLExtensions() const;
QList<int> possibleKeys(const QKeyEvent *e) const;
+ static bool isSessionLocked();
+
QWindowsMimeConverter &mimeConverter() const;
QWindowsScreenManager &screenManager();
QWindowsTabletSupport *tabletSupport() const;
diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri
index c1d4e907d9..db06a6a2a3 100644
--- a/src/plugins/platforms/windows/windows.pri
+++ b/src/plugins/platforms/windows/windows.pri
@@ -7,7 +7,7 @@ qtConfig(opengl):!qtConfig(opengles2):!qtConfig(dynamicgl): LIBS *= -lopengl32
mingw: LIBS *= -luuid
# For the dialog helpers:
-LIBS += -lshlwapi -lshell32 -ladvapi32
+LIBS += -lshlwapi -lshell32 -ladvapi32 -lwtsapi32
DEFINES *= QT_NO_CAST_FROM_ASCII QT_NO_FOREACH