summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/windows')
-rw-r--r--src/plugins/platforms/windows/openglblacklists/default.json14
-rw-r--r--src/plugins/platforms/windows/qwindowsclipboard.cpp17
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp76
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.h5
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.h3
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp18
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp30
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp3
9 files changed, 113 insertions, 59 deletions
diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json
index 3cfa7e3856..e37351f9e0 100644
--- a/src/plugins/platforms/windows/openglblacklists/default.json
+++ b/src/plugins/platforms/windows/openglblacklists/default.json
@@ -152,6 +152,18 @@
"features": [
"disable_program_cache"
]
- }
+ },
+ {
+ "id": 13,
+ "description": "Disable DesktopGL on Windows with Mobile Intel(R) 4 Series Express Chipset Family graphics card (QTBUG-58772)",
+ "vendor_id": "0x8086",
+ "device_id": [ "0x2A42" ],
+ "os": {
+ "type": "win"
+ },
+ "features": [
+ "disable_desktopgl"
+ ]
+ }
]
}
diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp
index b87e43f3f7..4e6d3306e1 100644
--- a/src/plugins/platforms/windows/qwindowsclipboard.cpp
+++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp
@@ -115,12 +115,21 @@ static QDebug operator<<(QDebug d, const QMimeData *mimeData)
IDataObject *QWindowsClipboardRetrievalMimeData::retrieveDataObject() const
{
+ enum : int { attempts = 3 };
IDataObject * pDataObj = nullptr;
- if (OleGetClipboard(&pDataObj) == S_OK) {
- if (QWindowsContext::verbose > 1)
- qCDebug(lcQpaMime) << __FUNCTION__ << pDataObj;
- return pDataObj;
+ // QTBUG-53979, retry in case the other application has clipboard locked
+ for (int i = 1; i <= attempts; ++i) {
+ if (SUCCEEDED(OleGetClipboard(&pDataObj))) {
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaMime) << __FUNCTION__ << pDataObj;
+ return pDataObj;
+ }
+ qCWarning(lcQpaMime, i == attempts
+ ? "Unable to obtain clipboard."
+ : "Retrying to obtain clipboard.");
+ QThread::msleep(50);
}
+
return nullptr;
}
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index 101db75d0b..d9521e7e08 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -196,6 +196,7 @@ bool QWindowsOpengl32DLL::init(bool softwareRendering)
wglShareLists = reinterpret_cast<BOOL (WINAPI *)(HGLRC, HGLRC)>(resolve("wglShareLists"));
wglSwapBuffers = reinterpret_cast<BOOL (WINAPI *)(HDC)>(resolve("wglSwapBuffers"));
wglSetPixelFormat = reinterpret_cast<BOOL (WINAPI *)(HDC, int, const PIXELFORMATDESCRIPTOR *)>(resolve("wglSetPixelFormat"));
+ wglDescribePixelFormat = reinterpret_cast<int (WINAPI *)(HDC, int, UINT, PIXELFORMATDESCRIPTOR *)>(resolve("wglDescribePixelFormat"));
glGetError = reinterpret_cast<GLenum (APIENTRY *)()>(resolve("glGetError"));
glGetIntegerv = reinterpret_cast<void (APIENTRY *)(GLenum , GLint *)>(resolve("glGetIntegerv"));
@@ -214,6 +215,11 @@ BOOL QWindowsOpengl32DLL::setPixelFormat(HDC dc, int pf, const PIXELFORMATDESCRI
return moduleIsNotOpengl32() ? wglSetPixelFormat(dc, pf, pfd) : SetPixelFormat(dc, pf, pfd);
}
+int QWindowsOpengl32DLL::describePixelFormat(HDC dc, int pf, UINT size, PIXELFORMATDESCRIPTOR *pfd)
+{
+ return moduleIsNotOpengl32() ? wglDescribePixelFormat(dc, pf, size, pfd) : DescribePixelFormat(dc, pf, size, pfd);
+}
+
QWindowsOpenGLContext *QOpenGLStaticContext::createContext(QOpenGLContext *context)
{
return new QWindowsGLContext(this, context);
@@ -322,11 +328,11 @@ static inline bool
static void describeFormats(HDC hdc)
{
- const int pfiMax = DescribePixelFormat(hdc, 0, 0, nullptr);
- for (int i = 0; i < pfiMax; i++) {
+ const int pfiMax = QOpenGLStaticContext::opengl32.describePixelFormat(hdc, 0, 0, nullptr);
+ for (int i = 1; i <= pfiMax; i++) {
PIXELFORMATDESCRIPTOR pfd;
initPixelFormatDescriptor(&pfd);
- DescribePixelFormat(hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
+ QOpenGLStaticContext::opengl32.describePixelFormat(hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
qCDebug(lcQpaGl) << '#' << i << '/' << pfiMax << ':' << pfd;
}
}
@@ -617,7 +623,7 @@ static int choosePixelFormat(HDC hdc,
// Verify if format is acceptable. Note that the returned
// formats have been observed to not contain PFD_SUPPORT_OPENGL, ignore.
initPixelFormatDescriptor(obtainedPfd);
- DescribePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), obtainedPfd);
+ QOpenGLStaticContext::opengl32.describePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), obtainedPfd);
if (!isAcceptableFormat(additional, *obtainedPfd, true)) {
qCDebug(lcQpaGl) << __FUNCTION__ << " obtained px #" << pixelFormat
<< " not acceptable=" << *obtainedPfd;
@@ -885,13 +891,6 @@ QWindowsOpenGLContextFormat QWindowsOpenGLContextFormat::current()
result.profile = QSurfaceFormat::CoreProfile;
else if (value & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
result.profile = QSurfaceFormat::CompatibilityProfile;
- if (result.version < 0x0400)
- return result;
- // v4.0 onwards
- value = 0;
- QOpenGLStaticContext::opengl32.glGetIntegerv(RESET_NOTIFICATION_STRATEGY_ARB, &value);
- if (value == LOSE_CONTEXT_ON_RESET_ARB)
- result.options |= QSurfaceFormat::ResetNotification;
return result;
}
@@ -969,6 +968,7 @@ QOpenGLTemporaryContext::~QOpenGLTemporaryContext()
*/
#define SAMPLE_BUFFER_EXTENSION "GL_ARB_multisample"
+#define ROBUSTNESS_EXTENSION "GL_ARB_robustness"
QOpenGLStaticContext::QOpenGLStaticContext() :
vendor(QOpenGLStaticContext::getGlString(GL_VENDOR)),
@@ -989,9 +989,31 @@ QOpenGLStaticContext::QOpenGLStaticContext() :
wglGetExtensionsStringARB(reinterpret_cast<WglGetExtensionsStringARB>(
reinterpret_cast<QFunctionPointer>(QOpenGLStaticContext::opengl32.wglGetProcAddress("wglGetExtensionsStringARB"))))
{
- if (extensionNames.startsWith(SAMPLE_BUFFER_EXTENSION " ")
- || extensionNames.indexOf(" " SAMPLE_BUFFER_EXTENSION " ") != -1)
- extensions |= SampleBuffers;
+ if (defaultFormat.version < 0x0300) {
+ if (extensionNames.startsWith(SAMPLE_BUFFER_EXTENSION " ")
+ || extensionNames.indexOf(" " SAMPLE_BUFFER_EXTENSION " ") != -1)
+ extensions |= SampleBuffers;
+ if (extensionNames.startsWith(ROBUSTNESS_EXTENSION " ")
+ || extensionNames.indexOf(" " ROBUSTNESS_EXTENSION " ") != -1)
+ extensions |= Robustness;
+ } else {
+ typedef const GLubyte * (APIENTRY *glGetStringi_t)(GLenum, GLuint);
+ auto glGetStringi = reinterpret_cast<glGetStringi_t>(
+ reinterpret_cast<QFunctionPointer>(QOpenGLStaticContext::opengl32.wglGetProcAddress("glGetStringi")));
+ if (glGetStringi) {
+ GLint n = 0;
+ QOpenGLStaticContext::opengl32.glGetIntegerv(GL_NUM_EXTENSIONS, &n);
+ for (GLint i = 0; i < n; ++i) {
+ const char *p = reinterpret_cast<const char *>(glGetStringi(GL_EXTENSIONS, i));
+ if (p) {
+ if (!strcmp(p, SAMPLE_BUFFER_EXTENSION))
+ extensions |= SampleBuffers;
+ else if (!strcmp(p, ROBUSTNESS_EXTENSION))
+ extensions |= Robustness;
+ }
+ }
+ }
+ }
}
QByteArray QOpenGLStaticContext::getGlString(unsigned int which)
@@ -1230,27 +1252,11 @@ bool QWindowsGLContext::updateObtainedParams(HDC hdc, int *obtainedSwapInterval)
if (m_staticContext->wglGetSwapInternalExt && obtainedSwapInterval)
*obtainedSwapInterval = m_staticContext->wglGetSwapInternalExt();
- bool hasRobustness = false;
- if (m_obtainedFormat.majorVersion() < 3) {
- const char *exts = reinterpret_cast<const char *>(QOpenGLStaticContext::opengl32.glGetString(GL_EXTENSIONS));
- hasRobustness = exts && strstr(exts, "GL_ARB_robustness");
- } else {
- typedef const GLubyte * (APIENTRY *glGetStringi_t)(GLenum, GLuint);
- auto glGetStringi = reinterpret_cast<glGetStringi_t>(
- reinterpret_cast<QFunctionPointer>(QOpenGLStaticContext::opengl32.wglGetProcAddress("glGetStringi")));
- if (glGetStringi) {
- GLint n = 0;
- QOpenGLStaticContext::opengl32.glGetIntegerv(GL_NUM_EXTENSIONS, &n);
- for (GLint i = 0; i < n; ++i) {
- const char *p = reinterpret_cast<const char *>(glGetStringi(GL_EXTENSIONS, i));
- if (p && !strcmp(p, "GL_ARB_robustness")) {
- hasRobustness = true;
- break;
- }
- }
- }
- }
- if (hasRobustness) {
+ if (testFlag(m_staticContext->extensions, QOpenGLStaticContext::Robustness)) {
+ GLint value = 0;
+ QOpenGLStaticContext::opengl32.glGetIntegerv(RESET_NOTIFICATION_STRATEGY_ARB, &value);
+ if (value == LOSE_CONTEXT_ON_RESET_ARB)
+ m_obtainedFormat.setOption(QSurfaceFormat::ResetNotification);
m_getGraphicsResetStatus = reinterpret_cast<GlGetGraphicsResetStatusArbType>(
reinterpret_cast<QFunctionPointer>(QOpenGLStaticContext::opengl32.wglGetProcAddress("glGetGraphicsResetStatusARB")));
}
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h
index 1abe2eb390..e5f6fefd5a 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.h
+++ b/src/plugins/platforms/windows/qwindowsglcontext.h
@@ -107,6 +107,7 @@ struct QWindowsOpengl32DLL
// Wrappers. Always use these instead of SwapBuffers/wglSwapBuffers/etc.
BOOL swapBuffers(HDC dc);
BOOL setPixelFormat(HDC dc, int pf, const PIXELFORMATDESCRIPTOR *pfd);
+ int describePixelFormat(HDC dc, int pf, UINT size, PIXELFORMATDESCRIPTOR *pfd);
// WGL
HGLRC (WINAPI * wglCreateContext)(HDC dc);
@@ -130,6 +131,7 @@ private:
// For Mesa llvmpipe shipped with a name other than opengl32.dll
BOOL (WINAPI * wglSwapBuffers)(HDC dc);
BOOL (WINAPI * wglSetPixelFormat)(HDC dc, int pf, const PIXELFORMATDESCRIPTOR *pfd);
+ int (WINAPI * wglDescribePixelFormat)(HDC dc, int pf, UINT size, PIXELFORMATDESCRIPTOR *pfd);
};
class QOpenGLStaticContext : public QWindowsStaticOpenGLContext
@@ -140,7 +142,8 @@ public:
enum Extensions
{
SampleBuffers = 0x1,
- sRGBCapableFramebuffer = 0x2
+ sRGBCapableFramebuffer = 0x2,
+ Robustness = 0x4,
};
typedef bool
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index 8cd09a34eb..df63adf558 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -42,6 +42,7 @@
#include "qwindowswindow.h"
#include "qwindowsintegration.h"
#include "qwindowscursor.h"
+#include "qwindowstheme.h"
#include <QtCore/qt_windows.h>
@@ -543,10 +544,13 @@ bool QWindowsScreenManager::handleScreenChanges()
// Look for changed monitors, add new ones
const WindowsScreenDataList newDataList = monitorData();
const bool lockScreen = newDataList.size() == 1 && (newDataList.front().flags & QWindowsScreenData::LockScreen);
+ bool primaryScreenChanged = false;
for (const QWindowsScreenData &newData : newDataList) {
const int existingIndex = indexOfMonitor(m_screens, newData.name);
if (existingIndex != -1) {
m_screens.at(existingIndex)->handleChanges(newData);
+ if (existingIndex == 0)
+ primaryScreenChanged = true;
} else {
auto *newScreen = new QWindowsScreen(newData);
m_screens.push_back(newScreen);
@@ -563,6 +567,8 @@ bool QWindowsScreenManager::handleScreenChanges()
removeScreen(i);
} // for existing screens
} // not lock screen
+ if (primaryScreenChanged)
+ QWindowsTheme::instance()->refreshFonts();
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h
index 4e24308445..07120230ce 100644
--- a/src/plugins/platforms/windows/qwindowstheme.h
+++ b/src/plugins/platforms/windows/qwindowstheme.h
@@ -85,6 +85,8 @@ public:
static bool useNativeMenus();
+ void refreshFonts();
+
static const char *name;
private:
@@ -92,7 +94,6 @@ private:
void clearPalettes();
void refreshPalettes();
void clearFonts();
- void refreshFonts();
void refreshIconPixmapSizes();
static QWindowsTheme *m_instance;
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 0a97305dd4..5c13bd9650 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1937,8 +1937,10 @@ void QWindowsWindow::handleGeometryChange()
{
const QRect previousGeometry = m_data.geometry;
m_data.geometry = geometry_sys();
- if (testFlag(WithinDpiChanged))
- return; // QGuiApplication will send resize
+ if (testFlag(WithinDpiChanged)
+ && QWindowsContext::instance()->screenManager().screenForHwnd(m_data.hwnd) != screen()) {
+ return; // QGuiApplication will send resize when screen actually changes
+ }
QWindowSystemInterface::handleGeometryChange(window(), m_data.geometry);
// QTBUG-32121: OpenGL/normal windows (with exception of ANGLE) do not receive
// expose events when shrinking, synthesize.
@@ -2695,10 +2697,16 @@ bool QWindowsWindow::handleNonClientHitTest(const QPoint &globalPos, LRESULT *re
return true;
}
if (localPos.y() < 0) {
- const int topResizeBarPos = -frameMargins().top();
- if (localPos.y() >= topResizeBarPos)
+ // We want to return HTCAPTION/true only over the outer sizing frame, not the entire title bar,
+ // otherwise the title bar buttons (close, etc.) become unresponsive on Windows 7 (QTBUG-78262).
+ // However, neither frameMargins() nor GetSystemMetrics(SM_CYSIZEFRAME), etc., give the correct
+ // sizing frame height in all Windows versions/scales. This empirical constant seems to work, though.
+ const int sizingHeight = 9;
+ const int topResizeBarPos = sizingHeight - frameMargins().top();
+ if (localPos.y() < topResizeBarPos) {
*result = HTCAPTION; // Extend caption over top resize bar, let's user move the window.
- return true;
+ return true;
+ }
}
}
if (fixedWidth && (localPos.x() < 0 || localPos.x() >= size.width())) {
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
index 943c1ff368..b2b401dd40 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
@@ -670,18 +670,26 @@ HRESULT QWindowsUiaMainProvider::ElementProviderFromPoint(double x, double y, IR
QPoint point;
nativeUiaPointToPoint(uiaPoint, window, &point);
- QAccessibleInterface *targetacc = accessible->childAt(point.x(), point.y());
-
- if (targetacc) {
- QAccessibleInterface *acc = targetacc;
- // Controls can be embedded within grouping elements. By default returns the innermost control.
- while (acc) {
- targetacc = acc;
- // For accessibility tools it may be better to return the text element instead of its subcomponents.
- if (targetacc->textInterface()) break;
- acc = acc->childAt(point.x(), point.y());
+ if (auto targetacc = accessible->childAt(point.x(), point.y())) {
+ auto acc = accessible->childAt(point.x(), point.y());
+ // Reject the cases where childAt() returns a different instance in each call for the same
+ // element (e.g., QAccessibleTree), as it causes an endless loop with Youdao Dictionary installed.
+ if (targetacc == acc) {
+ // Controls can be embedded within grouping elements. By default returns the innermost control.
+ while (acc) {
+ targetacc = acc;
+ // For accessibility tools it may be better to return the text element instead of its subcomponents.
+ if (targetacc->textInterface()) break;
+ acc = targetacc->childAt(point.x(), point.y());
+ if (acc != targetacc->childAt(point.x(), point.y())) {
+ qCDebug(lcQpaUiAutomation) << "Non-unique childAt() for" << targetacc;
+ break;
+ }
+ }
+ *pRetVal = providerForAccessible(targetacc);
+ } else {
+ qCDebug(lcQpaUiAutomation) << "Non-unique childAt() for" << accessible;
}
- *pRetVal = providerForAccessible(targetacc);
}
return S_OK;
}
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp
index 8e395669f8..d8b8f7281d 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp
@@ -48,6 +48,7 @@
#include <QtGui/qaccessible.h>
#include <QtCore/qloggingcategory.h>
#include <QtCore/qstring.h>
+#include <QtCore/qvarlengtharray.h>
QT_BEGIN_NAMESPACE
@@ -227,7 +228,7 @@ HRESULT QWindowsUiaTextRangeProvider::GetBoundingRectangles(SAFEARRAY **pRetVal)
return UIA_E_ELEMENTNOTAVAILABLE;
int len = textInterface->characterCount();
- QList<QRect> rectList;
+ QVarLengthArray<QRect> rectList;
if ((m_startOffset >= 0) && (m_endOffset <= len) && (m_startOffset < m_endOffset)) {
int start, end;