diff options
Diffstat (limited to 'src/plugins/platforms/windows')
12 files changed, 95 insertions, 41 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/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index 825602e7dc..4f669a5509 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -660,18 +660,18 @@ QPoint QWindowsCursor::mousePosition() return QPoint(p.x, p.y); } -QWindowsCursor::CursorState QWindowsCursor::cursorState() +QWindowsCursor::State QWindowsCursor::cursorState() { enum { cursorShowing = 0x1, cursorSuppressed = 0x2 }; // Windows 8: CURSOR_SUPPRESSED CURSORINFO cursorInfo; cursorInfo.cbSize = sizeof(CURSORINFO); if (GetCursorInfo(&cursorInfo)) { - if (cursorInfo.flags & CursorShowing) - return CursorShowing; + if (cursorInfo.flags & cursorShowing) + return State::Showing; if (cursorInfo.flags & cursorSuppressed) - return CursorSuppressed; + return State::Suppressed; } - return CursorHidden; + return State::Hidden; } QPoint QWindowsCursor::pos() const diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index 1816732594..8495b51a5a 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -89,10 +89,10 @@ typedef QSharedPointer<CursorHandle> CursorHandlePtr; class QWindowsCursor : public QPlatformCursor { public: - enum CursorState { - CursorShowing, - CursorHidden, - CursorSuppressed // Cursor suppressed by touch interaction (Windows 8). + enum class State { + Showing, + Hidden, + Suppressed // Cursor suppressed by touch interaction (Windows 8). }; struct PixmapCursor { @@ -119,7 +119,7 @@ public: static HCURSOR createCursorFromShape(Qt::CursorShape cursorShape, const QPlatformScreen *screen = nullptr); static QPoint mousePosition(); - static CursorState cursorState(); + static State cursorState(); CursorHandlePtr standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor); CursorHandlePtr pixmapWindowCursor(const QCursor &c); diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index 8d4e4dc611..b7d225cb00 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -260,7 +260,7 @@ private: }; QWindowsOleDropSource::QWindowsOleDropSource(QWindowsDrag *drag) - : m_mode(QWindowsCursor::cursorState() != QWindowsCursor::CursorSuppressed ? MouseDrag : TouchDrag) + : m_mode(QWindowsCursor::cursorState() != QWindowsCursor::State::Suppressed ? MouseDrag : TouchDrag) , m_drag(drag) , m_windowUnderMouse(QWindowsContext::instance()->windowUnderMouse()) , m_currentButtons(Qt::NoButton) @@ -455,7 +455,7 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect) break; case TouchDrag: // "Touch drag" with an unsuppressed cursor may happen with RDP (see createCursors()) - if (QWindowsCursor::cursorState() != QWindowsCursor::CursorSuppressed) + if (QWindowsCursor::cursorState() != QWindowsCursor::State::Suppressed) SetCursor(nullptr); if (!m_touchDragWindow) m_touchDragWindow = new QWindowsDragCursorWindow; diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 7d621126b9..9e03d09607 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -393,7 +393,7 @@ QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::doCreate() switch (requestedRenderer) { case QWindowsOpenGLTester::DesktopGl: if (QWindowsStaticOpenGLContext *glCtx = QOpenGLStaticContext::create()) { - if ((QWindowsOpenGLTester::supportedRenderers() & QWindowsOpenGLTester::DisableRotationFlag) + if ((QWindowsOpenGLTester::supportedRenderers(requestedRenderer) & QWindowsOpenGLTester::DisableRotationFlag) && !QWindowsScreen::setOrientationPreference(Qt::LandscapeOrientation)) { qCWarning(lcQpaGl, "Unable to disable rotation."); } @@ -407,19 +407,19 @@ QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::doCreate() case QWindowsOpenGLTester::AngleRendererD3d11Warp: return QWindowsEGLStaticContext::create(requestedRenderer); case QWindowsOpenGLTester::Gles: - return QWindowsEGLStaticContext::create(QWindowsOpenGLTester::supportedGlesRenderers()); + return QWindowsEGLStaticContext::create(requestedRenderer); case QWindowsOpenGLTester::SoftwareRasterizer: if (QWindowsStaticOpenGLContext *swCtx = QOpenGLStaticContext::create(true)) return swCtx; qCWarning(lcQpaGl, "Software OpenGL failed. Falling back to system OpenGL."); - if (QWindowsOpenGLTester::supportedRenderers() & QWindowsOpenGLTester::DesktopGl) + if (QWindowsOpenGLTester::supportedRenderers(requestedRenderer) & QWindowsOpenGLTester::DesktopGl) return QOpenGLStaticContext::create(); return nullptr; default: break; } - const QWindowsOpenGLTester::Renderers supportedRenderers = QWindowsOpenGLTester::supportedRenderers(); + const QWindowsOpenGLTester::Renderers supportedRenderers = QWindowsOpenGLTester::supportedRenderers(requestedRenderer); if (supportedRenderers.testFlag(QWindowsOpenGLTester::DisableProgramCacheFlag) && !QCoreApplication::testAttribute(Qt::AA_DisableShaderDiskCache)) { QCoreApplication::setAttribute(Qt::AA_DisableShaderDiskCache); @@ -441,7 +441,7 @@ QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::doCreate() #elif defined(QT_OPENGL_ES_2) QWindowsOpenGLTester::Renderers glesRenderers = QWindowsOpenGLTester::requestedGlesRenderer(); if (glesRenderers == QWindowsOpenGLTester::InvalidRenderer) - glesRenderers = QWindowsOpenGLTester::supportedGlesRenderers(); + glesRenderers = QWindowsOpenGLTester::supportedRenderers(QWindowsOpenGLTester::AngleRendererD3d11); return QWindowsEGLStaticContext::create(glesRenderers); #elif !defined(QT_NO_OPENGL) return QOpenGLStaticContext::create(); diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index 1209b6c4b4..9e6101b758 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -877,10 +877,26 @@ bool QWindowsKeyMapper::translateKeyEvent(QWindow *widget, HWND hwnd, bool QWindowsKeyMapper::translateMultimediaKeyEventInternal(QWindow *window, const MSG &msg) { #if defined(WM_APPCOMMAND) + const int cmd = GET_APPCOMMAND_LPARAM(msg.lParam); // QTBUG-57198, do not send mouse-synthesized commands as key events in addition - if (GET_DEVICE_LPARAM(msg.lParam) == FAPPCOMMAND_MOUSE) + switch (GET_DEVICE_LPARAM(msg.lParam)) { + case FAPPCOMMAND_MOUSE: return false; - const int cmd = GET_APPCOMMAND_LPARAM(msg.lParam); + case FAPPCOMMAND_KEY: + // QTBUG-62838, swallow WM_KEYDOWN, WM_KEYUP for commands that are + // reflected in VK(s) like VK_MEDIA_NEXT_TRACK. Don't do that for + // APPCOMMAND_BROWSER_HOME as that one does not trigger two events + if (cmd != APPCOMMAND_BROWSER_HOME) { + MSG peekedMsg; + if (PeekMessage(&peekedMsg, msg.hwnd, 0, 0, PM_NOREMOVE) + && peekedMsg.message == WM_KEYDOWN) { + PeekMessage(&peekedMsg, msg.hwnd, 0, 0, PM_REMOVE); + PeekMessage(&peekedMsg, msg.hwnd, 0, 0, PM_REMOVE); + } + } + break; + } + const int dwKeys = GET_KEYSTATE_LPARAM(msg.lParam); int state = 0; state |= (dwKeys & MK_SHIFT ? int(Qt::ShiftModifier) : 0); diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp index 9a630aff4f..3efccf0f32 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.cpp +++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp @@ -247,11 +247,12 @@ typedef QHash<QOpenGLConfig::Gpu, QWindowsOpenGLTester::Renderers> SupportedRend Q_GLOBAL_STATIC(SupportedRenderersCache, supportedRenderersCache) #endif -QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(const GpuDescription &gpu, bool glesOnly) +QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(const GpuDescription &gpu, + Renderer requested) { - Q_UNUSED(gpu) - Q_UNUSED(glesOnly) #if defined(QT_NO_OPENGL) + Q_UNUSED(gpu) + Q_UNUSED(requested) return 0; #else QOpenGLConfig::Gpu qgpu = QOpenGLConfig::Gpu::fromDevice(gpu.vendorId, gpu.deviceId, gpu.driverVersion, gpu.description); @@ -265,8 +266,11 @@ QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(c | QWindowsOpenGLTester::AngleRendererD3d11Warp | QWindowsOpenGLTester::SoftwareRasterizer); - if (!glesOnly && testDesktopGL()) - result |= QWindowsOpenGLTester::DesktopGl; + // Don't test for GL if explicitly requested or GLES only is requested + if (requested == DesktopGl + || ((requested & GlesMask) == 0 && testDesktopGL())) { + result |= QWindowsOpenGLTester::DesktopGl; + } const char bugListFileVar[] = "QT_OPENGL_BUGLIST"; QString buglistFileName = QStringLiteral(":/qt-project.org/windows/openglblacklists/default.json"); @@ -310,19 +314,11 @@ QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(c #endif // !QT_NO_OPENGL } -QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::supportedGlesRenderers() -{ - const GpuDescription gpu = GpuDescription::detect(); - const QWindowsOpenGLTester::Renderers result = detectSupportedRenderers(gpu, true); - qCDebug(lcQpaGl) << __FUNCTION__ << gpu << "renderer: " << result; - return result; -} - -QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::supportedRenderers() +QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::supportedRenderers(Renderer requested) { const GpuDescription gpu = GpuDescription::detect(); - const QWindowsOpenGLTester::Renderers result = detectSupportedRenderers(gpu, false); - qCDebug(lcQpaGl) << __FUNCTION__ << gpu << "renderer: " << result; + const QWindowsOpenGLTester::Renderers result = detectSupportedRenderers(gpu, requested); + qCDebug(lcQpaGl) << __FUNCTION__ << gpu << requested << "renderer: " << result; return result; } diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h index bec87c1f86..08628c2586 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.h +++ b/src/plugins/platforms/windows/qwindowsopengltester.h @@ -91,11 +91,10 @@ public: static Renderer requestedGlesRenderer(); static Renderer requestedRenderer(); - static Renderers supportedGlesRenderers(); - static Renderers supportedRenderers(); + static QWindowsOpenGLTester::Renderers supportedRenderers(Renderer requested); private: - static QWindowsOpenGLTester::Renderers detectSupportedRenderers(const GpuDescription &gpu, bool glesOnly); + static Renderers detectSupportedRenderers(const GpuDescription &gpu, Renderer requested); static bool testDesktopGL(); }; diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h index 11684de721..325d5b3de4 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h @@ -86,7 +86,7 @@ public: HRESULT STDMETHODCALLTYPE GetRuntimeId(SAFEARRAY **pRetVal) override; HRESULT STDMETHODCALLTYPE get_BoundingRectangle(UiaRect *pRetVal) override; HRESULT STDMETHODCALLTYPE GetEmbeddedFragmentRoots(SAFEARRAY **pRetVal) override; - HRESULT STDMETHODCALLTYPE SetFocus(); + HRESULT STDMETHODCALLTYPE SetFocus() override; HRESULT STDMETHODCALLTYPE get_FragmentRoot(IRawElementProviderFragmentRoot **pRetVal) override; // IRawElementProviderFragmentRoot methods 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 |