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>bb10
parent
76c4a70499
commit
ecfa33e751
|
|
@ -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"));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue