summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.json2
-rw-r--r--dist/changes-5.12.483
-rw-r--r--examples/widgets/doc/src/classwizard.qdoc2
-rw-r--r--mkspecs/features/ltcg.prf9
-rw-r--r--mkspecs/features/qt_module_headers.prf4
-rw-r--r--src/3rdparty/angle/src/libEGL/libEGL_mingw32.def142
-rw-r--r--src/3rdparty/angle/src/libEGL/libEGLd_mingw32.def142
-rw-r--r--src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def805
-rw-r--r--src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def805
-rw-r--r--src/concurrent/qtconcurrentrun.cpp16
-rw-r--r--src/corelib/animation/qabstractanimation.cpp2
-rw-r--r--src/corelib/io/qstorageinfo_unix.cpp3
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp4
-rw-r--r--src/corelib/kernel/qcoreapplication_win.cpp12
-rw-r--r--src/corelib/serialization/qjsoncbor.cpp10
-rw-r--r--src/corelib/thread/qfuture.qdoc8
-rw-r--r--src/corelib/thread/qfuturewatcher.cpp10
-rw-r--r--src/corelib/thread/qthread_unix.cpp6
-rw-r--r--src/dbus/doc/snippets/cmake/examples.cmake3
-rw-r--r--src/dbus/doc/src/qtdbus-cmake.qdoc224
-rw-r--r--src/gui/accessible/qaccessible.cpp1
-rw-r--r--src/gui/accessible/qaccessible.h1
-rw-r--r--src/gui/image/qimagereader.cpp10
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp2
-rw-r--r--src/gui/kernel/qhighdpiscaling_p.h264
-rw-r--r--src/gui/math3d/qvector3d.cpp2
-rw-r--r--src/gui/opengl/qopengltextureblitter.cpp3
-rw-r--r--src/gui/painting/qdrawhelper.cpp37
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp50
-rw-r--r--src/gui/painting/qstroker.cpp2
-rw-r--r--src/gui/text/qdistancefield.cpp5
-rw-r--r--src/gui/text/qdistancefield_p.h1
-rw-r--r--src/network/bearer/qnetworkconfigmanager.cpp27
-rw-r--r--src/network/bearer/qnetworksession.cpp3
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp189
-rw-r--r--src/network/ssl/qsslsocket_openssl11_symbols_p.h8
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp12
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h1
-rw-r--r--src/network/ssl/qsslsocket_opensslpre11_symbols_p.h2
-rw-r--r--src/platformsupport/linuxaccessibility/bridge.cpp2
-rw-r--r--src/plugins/bearer/qnetworksession_impl.cpp13
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp739
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.h6
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm24
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm31
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm10
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm8
-rw-r--r--src/plugins/platforms/cocoa/qcocoansmenu.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm20
-rw-r--r--src/plugins/platforms/ios/quiview_accessibility.mm8
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp5
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp6
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp20
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h4
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm14
-rw-r--r--src/widgets/kernel/qapplication.cpp59
-rw-r--r--src/widgets/kernel/qwidget.cpp81
-rw-r--r--src/widgets/kernel/qwidget_p.h2
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp54
-rw-r--r--src/widgets/widgets/qmdisubwindow.cpp16
-rw-r--r--src/widgets/widgets/qmenu.cpp12
-rw-r--r--src/widgets/widgets/qmenu_p.h2
-rw-r--r--src/widgets/widgets/qmenubar.cpp15
-rw-r--r--tests/auto/corelib/animation/qabstractanimation/tst_qabstractanimation.cpp15
-rw-r--r--tests/auto/gui/image/qimagereader/images/qticon16.pngbin0 -> 1884 bytes
-rw-r--r--tests/auto/gui/image/qimagereader/images/qticon16@2x.pngbin0 -> 3187 bytes
-rw-r--r--tests/auto/gui/image/qimagereader/images/qticon16@3x.pngbin0 -> 5307 bytes
-rw-r--r--tests/auto/gui/image/qimagereader/tst_qimagereader.cpp25
-rw-r--r--tests/auto/network/access/http2/tst_http2.cpp2
-rw-r--r--tests/auto/network/access/qftp/tst_qftp.cpp4
-rw-r--r--tests/auto/network/access/qnetworkreply/certs/qt-test-server-cacert.pem30
-rw-r--r--tests/auto/network/ssl/qsslsocket/certs/qt-test-server-cacert.pem30
-rw-r--r--tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp13
-rw-r--r--tests/auto/other/lancelot/scripts/degeneratebeziers.qps11
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp73
-rw-r--r--tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp1
81 files changed, 2496 insertions, 1781 deletions
diff --git a/configure.json b/configure.json
index 58f4fc0c58..f817101de1 100644
--- a/configure.json
+++ b/configure.json
@@ -82,7 +82,7 @@
"force-pkg-config": { "type": "void", "name": "pkg-config" },
"framework": "boolean",
"gc-binaries": { "type": "boolean", "name": "gc_binaries" },
- "gdb-index": { "type": "boolean", "name": "gdb_index" },
+ "gdb-index": { "type": "boolean", "name": "enable_gdb_index" },
"gcc-sysroot": "boolean",
"gcov": "boolean",
"gnumake": { "type": "boolean", "name": "GNUmake" },
diff --git a/dist/changes-5.12.4 b/dist/changes-5.12.4
new file mode 100644
index 0000000000..781e9766b9
--- /dev/null
+++ b/dist/changes-5.12.4
@@ -0,0 +1,83 @@
+Qt 5.12.4 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.12.0 through 5.12.3.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+https://doc.qt.io/qt-5/index.html
+
+The Qt version 5.12 series is binary compatible with the 5.11.x series.
+Applications compiled for 5.11 will continue to run with 5.12.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* Platform Specific Changes *
+****************************************************************************
+
+ - X11 / XCB:
+ * [QTBUG-45375] QTabletEvent coordinates now come from AbsX/AbsY
+ valuators in the X11 event, in more precise 32.32 fixed-point format,
+ scaled to fit the virtual desktop. It's possible to revert to using
+ the legacy 16.16-format event_x/event_y coordinates as in previous
+ releases by setting the QT_XCB_TABLET_LEGACY_COORDINATES environment
+ variable.
+
+****************************************************************************
+* QtCore *
+****************************************************************************
+
+ - Global:
+ * [QTBUG-72073] Added the QT_NO_FLOAT16_OPERATORS macro in order to work
+ around a Microsoft <= VS2017 compiler bug that is exposed when using
+ std::bitset along with any Qt header that includes <qfloat16.h>.
+
+ - QDeadlineTimer:
+ * [QTBUG-69750] Fixed integer overflows leading to immediate timeouts.
+
+ - QFile:
+ * Made QFile::copy() issue a filesystem-synchronization system call,
+ which would make it less likely to result in incomplete or corrupt
+ files if the system reboots or uncleanly shuts down soon after the
+ function returns. New code is advised to use QSaveFile instead, which
+ also allows to display a progress report while copying.
+
+ - QFileInfo:
+ * [QTBUG-63970][QTBUG-30401][QTBUG-20791] Fixed resolving of symbolic
+ links to UNC shares on NTFS file systems.
+
+ - QMetaObject:
+ * Non-copyable lambdas can now be used with invokeMethod(). For
+ consistency reasons, the functor object is now always moved.
+
+****************************************************************************
+* QtGui *
+****************************************************************************
+
+ - [QTBUG-73231] QWindow::mapToGlobal()/mapFromGlobal() now handle windows
+ spanning screens correctly.
+
+ - [QTBUG-75522] QBezier: Fix possible endless loop when stroking curves
+
+****************************************************************************
+* QtWidgets *
+****************************************************************************
+
+ - QMenu:
+ * Shortcuts are again shown by default in context menus, except on
+ macOS. They can be forced off by setting
+ AA_DontShowShortcutsInContextMenus to true.
+
+****************************************************************************
+* Third-Party Code *
+****************************************************************************
+
+ - libpng was updated to version 1.6.37
+ - Updated QLocale to CLDR v35.1
+ - Updated bundled SQLite to version 3.28.0
diff --git a/examples/widgets/doc/src/classwizard.qdoc b/examples/widgets/doc/src/classwizard.qdoc
index 6977cf5efa..7f3693b65e 100644
--- a/examples/widgets/doc/src/classwizard.qdoc
+++ b/examples/widgets/doc/src/classwizard.qdoc
@@ -30,7 +30,7 @@
\title Class Wizard Example
\ingroup examples-dialogs
- \brief The License Wizard example shows how to implement linear
+ \brief The Class Wizard example shows how to implement linear
wizards using QWizard.
\image classwizard.png Screenshot of the Class Wizard example
diff --git a/mkspecs/features/ltcg.prf b/mkspecs/features/ltcg.prf
index d113caf35c..43ba482954 100644
--- a/mkspecs/features/ltcg.prf
+++ b/mkspecs/features/ltcg.prf
@@ -28,7 +28,10 @@ CONFIG(release, debug|release) {
}
load(link_ltcg)
- QMAKE_CFLAGS *= $$QMAKE_CFLAGS_LTCG
- QMAKE_CXXFLAGS *= $$QMAKE_CXXFLAGS_LTCG
- QMAKE_LFLAGS *= $$QMAKE_LFLAGS_LTCG
+ QMAKE_CFLAGS -= $$QMAKE_CFLAGS_LTCG
+ QMAKE_CFLAGS += $$QMAKE_CFLAGS_LTCG
+ QMAKE_CXXFLAGS -= $$QMAKE_CXXFLAGS_LTCG
+ QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_LTCG
+ QMAKE_LFLAGS -= $$QMAKE_LFLAGS_LTCG
+ QMAKE_LFLAGS += $$QMAKE_LFLAGS_LTCG
}
diff --git a/mkspecs/features/qt_module_headers.prf b/mkspecs/features/qt_module_headers.prf
index 37b69e31c8..899a40103a 100644
--- a/mkspecs/features/qt_module_headers.prf
+++ b/mkspecs/features/qt_module_headers.prf
@@ -272,7 +272,7 @@ headersclean:!internal_module {
hcleanFLAGS += -std=c++98
}
- hcleanCOMMAND = $$QMAKE_CXX -c $(CXXFLAGS) $$hcleanFLAGS $(INCPATH) $$hcleanDEFS -xc++ ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
+ hcleanCOMMAND = $(CXX) -c $(CXXFLAGS) $$hcleanFLAGS $(INCPATH) $$hcleanDEFS -xc++ ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
} else: msvc:!intel_icl {
# 4180: qualifier applied to function type has no meaning; ignored
# 4458: declaration of 'identifier' hides class member
@@ -284,7 +284,7 @@ headersclean:!internal_module {
# 4577: 'noexcept' used with no exception handling mode specified; termination on exception is not guaranteed. Specify /EHsc
greaterThan(QMAKE_MSC_VER, 18): hcleanFLAGS += -wd4577
- hcleanCOMMAND = $$QMAKE_CXX -c $(CXXFLAGS) $$hcleanFLAGS $(INCPATH) $$hcleanDEFS -FI${QMAKE_FILE_IN} -Fo${QMAKE_FILE_OUT} \
+ hcleanCOMMAND = $(CXX) -c $(CXXFLAGS) $$hcleanFLAGS $(INCPATH) $$hcleanDEFS -FI${QMAKE_FILE_IN} -Fo${QMAKE_FILE_OUT} \
$$[QT_INSTALL_DATA/src]/mkspecs/features/data/dummy.cpp
}
diff --git a/src/3rdparty/angle/src/libEGL/libEGL_mingw32.def b/src/3rdparty/angle/src/libEGL/libEGL_mingw32.def
index e68d27295e..14eb331b3a 100644
--- a/src/3rdparty/angle/src/libEGL/libEGL_mingw32.def
+++ b/src/3rdparty/angle/src/libEGL/libEGL_mingw32.def
@@ -1,77 +1,77 @@
LIBRARY libEGL
EXPORTS
- eglBindAPI @14
- eglBindTexImage @20
- eglChooseConfig @7
- eglCopyBuffers @33
- eglCreateContext @23
- eglCreatePbufferFromClientBuffer @18
- eglCreatePbufferSurface @10
- eglCreatePixmapSurface @11
- eglCreateWindowSurface @9
- eglDestroyContext @24
- eglDestroySurface @12
- eglGetConfigAttrib @8
- eglGetConfigs @6
- eglGetCurrentContext @26
- eglGetCurrentDisplay @28
- eglGetCurrentSurface @27
- eglGetDisplay @2
- eglGetError @1
- eglGetProcAddress @34
- eglInitialize @3
- eglMakeCurrent @25
- eglQueryAPI @15
- eglQueryContext @29
- eglQueryString @5
- eglQuerySurface @13
- eglReleaseTexImage @21
- eglReleaseThread @17
- eglSurfaceAttrib @19
- eglSwapBuffers @32
- eglSwapInterval @22
- eglTerminate @4
- eglWaitClient @16
- eglWaitGL @30
- eglWaitNative @31
+ eglBindAPI@4 @14
+ eglBindTexImage@12 @20
+ eglChooseConfig@20 @7
+ eglCopyBuffers@12 @33
+ eglCreateContext@16 @23
+ eglCreatePbufferFromClientBuffer@20 @18
+ eglCreatePbufferSurface@12 @10
+ eglCreatePixmapSurface@16 @11
+ eglCreateWindowSurface@16 @9
+ eglDestroyContext@8 @24
+ eglDestroySurface@8 @12
+ eglGetConfigAttrib@16 @8
+ eglGetConfigs@16 @6
+ eglGetCurrentContext@0 @26
+ eglGetCurrentDisplay@0 @28
+ eglGetCurrentSurface@4 @27
+ eglGetDisplay@4 @2
+ eglGetError@0 @1
+ eglGetProcAddress@4 @34
+ eglInitialize@12 @3
+ eglMakeCurrent@16 @25
+ eglQueryAPI@0 @15
+ eglQueryContext@16 @29
+ eglQueryString@8 @5
+ eglQuerySurface@16 @13
+ eglReleaseTexImage@12 @21
+ eglReleaseThread@0 @17
+ eglSurfaceAttrib@16 @19
+ eglSwapBuffers@8 @32
+ eglSwapInterval@8 @22
+ eglTerminate@4 @4
+ eglWaitClient@0 @16
+ eglWaitGL@0 @30
+ eglWaitNative@4 @31
; Extensions
- eglGetPlatformDisplayEXT @35
- eglQuerySurfacePointerANGLE @36
- eglPostSubBufferNV @37
- eglQueryDisplayAttribEXT @48
- eglQueryDeviceAttribEXT @49
- eglQueryDeviceStringEXT @50
- eglCreateImageKHR @51
- eglDestroyImageKHR @52
- eglCreateDeviceANGLE @53
- eglReleaseDeviceANGLE @54
- eglCreateStreamKHR @55
- eglDestroyStreamKHR @56
- eglStreamAttribKHR @57
- eglQueryStreamKHR @58
- eglQueryStreamu64KHR @59
- eglStreamConsumerGLTextureExternalKHR @60
- eglStreamConsumerAcquireKHR @61
- eglStreamConsumerReleaseKHR @62
- eglStreamConsumerGLTextureExternalAttribsNV @63
- eglCreateStreamProducerD3DTextureNV12ANGLE @64
- eglStreamPostD3DTextureNV12ANGLE @65
- eglGetSyncValuesCHROMIUM @66
- eglSwapBuffersWithDamageEXT @67
- eglProgramCacheGetAttribANGLE @68
- eglProgramCachePopulateANGLE @69
- eglProgramCacheQueryANGLE @70
- eglProgramCacheResizeANGLE @71
+ eglGetPlatformDisplayEXT@12 @35
+ eglQuerySurfacePointerANGLE@16 @36
+ eglPostSubBufferNV@24 @37
+ eglQueryDisplayAttribEXT@12 @48
+ eglQueryDeviceAttribEXT@12 @49
+ eglQueryDeviceStringEXT@8 @50
+ eglCreateImageKHR@20 @51
+ eglDestroyImageKHR@8 @52
+ eglCreateDeviceANGLE@12 @53
+ eglReleaseDeviceANGLE@4 @54
+ eglCreateStreamKHR@8 @55
+ eglDestroyStreamKHR@8 @56
+ eglStreamAttribKHR@16 @57
+ eglQueryStreamKHR@16 @58
+ eglQueryStreamu64KHR@16 @59
+ eglStreamConsumerGLTextureExternalKHR@8 @60
+ eglStreamConsumerAcquireKHR@8 @61
+ eglStreamConsumerReleaseKHR@8 @62
+ eglStreamConsumerGLTextureExternalAttribsNV@12 @63
+ eglCreateStreamProducerD3DTextureNV12ANGLE@12 @64
+ eglStreamPostD3DTextureNV12ANGLE@16 @65
+ eglGetSyncValuesCHROMIUM@20 @66
+ eglSwapBuffersWithDamageEXT@16 @67
+ eglProgramCacheGetAttribANGLE@8 @68
+ eglProgramCachePopulateANGLE@20 @69
+ eglProgramCacheQueryANGLE@24 @70
+ eglProgramCacheResizeANGLE@12 @71
; 1.5 entry points
- eglCreateSync @38
- eglDestroySync @39
- eglClientWaitSync @40
- eglGetSyncAttrib @41
- eglCreateImage @42
- eglDestroyImage @43
- eglGetPlatformDisplay @44
- eglCreatePlatformWindowSurface @45
- eglCreatePlatformPixmapSurface @46
- eglWaitSync @47
+ eglCreateSync@12 @38
+ eglDestroySync@8 @39
+ eglClientWaitSync@20 @40
+ eglGetSyncAttrib@16 @41
+ eglCreateImage@20 @42
+ eglDestroyImage@8 @43
+ eglGetPlatformDisplay@12 @44
+ eglCreatePlatformWindowSurface@16 @45
+ eglCreatePlatformPixmapSurface@16 @46
+ eglWaitSync@12 @47
diff --git a/src/3rdparty/angle/src/libEGL/libEGLd_mingw32.def b/src/3rdparty/angle/src/libEGL/libEGLd_mingw32.def
index e68d27295e..14eb331b3a 100644
--- a/src/3rdparty/angle/src/libEGL/libEGLd_mingw32.def
+++ b/src/3rdparty/angle/src/libEGL/libEGLd_mingw32.def
@@ -1,77 +1,77 @@
LIBRARY libEGL
EXPORTS
- eglBindAPI @14
- eglBindTexImage @20
- eglChooseConfig @7
- eglCopyBuffers @33
- eglCreateContext @23
- eglCreatePbufferFromClientBuffer @18
- eglCreatePbufferSurface @10
- eglCreatePixmapSurface @11
- eglCreateWindowSurface @9
- eglDestroyContext @24
- eglDestroySurface @12
- eglGetConfigAttrib @8
- eglGetConfigs @6
- eglGetCurrentContext @26
- eglGetCurrentDisplay @28
- eglGetCurrentSurface @27
- eglGetDisplay @2
- eglGetError @1
- eglGetProcAddress @34
- eglInitialize @3
- eglMakeCurrent @25
- eglQueryAPI @15
- eglQueryContext @29
- eglQueryString @5
- eglQuerySurface @13
- eglReleaseTexImage @21
- eglReleaseThread @17
- eglSurfaceAttrib @19
- eglSwapBuffers @32
- eglSwapInterval @22
- eglTerminate @4
- eglWaitClient @16
- eglWaitGL @30
- eglWaitNative @31
+ eglBindAPI@4 @14
+ eglBindTexImage@12 @20
+ eglChooseConfig@20 @7
+ eglCopyBuffers@12 @33
+ eglCreateContext@16 @23
+ eglCreatePbufferFromClientBuffer@20 @18
+ eglCreatePbufferSurface@12 @10
+ eglCreatePixmapSurface@16 @11
+ eglCreateWindowSurface@16 @9
+ eglDestroyContext@8 @24
+ eglDestroySurface@8 @12
+ eglGetConfigAttrib@16 @8
+ eglGetConfigs@16 @6
+ eglGetCurrentContext@0 @26
+ eglGetCurrentDisplay@0 @28
+ eglGetCurrentSurface@4 @27
+ eglGetDisplay@4 @2
+ eglGetError@0 @1
+ eglGetProcAddress@4 @34
+ eglInitialize@12 @3
+ eglMakeCurrent@16 @25
+ eglQueryAPI@0 @15
+ eglQueryContext@16 @29
+ eglQueryString@8 @5
+ eglQuerySurface@16 @13
+ eglReleaseTexImage@12 @21
+ eglReleaseThread@0 @17
+ eglSurfaceAttrib@16 @19
+ eglSwapBuffers@8 @32
+ eglSwapInterval@8 @22
+ eglTerminate@4 @4
+ eglWaitClient@0 @16
+ eglWaitGL@0 @30
+ eglWaitNative@4 @31
; Extensions
- eglGetPlatformDisplayEXT @35
- eglQuerySurfacePointerANGLE @36
- eglPostSubBufferNV @37
- eglQueryDisplayAttribEXT @48
- eglQueryDeviceAttribEXT @49
- eglQueryDeviceStringEXT @50
- eglCreateImageKHR @51
- eglDestroyImageKHR @52
- eglCreateDeviceANGLE @53
- eglReleaseDeviceANGLE @54
- eglCreateStreamKHR @55
- eglDestroyStreamKHR @56
- eglStreamAttribKHR @57
- eglQueryStreamKHR @58
- eglQueryStreamu64KHR @59
- eglStreamConsumerGLTextureExternalKHR @60
- eglStreamConsumerAcquireKHR @61
- eglStreamConsumerReleaseKHR @62
- eglStreamConsumerGLTextureExternalAttribsNV @63
- eglCreateStreamProducerD3DTextureNV12ANGLE @64
- eglStreamPostD3DTextureNV12ANGLE @65
- eglGetSyncValuesCHROMIUM @66
- eglSwapBuffersWithDamageEXT @67
- eglProgramCacheGetAttribANGLE @68
- eglProgramCachePopulateANGLE @69
- eglProgramCacheQueryANGLE @70
- eglProgramCacheResizeANGLE @71
+ eglGetPlatformDisplayEXT@12 @35
+ eglQuerySurfacePointerANGLE@16 @36
+ eglPostSubBufferNV@24 @37
+ eglQueryDisplayAttribEXT@12 @48
+ eglQueryDeviceAttribEXT@12 @49
+ eglQueryDeviceStringEXT@8 @50
+ eglCreateImageKHR@20 @51
+ eglDestroyImageKHR@8 @52
+ eglCreateDeviceANGLE@12 @53
+ eglReleaseDeviceANGLE@4 @54
+ eglCreateStreamKHR@8 @55
+ eglDestroyStreamKHR@8 @56
+ eglStreamAttribKHR@16 @57
+ eglQueryStreamKHR@16 @58
+ eglQueryStreamu64KHR@16 @59
+ eglStreamConsumerGLTextureExternalKHR@8 @60
+ eglStreamConsumerAcquireKHR@8 @61
+ eglStreamConsumerReleaseKHR@8 @62
+ eglStreamConsumerGLTextureExternalAttribsNV@12 @63
+ eglCreateStreamProducerD3DTextureNV12ANGLE@12 @64
+ eglStreamPostD3DTextureNV12ANGLE@16 @65
+ eglGetSyncValuesCHROMIUM@20 @66
+ eglSwapBuffersWithDamageEXT@16 @67
+ eglProgramCacheGetAttribANGLE@8 @68
+ eglProgramCachePopulateANGLE@20 @69
+ eglProgramCacheQueryANGLE@24 @70
+ eglProgramCacheResizeANGLE@12 @71
; 1.5 entry points
- eglCreateSync @38
- eglDestroySync @39
- eglClientWaitSync @40
- eglGetSyncAttrib @41
- eglCreateImage @42
- eglDestroyImage @43
- eglGetPlatformDisplay @44
- eglCreatePlatformWindowSurface @45
- eglCreatePlatformPixmapSurface @46
- eglWaitSync @47
+ eglCreateSync@12 @38
+ eglDestroySync@8 @39
+ eglClientWaitSync@20 @40
+ eglGetSyncAttrib@16 @41
+ eglCreateImage@20 @42
+ eglDestroyImage@8 @43
+ eglGetPlatformDisplay@12 @44
+ eglCreatePlatformWindowSurface@16 @45
+ eglCreatePlatformPixmapSurface@16 @46
+ eglWaitSync@12 @47
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def
index 2ff4cc0579..a182c21a05 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def
+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def
@@ -1,412 +1,411 @@
LIBRARY libGLESv2
EXPORTS
- glActiveTexture @1
- glAttachShader @2
- glBindAttribLocation @3
- glBindBuffer @4
- glBindFramebuffer @5
- glBindRenderbuffer @6
- glBindTexture @7
- glBlendColor @8
- glBlendEquation @9
- glBlendEquationSeparate @10
- glBlendFunc @11
- glBlendFuncSeparate @12
- glBufferData @13
- glBufferSubData @14
- glCheckFramebufferStatus @15
- glClear @16
- glClearColor @17
- glClearDepthf @18
- glClearStencil @19
- glColorMask @20
- glCompileShader @21
- glCompressedTexImage2D @22
- glCompressedTexSubImage2D @23
- glCopyTexImage2D @24
- glCopyTexSubImage2D @25
- glCreateProgram @26
- glCreateShader @27
- glCullFace @28
- glDeleteBuffers @29
- glDeleteFramebuffers @30
- glDeleteProgram @32
- glDeleteRenderbuffers @33
- glDeleteShader @34
- glDeleteTextures @31
- glDepthFunc @36
- glDepthMask @37
- glDepthRangef @38
- glDetachShader @35
- glDisable @39
- glDisableVertexAttribArray @40
- glDrawArrays @41
- glDrawElements @42
- glEnable @43
- glEnableVertexAttribArray @44
- glFinish @45
- glFlush @46
- glFramebufferRenderbuffer @47
- glFramebufferTexture2D @48
- glFrontFace @49
- glGenBuffers @50
- glGenFramebuffers @52
- glGenRenderbuffers @53
- glGenTextures @54
- glGenerateMipmap @51
- glGetActiveAttrib @55
- glGetActiveUniform @56
- glGetAttachedShaders @57
- glGetAttribLocation @58
- glGetBooleanv @59
- glGetBufferParameteriv @60
- glGetError @61
- glGetFloatv @62
- glGetFramebufferAttachmentParameteriv @63
- glGetIntegerv @64
- glGetProgramInfoLog @66
- glGetProgramiv @65
- glGetRenderbufferParameteriv @67
- glGetShaderInfoLog @69
- glGetShaderPrecisionFormat @70
- glGetShaderSource @71
- glGetShaderiv @68
- glGetString @72
- glGetTexParameterfv @73
- glGetTexParameteriv @74
- glGetUniformLocation @77
- glGetUniformfv @75
- glGetUniformiv @76
- glGetVertexAttribPointerv @80
- glGetVertexAttribfv @78
- glGetVertexAttribiv @79
- glHint @81
- glIsBuffer @82
- glIsEnabled @83
- glIsFramebuffer @84
- glIsProgram @85
- glIsRenderbuffer @86
- glIsShader @87
- glIsTexture @88
- glLineWidth @89
- glLinkProgram @90
- glPixelStorei @91
- glPolygonOffset @92
- glReadPixels @93
- glReleaseShaderCompiler @94
- glRenderbufferStorage @95
- glSampleCoverage @96
- glScissor @97
- glShaderBinary @98
- glShaderSource @99
- glStencilFunc @100
- glStencilFuncSeparate @101
- glStencilMask @102
- glStencilMaskSeparate @103
- glStencilOp @104
- glStencilOpSeparate @105
- glTexImage2D @106
- glTexParameterf @107
- glTexParameterfv @108
- glTexParameteri @109
- glTexParameteriv @110
- glTexSubImage2D @111
- glUniform1f @112
- glUniform1fv @113
- glUniform1i @114
- glUniform1iv @115
- glUniform2f @116
- glUniform2fv @117
- glUniform2i @118
- glUniform2iv @119
- glUniform3f @120
- glUniform3fv @121
- glUniform3i @122
- glUniform3iv @123
- glUniform4f @124
- glUniform4fv @125
- glUniform4i @126
- glUniform4iv @127
- glUniformMatrix2fv @128
- glUniformMatrix3fv @129
- glUniformMatrix4fv @130
- glUseProgram @131
- glValidateProgram @132
- glVertexAttrib1f @133
- glVertexAttrib1fv @134
- glVertexAttrib2f @135
- glVertexAttrib2fv @136
- glVertexAttrib3f @137
- glVertexAttrib3fv @138
- glVertexAttrib4f @139
- glVertexAttrib4fv @140
- glVertexAttribPointer @141
- glViewport @142
+ glActiveTexture@4 @1
+ glAttachShader@8 @2
+ glBindAttribLocation@12 @3
+ glBindBuffer@8 @4
+ glBindFramebuffer@8 @5
+ glBindRenderbuffer@8 @6
+ glBindTexture@8 @7
+ glBlendColor@16 @8
+ glBlendEquation@4 @9
+ glBlendEquationSeparate@8 @10
+ glBlendFunc@8 @11
+ glBlendFuncSeparate@16 @12
+ glBufferData@16 @13
+ glBufferSubData@16 @14
+ glCheckFramebufferStatus@4 @15
+ glClear@4 @16
+ glClearColor@16 @17
+ glClearDepthf@4 @18
+ glClearStencil@4 @19
+ glColorMask@16 @20
+ glCompileShader@4 @21
+ glCompressedTexImage2D@32 @22
+ glCompressedTexSubImage2D@36 @23
+ glCopyTexImage2D@32 @24
+ glCopyTexSubImage2D@32 @25
+ glCreateProgram@0 @26
+ glCreateShader@4 @27
+ glCullFace@4 @28
+ glDeleteBuffers@8 @29
+ glDeleteFramebuffers@8 @30
+ glDeleteProgram@4 @32
+ glDeleteRenderbuffers@8 @33
+ glDeleteShader@4 @34
+ glDeleteTextures@8 @31
+ glDepthFunc@4 @36
+ glDepthMask@4 @37
+ glDepthRangef@8 @38
+ glDetachShader@8 @35
+ glDisable@4 @39
+ glDisableVertexAttribArray@4 @40
+ glDrawArrays@12 @41
+ glDrawElements@16 @42
+ glEnable@4 @43
+ glEnableVertexAttribArray@4 @44
+ glFinish@0 @45
+ glFlush@0 @46
+ glFramebufferRenderbuffer@16 @47
+ glFramebufferTexture2D@20 @48
+ glFrontFace@4 @49
+ glGenBuffers@8 @50
+ glGenFramebuffers@8 @52
+ glGenRenderbuffers@8 @53
+ glGenTextures@8 @54
+ glGenerateMipmap@4 @51
+ glGetActiveAttrib@28 @55
+ glGetActiveUniform@28 @56
+ glGetAttachedShaders@16 @57
+ glGetAttribLocation@8 @58
+ glGetBooleanv@8 @59
+ glGetBufferParameteriv@12 @60
+ glGetError@0 @61
+ glGetFloatv@8 @62
+ glGetFramebufferAttachmentParameteriv@16 @63
+ glGetIntegerv@8 @64
+ glGetProgramInfoLog@16 @66
+ glGetProgramiv@12 @65
+ glGetRenderbufferParameteriv@12 @67
+ glGetShaderInfoLog@16 @69
+ glGetShaderPrecisionFormat@16 @70
+ glGetShaderSource@16 @71
+ glGetShaderiv@12 @68
+ glGetString@4 @72
+ glGetTexParameterfv@12 @73
+ glGetTexParameteriv@12 @74
+ glGetUniformLocation@8 @77
+ glGetUniformfv@12 @75
+ glGetUniformiv@12 @76
+ glGetVertexAttribPointerv@12 @80
+ glGetVertexAttribfv@12 @78
+ glGetVertexAttribiv@12 @79
+ glHint@8 @81
+ glIsBuffer@4 @82
+ glIsEnabled@4 @83
+ glIsFramebuffer@4 @84
+ glIsProgram@4 @85
+ glIsRenderbuffer@4 @86
+ glIsShader@4 @87
+ glIsTexture@4 @88
+ glLineWidth@4 @89
+ glLinkProgram@4 @90
+ glPixelStorei@8 @91
+ glPolygonOffset@8 @92
+ glReadPixels@28 @93
+ glReleaseShaderCompiler@0 @94
+ glRenderbufferStorage@16 @95
+ glSampleCoverage@8 @96
+ glScissor@16 @97
+ glShaderBinary@20 @98
+ glShaderSource@16 @99
+ glStencilFunc@12 @100
+ glStencilFuncSeparate@16 @101
+ glStencilMask@4 @102
+ glStencilMaskSeparate@8 @103
+ glStencilOp@12 @104
+ glStencilOpSeparate@16 @105
+ glTexImage2D@36 @106
+ glTexParameterf@12 @107
+ glTexParameterfv@12 @108
+ glTexParameteri@12 @109
+ glTexParameteriv@12 @110
+ glTexSubImage2D@36 @111
+ glUniform1f@8 @112
+ glUniform1fv@12 @113
+ glUniform1i@8 @114
+ glUniform1iv@12 @115
+ glUniform2f@12 @116
+ glUniform2fv@12 @117
+ glUniform2i@12 @118
+ glUniform2iv@12 @119
+ glUniform3f@16 @120
+ glUniform3fv@12 @121
+ glUniform3i@16 @122
+ glUniform3iv@12 @123
+ glUniform4f@20 @124
+ glUniform4fv@12 @125
+ glUniform4i@20 @126
+ glUniform4iv@12 @127
+ glUniformMatrix2fv@16 @128
+ glUniformMatrix3fv@16 @129
+ glUniformMatrix4fv@16 @130
+ glUseProgram@4 @131
+ glValidateProgram@4 @132
+ glVertexAttrib1f@8 @133
+ glVertexAttrib1fv@8 @134
+ glVertexAttrib2f@12 @135
+ glVertexAttrib2fv@8 @136
+ glVertexAttrib3f@16 @137
+ glVertexAttrib3fv@8 @138
+ glVertexAttrib4f@20 @139
+ glVertexAttrib4fv@8 @140
+ glVertexAttribPointer@24 @141
+ glViewport@16 @142
; Extensions
- glBlitFramebufferANGLE @149
- glRenderbufferStorageMultisampleANGLE @150
- glDeleteFencesNV @151
- glFinishFenceNV @152
- glGenFencesNV @153
- glGetFenceivNV @154
- glIsFenceNV @155
- glSetFenceNV @156
- glTestFenceNV @157
- glGetTranslatedShaderSourceANGLE @159
- glTexStorage2DEXT @160
- glGetGraphicsResetStatusEXT @161
- glReadnPixelsEXT @162
- glGetnUniformfvEXT @163
- glGetnUniformivEXT @164
- glGenQueriesEXT @165
- glDeleteQueriesEXT @166
- glIsQueryEXT @167
- glBeginQueryEXT @168
- glEndQueryEXT @169
- glGetQueryivEXT @170
- glGetQueryObjectuivEXT @171
- glVertexAttribDivisorANGLE @172
- glDrawArraysInstancedANGLE @173
- glDrawElementsInstancedANGLE @174
- glProgramBinaryOES @175
- glGetProgramBinaryOES @176
- glDrawBuffersEXT @179
- glMapBufferOES @285
- glUnmapBufferOES @286
- glGetBufferPointervOES @287
- glMapBufferRangeEXT @288
- glFlushMappedBufferRangeEXT @289
- glDiscardFramebufferEXT @293
- glInsertEventMarkerEXT @294
- glPushGroupMarkerEXT @295
- glPopGroupMarkerEXT @296
- glEGLImageTargetTexture2DOES @297
- glEGLImageTargetRenderbufferStorageOES @298
- glBindVertexArrayOES @299
- glDeleteVertexArraysOES @300
- glGenVertexArraysOES @301
- glIsVertexArrayOES @302
- glDebugMessageControlKHR @303
- glDebugMessageInsertKHR @304
- glDebugMessageCallbackKHR @305
- glGetDebugMessageLogKHR @306
- glPushDebugGroupKHR @307
- glPopDebugGroupKHR @308
- glObjectLabelKHR @309
- glGetObjectLabelKHR @310
- glObjectPtrLabelKHR @311
- glGetObjectPtrLabelKHR @312
- glGetPointervKHR @313
- glQueryCounterEXT @314
- glGetQueryObjectivEXT @315
- glGetQueryObjecti64vEXT @316
- glGetQueryObjectui64vEXT @317
- glBindUniformLocationCHROMIUM @318
- glCoverageModulationCHROMIUM @319
+ glBlitFramebufferANGLE@40 @149
+ glRenderbufferStorageMultisampleANGLE@20 @150
+ glDeleteFencesNV@8 @151
+ glFinishFenceNV@4 @152
+ glGenFencesNV@8 @153
+ glGetFenceivNV@12 @154
+ glIsFenceNV@4 @155
+ glSetFenceNV@8 @156
+ glTestFenceNV@4 @157
+ glGetTranslatedShaderSourceANGLE@16 @159
+ glTexStorage2DEXT@20 @160
+ glGetGraphicsResetStatusEXT@0 @161
+ glReadnPixelsEXT@32 @162
+ glGetnUniformfvEXT@16 @163
+ glGetnUniformivEXT@16 @164
+ glGenQueriesEXT@8 @165
+ glDeleteQueriesEXT@8 @166
+ glIsQueryEXT@4 @167
+ glBeginQueryEXT@8 @168
+ glEndQueryEXT@4 @169
+ glGetQueryivEXT@12 @170
+ glGetQueryObjectuivEXT@12 @171
+ glVertexAttribDivisorANGLE@8 @172
+ glDrawArraysInstancedANGLE@16 @173
+ glDrawElementsInstancedANGLE@20 @174
+ glProgramBinaryOES@16 @175
+ glGetProgramBinaryOES@20 @176
+ glDrawBuffersEXT@8 @179
+ glMapBufferOES@8 @285
+ glUnmapBufferOES@4 @286
+ glGetBufferPointervOES@12 @287
+ glMapBufferRangeEXT@16 @288
+ glFlushMappedBufferRangeEXT@12 @289
+ glDiscardFramebufferEXT@12 @293
+ glInsertEventMarkerEXT@8 @294
+ glPushGroupMarkerEXT@8 @295
+ glPopGroupMarkerEXT@0 @296
+ glEGLImageTargetTexture2DOES@8 @297
+ glEGLImageTargetRenderbufferStorageOES@8 @298
+ glBindVertexArrayOES@4 @299
+ glDeleteVertexArraysOES@8 @300
+ glGenVertexArraysOES@8 @301
+ glIsVertexArrayOES@4 @302
+ glDebugMessageControlKHR@24 @303
+ glDebugMessageInsertKHR@24 @304
+ glDebugMessageCallbackKHR@8 @305
+ glGetDebugMessageLogKHR@32 @306
+ glPushDebugGroupKHR@16 @307
+ glPopDebugGroupKHR@0 @308
+ glObjectLabelKHR@16 @309
+ glGetObjectLabelKHR@20 @310
+ glObjectPtrLabelKHR@12 @311
+ glGetObjectPtrLabelKHR@16 @312
+ glGetPointervKHR@8 @313
+ glQueryCounterEXT@8 @314
+ glGetQueryObjectivEXT@12 @315
+ glGetQueryObjecti64vEXT@12 @316
+ glGetQueryObjectui64vEXT@12 @317
+ glBindUniformLocationCHROMIUM@12 @318
+ glCoverageModulationCHROMIUM@4 @319
+ glMatrixLoadfCHROMIUM@8 @320
+ glMatrixLoadIdentityCHROMIUM@4 @321
+ glGenPathsCHROMIUM@4 @322
+ glDeletePathsCHROMIUM@8 @323
+ glIsPathCHROMIUM@4 @324
+ glPathCommandsCHROMIUM@24 @325
+ glPathParameterfCHROMIUM@12 @326
+ glPathParameteriCHROMIUM@12 @327
+ glGetPathParameterfvCHROMIUM@12 @328
+ glGetPathParameterivCHROMIUM@12 @329
+ glPathStencilFuncCHROMIUM@12 @330
+ glStencilFillPathCHROMIUM@12 @331
+ glStencilStrokePathCHROMIUM@12 @332
+ glCoverFillPathCHROMIUM@8 @333
+ glCoverStrokePathCHROMIUM@8 @334
+ glStencilThenCoverFillPathCHROMIUM@16 @335
+ glStencilThenCoverStrokePathCHROMIUM@16 @336
+ glCoverFillPathInstancedCHROMIUM@28 @337
+ glCoverStrokePathInstancedCHROMIUM@28 @338
+ glStencilStrokePathInstancedCHROMIUM@32 @339
+ glStencilFillPathInstancedCHROMIUM@32 @340
+ glStencilThenCoverFillPathInstancedCHROMIUM@36 @341
+ glStencilThenCoverStrokePathInstancedCHROMIUM@36 @342
+ glBindFragmentInputLocationCHROMIUM@12 @343
+ glProgramPathFragmentInputGenCHROMIUM@20 @344
- glMatrixLoadfCHROMIUM @320
- glMatrixLoadIdentityCHROMIUM @321
- glGenPathsCHROMIUM @322
- glDeletePathsCHROMIUM @323
- glIsPathCHROMIUM @324
- glPathCommandsCHROMIUM @325
- glPathParameterfCHROMIUM @326
- glPathParameteriCHROMIUM @327
- glGetPathParameterfvCHROMIUM @328
- glGetPathParameterivCHROMIUM @329
- glPathStencilFuncCHROMIUM @330
- glStencilFillPathCHROMIUM @331
- glStencilStrokePathCHROMIUM @332
- glCoverFillPathCHROMIUM @333
- glCoverStrokePathCHROMIUM @334
- glStencilThenCoverFillPathCHROMIUM @335
- glStencilThenCoverStrokePathCHROMIUM @336
- glCoverFillPathInstancedCHROMIUM @337
- glCoverStrokePathInstancedCHROMIUM @338
- glStencilStrokePathInstancedCHROMIUM @339
- glStencilFillPathInstancedCHROMIUM @340
- glStencilThenCoverFillPathInstancedCHROMIUM @341
- glStencilThenCoverStrokePathInstancedCHROMIUM @342
- glBindFragmentInputLocationCHROMIUM @343
- glProgramPathFragmentInputGenCHROMIUM @344
-
- glFramebufferTextureMultiviewLayeredANGLE @413
- glFramebufferTextureMultiviewSideBySideANGLE @414
- glRequestExtensionANGLE @415
+ glFramebufferTextureMultiviewLayeredANGLE@24 @413
+ glFramebufferTextureMultiviewSideBySideANGLE@24 @414
+ glRequestExtensionANGLE@4 @415
; GLES 3.0 Functions
- glReadBuffer @180
- glDrawRangeElements @181
- glTexImage3D @182
- glTexSubImage3D @183
- glCopyTexSubImage3D @184
- glCompressedTexImage3D @185
- glCompressedTexSubImage3D @186
- glGenQueries @187
- glDeleteQueries @188
- glIsQuery @189
- glBeginQuery @190
- glEndQuery @191
- glGetQueryiv @192
- glGetQueryObjectuiv @193
- glUnmapBuffer @194
- glGetBufferPointerv @195
- glDrawBuffers @196
- glUniformMatrix2x3fv @197
- glUniformMatrix3x2fv @198
- glUniformMatrix2x4fv @199
- glUniformMatrix4x2fv @200
- glUniformMatrix3x4fv @201
- glUniformMatrix4x3fv @202
- glBlitFramebuffer @203
- glRenderbufferStorageMultisample @204
- glFramebufferTextureLayer @205
- glMapBufferRange @206
- glFlushMappedBufferRange @207
- glBindVertexArray @208
- glDeleteVertexArrays @209
- glGenVertexArrays @210
- glIsVertexArray @211
- glGetIntegeri_v @212
- glBeginTransformFeedback @213
- glEndTransformFeedback @214
- glBindBufferRange @215
- glBindBufferBase @216
- glTransformFeedbackVaryings @217
- glGetTransformFeedbackVarying @218
- glVertexAttribIPointer @219
- glGetVertexAttribIiv @220
- glGetVertexAttribIuiv @221
- glVertexAttribI4i @222
- glVertexAttribI4ui @223
- glVertexAttribI4iv @224
- glVertexAttribI4uiv @225
- glGetUniformuiv @226
- glGetFragDataLocation @227
- glUniform1ui @228
- glUniform2ui @229
- glUniform3ui @230
- glUniform4ui @231
- glUniform1uiv @232
- glUniform2uiv @233
- glUniform3uiv @234
- glUniform4uiv @235
- glClearBufferiv @236
- glClearBufferuiv @237
- glClearBufferfv @238
- glClearBufferfi @239
- glGetStringi @240
- glCopyBufferSubData @241
- glGetUniformIndices @242
- glGetActiveUniformsiv @243
- glGetUniformBlockIndex @244
- glGetActiveUniformBlockiv @245
- glGetActiveUniformBlockName @246
- glUniformBlockBinding @247
- glDrawArraysInstanced @248
- glDrawElementsInstanced @249
- glFenceSync @250
- glIsSync @251
- glDeleteSync @252
- glClientWaitSync @253
- glWaitSync @254
- glGetInteger64v @255
- glGetSynciv @256
- glGetInteger64i_v @257
- glGetBufferParameteri64v @258
- glGenSamplers @259
- glDeleteSamplers @260
- glIsSampler @261
- glBindSampler @262
- glSamplerParameteri @263
- glSamplerParameteriv @264
- glSamplerParameterf @265
- glSamplerParameterfv @266
- glGetSamplerParameteriv @267
- glGetSamplerParameterfv @268
- glVertexAttribDivisor @269
- glBindTransformFeedback @270
- glDeleteTransformFeedbacks @271
- glGenTransformFeedbacks @272
- glIsTransformFeedback @273
- glPauseTransformFeedback @274
- glResumeTransformFeedback @275
- glGetProgramBinary @276
- glProgramBinary @277
- glProgramParameteri @278
- glInvalidateFramebuffer @279
- glInvalidateSubFramebuffer @280
- glTexStorage2D @281
- glTexStorage3D @282
- glGetInternalformativ @283
+ glReadBuffer@4 @180
+ glDrawRangeElements@24 @181
+ glTexImage3D@40 @182
+ glTexSubImage3D@44 @183
+ glCopyTexSubImage3D@36 @184
+ glCompressedTexImage3D@36 @185
+ glCompressedTexSubImage3D@44 @186
+ glGenQueries@8 @187
+ glDeleteQueries@8 @188
+ glIsQuery@4 @189
+ glBeginQuery@8 @190
+ glEndQuery@4 @191
+ glGetQueryiv@12 @192
+ glGetQueryObjectuiv@12 @193
+ glUnmapBuffer@4 @194
+ glGetBufferPointerv@12 @195
+ glDrawBuffers@8 @196
+ glUniformMatrix2x3fv@16 @197
+ glUniformMatrix3x2fv@16 @198
+ glUniformMatrix2x4fv@16 @199
+ glUniformMatrix4x2fv@16 @200
+ glUniformMatrix3x4fv@16 @201
+ glUniformMatrix4x3fv@16 @202
+ glBlitFramebuffer@40 @203
+ glRenderbufferStorageMultisample@20 @204
+ glFramebufferTextureLayer@20 @205
+ glMapBufferRange@16 @206
+ glFlushMappedBufferRange@12 @207
+ glBindVertexArray@4 @208
+ glDeleteVertexArrays@8 @209
+ glGenVertexArrays@8 @210
+ glIsVertexArray@4 @211
+ glGetIntegeri_v@12 @212
+ glBeginTransformFeedback@4 @213
+ glEndTransformFeedback@0 @214
+ glBindBufferRange@20 @215
+ glBindBufferBase@12 @216
+ glTransformFeedbackVaryings@16 @217
+ glGetTransformFeedbackVarying@28 @218
+ glVertexAttribIPointer@20 @219
+ glGetVertexAttribIiv@12 @220
+ glGetVertexAttribIuiv@12 @221
+ glVertexAttribI4i@20 @222
+ glVertexAttribI4ui@20 @223
+ glVertexAttribI4iv@8 @224
+ glVertexAttribI4uiv@8 @225
+ glGetUniformuiv@12 @226
+ glGetFragDataLocation@8 @227
+ glUniform1ui@8 @228
+ glUniform2ui@12 @229
+ glUniform3ui@16 @230
+ glUniform4ui@20 @231
+ glUniform1uiv@12 @232
+ glUniform2uiv@12 @233
+ glUniform3uiv@12 @234
+ glUniform4uiv@12 @235
+ glClearBufferiv@12 @236
+ glClearBufferuiv@12 @237
+ glClearBufferfv@12 @238
+ glClearBufferfi@16 @239
+ glGetStringi@8 @240
+ glCopyBufferSubData@20 @241
+ glGetUniformIndices@16 @242
+ glGetActiveUniformsiv@20 @243
+ glGetUniformBlockIndex@8 @244
+ glGetActiveUniformBlockiv@16 @245
+ glGetActiveUniformBlockName@20 @246
+ glUniformBlockBinding@12 @247
+ glDrawArraysInstanced@16 @248
+ glDrawElementsInstanced@20 @249
+ glFenceSync@8 @250
+ glIsSync@4 @251
+ glDeleteSync@4 @252
+ glClientWaitSync@16 @253
+ glWaitSync@16 @254
+ glGetInteger64v@8 @255
+ glGetSynciv@20 @256
+ glGetInteger64i_v@12 @257
+ glGetBufferParameteri64v@12 @258
+ glGenSamplers@8 @259
+ glDeleteSamplers@8 @260
+ glIsSampler@4 @261
+ glBindSampler@8 @262
+ glSamplerParameteri@12 @263
+ glSamplerParameteriv@12 @264
+ glSamplerParameterf@12 @265
+ glSamplerParameterfv@12 @266
+ glGetSamplerParameteriv@12 @267
+ glGetSamplerParameterfv@12 @268
+ glVertexAttribDivisor@8 @269
+ glBindTransformFeedback@8 @270
+ glDeleteTransformFeedbacks@8 @271
+ glGenTransformFeedbacks@8 @272
+ glIsTransformFeedback@4 @273
+ glPauseTransformFeedback@0 @274
+ glResumeTransformFeedback@0 @275
+ glGetProgramBinary@20 @276
+ glProgramBinary@16 @277
+ glProgramParameteri@12 @278
+ glInvalidateFramebuffer@12 @279
+ glInvalidateSubFramebuffer@28 @280
+ glTexStorage2D@20 @281
+ glTexStorage3D@24 @282
+ glGetInternalformativ@20 @283
; GLES 3.1 Functions
- glDispatchCompute @345
- glDispatchComputeIndirect @346
- glDrawArraysIndirect @347
- glDrawElementsIndirect @348
- glFramebufferParameteri @349
- glGetFramebufferParameteriv @350
- glGetProgramInterfaceiv @351
- glGetProgramResourceIndex @352
- glGetProgramResourceName @353
- glGetProgramResourceiv @354
- glGetProgramResourceLocation @355
- glUseProgramStages @356
- glActiveShaderProgram @357
- glCreateShaderProgramv @358
- glBindProgramPipeline @359
- glDeleteProgramPipelines @360
- glGenProgramPipelines @361
- glIsProgramPipeline @362
- glGetProgramPipelineiv @363
- glProgramUniform1i @364
- glProgramUniform2i @365
- glProgramUniform3i @366
- glProgramUniform4i @367
- glProgramUniform1ui @368
- glProgramUniform2ui @369
- glProgramUniform3ui @370
- glProgramUniform4ui @371
- glProgramUniform1f @372
- glProgramUniform2f @373
- glProgramUniform3f @374
- glProgramUniform4f @375
- glProgramUniform1iv @376
- glProgramUniform2iv @377
- glProgramUniform3iv @378
- glProgramUniform4iv @379
- glProgramUniform1uiv @380
- glProgramUniform2uiv @381
- glProgramUniform3uiv @382
- glProgramUniform4uiv @383
- glProgramUniform1fv @384
- glProgramUniform2fv @385
- glProgramUniform3fv @386
- glProgramUniform4fv @387
- glProgramUniformMatrix2fv @388
- glProgramUniformMatrix3fv @389
- glProgramUniformMatrix4fv @390
- glProgramUniformMatrix2x3fv @391
- glProgramUniformMatrix3x2fv @392
- glProgramUniformMatrix2x4fv @393
- glProgramUniformMatrix4x2fv @394
- glProgramUniformMatrix3x4fv @395
- glProgramUniformMatrix4x3fv @396
- glValidateProgramPipeline @397
- glGetProgramPipelineInfoLog @398
- glBindImageTexture @399
- glGetBooleani_v @400
- glMemoryBarrier @401
- glMemoryBarrierByRegion @402
- glTexStorage2DMultisample @403
- glGetMultisamplefv @404
- glSampleMaski @405
- glGetTexLevelParameteriv @406
- glGetTexLevelParameterfv @407
- glBindVertexBuffer @408
- glVertexAttribFormat @409
- glVertexAttribIFormat @410
- glVertexAttribBinding @411
- glVertexBindingDivisor @412
+ glDispatchCompute@12 @345
+ glDispatchComputeIndirect@4 @346
+ glDrawArraysIndirect@8 @347
+ glDrawElementsIndirect@12 @348
+ glFramebufferParameteri@12 @349
+ glGetFramebufferParameteriv@12 @350
+ glGetProgramInterfaceiv@16 @351
+ glGetProgramResourceIndex@12 @352
+ glGetProgramResourceName@24 @353
+ glGetProgramResourceiv@32 @354
+ glGetProgramResourceLocation@12 @355
+ glUseProgramStages@12 @356
+ glActiveShaderProgram@8 @357
+ glCreateShaderProgramv@12 @358
+ glBindProgramPipeline@4 @359
+ glDeleteProgramPipelines@8 @360
+ glGenProgramPipelines@8 @361
+ glIsProgramPipeline@4 @362
+ glGetProgramPipelineiv@12 @363
+ glProgramUniform1i@12 @364
+ glProgramUniform2i@16 @365
+ glProgramUniform3i@20 @366
+ glProgramUniform4i@24 @367
+ glProgramUniform1ui@12 @368
+ glProgramUniform2ui@16 @369
+ glProgramUniform3ui@20 @370
+ glProgramUniform4ui@24 @371
+ glProgramUniform1f@12 @372
+ glProgramUniform2f@16 @373
+ glProgramUniform3f@20 @374
+ glProgramUniform4f@24 @375
+ glProgramUniform1iv@16 @376
+ glProgramUniform2iv@16 @377
+ glProgramUniform3iv@16 @378
+ glProgramUniform4iv@16 @379
+ glProgramUniform1uiv@16 @380
+ glProgramUniform2uiv@16 @381
+ glProgramUniform3uiv@16 @382
+ glProgramUniform4uiv@16 @383
+ glProgramUniform1fv@16 @384
+ glProgramUniform2fv@16 @385
+ glProgramUniform3fv@16 @386
+ glProgramUniform4fv@16 @387
+ glProgramUniformMatrix2fv@20 @388
+ glProgramUniformMatrix3fv@20 @389
+ glProgramUniformMatrix4fv@20 @390
+ glProgramUniformMatrix2x3fv@20 @391
+ glProgramUniformMatrix3x2fv@20 @392
+ glProgramUniformMatrix2x4fv@20 @393
+ glProgramUniformMatrix4x2fv@20 @394
+ glProgramUniformMatrix3x4fv@20 @395
+ glProgramUniformMatrix4x3fv@20 @396
+ glValidateProgramPipeline@4 @397
+ glGetProgramPipelineInfoLog@16 @398
+ glBindImageTexture@28 @399
+ glGetBooleani_v@12 @400
+ glMemoryBarrier@4 @401
+ glMemoryBarrierByRegion@4 @402
+ glTexStorage2DMultisample@24 @403
+ glGetMultisamplefv@12 @404
+ glSampleMaski@8 @405
+ glGetTexLevelParameteriv@16 @406
+ glGetTexLevelParameterfv@16 @407
+ glBindVertexBuffer@16 @408
+ glVertexAttribFormat@20 @409
+ glVertexAttribIFormat@16 @410
+ glVertexAttribBinding@8 @411
+ glVertexBindingDivisor@8 @412
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def
index 2ff4cc0579..a182c21a05 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def
+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def
@@ -1,412 +1,411 @@
LIBRARY libGLESv2
EXPORTS
- glActiveTexture @1
- glAttachShader @2
- glBindAttribLocation @3
- glBindBuffer @4
- glBindFramebuffer @5
- glBindRenderbuffer @6
- glBindTexture @7
- glBlendColor @8
- glBlendEquation @9
- glBlendEquationSeparate @10
- glBlendFunc @11
- glBlendFuncSeparate @12
- glBufferData @13
- glBufferSubData @14
- glCheckFramebufferStatus @15
- glClear @16
- glClearColor @17
- glClearDepthf @18
- glClearStencil @19
- glColorMask @20
- glCompileShader @21
- glCompressedTexImage2D @22
- glCompressedTexSubImage2D @23
- glCopyTexImage2D @24
- glCopyTexSubImage2D @25
- glCreateProgram @26
- glCreateShader @27
- glCullFace @28
- glDeleteBuffers @29
- glDeleteFramebuffers @30
- glDeleteProgram @32
- glDeleteRenderbuffers @33
- glDeleteShader @34
- glDeleteTextures @31
- glDepthFunc @36
- glDepthMask @37
- glDepthRangef @38
- glDetachShader @35
- glDisable @39
- glDisableVertexAttribArray @40
- glDrawArrays @41
- glDrawElements @42
- glEnable @43
- glEnableVertexAttribArray @44
- glFinish @45
- glFlush @46
- glFramebufferRenderbuffer @47
- glFramebufferTexture2D @48
- glFrontFace @49
- glGenBuffers @50
- glGenFramebuffers @52
- glGenRenderbuffers @53
- glGenTextures @54
- glGenerateMipmap @51
- glGetActiveAttrib @55
- glGetActiveUniform @56
- glGetAttachedShaders @57
- glGetAttribLocation @58
- glGetBooleanv @59
- glGetBufferParameteriv @60
- glGetError @61
- glGetFloatv @62
- glGetFramebufferAttachmentParameteriv @63
- glGetIntegerv @64
- glGetProgramInfoLog @66
- glGetProgramiv @65
- glGetRenderbufferParameteriv @67
- glGetShaderInfoLog @69
- glGetShaderPrecisionFormat @70
- glGetShaderSource @71
- glGetShaderiv @68
- glGetString @72
- glGetTexParameterfv @73
- glGetTexParameteriv @74
- glGetUniformLocation @77
- glGetUniformfv @75
- glGetUniformiv @76
- glGetVertexAttribPointerv @80
- glGetVertexAttribfv @78
- glGetVertexAttribiv @79
- glHint @81
- glIsBuffer @82
- glIsEnabled @83
- glIsFramebuffer @84
- glIsProgram @85
- glIsRenderbuffer @86
- glIsShader @87
- glIsTexture @88
- glLineWidth @89
- glLinkProgram @90
- glPixelStorei @91
- glPolygonOffset @92
- glReadPixels @93
- glReleaseShaderCompiler @94
- glRenderbufferStorage @95
- glSampleCoverage @96
- glScissor @97
- glShaderBinary @98
- glShaderSource @99
- glStencilFunc @100
- glStencilFuncSeparate @101
- glStencilMask @102
- glStencilMaskSeparate @103
- glStencilOp @104
- glStencilOpSeparate @105
- glTexImage2D @106
- glTexParameterf @107
- glTexParameterfv @108
- glTexParameteri @109
- glTexParameteriv @110
- glTexSubImage2D @111
- glUniform1f @112
- glUniform1fv @113
- glUniform1i @114
- glUniform1iv @115
- glUniform2f @116
- glUniform2fv @117
- glUniform2i @118
- glUniform2iv @119
- glUniform3f @120
- glUniform3fv @121
- glUniform3i @122
- glUniform3iv @123
- glUniform4f @124
- glUniform4fv @125
- glUniform4i @126
- glUniform4iv @127
- glUniformMatrix2fv @128
- glUniformMatrix3fv @129
- glUniformMatrix4fv @130
- glUseProgram @131
- glValidateProgram @132
- glVertexAttrib1f @133
- glVertexAttrib1fv @134
- glVertexAttrib2f @135
- glVertexAttrib2fv @136
- glVertexAttrib3f @137
- glVertexAttrib3fv @138
- glVertexAttrib4f @139
- glVertexAttrib4fv @140
- glVertexAttribPointer @141
- glViewport @142
+ glActiveTexture@4 @1
+ glAttachShader@8 @2
+ glBindAttribLocation@12 @3
+ glBindBuffer@8 @4
+ glBindFramebuffer@8 @5
+ glBindRenderbuffer@8 @6
+ glBindTexture@8 @7
+ glBlendColor@16 @8
+ glBlendEquation@4 @9
+ glBlendEquationSeparate@8 @10
+ glBlendFunc@8 @11
+ glBlendFuncSeparate@16 @12
+ glBufferData@16 @13
+ glBufferSubData@16 @14
+ glCheckFramebufferStatus@4 @15
+ glClear@4 @16
+ glClearColor@16 @17
+ glClearDepthf@4 @18
+ glClearStencil@4 @19
+ glColorMask@16 @20
+ glCompileShader@4 @21
+ glCompressedTexImage2D@32 @22
+ glCompressedTexSubImage2D@36 @23
+ glCopyTexImage2D@32 @24
+ glCopyTexSubImage2D@32 @25
+ glCreateProgram@0 @26
+ glCreateShader@4 @27
+ glCullFace@4 @28
+ glDeleteBuffers@8 @29
+ glDeleteFramebuffers@8 @30
+ glDeleteProgram@4 @32
+ glDeleteRenderbuffers@8 @33
+ glDeleteShader@4 @34
+ glDeleteTextures@8 @31
+ glDepthFunc@4 @36
+ glDepthMask@4 @37
+ glDepthRangef@8 @38
+ glDetachShader@8 @35
+ glDisable@4 @39
+ glDisableVertexAttribArray@4 @40
+ glDrawArrays@12 @41
+ glDrawElements@16 @42
+ glEnable@4 @43
+ glEnableVertexAttribArray@4 @44
+ glFinish@0 @45
+ glFlush@0 @46
+ glFramebufferRenderbuffer@16 @47
+ glFramebufferTexture2D@20 @48
+ glFrontFace@4 @49
+ glGenBuffers@8 @50
+ glGenFramebuffers@8 @52
+ glGenRenderbuffers@8 @53
+ glGenTextures@8 @54
+ glGenerateMipmap@4 @51
+ glGetActiveAttrib@28 @55
+ glGetActiveUniform@28 @56
+ glGetAttachedShaders@16 @57
+ glGetAttribLocation@8 @58
+ glGetBooleanv@8 @59
+ glGetBufferParameteriv@12 @60
+ glGetError@0 @61
+ glGetFloatv@8 @62
+ glGetFramebufferAttachmentParameteriv@16 @63
+ glGetIntegerv@8 @64
+ glGetProgramInfoLog@16 @66
+ glGetProgramiv@12 @65
+ glGetRenderbufferParameteriv@12 @67
+ glGetShaderInfoLog@16 @69
+ glGetShaderPrecisionFormat@16 @70
+ glGetShaderSource@16 @71
+ glGetShaderiv@12 @68
+ glGetString@4 @72
+ glGetTexParameterfv@12 @73
+ glGetTexParameteriv@12 @74
+ glGetUniformLocation@8 @77
+ glGetUniformfv@12 @75
+ glGetUniformiv@12 @76
+ glGetVertexAttribPointerv@12 @80
+ glGetVertexAttribfv@12 @78
+ glGetVertexAttribiv@12 @79
+ glHint@8 @81
+ glIsBuffer@4 @82
+ glIsEnabled@4 @83
+ glIsFramebuffer@4 @84
+ glIsProgram@4 @85
+ glIsRenderbuffer@4 @86
+ glIsShader@4 @87
+ glIsTexture@4 @88
+ glLineWidth@4 @89
+ glLinkProgram@4 @90
+ glPixelStorei@8 @91
+ glPolygonOffset@8 @92
+ glReadPixels@28 @93
+ glReleaseShaderCompiler@0 @94
+ glRenderbufferStorage@16 @95
+ glSampleCoverage@8 @96
+ glScissor@16 @97
+ glShaderBinary@20 @98
+ glShaderSource@16 @99
+ glStencilFunc@12 @100
+ glStencilFuncSeparate@16 @101
+ glStencilMask@4 @102
+ glStencilMaskSeparate@8 @103
+ glStencilOp@12 @104
+ glStencilOpSeparate@16 @105
+ glTexImage2D@36 @106
+ glTexParameterf@12 @107
+ glTexParameterfv@12 @108
+ glTexParameteri@12 @109
+ glTexParameteriv@12 @110
+ glTexSubImage2D@36 @111
+ glUniform1f@8 @112
+ glUniform1fv@12 @113
+ glUniform1i@8 @114
+ glUniform1iv@12 @115
+ glUniform2f@12 @116
+ glUniform2fv@12 @117
+ glUniform2i@12 @118
+ glUniform2iv@12 @119
+ glUniform3f@16 @120
+ glUniform3fv@12 @121
+ glUniform3i@16 @122
+ glUniform3iv@12 @123
+ glUniform4f@20 @124
+ glUniform4fv@12 @125
+ glUniform4i@20 @126
+ glUniform4iv@12 @127
+ glUniformMatrix2fv@16 @128
+ glUniformMatrix3fv@16 @129
+ glUniformMatrix4fv@16 @130
+ glUseProgram@4 @131
+ glValidateProgram@4 @132
+ glVertexAttrib1f@8 @133
+ glVertexAttrib1fv@8 @134
+ glVertexAttrib2f@12 @135
+ glVertexAttrib2fv@8 @136
+ glVertexAttrib3f@16 @137
+ glVertexAttrib3fv@8 @138
+ glVertexAttrib4f@20 @139
+ glVertexAttrib4fv@8 @140
+ glVertexAttribPointer@24 @141
+ glViewport@16 @142
; Extensions
- glBlitFramebufferANGLE @149
- glRenderbufferStorageMultisampleANGLE @150
- glDeleteFencesNV @151
- glFinishFenceNV @152
- glGenFencesNV @153
- glGetFenceivNV @154
- glIsFenceNV @155
- glSetFenceNV @156
- glTestFenceNV @157
- glGetTranslatedShaderSourceANGLE @159
- glTexStorage2DEXT @160
- glGetGraphicsResetStatusEXT @161
- glReadnPixelsEXT @162
- glGetnUniformfvEXT @163
- glGetnUniformivEXT @164
- glGenQueriesEXT @165
- glDeleteQueriesEXT @166
- glIsQueryEXT @167
- glBeginQueryEXT @168
- glEndQueryEXT @169
- glGetQueryivEXT @170
- glGetQueryObjectuivEXT @171
- glVertexAttribDivisorANGLE @172
- glDrawArraysInstancedANGLE @173
- glDrawElementsInstancedANGLE @174
- glProgramBinaryOES @175
- glGetProgramBinaryOES @176
- glDrawBuffersEXT @179
- glMapBufferOES @285
- glUnmapBufferOES @286
- glGetBufferPointervOES @287
- glMapBufferRangeEXT @288
- glFlushMappedBufferRangeEXT @289
- glDiscardFramebufferEXT @293
- glInsertEventMarkerEXT @294
- glPushGroupMarkerEXT @295
- glPopGroupMarkerEXT @296
- glEGLImageTargetTexture2DOES @297
- glEGLImageTargetRenderbufferStorageOES @298
- glBindVertexArrayOES @299
- glDeleteVertexArraysOES @300
- glGenVertexArraysOES @301
- glIsVertexArrayOES @302
- glDebugMessageControlKHR @303
- glDebugMessageInsertKHR @304
- glDebugMessageCallbackKHR @305
- glGetDebugMessageLogKHR @306
- glPushDebugGroupKHR @307
- glPopDebugGroupKHR @308
- glObjectLabelKHR @309
- glGetObjectLabelKHR @310
- glObjectPtrLabelKHR @311
- glGetObjectPtrLabelKHR @312
- glGetPointervKHR @313
- glQueryCounterEXT @314
- glGetQueryObjectivEXT @315
- glGetQueryObjecti64vEXT @316
- glGetQueryObjectui64vEXT @317
- glBindUniformLocationCHROMIUM @318
- glCoverageModulationCHROMIUM @319
+ glBlitFramebufferANGLE@40 @149
+ glRenderbufferStorageMultisampleANGLE@20 @150
+ glDeleteFencesNV@8 @151
+ glFinishFenceNV@4 @152
+ glGenFencesNV@8 @153
+ glGetFenceivNV@12 @154
+ glIsFenceNV@4 @155
+ glSetFenceNV@8 @156
+ glTestFenceNV@4 @157
+ glGetTranslatedShaderSourceANGLE@16 @159
+ glTexStorage2DEXT@20 @160
+ glGetGraphicsResetStatusEXT@0 @161
+ glReadnPixelsEXT@32 @162
+ glGetnUniformfvEXT@16 @163
+ glGetnUniformivEXT@16 @164
+ glGenQueriesEXT@8 @165
+ glDeleteQueriesEXT@8 @166
+ glIsQueryEXT@4 @167
+ glBeginQueryEXT@8 @168
+ glEndQueryEXT@4 @169
+ glGetQueryivEXT@12 @170
+ glGetQueryObjectuivEXT@12 @171
+ glVertexAttribDivisorANGLE@8 @172
+ glDrawArraysInstancedANGLE@16 @173
+ glDrawElementsInstancedANGLE@20 @174
+ glProgramBinaryOES@16 @175
+ glGetProgramBinaryOES@20 @176
+ glDrawBuffersEXT@8 @179
+ glMapBufferOES@8 @285
+ glUnmapBufferOES@4 @286
+ glGetBufferPointervOES@12 @287
+ glMapBufferRangeEXT@16 @288
+ glFlushMappedBufferRangeEXT@12 @289
+ glDiscardFramebufferEXT@12 @293
+ glInsertEventMarkerEXT@8 @294
+ glPushGroupMarkerEXT@8 @295
+ glPopGroupMarkerEXT@0 @296
+ glEGLImageTargetTexture2DOES@8 @297
+ glEGLImageTargetRenderbufferStorageOES@8 @298
+ glBindVertexArrayOES@4 @299
+ glDeleteVertexArraysOES@8 @300
+ glGenVertexArraysOES@8 @301
+ glIsVertexArrayOES@4 @302
+ glDebugMessageControlKHR@24 @303
+ glDebugMessageInsertKHR@24 @304
+ glDebugMessageCallbackKHR@8 @305
+ glGetDebugMessageLogKHR@32 @306
+ glPushDebugGroupKHR@16 @307
+ glPopDebugGroupKHR@0 @308
+ glObjectLabelKHR@16 @309
+ glGetObjectLabelKHR@20 @310
+ glObjectPtrLabelKHR@12 @311
+ glGetObjectPtrLabelKHR@16 @312
+ glGetPointervKHR@8 @313
+ glQueryCounterEXT@8 @314
+ glGetQueryObjectivEXT@12 @315
+ glGetQueryObjecti64vEXT@12 @316
+ glGetQueryObjectui64vEXT@12 @317
+ glBindUniformLocationCHROMIUM@12 @318
+ glCoverageModulationCHROMIUM@4 @319
+ glMatrixLoadfCHROMIUM@8 @320
+ glMatrixLoadIdentityCHROMIUM@4 @321
+ glGenPathsCHROMIUM@4 @322
+ glDeletePathsCHROMIUM@8 @323
+ glIsPathCHROMIUM@4 @324
+ glPathCommandsCHROMIUM@24 @325
+ glPathParameterfCHROMIUM@12 @326
+ glPathParameteriCHROMIUM@12 @327
+ glGetPathParameterfvCHROMIUM@12 @328
+ glGetPathParameterivCHROMIUM@12 @329
+ glPathStencilFuncCHROMIUM@12 @330
+ glStencilFillPathCHROMIUM@12 @331
+ glStencilStrokePathCHROMIUM@12 @332
+ glCoverFillPathCHROMIUM@8 @333
+ glCoverStrokePathCHROMIUM@8 @334
+ glStencilThenCoverFillPathCHROMIUM@16 @335
+ glStencilThenCoverStrokePathCHROMIUM@16 @336
+ glCoverFillPathInstancedCHROMIUM@28 @337
+ glCoverStrokePathInstancedCHROMIUM@28 @338
+ glStencilStrokePathInstancedCHROMIUM@32 @339
+ glStencilFillPathInstancedCHROMIUM@32 @340
+ glStencilThenCoverFillPathInstancedCHROMIUM@36 @341
+ glStencilThenCoverStrokePathInstancedCHROMIUM@36 @342
+ glBindFragmentInputLocationCHROMIUM@12 @343
+ glProgramPathFragmentInputGenCHROMIUM@20 @344
- glMatrixLoadfCHROMIUM @320
- glMatrixLoadIdentityCHROMIUM @321
- glGenPathsCHROMIUM @322
- glDeletePathsCHROMIUM @323
- glIsPathCHROMIUM @324
- glPathCommandsCHROMIUM @325
- glPathParameterfCHROMIUM @326
- glPathParameteriCHROMIUM @327
- glGetPathParameterfvCHROMIUM @328
- glGetPathParameterivCHROMIUM @329
- glPathStencilFuncCHROMIUM @330
- glStencilFillPathCHROMIUM @331
- glStencilStrokePathCHROMIUM @332
- glCoverFillPathCHROMIUM @333
- glCoverStrokePathCHROMIUM @334
- glStencilThenCoverFillPathCHROMIUM @335
- glStencilThenCoverStrokePathCHROMIUM @336
- glCoverFillPathInstancedCHROMIUM @337
- glCoverStrokePathInstancedCHROMIUM @338
- glStencilStrokePathInstancedCHROMIUM @339
- glStencilFillPathInstancedCHROMIUM @340
- glStencilThenCoverFillPathInstancedCHROMIUM @341
- glStencilThenCoverStrokePathInstancedCHROMIUM @342
- glBindFragmentInputLocationCHROMIUM @343
- glProgramPathFragmentInputGenCHROMIUM @344
-
- glFramebufferTextureMultiviewLayeredANGLE @413
- glFramebufferTextureMultiviewSideBySideANGLE @414
- glRequestExtensionANGLE @415
+ glFramebufferTextureMultiviewLayeredANGLE@24 @413
+ glFramebufferTextureMultiviewSideBySideANGLE@24 @414
+ glRequestExtensionANGLE@4 @415
; GLES 3.0 Functions
- glReadBuffer @180
- glDrawRangeElements @181
- glTexImage3D @182
- glTexSubImage3D @183
- glCopyTexSubImage3D @184
- glCompressedTexImage3D @185
- glCompressedTexSubImage3D @186
- glGenQueries @187
- glDeleteQueries @188
- glIsQuery @189
- glBeginQuery @190
- glEndQuery @191
- glGetQueryiv @192
- glGetQueryObjectuiv @193
- glUnmapBuffer @194
- glGetBufferPointerv @195
- glDrawBuffers @196
- glUniformMatrix2x3fv @197
- glUniformMatrix3x2fv @198
- glUniformMatrix2x4fv @199
- glUniformMatrix4x2fv @200
- glUniformMatrix3x4fv @201
- glUniformMatrix4x3fv @202
- glBlitFramebuffer @203
- glRenderbufferStorageMultisample @204
- glFramebufferTextureLayer @205
- glMapBufferRange @206
- glFlushMappedBufferRange @207
- glBindVertexArray @208
- glDeleteVertexArrays @209
- glGenVertexArrays @210
- glIsVertexArray @211
- glGetIntegeri_v @212
- glBeginTransformFeedback @213
- glEndTransformFeedback @214
- glBindBufferRange @215
- glBindBufferBase @216
- glTransformFeedbackVaryings @217
- glGetTransformFeedbackVarying @218
- glVertexAttribIPointer @219
- glGetVertexAttribIiv @220
- glGetVertexAttribIuiv @221
- glVertexAttribI4i @222
- glVertexAttribI4ui @223
- glVertexAttribI4iv @224
- glVertexAttribI4uiv @225
- glGetUniformuiv @226
- glGetFragDataLocation @227
- glUniform1ui @228
- glUniform2ui @229
- glUniform3ui @230
- glUniform4ui @231
- glUniform1uiv @232
- glUniform2uiv @233
- glUniform3uiv @234
- glUniform4uiv @235
- glClearBufferiv @236
- glClearBufferuiv @237
- glClearBufferfv @238
- glClearBufferfi @239
- glGetStringi @240
- glCopyBufferSubData @241
- glGetUniformIndices @242
- glGetActiveUniformsiv @243
- glGetUniformBlockIndex @244
- glGetActiveUniformBlockiv @245
- glGetActiveUniformBlockName @246
- glUniformBlockBinding @247
- glDrawArraysInstanced @248
- glDrawElementsInstanced @249
- glFenceSync @250
- glIsSync @251
- glDeleteSync @252
- glClientWaitSync @253
- glWaitSync @254
- glGetInteger64v @255
- glGetSynciv @256
- glGetInteger64i_v @257
- glGetBufferParameteri64v @258
- glGenSamplers @259
- glDeleteSamplers @260
- glIsSampler @261
- glBindSampler @262
- glSamplerParameteri @263
- glSamplerParameteriv @264
- glSamplerParameterf @265
- glSamplerParameterfv @266
- glGetSamplerParameteriv @267
- glGetSamplerParameterfv @268
- glVertexAttribDivisor @269
- glBindTransformFeedback @270
- glDeleteTransformFeedbacks @271
- glGenTransformFeedbacks @272
- glIsTransformFeedback @273
- glPauseTransformFeedback @274
- glResumeTransformFeedback @275
- glGetProgramBinary @276
- glProgramBinary @277
- glProgramParameteri @278
- glInvalidateFramebuffer @279
- glInvalidateSubFramebuffer @280
- glTexStorage2D @281
- glTexStorage3D @282
- glGetInternalformativ @283
+ glReadBuffer@4 @180
+ glDrawRangeElements@24 @181
+ glTexImage3D@40 @182
+ glTexSubImage3D@44 @183
+ glCopyTexSubImage3D@36 @184
+ glCompressedTexImage3D@36 @185
+ glCompressedTexSubImage3D@44 @186
+ glGenQueries@8 @187
+ glDeleteQueries@8 @188
+ glIsQuery@4 @189
+ glBeginQuery@8 @190
+ glEndQuery@4 @191
+ glGetQueryiv@12 @192
+ glGetQueryObjectuiv@12 @193
+ glUnmapBuffer@4 @194
+ glGetBufferPointerv@12 @195
+ glDrawBuffers@8 @196
+ glUniformMatrix2x3fv@16 @197
+ glUniformMatrix3x2fv@16 @198
+ glUniformMatrix2x4fv@16 @199
+ glUniformMatrix4x2fv@16 @200
+ glUniformMatrix3x4fv@16 @201
+ glUniformMatrix4x3fv@16 @202
+ glBlitFramebuffer@40 @203
+ glRenderbufferStorageMultisample@20 @204
+ glFramebufferTextureLayer@20 @205
+ glMapBufferRange@16 @206
+ glFlushMappedBufferRange@12 @207
+ glBindVertexArray@4 @208
+ glDeleteVertexArrays@8 @209
+ glGenVertexArrays@8 @210
+ glIsVertexArray@4 @211
+ glGetIntegeri_v@12 @212
+ glBeginTransformFeedback@4 @213
+ glEndTransformFeedback@0 @214
+ glBindBufferRange@20 @215
+ glBindBufferBase@12 @216
+ glTransformFeedbackVaryings@16 @217
+ glGetTransformFeedbackVarying@28 @218
+ glVertexAttribIPointer@20 @219
+ glGetVertexAttribIiv@12 @220
+ glGetVertexAttribIuiv@12 @221
+ glVertexAttribI4i@20 @222
+ glVertexAttribI4ui@20 @223
+ glVertexAttribI4iv@8 @224
+ glVertexAttribI4uiv@8 @225
+ glGetUniformuiv@12 @226
+ glGetFragDataLocation@8 @227
+ glUniform1ui@8 @228
+ glUniform2ui@12 @229
+ glUniform3ui@16 @230
+ glUniform4ui@20 @231
+ glUniform1uiv@12 @232
+ glUniform2uiv@12 @233
+ glUniform3uiv@12 @234
+ glUniform4uiv@12 @235
+ glClearBufferiv@12 @236
+ glClearBufferuiv@12 @237
+ glClearBufferfv@12 @238
+ glClearBufferfi@16 @239
+ glGetStringi@8 @240
+ glCopyBufferSubData@20 @241
+ glGetUniformIndices@16 @242
+ glGetActiveUniformsiv@20 @243
+ glGetUniformBlockIndex@8 @244
+ glGetActiveUniformBlockiv@16 @245
+ glGetActiveUniformBlockName@20 @246
+ glUniformBlockBinding@12 @247
+ glDrawArraysInstanced@16 @248
+ glDrawElementsInstanced@20 @249
+ glFenceSync@8 @250
+ glIsSync@4 @251
+ glDeleteSync@4 @252
+ glClientWaitSync@16 @253
+ glWaitSync@16 @254
+ glGetInteger64v@8 @255
+ glGetSynciv@20 @256
+ glGetInteger64i_v@12 @257
+ glGetBufferParameteri64v@12 @258
+ glGenSamplers@8 @259
+ glDeleteSamplers@8 @260
+ glIsSampler@4 @261
+ glBindSampler@8 @262
+ glSamplerParameteri@12 @263
+ glSamplerParameteriv@12 @264
+ glSamplerParameterf@12 @265
+ glSamplerParameterfv@12 @266
+ glGetSamplerParameteriv@12 @267
+ glGetSamplerParameterfv@12 @268
+ glVertexAttribDivisor@8 @269
+ glBindTransformFeedback@8 @270
+ glDeleteTransformFeedbacks@8 @271
+ glGenTransformFeedbacks@8 @272
+ glIsTransformFeedback@4 @273
+ glPauseTransformFeedback@0 @274
+ glResumeTransformFeedback@0 @275
+ glGetProgramBinary@20 @276
+ glProgramBinary@16 @277
+ glProgramParameteri@12 @278
+ glInvalidateFramebuffer@12 @279
+ glInvalidateSubFramebuffer@28 @280
+ glTexStorage2D@20 @281
+ glTexStorage3D@24 @282
+ glGetInternalformativ@20 @283
; GLES 3.1 Functions
- glDispatchCompute @345
- glDispatchComputeIndirect @346
- glDrawArraysIndirect @347
- glDrawElementsIndirect @348
- glFramebufferParameteri @349
- glGetFramebufferParameteriv @350
- glGetProgramInterfaceiv @351
- glGetProgramResourceIndex @352
- glGetProgramResourceName @353
- glGetProgramResourceiv @354
- glGetProgramResourceLocation @355
- glUseProgramStages @356
- glActiveShaderProgram @357
- glCreateShaderProgramv @358
- glBindProgramPipeline @359
- glDeleteProgramPipelines @360
- glGenProgramPipelines @361
- glIsProgramPipeline @362
- glGetProgramPipelineiv @363
- glProgramUniform1i @364
- glProgramUniform2i @365
- glProgramUniform3i @366
- glProgramUniform4i @367
- glProgramUniform1ui @368
- glProgramUniform2ui @369
- glProgramUniform3ui @370
- glProgramUniform4ui @371
- glProgramUniform1f @372
- glProgramUniform2f @373
- glProgramUniform3f @374
- glProgramUniform4f @375
- glProgramUniform1iv @376
- glProgramUniform2iv @377
- glProgramUniform3iv @378
- glProgramUniform4iv @379
- glProgramUniform1uiv @380
- glProgramUniform2uiv @381
- glProgramUniform3uiv @382
- glProgramUniform4uiv @383
- glProgramUniform1fv @384
- glProgramUniform2fv @385
- glProgramUniform3fv @386
- glProgramUniform4fv @387
- glProgramUniformMatrix2fv @388
- glProgramUniformMatrix3fv @389
- glProgramUniformMatrix4fv @390
- glProgramUniformMatrix2x3fv @391
- glProgramUniformMatrix3x2fv @392
- glProgramUniformMatrix2x4fv @393
- glProgramUniformMatrix4x2fv @394
- glProgramUniformMatrix3x4fv @395
- glProgramUniformMatrix4x3fv @396
- glValidateProgramPipeline @397
- glGetProgramPipelineInfoLog @398
- glBindImageTexture @399
- glGetBooleani_v @400
- glMemoryBarrier @401
- glMemoryBarrierByRegion @402
- glTexStorage2DMultisample @403
- glGetMultisamplefv @404
- glSampleMaski @405
- glGetTexLevelParameteriv @406
- glGetTexLevelParameterfv @407
- glBindVertexBuffer @408
- glVertexAttribFormat @409
- glVertexAttribIFormat @410
- glVertexAttribBinding @411
- glVertexBindingDivisor @412
+ glDispatchCompute@12 @345
+ glDispatchComputeIndirect@4 @346
+ glDrawArraysIndirect@8 @347
+ glDrawElementsIndirect@12 @348
+ glFramebufferParameteri@12 @349
+ glGetFramebufferParameteriv@12 @350
+ glGetProgramInterfaceiv@16 @351
+ glGetProgramResourceIndex@12 @352
+ glGetProgramResourceName@24 @353
+ glGetProgramResourceiv@32 @354
+ glGetProgramResourceLocation@12 @355
+ glUseProgramStages@12 @356
+ glActiveShaderProgram@8 @357
+ glCreateShaderProgramv@12 @358
+ glBindProgramPipeline@4 @359
+ glDeleteProgramPipelines@8 @360
+ glGenProgramPipelines@8 @361
+ glIsProgramPipeline@4 @362
+ glGetProgramPipelineiv@12 @363
+ glProgramUniform1i@12 @364
+ glProgramUniform2i@16 @365
+ glProgramUniform3i@20 @366
+ glProgramUniform4i@24 @367
+ glProgramUniform1ui@12 @368
+ glProgramUniform2ui@16 @369
+ glProgramUniform3ui@20 @370
+ glProgramUniform4ui@24 @371
+ glProgramUniform1f@12 @372
+ glProgramUniform2f@16 @373
+ glProgramUniform3f@20 @374
+ glProgramUniform4f@24 @375
+ glProgramUniform1iv@16 @376
+ glProgramUniform2iv@16 @377
+ glProgramUniform3iv@16 @378
+ glProgramUniform4iv@16 @379
+ glProgramUniform1uiv@16 @380
+ glProgramUniform2uiv@16 @381
+ glProgramUniform3uiv@16 @382
+ glProgramUniform4uiv@16 @383
+ glProgramUniform1fv@16 @384
+ glProgramUniform2fv@16 @385
+ glProgramUniform3fv@16 @386
+ glProgramUniform4fv@16 @387
+ glProgramUniformMatrix2fv@20 @388
+ glProgramUniformMatrix3fv@20 @389
+ glProgramUniformMatrix4fv@20 @390
+ glProgramUniformMatrix2x3fv@20 @391
+ glProgramUniformMatrix3x2fv@20 @392
+ glProgramUniformMatrix2x4fv@20 @393
+ glProgramUniformMatrix4x2fv@20 @394
+ glProgramUniformMatrix3x4fv@20 @395
+ glProgramUniformMatrix4x3fv@20 @396
+ glValidateProgramPipeline@4 @397
+ glGetProgramPipelineInfoLog@16 @398
+ glBindImageTexture@28 @399
+ glGetBooleani_v@12 @400
+ glMemoryBarrier@4 @401
+ glMemoryBarrierByRegion@4 @402
+ glTexStorage2DMultisample@24 @403
+ glGetMultisamplefv@12 @404
+ glSampleMaski@8 @405
+ glGetTexLevelParameteriv@16 @406
+ glGetTexLevelParameterfv@16 @407
+ glBindVertexBuffer@16 @408
+ glVertexAttribFormat@20 @409
+ glVertexAttribIFormat@16 @410
+ glVertexAttribBinding@8 @411
+ glVertexBindingDivisor@8 @412
diff --git a/src/concurrent/qtconcurrentrun.cpp b/src/concurrent/qtconcurrentrun.cpp
index bbd1f5ec62..d9867e1f1a 100644
--- a/src/concurrent/qtconcurrentrun.cpp
+++ b/src/concurrent/qtconcurrentrun.cpp
@@ -138,10 +138,10 @@
T is the same type as the return value of \a function. Non-void return
values can be accessed via the QFuture::result() function.
- Note that the QFuture returned by QtConcurrent::run() does not support
- canceling, pausing, or progress reporting. The QFuture returned can only
- be used to query for the running/finished status and the return value of
- the function.
+ \note The QFuture returned can only be used to query for the
+ running/finished status and the return value of the function. In particular,
+ canceling or pausing can be issued only if the computations behind the future
+ has not been started.
\sa {Concurrent Run}
*/
@@ -157,10 +157,10 @@
T is the same type as the return value of \a function. Non-void return
values can be accessed via the QFuture::result() function.
- Note that the QFuture returned by QtConcurrent::run() does not support
- canceling, pausing, or progress reporting. The QFuture returned can only
- be used to query for the running/finished status and the return value of
- the function.
+ \note The QFuture returned can only be used to query for the
+ running/finished status and the return value of the function. In particular,
+ canceling or pausing can be issued only if the computations behind the future
+ has not been started.
\sa {Concurrent Run}
*/
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp
index c879eb6d1a..46b01449d4 100644
--- a/src/corelib/animation/qabstractanimation.cpp
+++ b/src/corelib/animation/qabstractanimation.cpp
@@ -1063,7 +1063,7 @@ QAbstractAnimation::~QAbstractAnimation()
if (d->state != Stopped) {
QAbstractAnimation::State oldState = d->state;
d->state = Stopped;
- emit stateChanged(oldState, d->state);
+ emit stateChanged(d->state, oldState);
if (oldState == QAbstractAnimation::Running)
QAnimationTimer::unregisterAnimation(this);
}
diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp
index d25a607d9f..b6413d7902 100644
--- a/src/corelib/io/qstorageinfo_unix.cpp
+++ b/src/corelib/io/qstorageinfo_unix.cpp
@@ -846,6 +846,9 @@ QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes()
const QString mountDir = it.rootPath();
QStorageInfo info(mountDir);
+ info.d->device = it.device();
+ info.d->fileSystemType = it.fileSystemType();
+ info.d->subvolume = it.subvolume();
if (info.bytesTotal() == 0)
continue;
volumes.append(info);
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 2a17642ba7..5d300a0488 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -977,7 +977,11 @@ void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on)
QCoreApplicationPrivate::attribs |= 1 << attribute;
else
QCoreApplicationPrivate::attribs &= ~(1 << attribute);
+#if defined(QT_NO_QOBJECT)
if (Q_UNLIKELY(qApp)) {
+#else
+ if (Q_UNLIKELY(QCoreApplicationPrivate::is_app_running)) {
+#endif
switch (attribute) {
case Qt::AA_EnableHighDpiScaling:
case Qt::AA_DisableHighDpiScaling:
diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp
index 65e1db3745..822b68cf62 100644
--- a/src/corelib/kernel/qcoreapplication_win.cpp
+++ b/src/corelib/kernel/qcoreapplication_win.cpp
@@ -688,6 +688,12 @@ static const char *winPosInsertAfter(quintptr h)
static const char *sessionMgrLogOffOption(uint p)
{
+#ifndef ENDSESSION_CLOSEAPP
+#define ENDSESSION_CLOSEAPP 0x00000001
+#endif
+#ifndef ENDSESSION_CRITICAL
+#define ENDSESSION_CRITICAL 0x40000000
+#endif
static const QWinMessageMapping<uint> values[] = {
{ENDSESSION_CLOSEAPP, "Close application"},
{ENDSESSION_CRITICAL, "Force application end"},
@@ -881,12 +887,6 @@ QString decodeMSG(const MSG& msg)
parameters += QLatin1Char(')');
}
break;
-#ifndef ENDSESSION_CLOSEAPP
-#define ENDSESSION_CLOSEAPP 0x00000001
-#endif
-#ifndef ENDSESSION_CRITICAL
-#define ENDSESSION_CRITICAL 0x40000000
-#endif
case WM_QUERYENDSESSION:
parameters = QLatin1String("End session: ");
if (const char *logoffOption = sessionMgrLogOffOption(uint(wParam)))
diff --git a/src/corelib/serialization/qjsoncbor.cpp b/src/corelib/serialization/qjsoncbor.cpp
index dc5f384108..e0c390f610 100644
--- a/src/corelib/serialization/qjsoncbor.cpp
+++ b/src/corelib/serialization/qjsoncbor.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 Intel Corporation.
+** Copyright (C) 2019 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -598,10 +598,12 @@ QCborValue QCborValue::fromJsonValue(const QJsonValue &v)
switch (v.type()) {
case QJsonValue::Bool:
return v.b;
- case QJsonValue::Double:
- if (v.dbl == qint64(v.dbl))
- return qint64(v.dbl);
+ case QJsonValue::Double: {
+ qint64 i;
+ if (convertDoubleTo(v.dbl, &i))
+ return i;
return v.dbl;
+ }
case QJsonValue::String:
return v.toString();
case QJsonValue::Array:
diff --git a/src/corelib/thread/qfuture.qdoc b/src/corelib/thread/qfuture.qdoc
index 7db65dacd3..076725e19c 100644
--- a/src/corelib/thread/qfuture.qdoc
+++ b/src/corelib/thread/qfuture.qdoc
@@ -55,8 +55,8 @@
instance, the computation can be canceled with the cancel() function. To
pause the computation, use the setPaused() function or one of the pause(),
resume(), or togglePaused() convenience functions. Be aware that not all
- asynchronous computations can be canceled or paused. For example, the
- future returned by QtConcurrent::run() cannot be canceled; but the
+ running asynchronous computations can be canceled or paused. For example,
+ the future returned by QtConcurrent::run() cannot be canceled; but the
future returned by QtConcurrent::mappedReduced() can.
Progress information is provided by the progressValue(),
@@ -133,8 +133,8 @@
Any QFutureWatcher object that is watching this future will not deliver
progress and result ready signals on a canceled future.
- Be aware that not all asynchronous computations can be canceled. For
- example, the future returned by QtConcurrent::run() cannot be canceled;
+ Be aware that not all running asynchronous computations can be canceled.
+ For example, the future returned by QtConcurrent::run() cannot be canceled;
but the future returned by QtConcurrent::mappedReduced() can.
*/
diff --git a/src/corelib/thread/qfuturewatcher.cpp b/src/corelib/thread/qfuturewatcher.cpp
index ed369ce829..06bc4740f9 100644
--- a/src/corelib/thread/qfuturewatcher.cpp
+++ b/src/corelib/thread/qfuturewatcher.cpp
@@ -84,8 +84,8 @@ QT_BEGIN_NAMESPACE
\snippet code/src_corelib_thread_qfuturewatcher.cpp 0
- Be aware that not all asynchronous computations can be canceled or paused.
- For example, the future returned by QtConcurrent::run() cannot be
+ Be aware that not all running asynchronous computations can be canceled or
+ paused. For example, the future returned by QtConcurrent::run() cannot be
canceled; but the future returned by QtConcurrent::mappedReduced() can.
QFutureWatcher<void> is specialized to not contain any of the result
@@ -124,9 +124,9 @@ QFutureWatcherBase::QFutureWatcherBase(QObject *parent)
progressRangeChanged(), progressTextChanged(), resultReadyAt(), and
resultsReadyAt() signals.
- Be aware that not all asynchronous computations can be canceled. For
- example, the QFuture returned by QtConcurrent::run() cannot be canceled;
- but the QFuture returned by QtConcurrent::mappedReduced() can.
+ Be aware that not all running asynchronous computations can be canceled.
+ For example, the QFuture returned by QtConcurrent::run() cannot be
+ canceled; but the QFuture returned by QtConcurrent::mappedReduced() can.
*/
void QFutureWatcherBase::cancel()
{
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 7926323a4d..89efbff6aa 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -727,6 +727,12 @@ void QThread::start(Priority priority)
}
}
+#ifdef Q_OS_INTEGRITY
+ if (Q_LIKELY(objectName().isEmpty()))
+ pthread_attr_setthreadname(&attr, metaObject()->className());
+ else
+ pthread_attr_setthreadname(&attr, objectName().toLocal8Bit());
+#endif
pthread_t threadId;
int code = pthread_create(&threadId, &attr, QThreadPrivate::start, this);
if (code == EPERM) {
diff --git a/src/dbus/doc/snippets/cmake/examples.cmake b/src/dbus/doc/snippets/cmake/examples.cmake
new file mode 100644
index 0000000000..cb4f86844f
--- /dev/null
+++ b/src/dbus/doc/snippets/cmake/examples.cmake
@@ -0,0 +1,3 @@
+#! [qt5_add_dbus_adaptor]
+qt5_add_dbus_adaptor(GENERATED_SOURCES org.example.chat.xml chat.h ChatMainWindow)
+#! [qt5_add_dbus_adaptor]
diff --git a/src/dbus/doc/src/qtdbus-cmake.qdoc b/src/dbus/doc/src/qtdbus-cmake.qdoc
new file mode 100644
index 0000000000..de127fa9f4
--- /dev/null
+++ b/src/dbus/doc/src/qtdbus-cmake.qdoc
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+\page qtdbus-cmake-qt5-add-dbus-interface.html
+\ingroup cmake-commands-qtdbus
+
+\title qt5_add_dbus_interface
+
+\brief Generates C++ sources implementing an interface for a D-Bus interface
+description file.
+
+\section1 Synopsis
+
+\badcode
+qt5_add_dbus_interface(<VAR> dbus_spec basename)
+\endcode
+
+\section1 Description
+
+Generates C++ sources implementing an interface for a D-Bus interface description
+file defined in \c{dbus_spec}. The generated files are named after \c{basename}:
+\c{basename.h}, \c{basename.cpp}, \c{basename.moc}. The paths of the files
+are added to \c{<VAR>}.
+
+The function sets up a call to the \l{Qt D-Bus XML compiler (qdbusxml2cpp)}
+in interface (proxy) mode. By default, \c{qdbusxml2cpp} generates a C++
+class named after the interface name, with a namespaced alias:
+
+\table
+\header
+ \li D-Bus Interface Name
+ \li Class name
+ \li Namespaced name
+\row
+ \li \c{org.example.chat}
+ \li \c{OrgExampleChatInterface}
+ \li \c{org.example.chat}
+\endtable
+
+\section1 Options
+
+Options can be set using \c set_source_file_property on the \c dbus_spec:
+
+\table
+\header
+ \li Option
+ \li Value
+ \li Description
+\row
+ \li \c CLASSNAME
+ \li \c class_name
+ \li Override the default interface class name with \c{class_name}.
+\row
+ \li \c NO_NAMESPACE
+ \li boolean
+ \li Do not generate the namespaced name if set to \c{ON}.
+\row
+ \li \c INCLUDE
+ \li \c path
+ \li Add an \c{#include "path"} in the generated code.
+\endtable
+*/
+
+/*!
+\page qtdbus-cmake-qt5-add-dbus-interfaces.html
+\ingroup cmake-commands-qtdbus
+
+\title qt5_add_dbus_interfaces
+
+\brief Generates C++ sources implementing interfaces for D-Bus interface
+description files.
+
+\section1 Synopsis
+
+\badcode
+qt5_add_dbus_interfaces(<VAR> dbus_spec1 [dbus_spec2 ...])
+\endcode
+
+\section1 Description
+
+Generates C++ sources implementing D-Bus interfaces defined in \c{dbus_spec1},
+\c{dbus_spec2}, where each argument needs to be the path to a valid D-Bus
+interface description file. The paths of the generated files are added to
+\c{<VAR>}.
+
+For each argument, a call to the \l{Qt D-Bus XML compiler (qdbusxml2cpp)}
+in interface (proxy) mode is set up.
+
+The generated C++ source files are named after the XML file: For the file
+\c{org.example.chat.xml} the generated header will be named
+\c{orgexamplechatinterface.h}.
+
+\section1 Options
+
+Options can be set using \c set_source_file_property on each of the file
+arguments:
+
+\table
+\header
+ \li Option
+ \li Value
+ \li Description
+\row
+ \li \c CLASSNAME
+ \li \c class_name
+ \li Override the default interface class name with \c{class_name}.
+\row
+ \li \c NO_NAMESPACE
+ \li boolean
+ \li Do not generate the namespaced name if set to \c{ON}.
+\row
+ \li \c INCLUDE
+ \li \c path
+ \li Add an \c{#include "path"} in the generated code.
+\endtable
+*/
+
+/*!
+\page qtdbus-cmake-qt5-generate-dbus-interface.html
+\ingroup cmake-commands-qtdbus
+
+\title qt5_generate_dbus_interface
+
+\brief Generates a D-Bus interface from a header file.
+
+\section1 Synopsis
+
+\badcode
+qt5_generate_dbus_interface(header
+ [customName]
+ [OPTIONS options]
+)
+\endcode
+
+\section1 Description
+
+Parses the C++ source or header file containing a QObject-derived class
+declaration and generates a file containing the D-BUS Introspection XML.
+
+By default, the generated XML file is stored in the current binary directory,
+and has the same base name as the header. You can specify a different name or
+path by adding \c{customName} as an optional second argument.
+
+\section1 Options
+
+The function sets up a call to the \c{qdbuscpp2xml} command line tool. Further
+arguments to the tool can be set after \c{OPTIONS}.
+*/
+
+/*!
+\page qtdbus-cmake-qt5-add-dbus-adaptor.html
+\ingroup cmake-commands-qtdbus
+
+\title qt5_add_dbus_adaptor
+
+\brief Generates an adaptor class for a D-Bus interface.
+
+\section1 Synopsis
+
+\badcode
+qt5_add_dbus_adaptor(<VAR> dbus_spec header parent_class
+ [basename]
+ [classname])
+\endcode
+
+\section1 Description
+
+Generates a C++ header file implementing an adaptor for a D-Bus interface
+description file defined in \c{dbus_spec}. The path of the generated file is
+added to \c{<VAR>}. The generated adaptor class takes a pointer to
+\c{parent_class} as QObject parent. \c{parent_class} should be declared in
+\c{header}, which is included in the generated code as \c{#include "header"}.
+
+The function sets up a call to the \l{Qt D-Bus XML compiler (qdbusxml2cpp)}
+in adaptor mode. The default file and class name are generated from the last
+segment in the \c{dbus_spec} base name:
+
+\table
+\header
+ \li XML file
+ \li Header file
+ \li Class name
+\row
+ \li \c{org.example.chat}
+ \li \c{chatadaptor.h}
+ \li \c{ChatAdaptor}
+\endtable
+
+
+You can change the name of the header file to be generated by passing
+\c{basename} as the fifth argument. The \c{.h} suffix is always added.
+
+You can change the default class name by passing \c{classname} as the sixth
+argument.
+
+\section1 Examples
+
+\snippet cmake/examples.cmake qt5_add_dbus_adaptor
+*/
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp
index 68e36de24b..db47a3abc1 100644
--- a/src/gui/accessible/qaccessible.cpp
+++ b/src/gui/accessible/qaccessible.cpp
@@ -350,6 +350,7 @@ Q_LOGGING_CATEGORY(lcAccessibilityCore, "qt.accessibility.core");
\value MenuItem An item in a menu or menu bar.
\value NoRole The object has no role. This usually indicates an invalid object.
\value Note A section whose content is parenthetic or ancillary to the main content of the resource.
+ \value Notification An object that represents a notification (e.g. in the system tray). This role only has an effect on Linux.
\value PageTab A page tab that the user can select to switch to a different page in a dialog.
\value PageTabList A list of page tabs.
\value Paragraph A paragraph of text (usually found in documents).
diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h
index e2163b06d0..2220efd5cb 100644
--- a/src/gui/accessible/qaccessible.h
+++ b/src/gui/accessible/qaccessible.h
@@ -299,6 +299,7 @@ public:
Paragraph = 0x00000083,
WebDocument = 0x00000084,
Section = 0x00000085,
+ Notification = 0x00000086,
// IAccessible2 roles
// IA2_ROLE_CANVAS = 0x401, ### Qt 6 use this one instead of Canvas above
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index ae433ff651..2762b702b2 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -1321,10 +1321,12 @@ bool QImageReader::read(QImage *image)
}
}
- // successful read; check for "@2x" file name suffix and set device pixel ratio.
- static bool disable2xImageLoading = !qEnvironmentVariableIsEmpty("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING");
- if (!disable2xImageLoading && QFileInfo(fileName()).baseName().endsWith(QLatin1String("@2x"))) {
- image->setDevicePixelRatio(2.0);
+ // successful read; check for "@Nx" file name suffix and set device pixel ratio.
+ static bool disableNxImageLoading = !qEnvironmentVariableIsEmpty("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING");
+ if (!disableNxImageLoading) {
+ const QByteArray suffix = QFileInfo(fileName()).baseName().right(3).toLatin1();
+ if (suffix.length() == 3 && suffix[0] == '@' && suffix[1] >= '2' && suffix[1] <= '9' && suffix[2] == 'x')
+ image->setDevicePixelRatio(suffix[1] - '0');
}
if (autoTransform())
qt_imageTransform(*image, transformation());
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index 4f8e9a3817..93fcb1a216 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -400,7 +400,7 @@ QPoint QHighDpiScaling::mapPositionToGlobal(const QPoint &pos, const QPoint &win
QPoint QHighDpiScaling::mapPositionFromGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window)
{
QPoint windowPosCandidate = pos - windowGlobalPosition;
- if (QGuiApplicationPrivate::screen_list.size() <= 1)
+ if (QGuiApplicationPrivate::screen_list.size() <= 1 || window->handle() == nullptr)
return windowPosCandidate;
// Device independent global (screen) space may discontiguous when high-dpi scaling
diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h
index 91cfbcbfc7..6e89f85746 100644
--- a/src/gui/kernel/qhighdpiscaling_p.h
+++ b/src/gui/kernel/qhighdpiscaling_p.h
@@ -108,208 +108,114 @@ private:
namespace QHighDpi {
-inline QPointF fromNative(const QPointF &pos, qreal scaleFactor, const QPointF &origin)
+template <typename T>
+inline T scale(const T &value, qreal scaleFactor, QPoint origin = QPoint(0, 0))
{
- return (pos - origin) / scaleFactor + origin;
+ Q_UNUSED(origin)
+ return value * scaleFactor;
}
-inline QPointF toNative(const QPointF &pos, qreal scaleFactor, const QPointF &origin)
+inline QPointF scale(const QPointF &pos, qreal scaleFactor, QPointF origin = QPointF(0, 0))
{
return (pos - origin) * scaleFactor + origin;
}
-inline QPoint fromNative(const QPoint &pos, qreal scaleFactor, const QPoint &origin)
-{
- return (pos - origin) / scaleFactor + origin;
-}
-
-inline QPoint toNative(const QPoint &pos, qreal scaleFactor, const QPoint &origin)
+inline QPoint scale(const QPoint &pos, qreal scaleFactor, QPoint origin = QPoint(0, 0))
{
return (pos - origin) * scaleFactor + origin;
}
-inline QPoint fromNative(const QPoint &pos, qreal scaleFactor)
-{
- return pos / scaleFactor;
-}
-
-inline QPoint toNative(const QPoint &pos, qreal scaleFactor)
-{
- return pos * scaleFactor;
-}
-
-inline QSize fromNative(const QSize &size, qreal scaleFactor)
-{
- return size / scaleFactor; // TODO: should we round up?
-}
-
-inline QSize toNative(const QSize &size, qreal scaleFactor)
+inline QRect scale(const QRect &rect, qreal scaleFactor, QPoint origin = QPoint(0, 0))
{
- return size * scaleFactor;
-}
-
-inline QSizeF fromNative(const QSizeF &size, qreal scaleFactor)
-{
- return size / scaleFactor;
-}
-
-inline QSizeF toNative(const QSizeF &size, qreal scaleFactor)
-{
- return size * scaleFactor;
-}
-
-inline QRect fromNative(const QRect &rect, qreal scaleFactor, const QPoint &origin)
-{
- return QRect(fromNative(rect.topLeft(), scaleFactor, origin), fromNative(rect.size(), scaleFactor));
-}
-
-inline QRect toNative(const QRect &rect, qreal scaleFactor, const QPoint &origin)
-{
- return QRect(toNative(rect.topLeft(), scaleFactor, origin), toNative(rect.size(), scaleFactor));
-
-}
-
-inline QRect fromNative(const QRect &rect, const QScreen *screen, const QPoint &screenOrigin)
-{
- return fromNative(rect, QHighDpiScaling::factor(screen), screenOrigin);
-}
-
-inline QRect fromNativeScreenGeometry(const QRect &nativeScreenGeometry, const QScreen *screen)
-{
- return QRect(nativeScreenGeometry.topLeft(),
- fromNative(nativeScreenGeometry.size(), QHighDpiScaling::factor(screen)));
-}
-
-inline QPoint fromNativeLocalPosition(const QPoint &pos, const QWindow *window)
-{
- const qreal scaleFactor = QHighDpiScaling::factor(window);
- return pos / scaleFactor;
-}
-
-inline QPoint toNativeLocalPosition(const QPoint &pos, const QWindow *window)
-{
- const qreal scaleFactor = QHighDpiScaling::factor(window);
- return pos * scaleFactor;
-}
-
-inline QPointF fromNativeLocalPosition(const QPointF &pos, const QWindow *window)
-{
- const qreal scaleFactor = QHighDpiScaling::factor(window);
- return pos / scaleFactor;
-}
-
-inline QPointF toNativeLocalPosition(const QPointF &pos, const QWindow *window)
-{
- const qreal scaleFactor = QHighDpiScaling::factor(window);
- return pos * scaleFactor;
+ return QRect(scale(rect.topLeft(), scaleFactor, origin), scale(rect.size(), scaleFactor));
}
-template <typename C>
-inline QRect fromNativePixels(const QRect &pixelRect, const C *context)
+inline QRectF scale(const QRectF &rect, qreal scaleFactor, QPoint origin = QPoint(0, 0))
{
- const qreal scaleFactor = QHighDpiScaling::factor(context);
- const QPoint origin = QHighDpiScaling::origin(context);
- return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin),
- fromNative(pixelRect.size(), scaleFactor));
+ return QRectF(scale(rect.topLeft(), scaleFactor, origin), scale(rect.size(), scaleFactor));
}
-template <typename C>
-inline QRect toNativePixels(const QRect &pointRect, const C *context)
+inline QMargins scale(const QMargins &margins, qreal scaleFactor, QPoint origin = QPoint(0, 0))
{
- const qreal scaleFactor = QHighDpiScaling::factor(context);
- const QPoint origin = QHighDpiScaling::origin(context);
- return QRect(toNative(pointRect.topLeft(), scaleFactor, origin),
- toNative(pointRect.size(), scaleFactor));
+ Q_UNUSED(origin)
+ return QMargins(qRound(qreal(margins.left()) * scaleFactor), qRound(qreal(margins.top()) * scaleFactor),
+ qRound(qreal(margins.right()) * scaleFactor), qRound(qreal(margins.bottom()) * scaleFactor));
}
-template <typename C>
-inline QRectF toNativePixels(const QRectF &pointRect, const C *context)
+template <typename T>
+QVector<T> scale(const QVector<T> &vector, qreal scaleFactor, QPoint origin = QPoint(0, 0))
{
- const qreal scaleFactor = QHighDpiScaling::factor(context);
- const QPoint origin = QHighDpiScaling::origin(context);
- return QRectF(toNative(pointRect.topLeft(), scaleFactor, origin),
- toNative(pointRect.size(), scaleFactor));
-}
+ if (!QHighDpiScaling::isActive())
+ return vector;
-template <typename C>
-inline QRectF fromNativePixels(const QRectF &pixelRect, const C *context)
-{
- const qreal scaleFactor = QHighDpiScaling::factor(context);
- const QPoint origin = QHighDpiScaling::origin(context);
- return QRectF(fromNative(pixelRect.topLeft(), scaleFactor, origin),
- fromNative(pixelRect.size(), scaleFactor));
+ QVector<T> scaled;
+ scaled.reserve(vector.size());
+ for (const T &item : vector)
+ scaled.append(scale(item, scaleFactor, origin));
+ return scaled;
}
-inline QSize fromNativePixels(const QSize &pixelSize, const QWindow *window)
+inline QRegion scale(const QRegion &region, qreal scaleFactor, QPoint origin = QPoint(0, 0))
{
- return pixelSize / QHighDpiScaling::factor(window);
-}
+ if (!QHighDpiScaling::isActive())
+ return region;
-inline QSize toNativePixels(const QSize &pointSize, const QWindow *window)
-{
- return pointSize * QHighDpiScaling::factor(window);
+ QRegion scaled;
+ for (const QRect &rect : region)
+ scaled += scale(rect, scaleFactor, origin);
+ return scaled;
}
-inline QSizeF fromNativePixels(const QSizeF &pixelSize, const QWindow *window)
+template <typename T, typename C>
+T fromNativePixels(const T &value, const C *context)
{
- return pixelSize / QHighDpiScaling::factor(window);
+ return scale(value, qreal(1) / QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
}
-inline QSizeF toNativePixels(const QSizeF &pointSize, const QWindow *window)
+template <typename T, typename C>
+T toNativePixels(const T &value, const C *context)
{
- return pointSize * QHighDpiScaling::factor(window);
+ return scale(value, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
}
-template <typename C>
-inline QPoint fromNativePixels(const QPoint &pixelPoint, const C *context)
+template <typename T, typename C>
+T fromNativeLocalPosition(const T &value, const C *context)
{
- return fromNative(pixelPoint, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
+ return scale(value, qreal(1) / QHighDpiScaling::factor(context));
}
-template <typename C>
-inline QPoint toNativePixels(const QPoint &pointPoint, const C *context)
+template <typename T, typename C>
+T toNativeLocalPosition(const T &value, const C *context)
{
- return toNative(pointPoint, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
+ return scale(value, QHighDpiScaling::factor(context));
}
-template <typename C>
-inline QPointF fromNativePixels(const QPointF &pixelPoint, const C *context)
+template <typename T>
+inline T fromNative(const T &value, qreal scaleFactor, QPoint origin = QPoint(0, 0))
{
- return fromNative(pixelPoint, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
+ return scale(value, qreal(1) / scaleFactor, origin);
}
-template <typename C>
-inline QPointF toNativePixels(const QPointF &pointPoint, const C *context)
+template <typename T>
+inline T toNative(const T &value, qreal scaleFactor, QPoint origin = QPoint(0, 0))
{
- return toNative(pointPoint, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context));
+ return scale(value, scaleFactor, origin);
}
-inline QMargins fromNativePixels(const QMargins &pixelMargins, const QWindow *window)
+inline QRect fromNative(const QRect &rect, const QScreen *screen, const QPoint &screenOrigin)
{
- const qreal scaleFactor = QHighDpiScaling::factor(window);
- return QMargins(pixelMargins.left() / scaleFactor, pixelMargins.top() / scaleFactor,
- pixelMargins.right() / scaleFactor, pixelMargins.bottom() / scaleFactor);
+ return scale(rect, qreal(1) / QHighDpiScaling::factor(screen), screenOrigin);
}
-inline QMargins toNativePixels(const QMargins &pointMargins, const QWindow *window)
+inline QRect fromNativeScreenGeometry(const QRect &nativeScreenGeometry, const QScreen *screen)
{
- const qreal scaleFactor = QHighDpiScaling::factor(window);
- return QMargins(pointMargins.left() * scaleFactor, pointMargins.top() * scaleFactor,
- pointMargins.right() * scaleFactor, pointMargins.bottom() * scaleFactor);
+ return QRect(nativeScreenGeometry.topLeft(),
+ scale(nativeScreenGeometry.size(), qreal(1) / QHighDpiScaling::factor(screen)));
}
inline QRegion fromNativeLocalRegion(const QRegion &pixelRegion, const QWindow *window)
{
- if (!QHighDpiScaling::isActive())
- return pixelRegion;
-
- qreal scaleFactor = QHighDpiScaling::factor(window);
- QRegion pointRegion;
- for (const QRect &rect : pixelRegion) {
- pointRegion += QRect(fromNative(rect.topLeft(), scaleFactor),
- fromNative(rect.size(), scaleFactor));
- }
- return pointRegion;
+ return scale(pixelRegion, qreal(1) / QHighDpiScaling::factor(window));
}
// When mapping expose events to Qt rects: round top/left towards the origin and
@@ -333,67 +239,7 @@ inline QRegion fromNativeLocalExposedRegion(const QRegion &pixelRegion, const QW
inline QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *window)
{
- if (!QHighDpiScaling::isActive())
- return pointRegion;
-
- qreal scaleFactor = QHighDpiScaling::factor(window);
- QRegion pixelRegon;
- for (const QRect &rect : pointRegion) {
- pixelRegon += QRect(toNative(rect.topLeft(), scaleFactor),
- toNative(rect.size(), scaleFactor));
- }
- return pixelRegon;
-}
-
-// Any T that has operator/()
-template <typename T, typename C>
-T fromNativePixels(const T &pixelValue, const C *context)
-{
- if (!QHighDpiScaling::isActive())
- return pixelValue;
-
- return pixelValue / QHighDpiScaling::factor(context);
-
-}
-
-// Any T that has operator*()
-template <typename T, typename C>
-T toNativePixels(const T &pointValue, const C *context)
-{
- if (!QHighDpiScaling::isActive())
- return pointValue;
-
- return pointValue * QHighDpiScaling::factor(context);
-}
-
-// Any QVector<T> where T has operator/()
-template <typename T>
-QVector<T> fromNativePixels(const QVector<T> &pixelValues, const QWindow *window)
-{
- if (!QHighDpiScaling::isActive())
- return pixelValues;
-
- QVector<T> pointValues;
- pointValues.reserve(pixelValues.size());
- const auto factor = QHighDpiScaling::factor(window);
- for (const T &pixelValue : pixelValues)
- pointValues.append(pixelValue / factor);
- return pointValues;
-}
-
-// Any QVector<T> where T has operator*()
-template <typename T>
-QVector<T> toNativePixels(const QVector<T> &pointValues, const QWindow *window)
-{
- if (!QHighDpiScaling::isActive())
- return pointValues;
-
- QVector<T> pixelValues;
- pixelValues.reserve(pointValues.size());
- const auto factor = QHighDpiScaling::factor(window);
- for (const T &pointValue : pointValues)
- pixelValues.append(pointValue * factor);
- return pixelValues;
+ return scale(pointRegion, QHighDpiScaling::factor(window));
}
} // namespace QHighDpi
diff --git a/src/gui/math3d/qvector3d.cpp b/src/gui/math3d/qvector3d.cpp
index 12a7902272..4f72c1da66 100644
--- a/src/gui/math3d/qvector3d.cpp
+++ b/src/gui/math3d/qvector3d.cpp
@@ -514,7 +514,7 @@ float QVector3D::distanceToPlane
/*!
\overload
- Returns the distance from this vertex a plane defined by
+ Returns the distance from this vertex to a plane defined by
the vertices \a plane1, \a plane2 and \a plane3.
The return value will be negative if the vertex is below the plane,
diff --git a/src/gui/opengl/qopengltextureblitter.cpp b/src/gui/opengl/qopengltextureblitter.cpp
index b65df9dc82..b709f2f639 100644
--- a/src/gui/opengl/qopengltextureblitter.cpp
+++ b/src/gui/opengl/qopengltextureblitter.cpp
@@ -349,6 +349,9 @@ bool QOpenGLTextureBlitterPrivate::buildProgram(ProgramIndex idx, const char *vs
p->glProgram->setUniformValue(p->swizzleUniformPos, false);
+ // minmize state left set after a create()
+ p->glProgram->release();
+
return true;
}
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index ac15d8f4f4..006befea22 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -4566,7 +4566,9 @@ static void blend_color_rgb16(int count, const QSpan *spans, void *userData)
if (mode == QPainter::CompositionMode_Source) {
// inline for performance
ushort c = data->solidColor.toRgb16();
- while (count--) {
+ for (; count--; spans++) {
+ if (!spans->len)
+ continue;
ushort *target = ((ushort *)data->rasterBuffer->scanLine(spans->y)) + spans->x;
if (spans->coverage == 255) {
qt_memfill(target, c, spans->len);
@@ -4579,13 +4581,14 @@ static void blend_color_rgb16(int count, const QSpan *spans, void *userData)
++target;
}
}
- ++spans;
}
return;
}
if (mode == QPainter::CompositionMode_SourceOver) {
- while (count--) {
+ for (; count--; spans++) {
+ if (!spans->len)
+ continue;
uint color = BYTE_MUL(data->solidColor.toArgb32(), spans->coverage);
int ialpha = qAlpha(~color);
ushort c = qConvertRgb32To16(color);
@@ -4617,7 +4620,6 @@ static void blend_color_rgb16(int count, const QSpan *spans, void *userData)
// one last pixel beyond a full word
*target = c + BYTE_MUL_RGB16(*target, ialpha);
}
- ++spans;
}
return;
}
@@ -4634,6 +4636,11 @@ void handleSpans(int count, const QSpan *spans, const QSpanData *data, T &handle
int coverage = 0;
while (count) {
+ if (!spans->len) {
+ ++spans;
+ --count;
+ continue;
+ }
int x = spans->x;
const int y = spans->y;
int right = x + spans->len;
@@ -4790,7 +4797,9 @@ static void blend_untransformed_generic(int count, const QSpan *spans, void *use
int xoff = -qRound(-data->dx);
int yoff = -qRound(-data->dy);
- while (count--) {
+ for (; count--; spans++) {
+ if (!spans->len)
+ continue;
int x = spans->x;
int length = spans->len;
int sx = xoff + x;
@@ -4818,7 +4827,6 @@ static void blend_untransformed_generic(int count, const QSpan *spans, void *use
}
}
}
- ++spans;
}
}
@@ -4840,7 +4848,9 @@ static void blend_untransformed_generic_rgb64(int count, const QSpan *spans, voi
int xoff = -qRound(-data->dx);
int yoff = -qRound(-data->dy);
- while (count--) {
+ for (; count--; spans++) {
+ if (!spans->len)
+ continue;
int x = spans->x;
int length = spans->len;
int sx = xoff + x;
@@ -4868,7 +4878,6 @@ static void blend_untransformed_generic_rgb64(int count, const QSpan *spans, voi
}
}
}
- ++spans;
}
}
#endif
@@ -4889,7 +4898,9 @@ static void blend_untransformed_argb(int count, const QSpan *spans, void *userDa
int xoff = -qRound(-data->dx);
int yoff = -qRound(-data->dy);
- while (count--) {
+ for (; count--; spans++) {
+ if (!spans->len)
+ continue;
int x = spans->x;
int length = spans->len;
int sx = xoff + x;
@@ -4909,7 +4920,6 @@ static void blend_untransformed_argb(int count, const QSpan *spans, void *userDa
op.func(dest, src, length, coverage);
}
}
- ++spans;
}
}
@@ -4982,7 +4992,12 @@ static void blend_untransformed_rgb565(int count, const QSpan *spans, void *user
int xoff = -qRound(-data->dx);
int yoff = -qRound(-data->dy);
- while (count--) {
+ const QSpan *end = spans + count;
+ while (spans < end) {
+ if (!spans->len) {
+ ++spans;
+ continue;
+ }
const quint8 coverage = (data->texture.const_alpha * spans->coverage) >> 8;
if (coverage == 0) {
++spans;
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 85ddff53db..64183c2be6 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -4149,7 +4149,7 @@ static void qt_span_fill_clipped(int spanCount, const QSpan *spans, void *userDa
Clip spans to \a{clip}-rectangle.
Returns number of unclipped spans
*/
-static int qt_intersect_spans(QT_FT_Span *spans, int numSpans,
+static int qt_intersect_spans(QT_FT_Span *&spans, int numSpans,
const QRect &clip)
{
const short minx = clip.left();
@@ -4157,29 +4157,32 @@ static int qt_intersect_spans(QT_FT_Span *spans, int numSpans,
const short maxx = clip.right();
const short maxy = clip.bottom();
- int n = 0;
- for (int i = 0; i < numSpans; ++i) {
- if (spans[i].y > maxy)
+ QT_FT_Span *end = spans + numSpans;
+ while (spans < end) {
+ if (spans->y >= miny)
break;
- if (spans[i].y < miny
- || spans[i].x > maxx
- || spans[i].x + spans[i].len <= minx) {
+ ++spans;
+ }
+
+ QT_FT_Span *s = spans;
+ while (s < end) {
+ if (s->y > maxy)
+ break;
+ if (s->x > maxx || s->x + s->len <= minx) {
+ s->len = 0;
+ ++s;
continue;
}
- if (spans[i].x < minx) {
- spans[n].len = qMin(spans[i].len - (minx - spans[i].x), maxx - minx + 1);
- spans[n].x = minx;
+ if (s->x < minx) {
+ s->len = qMin(s->len - (minx - s->x), maxx - minx + 1);
+ s->x = minx;
} else {
- spans[n].x = spans[i].x;
- spans[n].len = qMin(spans[i].len, ushort(maxx - spans[n].x + 1));
+ s->len = qMin(s->len, ushort(maxx - s->x + 1));
}
- if (spans[n].len == 0)
- continue;
- spans[n].y = spans[i].y;
- spans[n].coverage = spans[i].coverage;
- ++n;
+ ++s;
}
- return n;
+
+ return s - spans;
}
@@ -4192,11 +4195,12 @@ static void qt_span_fill_clipRect(int count, const QSpan *spans,
Q_ASSERT(fillData->clip);
Q_ASSERT(!fillData->clip->clipRect.isEmpty());
+ QSpan *s = const_cast<QSpan *>(spans);
// hw: check if this const_cast<> is safe!!!
- count = qt_intersect_spans(const_cast<QSpan*>(spans), count,
+ count = qt_intersect_spans(s, count,
fillData->clip->clipRect);
if (count > 0)
- fillData->unclipped_blend(count, spans, fillData);
+ fillData->unclipped_blend(count, s, fillData);
}
static void qt_span_clip(int count, const QSpan *spans, void *userData)
@@ -4773,7 +4777,8 @@ static inline void drawEllipsePoints(int x, int y, int length,
if (length == 0)
return;
- QT_FT_Span outline[4];
+ QT_FT_Span _outline[4];
+ QT_FT_Span *outline = _outline;
const int midx = rect.x() + (rect.width() + 1) / 2;
const int midy = rect.y() + (rect.height() + 1) / 2;
@@ -4805,7 +4810,8 @@ static inline void drawEllipsePoints(int x, int y, int length,
outline[3].coverage = 255;
if (brush_func && outline[0].x + outline[0].len < outline[1].x) {
- QT_FT_Span fill[2];
+ QT_FT_Span _fill[2];
+ QT_FT_Span *fill = _fill;
// top fill
fill[0].x = outline[0].x + outline[0].len - 1;
diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp
index 5b6990e667..271d3ba6bf 100644
--- a/src/gui/painting/qstroker.cpp
+++ b/src/gui/painting/qstroker.cpp
@@ -522,7 +522,7 @@ void QStroker::joinPoints(qfixed focal_x, qfixed focal_y, const QLineF &nextLine
QLineF shortCut(prevLine.p2(), nextLine.p1());
qreal angle = shortCut.angleTo(prevLine);
- if (type == QLineF::BoundedIntersection || (angle > 90 && !qFuzzyCompare(angle, (qreal)90))) {
+ if ((type == QLineF::BoundedIntersection || (angle > qreal(90.01))) && nextLine.length() > offset) {
emitLineTo(focal_x, focal_y);
emitLineTo(qt_real_to_fixed(nextLine.x1()), qt_real_to_fixed(nextLine.y1()));
return;
diff --git a/src/gui/text/qdistancefield.cpp b/src/gui/text/qdistancefield.cpp
index 3f7129383b..17824a5ba1 100644
--- a/src/gui/text/qdistancefield.cpp
+++ b/src/gui/text/qdistancefield.cpp
@@ -899,11 +899,6 @@ QDistanceField::QDistanceField(int width, int height)
{
}
-QDistanceField::QDistanceField(const QDistanceField &other)
-{
- d = other.d;
-}
-
QDistanceField &QDistanceField::operator=(const QDistanceField &)
= default;
diff --git a/src/gui/text/qdistancefield_p.h b/src/gui/text/qdistancefield_p.h
index dc5d5a9a02..d6d8edd85d 100644
--- a/src/gui/text/qdistancefield_p.h
+++ b/src/gui/text/qdistancefield_p.h
@@ -94,7 +94,6 @@ public:
QDistanceField(const QRawFont &font, glyph_t glyph, bool doubleResolution = false);
QDistanceField(QFontEngine *fontEngine, glyph_t glyph, bool doubleResolution = false);
QDistanceField(const QPainterPath &path, glyph_t glyph, bool doubleResolution = false);
- QDistanceField(const QDistanceField &other);
QDistanceField &operator=(const QDistanceField &other);
bool isNull() const;
diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp
index 81b5e01d6a..cd87c3669c 100644
--- a/src/network/bearer/qnetworkconfigmanager.cpp
+++ b/src/network/bearer/qnetworkconfigmanager.cpp
@@ -233,19 +233,20 @@ QNetworkConfigurationManager::QNetworkConfigurationManager(QObject *parent)
: QObject(parent)
{
QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate();
-
- connect(priv, SIGNAL(configurationAdded(QNetworkConfiguration)),
- this, SIGNAL(configurationAdded(QNetworkConfiguration)));
- connect(priv, SIGNAL(configurationRemoved(QNetworkConfiguration)),
- this, SIGNAL(configurationRemoved(QNetworkConfiguration)));
- connect(priv, SIGNAL(configurationChanged(QNetworkConfiguration)),
- this, SIGNAL(configurationChanged(QNetworkConfiguration)));
- connect(priv, SIGNAL(onlineStateChanged(bool)),
- this, SIGNAL(onlineStateChanged(bool)));
- connect(priv, SIGNAL(configurationUpdateComplete()),
- this, SIGNAL(updateCompleted()));
-
- priv->enablePolling();
+ if (priv) {
+ connect(priv, SIGNAL(configurationAdded(QNetworkConfiguration)),
+ this, SIGNAL(configurationAdded(QNetworkConfiguration)));
+ connect(priv, SIGNAL(configurationRemoved(QNetworkConfiguration)),
+ this, SIGNAL(configurationRemoved(QNetworkConfiguration)));
+ connect(priv, SIGNAL(configurationChanged(QNetworkConfiguration)),
+ this, SIGNAL(configurationChanged(QNetworkConfiguration)));
+ connect(priv, SIGNAL(onlineStateChanged(bool)),
+ this, SIGNAL(onlineStateChanged(bool)));
+ connect(priv, SIGNAL(configurationUpdateComplete()),
+ this, SIGNAL(updateCompleted()));
+
+ priv->enablePolling();
+ }
}
/*!
diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp
index 471d322998..1636bcee97 100644
--- a/src/network/bearer/qnetworksession.cpp
+++ b/src/network/bearer/qnetworksession.cpp
@@ -258,7 +258,8 @@ QNetworkSession::QNetworkSession(const QNetworkConfiguration &connectionConfig,
// invalid configuration
if (!connectionConfig.identifier().isEmpty()) {
- const auto engines = qNetworkConfigurationManagerPrivate()->engines();
+ auto priv = qNetworkConfigurationManagerPrivate();
+ const auto engines = priv ? priv->engines() : QList<QBearerEngine *>();
for (QBearerEngine *engine : engines) {
if (engine->hasIdentifier(connectionConfig.identifier())) {
d = engine->createSessionBackend();
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 3927a592cb..d4bad1b1a5 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -71,6 +71,10 @@
#include "qwindowscarootfetcher_p.h"
#endif
+#if !QT_CONFIG(opensslv11)
+#include <openssl/x509_vfy.h>
+#endif
+
#include <QtCore/qdatetime.h>
#include <QtCore/qdebug.h>
#include <QtCore/qdir.h>
@@ -137,6 +141,55 @@ static unsigned int q_ssl_psk_server_callback(SSL *ssl,
Q_ASSERT(d);
return d->tlsPskServerCallback(identity, psk, max_psk_len);
}
+
+#ifdef TLS1_3_VERSION
+#ifndef OPENSSL_NO_PSK
+static unsigned int q_ssl_psk_restore_client(SSL *ssl,
+ const char *hint,
+ char *identity, unsigned int max_identity_len,
+ unsigned char *psk, unsigned int max_psk_len)
+{
+ Q_UNUSED(hint);
+ Q_UNUSED(identity);
+ Q_UNUSED(max_identity_len);
+ Q_UNUSED(psk);
+ Q_UNUSED(max_psk_len);
+
+#ifdef QT_DEBUG
+ QSslSocketBackendPrivate *d = reinterpret_cast<QSslSocketBackendPrivate *>(q_SSL_get_ex_data(ssl, QSslSocketBackendPrivate::s_indexForSSLExtraData));
+ Q_ASSERT(d);
+ Q_ASSERT(d->mode == QSslSocket::SslClientMode);
+#endif
+ q_SSL_set_psk_client_callback(ssl, &q_ssl_psk_client_callback);
+
+ return 0;
+}
+#endif // !OPENSSL_NO_PSK
+
+static int q_ssl_psk_use_session_callback(SSL *ssl, const EVP_MD *md, const unsigned char **id,
+ size_t *idlen, SSL_SESSION **sess)
+{
+ Q_UNUSED(ssl);
+ Q_UNUSED(md);
+ Q_UNUSED(id);
+ Q_UNUSED(idlen);
+ Q_UNUSED(sess);
+
+#ifndef OPENSSL_NO_PSK
+#ifdef QT_DEBUG
+ QSslSocketBackendPrivate *d = reinterpret_cast<QSslSocketBackendPrivate *>(q_SSL_get_ex_data(ssl, QSslSocketBackendPrivate::s_indexForSSLExtraData));
+ Q_ASSERT(d);
+ Q_ASSERT(d->mode == QSslSocket::SslClientMode);
+#endif
+
+ // Temporarily rebind the psk because it will be called next. The function will restore it.
+ q_SSL_set_psk_client_callback(ssl, &q_ssl_psk_restore_client);
+#endif
+
+ return 1; // need to return 1 or else "the connection setup fails."
+}
+#endif // TLS1_3_VERSION
+
#endif
#if QT_CONFIG(ocsp)
@@ -345,47 +398,41 @@ bool qt_OCSP_certificate_match(OCSP_SINGLERESP *singleResponse, X509 *peerCert,
#endif // ocsp
-// ### This list is shared between all threads, and protected by a
-// mutex. Investigate using thread local storage instead. Or better properly
-// use OpenSSL's ability to attach application data to an SSL/SSL_CTX
-// and extract it in a callback. See how it's done, for example, in PSK
-// callback or in DTLS verification callback.
-struct QSslErrorList
-{
- QMutex mutex;
- QVector<QSslErrorEntry> errors;
-};
-
-Q_GLOBAL_STATIC(QSslErrorList, _q_sslErrorList)
-
int q_X509Callback(int ok, X509_STORE_CTX *ctx)
{
if (!ok) {
// Store the error and at which depth the error was detected.
- _q_sslErrorList()->errors << QSslErrorEntry::fromStoreContext(ctx);
-#if !QT_CONFIG(opensslv11)
-#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << "verification error: dumping bad certificate";
- qCDebug(lcSsl) << QSslCertificatePrivate::QSslCertificate_from_X509(q_X509_STORE_CTX_get_current_cert(ctx)).toPem();
- qCDebug(lcSsl) << "dumping chain";
- const auto certs = QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(q_X509_STORE_CTX_get_chain(ctx));
- for (const QSslCertificate &cert : certs) {
- qCDebug(lcSsl) << "Issuer:" << "O=" << cert.issuerInfo(QSslCertificate::Organization)
- << "CN=" << cert.issuerInfo(QSslCertificate::CommonName)
- << "L=" << cert.issuerInfo(QSslCertificate::LocalityName)
- << "OU=" << cert.issuerInfo(QSslCertificate::OrganizationalUnitName)
- << "C=" << cert.issuerInfo(QSslCertificate::CountryName)
- << "ST=" << cert.issuerInfo(QSslCertificate::StateOrProvinceName);
- qCDebug(lcSsl) << "Subject:" << "O=" << cert.subjectInfo(QSslCertificate::Organization)
- << "CN=" << cert.subjectInfo(QSslCertificate::CommonName)
- << "L=" << cert.subjectInfo(QSslCertificate::LocalityName)
- << "OU=" << cert.subjectInfo(QSslCertificate::OrganizationalUnitName)
- << "C=" << cert.subjectInfo(QSslCertificate::CountryName)
- << "ST=" << cert.subjectInfo(QSslCertificate::StateOrProvinceName);
- qCDebug(lcSsl) << "Valid:" << cert.effectiveDate() << '-' << cert.expiryDate();
+
+ using ErrorListPtr = QVector<QSslErrorEntry>*;
+ ErrorListPtr errors = nullptr;
+
+ // Error list is attached to either 'SSL' or 'X509_STORE'.
+ if (X509_STORE *store = q_X509_STORE_CTX_get0_store(ctx)) { // We try store first:
+#if QT_CONFIG(opensslv11)
+ errors = ErrorListPtr(q_X509_STORE_get_ex_data(store, 0));
+#else
+ errors = ErrorListPtr(q_CRYPTO_get_ex_data(&store->ex_data, 0));
+#endif // opensslv11
}
-#endif // QSSLSOCKET_DEBUG
-#endif // !QT_CONFIG(opensslv11)
+
+ if (!errors) {
+ // Not found on store? Try SSL and its external data then. According to the OpenSSL's
+ // documentation:
+ //
+ // "Whenever a X509_STORE_CTX object is created for the verification of the peers certificate
+ // during a handshake, a pointer to the SSL object is stored into the X509_STORE_CTX object
+ // to identify the connection affected. To retrieve this pointer the X509_STORE_CTX_get_ex_data()
+ // function can be used with the correct index."
+ if (SSL *ssl = static_cast<SSL *>(q_X509_STORE_CTX_get_ex_data(ctx, q_SSL_get_ex_data_X509_STORE_CTX_idx())))
+ errors = ErrorListPtr(q_SSL_get_ex_data(ssl, QSslSocketBackendPrivate::s_indexForSSLExtraData + 1));
+ }
+
+ if (!errors) {
+ qCWarning(lcSsl, "Neither X509_STORE, nor SSL contains error list, handshake failure");
+ return 0;
+ }
+
+ errors->append(QSslErrorEntry::fromStoreContext(ctx));
}
// Always return OK to allow verification to continue. We handle the
// errors gracefully after collecting all errors, after verification has
@@ -541,11 +588,7 @@ bool QSslSocketBackendPrivate::initSslContext()
else
q_SSL_set_accept_state(ssl);
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
- // Save a pointer to this object into the SSL structure.
- if (QSslSocket::sslLibraryVersionNumber() >= 0x10001000L)
- q_SSL_set_ex_data(ssl, s_indexForSSLExtraData, this);
-#endif
+ q_SSL_set_ex_data(ssl, s_indexForSSLExtraData, this);
#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
// Set the client callback for PSK
@@ -556,6 +599,13 @@ bool QSslSocketBackendPrivate::initSslContext()
q_SSL_set_psk_server_callback(ssl, &q_ssl_psk_server_callback);
}
#endif
+#if OPENSSL_VERSION_NUMBER >= 0x10101006L
+ // Set the client callback for TLSv1.3 PSK
+ if (mode == QSslSocket::SslClientMode
+ && QSslSocket::sslLibraryBuildVersionNumber() >= 0x10101006L) {
+ q_SSL_set_psk_use_session_callback(ssl, &q_ssl_psk_use_session_callback);
+ }
+#endif // openssl version >= 0x10101006L
#if QT_CONFIG(ocsp)
if (configuration.ocspStaplingEnabled) {
@@ -1123,14 +1173,14 @@ bool QSslSocketBackendPrivate::startHandshake()
if (inSetAndEmitError)
return false;
- QMutexLocker locker(&_q_sslErrorList()->mutex);
- _q_sslErrorList()->errors.clear();
+ QVector<QSslErrorEntry> lastErrors;
+ q_SSL_set_ex_data(ssl, s_indexForSSLExtraData + 1, &lastErrors);
int result = (mode == QSslSocket::SslClientMode) ? q_SSL_connect(ssl) : q_SSL_accept(ssl);
+ q_SSL_set_ex_data(ssl, s_indexForSSLExtraData + 1, nullptr);
- const auto &lastErrors = _q_sslErrorList()->errors;
if (!lastErrors.isEmpty())
storePeerCertificates();
- for (const auto &currentError : lastErrors) {
+ for (const auto &currentError : qAsConst(lastErrors)) {
emit q->peerVerifyError(_q_OpenSSL_to_QSslError(currentError.code,
configuration.peerCertificateChain.value(currentError.depth)));
if (q->state() != QAbstractSocket::ConnectedState)
@@ -1138,7 +1188,6 @@ bool QSslSocketBackendPrivate::startHandshake()
}
errorList << lastErrors;
- locker.unlock();
// Connection aborted during handshake phase.
if (q->state() != QAbstractSocket::ConnectedState)
@@ -1520,28 +1569,14 @@ bool QSslSocketBackendPrivate::checkOcspStatus()
// 3) It checks CertID in response.
// 4) Ensures the responder is authorized to sign the status respond.
//
- // Here it's important to notice that it calls X509_cert_verify and
- // as a result, possibly, our verification callback. Given this callback
- // at the moment uses a global variable, we have to lock. This will change
- // as soon as we fix our verification procedure.
- // Also note, OpenSSL prior to 1.0.2b would only use bs->certs to
+ // Note, OpenSSL prior to 1.0.2b would only use bs->certs to
// verify the responder's chain (see their commit 4ba9a4265bd).
// Working this around - is too much fuss for ancient versions we
// are dropping quite soon anyway.
- {
- const unsigned long verificationFlags = 0;
- const QMutexLocker locker(&_q_sslErrorList()->mutex);
- // Before unlocking the mutex, startHandshake() stores errors (found in SSL_connect()
- // or SSL_accept()) into the local variable, so it's safe to clear it here - as soon
- // as we managed to lock, whoever had the lock before, already stored their own copy
- // of errors.
- _q_sslErrorList()->errors.clear();
- const int success = q_OCSP_basic_verify(basicResponse, peerChain, store, verificationFlags);
- if (success <= 0 || _q_sslErrorList()->errors.size()) {
- _q_sslErrorList()->errors.clear();
- ocspErrors.push_back(QSslError::OcspResponseCannotBeTrusted);
- }
- }
+ const unsigned long verificationFlags = 0;
+ const int success = q_OCSP_basic_verify(basicResponse, peerChain, store, verificationFlags);
+ if (success <= 0)
+ ocspErrors.push_back(QSslError::OcspResponseCannotBeTrusted);
if (q_OCSP_resp_count(basicResponse) != 1) {
ocspErrors.push_back(QSslError::OcspMalformedResponse);
@@ -1752,7 +1787,20 @@ QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &
}
}
- QMutexLocker sslErrorListMutexLocker(&_q_sslErrorList()->mutex);
+ QVector<QSslErrorEntry> lastErrors;
+#if QT_CONFIG(opensslv11)
+ if (!q_X509_STORE_set_ex_data(certStore, 0, &lastErrors)) {
+ qCWarning(lcSsl) << "Unable to attach external data (error list) to a store";
+ errors << QSslError(QSslError::UnspecifiedError);
+ return errors;
+ }
+#else
+ if (!q_CRYPTO_set_ex_data(&certStore->ex_data, 0, &lastErrors)) {
+ qCWarning(lcSsl) << "Unable to attach external data (error list) to a store";
+ errors << QSslError(QSslError::UnspecifiedError);
+ return errors;
+ }
+#endif // opensslv11
// Register a custom callback to get all verification errors.
q_X509_STORE_set_verify_cb(certStore, q_X509Callback);
@@ -1802,12 +1850,7 @@ QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &
q_OPENSSL_sk_free((OPENSSL_STACK *)intermediates);
// Now process the errors
- const auto errorList = std::move(_q_sslErrorList()->errors);
- _q_sslErrorList()->errors.clear();
- sslErrorListMutexLocker.unlock();
-
- // Translate the errors
if (QSslCertificatePrivate::isBlacklisted(certificateChain[0])) {
QSslError error(QSslError::CertificateBlacklisted, certificateChain[0]);
errors << error;
@@ -1821,8 +1864,8 @@ QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &
}
// Translate errors from the error list into QSslErrors.
- errors.reserve(errors.size() + errorList.size());
- for (const auto &error : qAsConst(errorList))
+ errors.reserve(errors.size() + lastErrors.size());
+ for (const auto &error : qAsConst(lastErrors))
errors << _q_OpenSSL_to_QSslError(error.code, certificateChain.value(error.depth));
q_X509_STORE_free(certStore);
diff --git a/src/network/ssl/qsslsocket_openssl11_symbols_p.h b/src/network/ssl/qsslsocket_openssl11_symbols_p.h
index 9d0a14360d..0fe0899d4f 100644
--- a/src/network/ssl/qsslsocket_openssl11_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl11_symbols_p.h
@@ -107,6 +107,8 @@ Q_AUTOTEST_EXPORT void q_X509_up_ref(X509 *a);
long q_X509_get_version(X509 *a);
EVP_PKEY *q_X509_get_pubkey(X509 *a);
void q_X509_STORE_set_verify_cb(X509_STORE *ctx, X509_STORE_CTX_verify_cb verify_cb);
+int q_X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data);
+void *q_X509_STORE_get_ex_data(X509_STORE *r, int idx);
STACK_OF(X509) *q_X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx);
void q_DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
int q_DH_bits(DH *dh);
@@ -184,4 +186,10 @@ const OCSP_CERTID *q_OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *x);
#define q_SSL_CTX_set_max_proto_version(ctx, version) \
q_SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, nullptr)
+extern "C" {
+typedef int (*q_SSL_psk_use_session_cb_func_t)(SSL *, const EVP_MD *, const unsigned char **, size_t *,
+ SSL_SESSION **);
+}
+void q_SSL_set_psk_use_session_callback(SSL *s, q_SSL_psk_use_session_cb_func_t);
+
#endif
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index 6f935a02e4..2eb9763e90 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -164,6 +164,7 @@ DEFINEFUNC(int, SSL_session_reused, SSL *a, a, return 0, return)
DEFINEFUNC2(unsigned long, SSL_CTX_set_options, SSL_CTX *ctx, ctx, unsigned long op, op, return 0, return)
#ifdef TLS1_3_VERSION
DEFINEFUNC2(int, SSL_CTX_set_ciphersuites, SSL_CTX *ctx, ctx, const char *str, str, return 0, return)
+DEFINEFUNC2(void, SSL_set_psk_use_session_callback, SSL *ssl, ssl, q_SSL_psk_use_session_cb_func_t callback, callback, return, DUMMYARG)
#endif
DEFINEFUNC3(size_t, SSL_get_client_random, SSL *a, a, unsigned char *out, out, size_t outlen, outlen, return 0, return)
DEFINEFUNC3(size_t, SSL_SESSION_get_master_key, const SSL_SESSION *ses, ses, unsigned char *out, out, size_t outlen, outlen, return 0, return)
@@ -179,6 +180,8 @@ DEFINEFUNC(ASN1_TIME *, X509_getm_notAfter, X509 *a, a, return nullptr, return)
DEFINEFUNC(long, X509_get_version, X509 *a, a, return -1, return)
DEFINEFUNC(EVP_PKEY *, X509_get_pubkey, X509 *a, a, return nullptr, return)
DEFINEFUNC2(void, X509_STORE_set_verify_cb, X509_STORE *a, a, X509_STORE_CTX_verify_cb verify_cb, verify_cb, return, DUMMYARG)
+DEFINEFUNC3(int, X509_STORE_set_ex_data, X509_STORE *a, a, int idx, idx, void *data, data, return 0, return)
+DEFINEFUNC2(void *, X509_STORE_get_ex_data, X509_STORE *r, r, int idx, idx, return nullptr, return)
DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get0_chain, X509_STORE_CTX *a, a, return nullptr, return)
DEFINEFUNC3(void, CRYPTO_free, void *str, str, const char *file, file, int line, line, return, DUMMYARG)
DEFINEFUNC(long, OpenSSL_version_num, void, DUMMYARG, return 0, return)
@@ -253,6 +256,8 @@ DEFINEFUNC(int, CRYPTO_num_locks, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(void, CRYPTO_set_locking_callback, void (*a)(int, int, const char *, int), a, return, DUMMYARG)
DEFINEFUNC(void, CRYPTO_set_id_callback, unsigned long (*a)(), a, return, DUMMYARG)
DEFINEFUNC(void, CRYPTO_free, void *a, a, return, DUMMYARG)
+DEFINEFUNC3(int, CRYPTO_set_ex_data, CRYPTO_EX_DATA *ad, ad, int idx, idx, void *val, val, return 0, return)
+DEFINEFUNC2(void *, CRYPTO_get_ex_data, const CRYPTO_EX_DATA *ad, ad, int idx, idx, return nullptr, return)
DEFINEFUNC(unsigned long, ERR_peek_last_error, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(void, ERR_free_strings, void, DUMMYARG, return, DUMMYARG)
DEFINEFUNC(void, EVP_CIPHER_CTX_cleanup, EVP_CIPHER_CTX *a, a, return, DUMMYARG)
@@ -525,6 +530,7 @@ DEFINEFUNC2(int, X509_STORE_CTX_set_purpose, X509_STORE_CTX *a, a, int b, b, ret
DEFINEFUNC(int, X509_STORE_CTX_get_error, X509_STORE_CTX *a, a, return -1, return)
DEFINEFUNC(int, X509_STORE_CTX_get_error_depth, X509_STORE_CTX *a, a, return -1, return)
DEFINEFUNC(X509 *, X509_STORE_CTX_get_current_cert, X509_STORE_CTX *a, a, return nullptr, return)
+DEFINEFUNC(X509_STORE *, X509_STORE_CTX_get0_store, X509_STORE_CTX *ctx, ctx, return nullptr, return)
DEFINEFUNC(X509_STORE_CTX *, X509_STORE_CTX_new, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC2(void *, X509_STORE_CTX_get_ex_data, X509_STORE_CTX *ctx, ctx, int idx, idx, return nullptr, return)
DEFINEFUNC(int, SSL_get_ex_data_X509_STORE_CTX_idx, DUMMYARG, DUMMYARG, return -1, return)
@@ -975,6 +981,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSL_CTX_set_options)
#ifdef TLS1_3_VERSION
RESOLVEFUNC(SSL_CTX_set_ciphersuites)
+ RESOLVEFUNC(SSL_set_psk_use_session_callback)
#endif // TLS 1.3 or OpenSSL > 1.1.1
RESOLVEFUNC(SSL_get_client_random)
RESOLVEFUNC(SSL_SESSION_get_master_key)
@@ -992,6 +999,8 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(X509_get_version)
RESOLVEFUNC(X509_get_pubkey)
RESOLVEFUNC(X509_STORE_set_verify_cb)
+ RESOLVEFUNC(X509_STORE_set_ex_data)
+ RESOLVEFUNC(X509_STORE_get_ex_data)
RESOLVEFUNC(CRYPTO_free)
RESOLVEFUNC(OpenSSL_version_num)
RESOLVEFUNC(OpenSSL_version)
@@ -1063,6 +1072,8 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(CRYPTO_num_locks)
RESOLVEFUNC(CRYPTO_set_id_callback)
RESOLVEFUNC(CRYPTO_set_locking_callback)
+ RESOLVEFUNC(CRYPTO_set_ex_data)
+ RESOLVEFUNC(CRYPTO_get_ex_data)
RESOLVEFUNC(ERR_peek_last_error)
RESOLVEFUNC(ERR_free_strings)
RESOLVEFUNC(EVP_CIPHER_CTX_cleanup)
@@ -1324,6 +1335,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(X509_STORE_CTX_get_error)
RESOLVEFUNC(X509_STORE_CTX_get_error_depth)
RESOLVEFUNC(X509_STORE_CTX_get_current_cert)
+ RESOLVEFUNC(X509_STORE_CTX_get0_store)
RESOLVEFUNC(X509_cmp)
RESOLVEFUNC(X509_STORE_CTX_get_ex_data)
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index fcf96dbd47..69b2b90fbd 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -464,6 +464,7 @@ int q_X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
int q_X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
int q_X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
X509 *q_X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
+X509_STORE *q_X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx);
// Diffie-Hellman support
DH *q_DH_new();
diff --git a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
index 46b6505346..f5626d5d16 100644
--- a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
+++ b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
@@ -84,6 +84,8 @@ int q_CRYPTO_num_locks();
void q_CRYPTO_set_locking_callback(void (*a)(int, int, const char *, int));
void q_CRYPTO_set_id_callback(unsigned long (*a)());
void q_CRYPTO_free(void *a);
+int q_CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val);
+void *q_CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx);
unsigned long q_ERR_peek_last_error();
void q_ERR_free_strings();
void q_EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
diff --git a/src/platformsupport/linuxaccessibility/bridge.cpp b/src/platformsupport/linuxaccessibility/bridge.cpp
index a96fe258df..fdc8cd3198 100644
--- a/src/platformsupport/linuxaccessibility/bridge.cpp
+++ b/src/platformsupport/linuxaccessibility/bridge.cpp
@@ -265,6 +265,8 @@ static RoleMapping map[] = {
//: Role of an accessible object
{ QAccessible::Desktop, ATSPI_ROLE_DESKTOP_FRAME, QT_TRANSLATE_NOOP("QSpiAccessibleBridge", "desktop") },
//: Role of an accessible object
+ { QAccessible::Notification, ATSPI_ROLE_NOTIFICATION, QT_TRANSLATE_NOOP("QSpiAccessibleBridge", "notification") },
+ //: Role of an accessible object
{ QAccessible::UserRole, ATSPI_ROLE_UNKNOWN, QT_TRANSLATE_NOOP("QSpiAccessibleBridge", "unknown") }
};
diff --git a/src/plugins/bearer/qnetworksession_impl.cpp b/src/plugins/bearer/qnetworksession_impl.cpp
index a09ae72cb5..c6b678ab20 100644
--- a/src/plugins/bearer/qnetworksession_impl.cpp
+++ b/src/plugins/bearer/qnetworksession_impl.cpp
@@ -56,12 +56,13 @@ QT_BEGIN_NAMESPACE
static QBearerEngineImpl *getEngineFromId(const QString &id)
{
QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate();
-
- const auto engines = priv->engines();
- for (QBearerEngine *engine : engines) {
- QBearerEngineImpl *engineImpl = qobject_cast<QBearerEngineImpl *>(engine);
- if (engineImpl && engineImpl->hasIdentifier(id))
- return engineImpl;
+ if (priv) {
+ const auto engines = priv->engines();
+ for (QBearerEngine *engine : engines) {
+ QBearerEngineImpl *engineImpl = qobject_cast<QBearerEngineImpl *>(engine);
+ if (engineImpl && engineImpl->hasIdentifier(id))
+ return engineImpl;
+ }
}
return 0;
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index 297c08b4a4..fa07af8c46 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -64,29 +64,33 @@
QT_BEGIN_NAMESPACE
-template <typename T>
-class ScopedValueChangeBack
+namespace {
+
+class BatchEditLock
{
public:
- ScopedValueChangeBack(T &variable, T newValue)
- : m_oldValue(variable),
- m_variable(variable)
- {
- m_variable = newValue;
- }
- inline void setOldValue()
+
+ explicit BatchEditLock(QAndroidInputContext *context)
+ : m_context(context)
{
- m_variable = m_oldValue;
+ m_context->beginBatchEdit();
}
- ~ScopedValueChangeBack()
+
+ ~BatchEditLock()
{
- setOldValue();
+ m_context->endBatchEdit();
}
+
+ BatchEditLock(const BatchEditLock &) = delete;
+ BatchEditLock &operator=(const BatchEditLock &) = delete;
+
private:
- T m_oldValue;
- T &m_variable;
+
+ QAndroidInputContext *m_context;
};
+} // namespace anonymous
+
static QAndroidInputContext *m_androidInputContext = 0;
static char const *const QtNativeInputConnectionClassName = "org/qtproject/qt5/android/QtNativeInputConnection";
static char const *const QtExtractedTextClassName = "org/qtproject/qt5/android/QtExtractedText";
@@ -423,8 +427,12 @@ static QRect inputItemRectangle()
}
QAndroidInputContext::QAndroidInputContext()
- : QPlatformInputContext(), m_composingTextStart(-1), m_blockUpdateSelection(false),
- m_handleMode(Hidden), m_batchEditNestingLevel(0), m_focusObject(0)
+ : QPlatformInputContext()
+ , m_composingTextStart(-1)
+ , m_composingCursor(-1)
+ , m_handleMode(Hidden)
+ , m_batchEditNestingLevel(0)
+ , m_focusObject(0)
{
jclass clazz = QJNIEnvironmentPrivate::findClass(QtNativeInputConnectionClassName);
if (Q_UNLIKELY(!clazz)) {
@@ -565,13 +573,13 @@ void QAndroidInputContext::reset()
void QAndroidInputContext::commit()
{
- finishComposingText();
+ focusObjectStopComposing();
}
void QAndroidInputContext::updateCursorPosition()
{
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
- if (!query.isNull() && !m_blockUpdateSelection && !m_batchEditNestingLevel) {
+ if (!query.isNull() && m_batchEditNestingLevel == 0) {
const int cursorPos = getAbsoluteCursorPosition(query);
const int composeLength = m_composingText.length();
@@ -579,24 +587,29 @@ void QAndroidInputContext::updateCursorPosition()
if (m_composingText.isEmpty() != (m_composingTextStart == -1))
qWarning() << "Input method out of sync" << m_composingText << m_composingTextStart;
- int realCursorPosition = cursorPos;
- int realAnchorPosition = cursorPos;
+ int realSelectionStart = cursorPos;
+ int realSelectionEnd = cursorPos;
int cpos = query->value(Qt::ImCursorPosition).toInt();
int anchor = query->value(Qt::ImAnchorPosition).toInt();
if (cpos != anchor) {
if (!m_composingText.isEmpty()) {
qWarning("Selecting text while preediting may give unpredictable results.");
- finishComposingText();
+ focusObjectStopComposing();
}
int blockPos = getBlockPosition(query);
- realCursorPosition = blockPos + cpos;
- realAnchorPosition = blockPos + anchor;
+ realSelectionStart = blockPos + cpos;
+ realSelectionEnd = blockPos + anchor;
}
// Qt's idea of the cursor position is the start of the preedit area, so we maintain our own preedit cursor pos
- if (!m_composingText.isEmpty())
- realCursorPosition = realAnchorPosition = m_composingCursor;
- QtAndroidInput::updateSelection(realCursorPosition, realAnchorPosition,
+ if (focusObjectIsComposing())
+ realSelectionStart = realSelectionEnd = m_composingCursor;
+
+ // Some keyboards misbahave when selStart > selEnd
+ if (realSelectionStart > realSelectionEnd)
+ std::swap(realSelectionStart, realSelectionEnd);
+
+ QtAndroidInput::updateSelection(realSelectionStart, realSelectionEnd,
m_composingTextStart, m_composingTextStart + composeLength); // pre-edit text
}
}
@@ -666,13 +679,11 @@ void QAndroidInputContext::updateSelectionHandles()
*/
void QAndroidInputContext::handleLocationChanged(int handleId, int x, int y)
{
- if (m_batchEditNestingLevel.loadRelaxed() || m_blockUpdateSelection) {
+ if (m_batchEditNestingLevel != 0) {
qWarning() << "QAndroidInputContext::handleLocationChanged returned";
return;
}
- finishComposingText();
-
auto im = qGuiApp->inputMethod();
auto leftRect = im->cursorRectangle();
// The handle is down of the cursor, but we want the position in the middle.
@@ -682,63 +693,96 @@ void QAndroidInputContext::handleLocationChanged(int handleId, int x, int y)
: QHighDpiScaling::factor(QtAndroid::androidPlatformIntegration()->screen());
QPointF point(x / pixelDensity, y / pixelDensity);
point.setY(point.y() - leftRect.width() / 2);
- if (handleId == 1) {
- setSelectionOnFocusObject(point, point);
- return;
- }
- QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImAnchorPosition | Qt::ImCurrentSelection);
+ QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImAnchorPosition
+ | Qt::ImAbsolutePosition | Qt::ImCurrentSelection);
QCoreApplication::sendEvent(m_focusObject, &query);
int cpos = query.value(Qt::ImCursorPosition).toInt();
int anchor = query.value(Qt::ImAnchorPosition).toInt();
- bool rtl = query.value(Qt::ImCurrentSelection).toString().isRightToLeft();
auto rightRect = im->anchorRectangle();
if (cpos > anchor)
std::swap(leftRect, rightRect);
- auto checkLeftHandle = [&rightRect](QPointF &handlePos) {
- if (handlePos.y() > rightRect.center().y())
- handlePos.setY(rightRect.center().y()); // adjust Y handle pos
- if (handlePos.y() >= rightRect.y() && handlePos.y() <= rightRect.bottom() && handlePos.x() >= rightRect.x())
- return false; // same line and wrong X pos ?
- return true;
- };
-
- auto checkRtlRightHandle = [&rightRect](QPointF &handlePos) {
- if (handlePos.y() > rightRect.center().y())
- handlePos.setY(rightRect.center().y()); // adjust Y handle pos
- if (handlePos.y() >= rightRect.y() && handlePos.y() <= rightRect.bottom() && rightRect.x() >= handlePos.x())
- return false; // same line and wrong X pos ?
- return true;
- };
-
- auto checkRightHandle = [&leftRect](QPointF &handlePos) {
- if (handlePos.y() < leftRect.center().y())
- handlePos.setY(leftRect.center().y()); // adjust Y handle pos
- if (handlePos.y() >= leftRect.y() && handlePos.y() <= leftRect.bottom() && leftRect.x() >= handlePos.x())
- return false; // same line and wrong X pos ?
- return true;
- };
-
- auto checkRtlLeftHandle = [&leftRect](QPointF &handlePos) {
- if (handlePos.y() < leftRect.center().y())
- handlePos.setY(leftRect.center().y()); // adjust Y handle pos
- if (handlePos.y() >= leftRect.y() && handlePos.y() <= leftRect.bottom() && handlePos.x() >= leftRect.x())
- return false; // same line and wrong X pos ?
- return true;
- };
-
- if (handleId == 2) {
- QPointF rightPoint(rightRect.center());
- if ((!rtl && !checkLeftHandle(point)) || (rtl && !checkRtlRightHandle(point)))
- return;
- setSelectionOnFocusObject(point, rightPoint);
+ // Do not allow dragging left handle below right handle, or right handle above left handle
+ if (handleId == 2 && point.y() > rightRect.center().y()) {
+ point.setY(rightRect.center().y());
+ } else if (handleId == 3 && point.y() < leftRect.center().y()) {
+ point.setY(leftRect.center().y());
+ }
+
+ const QPointF pointLocal = im->inputItemTransform().inverted().map(point);
+ bool ok;
+ const int handlePos =
+ QInputMethod::queryFocusObject(Qt::ImCursorPosition, pointLocal).toInt(&ok);
+ if (!ok)
+ return;
+
+ int newCpos = cpos;
+ int newAnchor = anchor;
+ if (newAnchor > newCpos)
+ std::swap(newAnchor, newCpos);
+
+ if (handleId == 1) {
+ newCpos = handlePos;
+ newAnchor = handlePos;
+ } else if (handleId == 2) {
+ newAnchor = handlePos;
} else if (handleId == 3) {
- QPointF leftPoint(leftRect.center());
- if ((!rtl && !checkRightHandle(point)) || (rtl && !checkRtlLeftHandle(point)))
+ newCpos = handlePos;
+ }
+
+ /*
+ Do not allow clearing selection by dragging selection handles and do not allow swapping
+ selection handles for consistency with Android's native text editing controls. Ensure that at
+ least one symbol remains selected.
+ */
+ if ((handleId == 2 || handleId == 3) && newCpos <= newAnchor) {
+ QTextBoundaryFinder finder(QTextBoundaryFinder::Grapheme,
+ query.value(Qt::ImCurrentSelection).toString());
+
+ const int oldSelectionStartPos = qMin(cpos, anchor);
+
+ if (handleId == 2) {
+ finder.toEnd();
+ finder.toPreviousBoundary();
+ newAnchor = finder.position() + oldSelectionStartPos;
+ } else {
+ finder.toStart();
+ finder.toNextBoundary();
+ newCpos = finder.position() + oldSelectionStartPos;
+ }
+ }
+
+ // Check if handle has been dragged far enough
+ if (!focusObjectIsComposing() && newCpos == cpos && newAnchor == anchor)
+ return;
+
+ /*
+ If the editor is currently in composing state, we have to compare newCpos with
+ m_composingCursor instead of cpos. And since there is nothing to compare with newAnchor, we
+ perform the check only when user drags the cursor handle.
+ */
+ if (focusObjectIsComposing() && handleId == 1) {
+ int absoluteCpos = query.value(Qt::ImAbsolutePosition).toInt(&ok);
+ if (!ok)
+ absoluteCpos = cpos;
+ const int blockPos = absoluteCpos - cpos;
+
+ if (blockPos + newCpos == m_composingCursor)
return;
- setSelectionOnFocusObject(leftPoint, point);
}
+
+ BatchEditLock batchEditLock(this);
+
+ focusObjectStopComposing();
+
+ QList<QInputMethodEvent::Attribute> attributes;
+ attributes.append({ QInputMethodEvent::Selection, newAnchor, newCpos - newAnchor });
+ if (newCpos != newAnchor)
+ attributes.append({ QInputMethodEvent::Cursor, 0, 0 });
+
+ QInputMethodEvent event(QString(), attributes);
+ QGuiApplication::sendEvent(m_focusObject, &event);
}
void QAndroidInputContext::touchDown(int x, int y)
@@ -748,7 +792,7 @@ void QAndroidInputContext::touchDown(int x, int y)
m_handleMode = ShowCursor;
// The VK will appear in a moment, stop the timer
m_hideCursorHandleTimer.stop();
- finishComposingText();
+ focusObjectStopComposing();
updateSelectionHandles();
}
}
@@ -760,13 +804,19 @@ void QAndroidInputContext::longPress(int x, int y)
return;
if (m_focusObject && inputItemRectangle().contains(x, y)) {
- finishComposingText();
+ BatchEditLock batchEditLock(this);
+
+ focusObjectStopComposing();
// Release left button, otherwise the following events will cancel the menu popup
QtAndroidInput::releaseMouse(x, y);
- handleLocationChanged(1, x, y);
- ScopedValueChangeBack<bool> svcb(m_blockUpdateSelection, true);
+ const double pixelDensity =
+ QGuiApplication::focusWindow()
+ ? QHighDpiScaling::factor(QGuiApplication::focusWindow())
+ : QHighDpiScaling::factor(QtAndroid::androidPlatformIntegration()->screen());
+ const QPointF touchPoint(x / pixelDensity, y / pixelDensity);
+ setSelectionOnFocusObject(touchPoint, touchPoint);
QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImAnchorPosition | Qt::ImTextBeforeCursor | Qt::ImTextAfterCursor);
QCoreApplication::sendEvent(m_focusObject, &query);
@@ -905,6 +955,7 @@ void QAndroidInputContext::clear()
{
m_composingText.clear();
m_composingTextStart = -1;
+ m_composingCursor = -1;
m_extractedText.clear();
}
@@ -912,9 +963,8 @@ void QAndroidInputContext::clear()
void QAndroidInputContext::setFocusObject(QObject *object)
{
if (object != m_focusObject) {
+ focusObjectStopComposing();
m_focusObject = object;
- if (!m_composingText.isEmpty())
- finishComposingText();
reset();
}
QPlatformInputContext::setFocusObject(object);
@@ -929,78 +979,135 @@ jboolean QAndroidInputContext::beginBatchEdit()
jboolean QAndroidInputContext::endBatchEdit()
{
- if (--m_batchEditNestingLevel == 0 && !m_blockUpdateSelection) //ending batch edit mode
+ if (--m_batchEditNestingLevel == 0) { //ending batch edit mode
+ focusObjectStartComposing();
updateCursorPosition();
+ }
return JNI_TRUE;
}
/*
- Android docs say: If composing, replace compose text with \a text.
- Otherwise insert \a text at current cursor position.
-
- The cursor should then be moved to newCursorPosition. If > 0, this is
- relative to the end of the text - 1; if <= 0, this is relative to the start
- of the text. updateSelection() needs to be called.
+ Android docs say: This behaves like calling setComposingText(text, newCursorPosition) then
+ finishComposingText().
*/
jboolean QAndroidInputContext::commitText(const QString &text, jint newCursorPosition)
{
- ScopedValueChangeBack<bool> svcb(m_blockUpdateSelection, true);
- QInputMethodEvent event;
- event.setCommitString(text);
- sendInputMethodEvent(&event);
- clear();
-
- // Qt has now put the cursor at the end of the text, corresponding to newCursorPosition == 1
- if (newCursorPosition != 1) {
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
- if (!query.isNull()) {
- QList<QInputMethodEvent::Attribute> attributes;
- const int localPos = query->value(Qt::ImCursorPosition).toInt();
- const int newLocalPos = newCursorPosition > 0
- ? localPos + newCursorPosition - 1
- : localPos - text.length() + newCursorPosition;
- //move the cursor
- attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection,
- newLocalPos, 0));
- }
- }
- svcb.setOldValue();
- updateCursorPosition();
- return JNI_TRUE;
+ BatchEditLock batchEditLock(this);
+ return setComposingText(text, newCursorPosition) && finishComposingText();
}
jboolean QAndroidInputContext::deleteSurroundingText(jint leftLength, jint rightLength)
{
+ BatchEditLock batchEditLock(this);
+
+ focusObjectStopComposing();
+
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
return JNI_TRUE;
- m_composingText.clear();
- m_composingTextStart = -1;
-
if (leftLength < 0) {
rightLength += -leftLength;
leftLength = 0;
}
+ const int initialBlockPos = getBlockPosition(query);
+ const int initialCursorPos = getAbsoluteCursorPosition(query);
+ const int initialAnchorPos = initialBlockPos + query->value(Qt::ImAnchorPosition).toInt();
+
+ /*
+ According to documentation, we should delete leftLength characters before current selection
+ and rightLength characters after current selection (without affecting selection). But that is
+ absolutely not what Android's native EditText does. It deletes leftLength characters before
+ min(selection start, composing region start) and rightLength characters after max(selection
+ end, composing region end). There are no known keyboards that depend on this behavior, but
+ it is better to be consistent with EditText behavior, because there definetly should be no
+ keyboards that depend on documented behavior.
+ */
+ const int leftEnd =
+ m_composingText.isEmpty()
+ ? qMin(initialCursorPos, initialAnchorPos)
+ : qMin(qMin(initialCursorPos, initialAnchorPos), m_composingTextStart);
+
+ const int rightBegin =
+ m_composingText.isEmpty()
+ ? qMax(initialCursorPos, initialAnchorPos)
+ : qMax(qMax(initialCursorPos, initialAnchorPos),
+ m_composingTextStart + m_composingText.length());
+
+ int textBeforeCursorLen;
+ int textAfterCursorLen;
+
QVariant textBeforeCursor = query->value(Qt::ImTextBeforeCursor);
QVariant textAfterCursor = query->value(Qt::ImTextAfterCursor);
if (textBeforeCursor.isValid() && textAfterCursor.isValid()) {
- leftLength = qMin(leftLength, textBeforeCursor.toString().length());
- rightLength = qMin(rightLength, textAfterCursor.toString().length());
+ textBeforeCursorLen = textBeforeCursor.toString().length();
+ textAfterCursorLen = textAfterCursor.toString().length();
} else {
- int cursorPos = query->value(Qt::ImCursorPosition).toInt();
- leftLength = qMin(leftLength, cursorPos);
- rightLength = qMin(rightLength, query->value(Qt::ImSurroundingText).toString().length() - cursorPos);
+ textBeforeCursorLen = initialCursorPos - initialBlockPos;
+ textAfterCursorLen =
+ query->value(Qt::ImSurroundingText).toString().length() - textBeforeCursorLen;
}
+ leftLength = qMin(qMax(0, textBeforeCursorLen - (initialCursorPos - leftEnd)), leftLength);
+ rightLength = qMin(qMax(0, textAfterCursorLen - (rightBegin - initialCursorPos)), rightLength);
+
if (leftLength == 0 && rightLength == 0)
return JNI_TRUE;
- QInputMethodEvent event;
- event.setCommitString(QString(), -leftLength, leftLength+rightLength);
- sendInputMethodEvent(&event);
- clear();
+ if (leftEnd == rightBegin) {
+ // We have no selection and no composing region; we can do everything using one event
+ QInputMethodEvent event;
+ event.setCommitString({}, -leftLength, leftLength + rightLength);
+ QGuiApplication::sendEvent(m_focusObject, &event);
+ } else {
+ if (initialCursorPos != initialAnchorPos) {
+ QInputMethodEvent event({}, {
+ { QInputMethodEvent::Selection, initialCursorPos - initialBlockPos, 0 }
+ });
+
+ QGuiApplication::sendEvent(m_focusObject, &event);
+ }
+
+ int currentCursorPos = initialCursorPos;
+
+ if (rightLength > 0) {
+ QInputMethodEvent event;
+ event.setCommitString({}, rightBegin - currentCursorPos, rightLength);
+ QGuiApplication::sendEvent(m_focusObject, &event);
+
+ currentCursorPos = rightBegin;
+ }
+
+ if (leftLength > 0) {
+ const int leftBegin = leftEnd - leftLength;
+
+ QInputMethodEvent event;
+ event.setCommitString({}, leftBegin - currentCursorPos, leftLength);
+ QGuiApplication::sendEvent(m_focusObject, &event);
+
+ currentCursorPos = leftBegin;
+
+ if (!m_composingText.isEmpty())
+ m_composingTextStart -= leftLength;
+ }
+
+ // Restore cursor position or selection
+ if (currentCursorPos != initialCursorPos - leftLength
+ || initialCursorPos != initialAnchorPos) {
+ // If we have deleted a newline character, we are now in a new block
+ const int currentBlockPos = getBlockPosition(
+ focusObjectInputMethodQuery(Qt::ImAbsolutePosition | Qt::ImCursorPosition));
+
+ QInputMethodEvent event({}, {
+ { QInputMethodEvent::Selection, initialCursorPos - leftLength - currentBlockPos,
+ initialAnchorPos - initialCursorPos },
+ { QInputMethodEvent::Cursor, 0, 0 }
+ });
+
+ QGuiApplication::sendEvent(m_focusObject, &event);
+ }
+ }
return JNI_TRUE;
}
@@ -1008,16 +1115,70 @@ jboolean QAndroidInputContext::deleteSurroundingText(jint leftLength, jint right
// Android docs say the cursor must not move
jboolean QAndroidInputContext::finishComposingText()
{
- if (m_composingText.isEmpty())
- return JNI_TRUE; // not composing
+ BatchEditLock batchEditLock(this);
+
+ if (!focusObjectStopComposing())
+ return JNI_FALSE;
+
+ clear();
+ return JNI_TRUE;
+}
+
+bool QAndroidInputContext::focusObjectIsComposing() const
+{
+ return m_composingCursor != -1;
+}
+
+void QAndroidInputContext::focusObjectStartComposing()
+{
+ if (focusObjectIsComposing() || m_composingText.isEmpty())
+ return;
+
+ // Composing strings containing newline characters are rare and may cause problems
+ if (m_composingText.contains(QLatin1Char('\n')))
+ return;
+
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
+ if (!query)
+ return;
+
+ if (query->value(Qt::ImCursorPosition).toInt() != query->value(Qt::ImAnchorPosition).toInt())
+ return;
+
+ const int absoluteCursorPos = getAbsoluteCursorPosition(query);
+ if (absoluteCursorPos < m_composingTextStart
+ || absoluteCursorPos > m_composingTextStart + m_composingText.length())
+ return;
+
+ m_composingCursor = absoluteCursorPos;
+
+ QTextCharFormat underlined;
+ underlined.setFontUnderline(true);
+
+ QInputMethodEvent event(m_composingText, {
+ { QInputMethodEvent::Cursor, absoluteCursorPos - m_composingTextStart, 1 },
+ { QInputMethodEvent::TextFormat, 0, m_composingText.length(), underlined }
+ });
+
+ event.setCommitString({}, m_composingTextStart - absoluteCursorPos, m_composingText.length());
+
+ QGuiApplication::sendEvent(m_focusObject, &event);
+}
+
+bool QAndroidInputContext::focusObjectStopComposing()
+{
+ if (!focusObjectIsComposing())
+ return true; // not composing
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
- return JNI_FALSE;
+ return false;
const int blockPos = getBlockPosition(query);
const int localCursorPos = m_composingCursor - blockPos;
+ m_composingCursor = -1;
+
// Moving Qt's cursor to where the preedit cursor used to be
QList<QInputMethodEvent::Attribute> attributes;
attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, localCursorPos, 0));
@@ -1025,9 +1186,8 @@ jboolean QAndroidInputContext::finishComposingText()
QInputMethodEvent event(QString(), attributes);
event.setCommitString(m_composingText);
sendInputMethodEvent(&event);
- clear();
- return JNI_TRUE;
+ return true;
}
jint QAndroidInputContext::getCursorCapsMode(jint /*reqModes*/)
@@ -1067,52 +1227,51 @@ const QAndroidInputContext::ExtractedText &QAndroidInputContext::getExtractedTex
// updateExtractedText(View, int, ExtractedText) whenever you call
// updateSelection(View, int, int, int, int)." QTBUG-37980
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery(
+ Qt::ImCursorPosition | Qt::ImAbsolutePosition | Qt::ImAnchorPosition);
if (query.isNull())
return m_extractedText;
- int localPos = query->value(Qt::ImCursorPosition).toInt(); //position before pre-edit text relative to the current block
- int blockPos = getBlockPosition(query);
- QString blockText = query->value(Qt::ImSurroundingText).toString();
- int composeLength = m_composingText.length();
-
- if (composeLength > 0) {
- //Qt doesn't give us the preedit text, so we have to insert it at the correct position
- int localComposePos = m_composingTextStart - blockPos;
- blockText = blockText.leftRef(localComposePos) + m_composingText + blockText.midRef(localComposePos);
- }
-
- int cpos = localPos + composeLength; //actual cursor pos relative to the current block
-
- int localOffset = 0; // start of extracted text relative to the current block
- if (blockPos > 0) {
- QString prevBlockEnding = query->value(Qt::ImTextBeforeCursor).toString();
- prevBlockEnding.chop(localPos);
- if (prevBlockEnding.endsWith(QLatin1Char('\n'))) {
- localOffset = -qMin(20, prevBlockEnding.length());
- blockText = prevBlockEnding.right(-localOffset) + blockText;
- }
- }
+ const int cursorPos = getAbsoluteCursorPosition(query);
+ const int blockPos = getBlockPosition(query);
// It is documented that we should try to return hintMaxChars
- // characters, but that's not what the standard Android controls do, and
+ // characters, but standard Android controls always return all text, and
// there are input methods out there that (surprise) seem to depend on
// what happens in reality rather than what's documented.
- m_extractedText.text = blockText;
- m_extractedText.startOffset = blockPos + localOffset;
+ QVariant textBeforeCursor = QInputMethod::queryFocusObject(Qt::ImTextBeforeCursor, INT_MAX);
+ QVariant textAfterCursor = QInputMethod::queryFocusObject(Qt::ImTextAfterCursor, INT_MAX);
+ if (textBeforeCursor.isValid() && textAfterCursor.isValid()) {
+ if (focusObjectIsComposing()) {
+ m_extractedText.text =
+ textBeforeCursor.toString() + m_composingText + textAfterCursor.toString();
+ } else {
+ m_extractedText.text = textBeforeCursor.toString() + textAfterCursor.toString();
+ }
+
+ m_extractedText.startOffset = qMax(0, cursorPos - textBeforeCursor.toString().length());
+ } else {
+ m_extractedText.text = focusObjectInputMethodQuery(Qt::ImSurroundingText)
+ ->value(Qt::ImSurroundingText).toString();
+
+ if (focusObjectIsComposing())
+ m_extractedText.text.insert(cursorPos - blockPos, m_composingText);
- const QString &selection = query->value(Qt::ImCurrentSelection).toString();
- const int selLen = selection.length();
- if (selLen) {
- m_extractedText.selectionStart = query->value(Qt::ImAnchorPosition).toInt() - localOffset;
- m_extractedText.selectionEnd = m_extractedText.selectionStart + selLen;
- } else if (composeLength > 0) {
+ m_extractedText.startOffset = blockPos;
+ }
+
+ if (focusObjectIsComposing()) {
m_extractedText.selectionStart = m_composingCursor - m_extractedText.startOffset;
- m_extractedText.selectionEnd = m_composingCursor - m_extractedText.startOffset;
- } else {
- m_extractedText.selectionStart = cpos - localOffset;
- m_extractedText.selectionEnd = cpos - localOffset;
+ m_extractedText.selectionEnd = m_extractedText.selectionStart;
+ } else {
+ m_extractedText.selectionStart = cursorPos - m_extractedText.startOffset;
+ m_extractedText.selectionEnd =
+ blockPos + query->value(Qt::ImAnchorPosition).toInt() - m_extractedText.startOffset;
+
+ // Some keyboards misbehave when selectionStart > selectionEnd
+ if (m_extractedText.selectionStart > m_extractedText.selectionEnd)
+ std::swap(m_extractedText.selectionStart, m_extractedText.selectionEnd);
}
return m_extractedText;
@@ -1147,10 +1306,20 @@ QString QAndroidInputContext::getTextAfterCursor(jint length, jint /*flags*/)
}
}
- // Controls do not report preedit text, so we have to add it
- if (!m_composingText.isEmpty()) {
+ if (focusObjectIsComposing()) {
+ // Controls do not report preedit text, so we have to add it
const int cursorPosInsidePreedit = m_composingCursor - m_composingTextStart;
text = m_composingText.midRef(cursorPosInsidePreedit) + text;
+ } else {
+ // We must not return selected text if there is any
+ QSharedPointer<QInputMethodQueryEvent> query =
+ focusObjectInputMethodQuery(Qt::ImCursorPosition | Qt::ImAnchorPosition);
+ if (query) {
+ const int cursorPos = query->value(Qt::ImCursorPosition).toInt();
+ const int anchorPos = query->value(Qt::ImAnchorPosition).toInt();
+ if (anchorPos > cursorPos)
+ text.remove(0, anchorPos - cursorPos);
+ }
}
text.truncate(length);
@@ -1177,10 +1346,20 @@ QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/)
}
}
- // Controls do not report preedit text, so we have to add it
- if (!m_composingText.isEmpty()) {
+ if (focusObjectIsComposing()) {
+ // Controls do not report preedit text, so we have to add it
const int cursorPosInsidePreedit = m_composingCursor - m_composingTextStart;
text += m_composingText.leftRef(cursorPosInsidePreedit);
+ } else {
+ // We must not return selected text if there is any
+ QSharedPointer<QInputMethodQueryEvent> query =
+ focusObjectInputMethodQuery(Qt::ImCursorPosition | Qt::ImAnchorPosition);
+ if (query) {
+ const int cursorPos = query->value(Qt::ImCursorPosition).toInt();
+ const int anchorPos = query->value(Qt::ImAnchorPosition).toInt();
+ if (anchorPos < cursorPos)
+ text.chop(cursorPos - anchorPos);
+ }
}
if (text.length() > length)
@@ -1189,11 +1368,13 @@ QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/)
}
/*
- Android docs say that this function should remove the current preedit text
- if any, and replace it with the given text. Any selected text should be
- removed. The cursor is then moved to newCursorPosition. If > 0, this is
- relative to the end of the text - 1; if <= 0, this is relative to the start
- of the text.
+ Android docs say that this function should:
+ - remove the current composing text, if there is any
+ - otherwise remove currently selected text, if there is any
+ - insert new text in place of old composing text or, if there was none, at current cursor position
+ - mark the inserted text as composing
+ - move cursor as specified by newCursorPosition: if > 0, it is relative to the end of inserted
+ text - 1; if <= 0, it is relative to the start of inserted text
*/
jboolean QAndroidInputContext::setComposingText(const QString &text, jint newCursorPosition)
@@ -1202,47 +1383,110 @@ jboolean QAndroidInputContext::setComposingText(const QString &text, jint newCur
if (query.isNull())
return JNI_FALSE;
- const int cursorPos = getAbsoluteCursorPosition(query);
- if (newCursorPosition > 0)
- newCursorPosition += text.length() - 1;
+ BatchEditLock batchEditLock(this);
+
+ const int absoluteCursorPos = getAbsoluteCursorPosition(query);
+ int absoluteAnchorPos = getBlockPosition(query) + query->value(Qt::ImAnchorPosition).toInt();
+
+ // If we have composing region and selection (and therefore focusObjectIsComposing() == false),
+ // we must clear selection so that we won't delete it when we will be replacing composing text
+ if (!m_composingText.isEmpty() && absoluteCursorPos != absoluteAnchorPos) {
+ const int cursorPos = query->value(Qt::ImCursorPosition).toInt();
+ QInputMethodEvent event({}, { { QInputMethodEvent::Selection, cursorPos, 0 } });
+ QGuiApplication::sendEvent(m_focusObject, &event);
+
+ absoluteAnchorPos = absoluteCursorPos;
+ }
+
+ // If we had no composing region, pretend that we had a zero-length composing region at current
+ // cursor position to simplify code. Also account for that we must delete selected text if there
+ // (still) is any.
+ const int effectiveAbsoluteCursorPos = qMin(absoluteCursorPos, absoluteAnchorPos);
+ if (m_composingTextStart == -1)
+ m_composingTextStart = effectiveAbsoluteCursorPos;
+ const int oldComposingTextLen = m_composingText.length();
m_composingText = text;
- m_composingTextStart = text.isEmpty() ? -1 : cursorPos;
- m_composingCursor = cursorPos + newCursorPosition;
- QList<QInputMethodEvent::Attribute> attributes;
- attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor,
- newCursorPosition,
- 1));
- // Show compose text underlined
- QTextCharFormat underlined;
- underlined.setFontUnderline(true);
- attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,0, text.length(),
- QVariant(underlined)));
- QInputMethodEvent event(m_composingText, attributes);
- sendInputMethodEvent(&event);
+ const int newAbsoluteCursorPos =
+ newCursorPosition <= 0
+ ? m_composingTextStart + newCursorPosition
+ : m_composingTextStart + m_composingText.length() + newCursorPosition - 1;
- QMetaObject::invokeMethod(this, "keyDown");
+ const bool focusObjectWasComposing = focusObjectIsComposing();
+
+ // Same checks as in focusObjectStartComposing()
+ if (!m_composingText.isEmpty() && !m_composingText.contains(QLatin1Char('\n'))
+ && newAbsoluteCursorPos >= m_composingTextStart
+ && newAbsoluteCursorPos <= m_composingTextStart + m_composingText.length())
+ m_composingCursor = newAbsoluteCursorPos;
+ else
+ m_composingCursor = -1;
- updateCursorPosition();
+ QInputMethodEvent event;
+ if (focusObjectIsComposing()) {
+ QTextCharFormat underlined;
+ underlined.setFontUnderline(true);
+
+ event = QInputMethodEvent(m_composingText, {
+ { QInputMethodEvent::TextFormat, 0, m_composingText.length(), underlined },
+ { QInputMethodEvent::Cursor, m_composingCursor - m_composingTextStart, 1 }
+ });
+
+ if (oldComposingTextLen > 0 && !focusObjectWasComposing) {
+ event.setCommitString({}, m_composingTextStart - effectiveAbsoluteCursorPos,
+ oldComposingTextLen);
+ }
+ } else {
+ event = QInputMethodEvent({}, {});
+
+ if (focusObjectWasComposing) {
+ event.setCommitString(m_composingText);
+ } else {
+ event.setCommitString(m_composingText,
+ m_composingTextStart - effectiveAbsoluteCursorPos,
+ oldComposingTextLen);
+ }
+ }
+
+ if (m_composingText.isEmpty())
+ clear();
+
+ QGuiApplication::sendEvent(m_focusObject, &event);
+
+ if (!focusObjectIsComposing() && newCursorPosition != 1) {
+ // Move cursor using a separate event because if we have inserted or deleted a newline
+ // character, then we are now inside an another block
+
+ const int newBlockPos = getBlockPosition(
+ focusObjectInputMethodQuery(Qt::ImCursorPosition | Qt::ImAbsolutePosition));
+
+ event = QInputMethodEvent({}, {
+ { QInputMethodEvent::Selection, newAbsoluteCursorPos - newBlockPos, 0 }
+ });
+
+ QGuiApplication::sendEvent(m_focusObject, &event);
+ }
+
+ keyDown();
return JNI_TRUE;
}
// Android docs say:
// * start may be after end, same meaning as if swapped
-// * this function should not trigger updateSelection
+// * this function should not trigger updateSelection, but Android's native EditText does trigger it
// * if start == end then we should stop composing
jboolean QAndroidInputContext::setComposingRegion(jint start, jint end)
{
+ BatchEditLock batchEditLock(this);
+
// Qt will not include the current preedit text in the query results, and interprets all
// parameters relative to the text excluding the preedit. The simplest solution is therefore to
// tell Qt that we commit the text before we set the new region. This may cause a little flicker, but is
// much more robust than trying to keep the two different world views in sync
- bool wasComposing = !m_composingText.isEmpty();
- if (wasComposing)
- finishComposingText();
+ finishComposingText();
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
@@ -1253,54 +1497,42 @@ jboolean QAndroidInputContext::setComposingRegion(jint start, jint end)
if (start > end)
qSwap(start, end);
- /*
- start and end are cursor positions, not character positions,
- i.e. selecting the first character is done by start == 0 and end == 1,
- and start == end means no character selected
-
- Therefore, the length of the region is end - start
- */
-
- int length = end - start;
- int localPos = query->value(Qt::ImCursorPosition).toInt();
- int blockPosition = getBlockPosition(query);
- int localStart = start - blockPosition; // Qt uses position inside block
- int currentCursor = wasComposing ? m_composingCursor : blockPosition + localPos;
-
- ScopedValueChangeBack<bool> svcb(m_blockUpdateSelection, true);
-
QString text = query->value(Qt::ImSurroundingText).toString();
+ int textOffset = getBlockPosition(query);
- m_composingText = text.mid(localStart, length);
- m_composingTextStart = start;
- m_composingCursor = currentCursor;
-
- //in the Qt text controls, the preedit is defined relative to the cursor position
- int relativeStart = localStart - localPos;
+ if (start < textOffset || end > textOffset + text.length()) {
+ const int cursorPos = query->value(Qt::ImCursorPosition).toInt();
- QList<QInputMethodEvent::Attribute> attributes;
+ if (end - textOffset > text.length()) {
+ const QString after = query->value(Qt::ImTextAfterCursor).toString();
+ const int additionalSuffixLen = after.length() - (text.length() - cursorPos);
- // Show compose text underlined
- QTextCharFormat underlined;
- underlined.setFontUnderline(true);
- attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,0, length,
- QVariant(underlined)));
+ if (additionalSuffixLen > 0)
+ text += after.rightRef(additionalSuffixLen);
+ }
- // Keep the cursor position unchanged (don't move to end of preedit)
- attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, currentCursor - start, 1));
+ if (start < textOffset) {
+ QString before = query->value(Qt::ImTextBeforeCursor).toString();
+ before.chop(cursorPos);
- QInputMethodEvent event(m_composingText, attributes);
- event.setCommitString(QString(), relativeStart, length);
- sendInputMethodEvent(&event);
+ if (!before.isEmpty()) {
+ text = before + text;
+ textOffset -= before.length();
+ }
+ }
+ if (start < textOffset || end - textOffset > text.length()) {
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
- QSharedPointer<QInputMethodQueryEvent> query2 = focusObjectInputMethodQuery();
- if (!query2.isNull()) {
- qDebug() << "Setting. Prev local cpos:" << localPos << "block pos:" <<blockPosition << "comp.start:" << m_composingTextStart << "rel.start:" << relativeStart << "len:" << length << "cpos attr:" << localPos - localStart;
- qDebug() << "New cursor pos" << getAbsoluteCursorPosition(query2);
- }
+ qWarning("setComposingRegion: failed to retrieve text from composing region");
#endif
+ return JNI_TRUE;
+ }
+ }
+
+ m_composingText = text.mid(start - textOffset, end - start);
+ m_composingTextStart = start;
+
return JNI_TRUE;
}
@@ -1310,15 +1542,18 @@ jboolean QAndroidInputContext::setSelection(jint start, jint end)
if (query.isNull())
return JNI_FALSE;
+ BatchEditLock batchEditLock(this);
+
int blockPosition = getBlockPosition(query);
int localCursorPos = start - blockPosition;
- QList<QInputMethodEvent::Attribute> attributes;
- if (!m_composingText.isEmpty() && start == end) {
+ if (focusObjectIsComposing() && start == end && start >= m_composingTextStart
+ && start <= m_composingTextStart + m_composingText.length()) {
// not actually changing the selection; just moving the
// preedit cursor
int localOldPos = query->value(Qt::ImCursorPosition).toInt();
int pos = localCursorPos - localOldPos;
+ QList<QInputMethodEvent::Attribute> attributes;
attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, pos, 1));
//but we have to tell Qt about the compose text all over again
@@ -1330,21 +1565,26 @@ jboolean QAndroidInputContext::setSelection(jint start, jint end)
QVariant(underlined)));
m_composingCursor = start;
+ QInputMethodEvent event(m_composingText, attributes);
+ QGuiApplication::sendEvent(m_focusObject, &event);
} else {
// actually changing the selection
+ focusObjectStopComposing();
+ QList<QInputMethodEvent::Attribute> attributes;
attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection,
localCursorPos,
end - start));
+ QInputMethodEvent event({}, attributes);
+ QGuiApplication::sendEvent(m_focusObject, &event);
}
- QInputMethodEvent event(m_composingText, attributes);
- sendInputMethodEvent(&event);
- updateCursorPosition();
return JNI_TRUE;
}
jboolean QAndroidInputContext::selectAll()
{
- finishComposingText();
+ BatchEditLock batchEditLock(this);
+
+ focusObjectStopComposing();
m_handleMode = ShowCursor;
sendShortcut(QKeySequence::SelectAll);
return JNI_TRUE;
@@ -1352,7 +1592,12 @@ jboolean QAndroidInputContext::selectAll()
jboolean QAndroidInputContext::cut()
{
+ BatchEditLock batchEditLock(this);
+
+ // This is probably not what native EditText would do, but normally if there is selection, then
+ // there will be no composing region
finishComposingText();
+
m_handleMode = ShowCursor;
sendShortcut(QKeySequence::Cut);
return JNI_TRUE;
@@ -1360,7 +1605,9 @@ jboolean QAndroidInputContext::cut()
jboolean QAndroidInputContext::copy()
{
- finishComposingText();
+ BatchEditLock batchEditLock(this);
+
+ focusObjectStopComposing();
m_handleMode = ShowCursor;
sendShortcut(QKeySequence::Copy);
return JNI_TRUE;
@@ -1374,7 +1621,11 @@ jboolean QAndroidInputContext::copyURL()
jboolean QAndroidInputContext::paste()
{
+ BatchEditLock batchEditLock(this);
+
+ // TODO: This is not what native EditText does
finishComposingText();
+
m_handleMode = ShowCursor;
sendShortcut(QKeySequence::Paste);
return JNI_TRUE;
@@ -1386,8 +1637,12 @@ void QAndroidInputContext::sendShortcut(const QKeySequence &sequence)
const int keys = sequence[i];
Qt::Key key = Qt::Key(keys & ~Qt::KeyboardModifierMask);
Qt::KeyboardModifiers mod = Qt::KeyboardModifiers(keys & Qt::KeyboardModifierMask);
- QGuiApplication::postEvent(m_focusObject, new QKeyEvent(QEvent::KeyPress, key, mod));
- QGuiApplication::postEvent(m_focusObject, new QKeyEvent(QEvent::KeyRelease, key, mod));
+
+ QKeyEvent pressEvent(QEvent::KeyPress, key, mod);
+ QKeyEvent releaseEvent(QEvent::KeyRelease, key, mod);
+
+ QGuiApplication::sendEvent(m_focusObject, &pressEvent);
+ QGuiApplication::sendEvent(m_focusObject, &releaseEvent);
}
}
diff --git a/src/plugins/platforms/android/qandroidinputcontext.h b/src/plugins/platforms/android/qandroidinputcontext.h
index bd3edb30f0..e9bfb98e66 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.h
+++ b/src/plugins/platforms/android/qandroidinputcontext.h
@@ -151,6 +151,9 @@ private slots:
private:
void sendInputMethodEvent(QInputMethodEvent *event);
QSharedPointer<QInputMethodQueryEvent> focusObjectInputMethodQuery(Qt::InputMethodQueries queries = Qt::ImQueryAll);
+ bool focusObjectIsComposing() const;
+ void focusObjectStartComposing();
+ bool focusObjectStopComposing();
private:
ExtractedText m_extractedText;
@@ -158,9 +161,8 @@ private:
int m_composingTextStart;
int m_composingCursor;
QMetaObject::Connection m_updateCursorPosConnection;
- bool m_blockUpdateSelection;
HandleModes m_handleMode;
- QAtomicInt m_batchEditNestingLevel;
+ int m_batchEditNestingLevel;
QObject *m_focusObject;
QTimer m_hideCursorHandleTimer;
};
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h
index acddc3ecc8..2398e6351e 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.h
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h
@@ -55,6 +55,7 @@ public:
QNSWindowBackingStore(QWindow *window);
~QNSWindowBackingStore();
+ void resize(const QSize &size, const QRegion &staticContents) override;
void flush(QWindow *, const QRegion &, const QPoint &) override;
private:
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index c381f87844..01b4894324 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -71,6 +71,24 @@ QImage::Format QNSWindowBackingStore::format() const
return QRasterBackingStore::format();
}
+void QNSWindowBackingStore::resize(const QSize &size, const QRegion &staticContents)
+{
+ qCDebug(lcQpaBackingStore) << "Resize requested to" << size;
+ QRasterBackingStore::resize(size, staticContents);
+
+ // The window shadow rendered by AppKit is based on the shape/content of the
+ // NSWindow surface. Technically any flush of the backingstore can result in
+ // a potentially new shape of the window, and would need a shadow invalidation,
+ // but this is likely too expensive to do at every flush for the few cases where
+ // clients change the shape dynamically. One case where we do know that the shadow
+ // likely needs invalidation, if the window has partially transparent content,
+ // is after a resize, where AppKit's default shadow may be based on the previous
+ // window content.
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle());
+ if (cocoaWindow->isContentView() && !cocoaWindow->isOpaque())
+ cocoaWindow->m_needsInvalidateShadow = true;
+}
+
/*!
Flushes the given \a region from the specified \a window onto the
screen.
@@ -217,6 +235,7 @@ void QNSWindowBackingStore::flush(QWindow *window, const QRegion &region, const
QCocoaWindow *topLevelCocoaWindow = static_cast<QCocoaWindow *>(topLevelWindow->handle());
if (Q_UNLIKELY(topLevelCocoaWindow->m_needsInvalidateShadow)) {
+ qCDebug(lcQpaBackingStore) << "Invalidating window shadow for" << topLevelCocoaWindow;
[topLevelView.window invalidateShadow];
topLevelCocoaWindow->m_needsInvalidateShadow = false;
}
@@ -382,10 +401,11 @@ void QCALayerBackingStore::ensureBackBuffer()
bool QCALayerBackingStore::recreateBackBufferIfNeeded()
{
- const qreal devicePixelRatio = window()->devicePixelRatio();
+ const QCocoaWindow *platformWindow = static_cast<QCocoaWindow *>(window()->handle());
+ const qreal devicePixelRatio = platformWindow->devicePixelRatio();
QSize requestedBufferSize = m_requestedSize * devicePixelRatio;
- const NSView *backingStoreView = static_cast<QCocoaWindow *>(window()->handle())->view();
+ const NSView *backingStoreView = platformWindow->view();
Q_UNUSED(backingStoreView);
auto bufferSizeMismatch = [&](const QSize requested, const QSize actual) {
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
index 9771cd0289..69587a24be 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
@@ -191,6 +191,7 @@ public:
static void waitingObserverCallback(CFRunLoopObserverRef observer,
CFRunLoopActivity activity, void *info);
static void firstLoopEntry(CFRunLoopObserverRef ref, CFRunLoopActivity activity, void *info);
+ bool sendQueuedUserInputEvents();
void processPostedEvents();
};
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
index 84ffadea83..d3bb0711f0 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -377,16 +377,9 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
NSEvent* event = nil;
// First, send all previously excluded input events, if any:
- if (!excludeUserEvents) {
- while (!d->queuedUserInputEvents.isEmpty()) {
- event = static_cast<NSEvent *>(d->queuedUserInputEvents.takeFirst());
- if (!filterNativeEvent("NSEvent", event, nullptr)) {
- [NSApp sendEvent:event];
- retVal = true;
- }
- [event release];
- }
- }
+ if (d->sendQueuedUserInputEvents())
+ retVal = true;
+
// If Qt is used as a plugin, or as an extension in a native cocoa
// application, we should not run or stop NSApplication; This will be
@@ -843,6 +836,23 @@ void QCocoaEventDispatcherPrivate::waitingObserverCallback(CFRunLoopObserverRef,
emit static_cast<QCocoaEventDispatcher*>(info)->awake();
}
+bool QCocoaEventDispatcherPrivate::sendQueuedUserInputEvents()
+{
+ Q_Q(QCocoaEventDispatcher);
+ if (processEventsFlags & QEventLoop::ExcludeUserInputEvents)
+ return false;
+ bool didSendEvent = false;
+ while (!queuedUserInputEvents.isEmpty()) {
+ NSEvent *event = static_cast<NSEvent *>(queuedUserInputEvents.takeFirst());
+ if (!q->filterNativeEvent("NSEvent", event, nullptr)) {
+ [NSApp sendEvent:event];
+ didSendEvent = true;
+ }
+ [event release];
+ }
+ return didSendEvent;
+}
+
void QCocoaEventDispatcherPrivate::processPostedEvents()
{
if (blockSendPostedEvents) {
@@ -896,6 +906,7 @@ void QCocoaEventDispatcherPrivate::postedEventsSourceCallback(void *info)
d->maybeCancelWaitForMoreEvents();
return;
}
+ d->sendQueuedUserInputEvents();
d->processPostedEvents();
d->maybeCancelWaitForMoreEvents();
}
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h
index 34d8428188..a957710a88 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.h
+++ b/src/plugins/platforms/cocoa/qcocoamenu.h
@@ -92,6 +92,9 @@ public:
bool isOpen() const;
void setIsOpen(bool isOpen);
+ bool isAboutToShow() const;
+ void setIsAboutToShow(bool isAbout);
+
void timerEvent(QTimerEvent *e) override;
void syncMenuItem_helper(QPlatformMenuItem *menuItem, bool menubarUpdate);
@@ -111,6 +114,7 @@ private:
bool m_parentEnabled:1;
bool m_visible:1;
bool m_isOpen:1;
+ bool m_isAboutToShow:1;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index f34988721d..8c4fca0d29 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -178,6 +178,16 @@ void QCocoaMenu::setIsOpen(bool isOpen)
m_isOpen = isOpen;
}
+bool QCocoaMenu::isAboutToShow() const
+{
+ return m_isAboutToShow;
+}
+
+void QCocoaMenu::setIsAboutToShow(bool isAbout)
+{
+ m_isAboutToShow = isAbout;
+}
+
void QCocoaMenu::removeMenuItem(QPlatformMenuItem *menuItem)
{
QMacAutoReleasePool pool;
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index 32fc3ab660..c35cf6d799 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -141,6 +141,12 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
if (menu == m_menu)
return;
+ bool setAttached = false;
+ if ([m_native.menu isKindOfClass:[QCocoaNSMenu class]]) {
+ auto parentMenu = static_cast<QCocoaNSMenu *>(m_native.menu);
+ setAttached = parentMenu.platformMenu && parentMenu.platformMenu->isAboutToShow();
+ }
+
if (m_menu && m_menu->menuParent() == this) {
m_menu->setMenuParent(nullptr);
// Free the menu from its parent's influence
@@ -154,6 +160,8 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
if (m_menu) {
m_menu->setMenuParent(this);
m_menu->propagateEnabledState(isEnabled());
+ if (setAttached)
+ m_menu->setAttachedItem(m_native);
} else {
// we previously had a menu, but no longer
// clear out our item so the nexy sync() call builds a new one
diff --git a/src/plugins/platforms/cocoa/qcocoansmenu.mm b/src/plugins/platforms/cocoa/qcocoansmenu.mm
index 65b0832d9f..c51460282a 100644
--- a/src/plugins/platforms/cocoa/qcocoansmenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoansmenu.mm
@@ -195,7 +195,9 @@ static NSString *qt_mac_removePrivateUnicode(NSString *string)
return;
platformMenu->setIsOpen(true);
+ platformMenu->setIsAboutToShow(true);
emit platformMenu->aboutToShow();
+ platformMenu->setIsAboutToShow(false);
}
- (void)menuDidClose:(NSMenu *)menu
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 67b0cbdfe9..363a026e71 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -1011,16 +1011,16 @@ void QCocoaWindow::setMask(const QRegion &region)
} else {
m_view.layer.mask = nil;
}
- }
-
- if (isContentView()) {
- // Setting the mask requires invalidating the NSWindow shadow, but that needs
- // to happen after the backingstore has been redrawn, so that AppKit can pick
- // up the new window shape based on the backingstore content. Doing a display
- // directly here is not an option, as the window might not be exposed at this
- // time, and so would not result in an updated backingstore.
- m_needsInvalidateShadow = true;
- [m_view setNeedsDisplay:YES];
+ } else {
+ if (isContentView()) {
+ // Setting the mask requires invalidating the NSWindow shadow, but that needs
+ // to happen after the backingstore has been redrawn, so that AppKit can pick
+ // up the new window shape based on the backingstore content. Doing a display
+ // directly here is not an option, as the window might not be exposed at this
+ // time, and so would not result in an updated backingstore.
+ m_needsInvalidateShadow = true;
+ [m_view setNeedsDisplay:YES];
+ }
}
}
diff --git a/src/plugins/platforms/ios/quiview_accessibility.mm b/src/plugins/platforms/ios/quiview_accessibility.mm
index a3f4156a59..458ddcc9b8 100644
--- a/src/plugins/platforms/ios/quiview_accessibility.mm
+++ b/src/plugins/platforms/ios/quiview_accessibility.mm
@@ -101,6 +101,8 @@
- (id)accessibilityElementAtIndex:(NSInteger)index
{
[self initAccessibility];
+ if (index >= [m_accessibleElements count])
+ return nil;
return m_accessibleElements[index];
}
@@ -110,4 +112,10 @@
return [m_accessibleElements indexOfObject:element];
}
+- (NSArray *)accessibilityElements
+{
+ [self initAccessibility];
+ return m_accessibleElements;
+}
+
@end
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index f3a7c78f73..bb349f08a7 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -77,6 +77,7 @@
#include <QtCore/qoperatingsystemversion.h>
#include <QtCore/qsysinfo.h>
#include <QtCore/qscopedpointer.h>
+#include <QtCore/quuid.h>
#include <QtCore/private/qsystemlibrary_p.h>
#include <QtEventDispatcherSupport/private/qwindowsguieventdispatcher_p.h>
@@ -544,7 +545,7 @@ QString QWindowsContext::registerWindowClass(QString cname,
// each one has to have window class names with a unique name
// The first instance gets the unmodified name; if the class
// has already been registered by another instance of Qt then
- // add an instance-specific ID, the address of the window proc.
+ // add a UUID.
static int classExists = -1;
const auto appInstance = static_cast<HINSTANCE>(GetModuleHandle(nullptr));
@@ -555,7 +556,7 @@ QString QWindowsContext::registerWindowClass(QString cname,
}
if (classExists)
- cname += QString::number(reinterpret_cast<quintptr>(proc));
+ cname += QUuid::createUuid().toString();
if (d->m_registeredWindowClassNames.contains(cname)) // already registered in our list
return cname;
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
index 4adf662152..f26f698e76 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
@@ -204,7 +204,6 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
, m_shareContext(0)
, m_format(format)
, m_isPBufferCurrent(false)
- , m_swapInterval(-1)
, m_ownsContext(nativeHandle.isNull())
, m_getGraphicsResetStatus(0)
, m_lost(false)
@@ -567,9 +566,9 @@ bool QGLXContext::makeCurrent(QPlatformSurface *surface)
if (success && surfaceClass == QSurface::Window) {
int interval = surface->format().swapInterval();
+ QXcbWindow *window = static_cast<QXcbWindow *>(surface);
QXcbScreen *screen = screenForPlatformSurface(surface);
- if (interval >= 0 && m_swapInterval != interval && screen) {
- m_swapInterval = interval;
+ if (interval >= 0 && interval != window->swapInterval() && screen) {
typedef void (*qt_glXSwapIntervalEXT)(Display *, GLXDrawable, int);
typedef void (*qt_glXSwapIntervalMESA)(unsigned int);
static qt_glXSwapIntervalEXT glXSwapIntervalEXT = 0;
@@ -588,6 +587,7 @@ bool QGLXContext::makeCurrent(QPlatformSurface *surface)
glXSwapIntervalEXT(m_display, glxDrawable, interval);
else if (glXSwapIntervalMESA)
glXSwapIntervalMESA(interval);
+ window->setSwapInterval(interval);
}
}
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.h b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.h
index be9d3f5dcb..2a88fd6e59 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.h
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.h
@@ -87,7 +87,6 @@ private:
GLXContext m_shareContext;
QSurfaceFormat m_format;
bool m_isPBufferCurrent;
- int m_swapInterval;
bool m_ownsContext;
GLenum (APIENTRY * m_getGraphicsResetStatus)();
bool m_lost;
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index bfc105a040..8c34bd9c91 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -658,16 +658,24 @@ QImage::Format QXcbScreen::format() const
return format;
}
-QDpi QXcbScreen::logicalDpi() const
+int QXcbScreen::forcedDpi() const
{
static const int overrideDpi = qEnvironmentVariableIntValue("QT_FONT_DPI");
if (overrideDpi)
- return QDpi(overrideDpi, overrideDpi);
+ return overrideDpi;
const int forcedDpi = m_virtualDesktop->forcedDpi();
- if (forcedDpi > 0) {
+ if (forcedDpi > 0)
+ return forcedDpi;
+ return 0;
+}
+
+QDpi QXcbScreen::logicalDpi() const
+{
+ const int forcedDpi = this->forcedDpi();
+ if (forcedDpi > 0)
return QDpi(forcedDpi, forcedDpi);
- }
+
return m_virtualDesktop->dpi();
}
@@ -739,7 +747,9 @@ void QXcbScreen::updateGeometry(const QRect &geometry, uint8_t rotation)
if (m_sizeMillimeters.isEmpty())
m_sizeMillimeters = sizeInMillimeters(geometry.size(), m_virtualDesktop->dpi());
- qreal dpi = geometry.width() / physicalSize().width() * qreal(25.4);
+ qreal dpi = forcedDpi();
+ if (dpi <= 0)
+ dpi = geometry.width() / physicalSize().width() * qreal(25.4);
// Use 128 as a reference DPI on small screens. This favors "small UI" over "large UI".
qreal referenceDpi = physicalSize().width() <= 320 ? 128 : 96;
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index be6c45e415..ec3b07bfb7 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -208,6 +208,7 @@ public:
private:
void sendStartupMessage(const QByteArray &message) const;
+ int forcedDpi() const;
QByteArray getOutputProperty(xcb_atom_t atom) const;
QByteArray getEdid() const;
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index e4a04f5308..5de5974ca7 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -184,6 +184,9 @@ public:
static void setWindowTitle(const QXcbConnection *conn, xcb_window_t window, const QString &title);
static QString windowTitle(const QXcbConnection *conn, xcb_window_t window);
+ int swapInterval() const { return m_swapInterval; }
+ void setSwapInterval(int swapInterval) { m_swapInterval = swapInterval; }
+
public Q_SLOTS:
void updateSyncRequestCounter();
@@ -276,6 +279,7 @@ protected:
SyncState m_syncState = NoSyncNeeded;
QXcbSyncWindowRequest *m_pendingSyncRequest = nullptr;
+ int m_swapInterval = -1;
};
class QXcbForeignWindow : public QXcbWindow
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index 05c397a6f1..6c4605b5d2 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -2001,7 +2001,8 @@ QMacStyle::QMacStyle()
Q_D(QMacStyle);
// FIXME: Tie this logic into theme change, or even polish/unpolish
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave) {
- d->appearanceObserver = QMacKeyValueObserver(NSApp, @"effectiveAppearance", [&d] {
+ d->appearanceObserver = QMacKeyValueObserver(NSApp, @"effectiveAppearance", [this] {
+ Q_D(QMacStyle);
for (NSView *b : d->cocoaControls)
[b release];
d->cocoaControls.clear();
@@ -2495,11 +2496,12 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW
QPalette QMacStyle::standardPalette() const
{
- QPalette pal = QCommonStyle::standardPalette();
- pal.setColor(QPalette::Disabled, QPalette::Dark, QColor(191, 191, 191));
- pal.setColor(QPalette::Active, QPalette::Dark, QColor(191, 191, 191));
- pal.setColor(QPalette::Inactive, QPalette::Dark, QColor(191, 191, 191));
- return pal;
+ auto platformTheme = QGuiApplicationPrivate::platformTheme();
+ auto styleNames = platformTheme->themeHint(QPlatformTheme::StyleNames);
+ if (styleNames.toStringList().contains("macintosh"))
+ return *platformTheme->palette();
+ else
+ return QStyle::standardPalette();
}
int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w,
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index ba8878be57..526bf0a0ff 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -381,8 +381,6 @@ QWidget *QApplication::topLevelAt(const QPoint &pos)
0 if there is no such widget.
*/
-void qt_init(QApplicationPrivate *priv, int type
- );
void qt_init_tooltip_palette();
void qt_cleanup();
@@ -428,16 +426,10 @@ bool Q_WIDGETS_EXPORT qt_tab_all_widgets()
// ######## move to QApplicationPrivate
// Default application palettes and fonts (per widget type)
Q_GLOBAL_STATIC(PaletteHash, app_palettes)
-PaletteHash *qt_app_palettes_hash()
-{
- return app_palettes();
-}
-
Q_GLOBAL_STATIC(FontHash, app_fonts)
-FontHash *qt_app_fonts_hash()
-{
- return app_fonts();
-}
+// Exported accessors for use outside of this file
+PaletteHash *qt_app_palettes_hash() { return app_palettes(); }
+FontHash *qt_app_fonts_hash() { return app_fonts(); }
QWidgetList *QApplicationPrivate::popupWidgets = 0; // has keyboard input focus
@@ -571,7 +563,10 @@ void QApplicationPrivate::init()
process_cmdline();
// Must be called before initialize()
- qt_init(this, application_type);
+ QColormap::initialize();
+ qt_init_tooltip_palette();
+ QApplicationPrivate::initializeWidgetFontHash();
+
initialize();
eventDispatcher->startingUp();
@@ -582,18 +577,6 @@ void QApplicationPrivate::init()
}
-void qt_init(QApplicationPrivate *priv, int type)
-{
- Q_UNUSED(priv);
- Q_UNUSED(type);
-
- QColormap::initialize();
-
- qt_init_tooltip_palette();
-
- QApplicationPrivate::initializeWidgetFontHash();
-}
-
void qt_init_tooltip_palette()
{
#ifndef QT_NO_TOOLTIP
@@ -659,7 +642,7 @@ void QApplicationPrivate::initializeWidgetPaletteHash()
QPlatformTheme *platformTheme = QGuiApplicationPrivate::platformTheme();
if (!platformTheme)
return;
- qt_app_palettes_hash()->clear();
+ app_palettes()->clear();
setPossiblePalette(platformTheme->palette(QPlatformTheme::ToolButtonPalette), "QToolButton");
setPossiblePalette(platformTheme->palette(QPlatformTheme::ButtonPalette), "QAbstractButton");
@@ -683,7 +666,7 @@ void QApplicationPrivate::initializeWidgetFontHash()
const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
if (!theme)
return;
- FontHash *fontHash = qt_app_fonts_hash();
+ FontHash *fontHash = app_fonts();
fontHash->clear();
if (const QFont *font = theme->font(QPlatformTheme::MenuFont))
@@ -1162,9 +1145,7 @@ void QApplication::setStyle(QStyle *style)
} else if (QApplicationPrivate::sys_pal) {
clearSystemPalette();
initSystemPalette();
- QApplicationPrivate::initializeWidgetPaletteHash();
QApplicationPrivate::initializeWidgetFontHash();
- QApplicationPrivate::setPalette_helper(*QApplicationPrivate::sys_pal, /*className=*/0, /*clearWidgetPaletteHash=*/false);
} else if (!QApplicationPrivate::sys_pal) {
// Initialize the sys_pal if it hasn't happened yet...
QApplicationPrivate::setSystemPalette(QApplicationPrivate::app_style->standardPalette());
@@ -1462,28 +1443,10 @@ void QApplication::setPalette(const QPalette &palette, const char* className)
void QApplicationPrivate::setSystemPalette(const QPalette &pal)
{
- QPalette adjusted;
-
-#if 0
- // adjust the system palette to avoid dithering
- QColormap cmap = QColormap::instance();
- if (cmap.depths() > 4 && cmap.depths() < 24) {
- for (int g = 0; g < QPalette::NColorGroups; g++)
- for (int i = 0; i < QPalette::NColorRoles; i++) {
- QColor color = pal.color((QPalette::ColorGroup)g, (QPalette::ColorRole)i);
- color = cmap.colorAt(cmap.pixel(color));
- adjusted.setColor((QPalette::ColorGroup)g, (QPalette::ColorRole) i, color);
- }
- }
-#else
- adjusted = pal;
-#endif
-
if (!sys_pal)
- sys_pal = new QPalette(adjusted);
+ sys_pal = new QPalette(pal);
else
- *sys_pal = adjusted;
-
+ *sys_pal = pal;
if (!QApplicationPrivate::set_pal)
QApplication::setPalette(*sys_pal);
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index be2906a743..2176c612d0 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -1,4 +1,4 @@
-/****************************************************************************
+/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
@@ -2617,14 +2617,27 @@ bool QWidgetPrivate::setScreenForPoint(const QPoint &pos)
Q_Q(QWidget);
if (!q->isWindow())
return false;
- // Find the screen for pos and make the widget undertand it is on that screen.
+ // Find the screen for pos and make the widget understand it is on that screen.
+ return setScreen(QGuiApplication::screenAt(pos));
+}
+
+/*!
+\internal
+Ensures that the widget's QWindow is set to be on the given \a screen.
+Returns true if the screen was changed.
+*/
+
+bool QWidgetPrivate::setScreen(QScreen *screen)
+{
+ Q_Q(QWidget);
+ if (!screen || !q->isWindow())
+ return false;
const QScreen *currentScreen = windowHandle() ? windowHandle()->screen() : nullptr;
- QScreen *actualScreen = QGuiApplication::screenAt(pos);
- if (actualScreen && currentScreen != actualScreen) {
+ if (currentScreen != screen) {
if (!windowHandle()) // Try to create a window handle if not created.
createWinId();
if (windowHandle())
- windowHandle()->setScreen(actualScreen);
+ windowHandle()->setScreen(screen);
return true;
}
return false;
@@ -7025,37 +7038,41 @@ void QWidget::setTabOrder(QWidget* first, QWidget *second)
lastFocusChild = focusNext;
}
};
+ auto setPrev = [](QWidget *w, QWidget *prev)
+ {
+ w->d_func()->focus_prev = prev;
+ };
+ auto setNext = [](QWidget *w, QWidget *next)
+ {
+ w->d_func()->focus_next = next;
+ };
- QWidget *lastFocusChildOfFirst, *lastFocusChildOfSecond;
- determineLastFocusChild(first, lastFocusChildOfFirst);
+ // remove the second widget from the chain
+ QWidget *lastFocusChildOfSecond;
determineLastFocusChild(second, lastFocusChildOfSecond);
-
- // If the tab order is already correct, exit early
- if (lastFocusChildOfFirst == second ||
- lastFocusChildOfFirst->d_func()->focus_next == second) {
- return;
+ {
+ QWidget *oldPrev = second->d_func()->focus_prev;
+ QWidget *prevWithFocus = oldPrev;
+ while (prevWithFocus->focusPolicy() == Qt::NoFocus)
+ prevWithFocus = prevWithFocus->d_func()->focus_prev;
+ // only widgets between first and second -> all is fine
+ if (prevWithFocus == first)
+ return;
+ QWidget *oldNext = lastFocusChildOfSecond->d_func()->focus_next;
+ setPrev(oldNext, oldPrev);
+ setNext(oldPrev, oldNext);
}
- // Note that we need to handle two different sections in the tab chain; The section
- // that 'first' belongs to (firstSection), where we are about to insert 'second', and
- // the section that 'second' used be a part of (secondSection). When we pull 'second'
- // out of the second section and insert it into the first, we also need to ensure
- // that we leave the second section in a connected state.
- QWidget *firstChainOldSecond = lastFocusChildOfFirst->d_func()->focus_next;
- QWidget *secondChainNewFirst = second->d_func()->focus_prev;
- QWidget *secondChainNewSecond = lastFocusChildOfSecond->d_func()->focus_next;
-
- // Insert 'second' after 'first'
- lastFocusChildOfFirst->d_func()->focus_next = second;
- second->d_func()->focus_prev = lastFocusChildOfFirst;
-
- // The widget that used to be 'second' in the first section, should now become 'third'
- lastFocusChildOfSecond->d_func()->focus_next = firstChainOldSecond;
- firstChainOldSecond->d_func()->focus_prev = lastFocusChildOfSecond;
-
- // Repair the second section after we pulled 'second' out of it
- secondChainNewFirst->d_func()->focus_next = secondChainNewSecond;
- secondChainNewSecond->d_func()->focus_prev = secondChainNewFirst;
+ // insert the second widget into the chain
+ QWidget *lastFocusChildOfFirst;
+ determineLastFocusChild(first, lastFocusChildOfFirst);
+ {
+ QWidget *oldNext = lastFocusChildOfFirst->d_func()->focus_next;
+ setPrev(second, lastFocusChildOfFirst);
+ setNext(lastFocusChildOfFirst, second);
+ setPrev(oldNext, lastFocusChildOfSecond);
+ setNext(lastFocusChildOfSecond, oldNext);
+ }
}
/*!\internal
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index 1f36c192f5..99ec38e050 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -181,6 +181,7 @@ struct QTLWExtra {
QRect frameStrut;
QRect normalGeometry; // used by showMin/maximized/FullScreen
Qt::WindowFlags savedFlags; // Save widget flags while showing fullscreen
+ // ### TODO replace initialScreenIndex with QScreen *, in case the screens change at runtime
int initialScreenIndex; // Screen number when passing a QDesktop[Screen]Widget as parent.
QVector<QPlatformTextureList *> widgetTextures;
@@ -364,6 +365,7 @@ public:
void createWinId();
bool setScreenForPoint(const QPoint &pos);
+ bool setScreen(QScreen *screen);
void createTLExtra();
void createExtra();
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index 025e1e0044..c1f498cd0c 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -3706,17 +3706,6 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
bool dis = !(opt->state & QStyle::State_Enabled),
act = opt->state & QStyle::State_Selected;
- int checkableOffset = 0;
- if (checkable) {
- QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark);
- QStyleOptionMenuItem newMi = mi;
- newMi.rect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction);
- // align with icons if there are some
- checkableOffset = std::max(m->maxIconWidth, newMi.rect.width());
- if (subSubRule.hasDrawable() || checked)
- drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, w);
- }
-
if (!mi.icon.isNull()) {
QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
if (act && !dis)
@@ -3733,24 +3722,28 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
}
QRect iconRect = positionRect(w, subRule, iconRule, PseudoElement_MenuIcon, opt->rect, opt->direction);
if (opt->direction == Qt::LeftToRight)
- iconRect.moveLeft(iconRect.left() + checkableOffset);
+ iconRect.moveLeft(iconRect.left());
else
- iconRect.moveRight(iconRect.right() - checkableOffset);
+ iconRect.moveRight(iconRect.right());
iconRule.drawRule(p, iconRect);
QRect pmr(0, 0, pixw, pixh);
pmr.moveCenter(iconRect.center());
p->drawPixmap(pmr.topLeft(), pixmap);
+ } else if (checkable) {
+ QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark);
+ if (subSubRule.hasDrawable() || checked) {
+ QStyleOptionMenuItem newMi = mi;
+ if (!dis)
+ newMi.state |= State_Enabled;
+ if (act)
+ newMi.state |= State_On;
+ newMi.rect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction);
+ drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, w);
+ }
}
- int textOffset = 0;
- // padding overrules it all
- if (!subRule.hasBox() || subRule.box()->paddings[LeftEdge] == 0) {
- textOffset = checkableOffset;
- if (!m->icon.isNull() || !checkable)
- textOffset += m->maxIconWidth;
- }
QRect textRect = subRule.contentsRect(opt->rect);
- textRect.setLeft(textRect.left() + textOffset);
+ textRect.setLeft(textRect.left() + m->maxIconWidth);
textRect.setWidth(textRect.width() - mi.tabWidth);
const QRect vTextRect = visualRect(opt->direction, m->rect, textRect);
@@ -5106,27 +5099,20 @@ QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *op
if (mi->text.contains(QLatin1Char('\t')))
sz.rwidth() += 12; //as in QCommonStyle
bool checkable = mi->checkType != QStyleOptionMenuItem::NotCheckable;
- int checkableWidth = 0;
- if (checkable) {
+ if (!mi->icon.isNull()) {
+ const int pmSmall = pixelMetric(PM_SmallIconSize);
+ const QSize pmSize = mi->icon.actualSize(QSize(pmSmall, pmSmall));
+ sz.rwidth() += pmSize.width() + 4;
+ } else if (checkable) {
QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark);
QRect checkmarkRect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction);
- checkableWidth = std::max(mi->maxIconWidth, checkmarkRect.width());
- }
- if (!mi->icon.isNull()) {
- QPixmap pixmap = mi->icon.pixmap(pixelMetric(PM_SmallIconSize));
- sz.rwidth() += pixmap.width();
+ sz.rwidth() += std::max(mi->maxIconWidth, checkmarkRect.width()) + 4;
}
if (subRule.hasFont) {
QFontMetrics fm(subRule.font);
const QRect r = fm.boundingRect(QRect(), Qt::TextSingleLine | Qt::TextShowMnemonic, mi->text);
sz = sz.expandedTo(r.size());
}
- // padding overrules it all
- if (!subRule.hasBox() || subRule.box()->paddings[LeftEdge] == 0) {
- sz.rwidth() += checkableWidth;
- if (!mi->icon.isNull() || !checkable)
- sz.rwidth() += mi->maxIconWidth;
- }
return subRule.boxSize(subRule.adjustSize(sz));
}
}
diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp
index e25bc6de7a..685c5e159e 100644
--- a/src/widgets/widgets/qmdisubwindow.cpp
+++ b/src/widgets/widgets/qmdisubwindow.cpp
@@ -3141,8 +3141,6 @@ void QMdiSubWindow::paintEvent(QPaintEvent *paintEvent)
}
Q_D(QMdiSubWindow);
- if (isMaximized() && !d->drawTitleBarWhenMaximized())
- return;
if (d->resizeTimerId != -1) {
// Only update the style option rect and the window title.
@@ -3162,6 +3160,17 @@ void QMdiSubWindow::paintEvent(QPaintEvent *paintEvent)
}
QStylePainter painter(this);
+ QStyleOptionFrame frameOptions;
+ frameOptions.initFrom(this);
+ frameOptions.state.setFlag(QStyle::State_Active, d->isActive);
+ if (isMaximized() && !d->drawTitleBarWhenMaximized()) {
+ if (!autoFillBackground() && (!widget() || !qt_widget_private(widget())->isOpaque)) {
+ // make sure we paint all pixels of a maximized QMdiSubWindow if no-one else does
+ painter.drawPrimitive(QStyle::PE_FrameWindow, frameOptions);
+ }
+ return;
+ }
+
if (!d->windowTitle.isEmpty())
painter.setFont(d->font);
painter.drawComplexControl(QStyle::CC_TitleBar, d->cachedStyleOptions);
@@ -3169,10 +3178,7 @@ void QMdiSubWindow::paintEvent(QPaintEvent *paintEvent)
if (isMinimized() && !d->hasBorder(d->cachedStyleOptions))
return;
- QStyleOptionFrame frameOptions;
- frameOptions.initFrom(this);
frameOptions.lineWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, 0, this);
- frameOptions.state.setFlag(QStyle::State_Active, d->isActive);
// ### Ensure that we do not require setting the cliprect for 4.4
if (!isMinimized() && !d->hasBorder(d->cachedStyleOptions))
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 287be3e272..7b6a1b6da8 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -2331,8 +2331,18 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
d->updateLayoutDirection();
// Ensure that we get correct sizeHints by placing this window on the correct screen.
- if (d->setScreenForPoint(p))
+ // However if the QMenu was constructed with a QDesktopScreenWidget as its parent,
+ // then initialScreenIndex was set, so we should respect that for the lifetime of this menu.
+ // Use d->popupScreen to remember, because initialScreenIndex will be reset after the first showing.
+ const int screenIndex = d->topData()->initialScreenIndex;
+ if (screenIndex >= 0)
+ d->popupScreen = screenIndex;
+ if (auto s = QGuiApplication::screens().value(d->popupScreen)) {
+ if (d->setScreen(s))
+ d->itemsDirty = true;
+ } else if (d->setScreenForPoint(p)) {
d->itemsDirty = true;
+ }
const bool contextMenu = d->isContextMenu();
if (d->lastContextMenu != contextMenu) {
diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h
index ef152cd71b..efbbc099a1 100644
--- a/src/widgets/widgets/qmenu_p.h
+++ b/src/widgets/widgets/qmenu_p.h
@@ -515,6 +515,8 @@ public:
bool tearoffHighlighted : 1;
//menu fading/scrolling effects
bool doChildEffects : 1;
+
+ int popupScreen = -1;
};
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp
index a53d7841f4..9a60f1477d 100644
--- a/src/widgets/widgets/qmenubar.cpp
+++ b/src/widgets/widgets/qmenubar.cpp
@@ -68,6 +68,7 @@
#include "qmenu_p.h"
#include "qmenubar_p.h"
+#include <private/qscreen_p.h>
#include "qdebug.h"
QT_BEGIN_NAMESPACE
@@ -322,11 +323,18 @@ void QMenuBarPrivate::popupAction(QAction *action, bool activateFirst)
QRect adjustedActionRect = actionRect(action);
QPoint pos(q->mapToGlobal(QPoint(adjustedActionRect.left(), adjustedActionRect.bottom() + 1)));
QSize popup_size = activeMenu->sizeHint();
-
//we put the popup menu on the screen containing the bottom-center of the action rect
- QRect screenRect = QDesktopWidgetPrivate::screenGeometry(pos + QPoint(adjustedActionRect.width() / 2, 0));
+ QScreen *popupScreen = q->window()->windowHandle()->screen();
+ QPoint bottomMiddlePos = pos + QPoint(adjustedActionRect.width() / 2, 0);
+ const auto &siblings = popupScreen->virtualSiblings();
+ for (QScreen *sibling : siblings) {
+ if (sibling->geometry().contains(bottomMiddlePos)) {
+ popupScreen = sibling;
+ break;
+ }
+ }
+ QRect screenRect = popupScreen->geometry();
pos = QPoint(qMax(pos.x(), screenRect.x()), qMax(pos.y(), screenRect.y()));
-
const bool fitUp = (pos.y() - popup_size.height() >= screenRect.top());
const bool fitDown = (pos.y() + popup_size.height() <= screenRect.bottom());
const bool rtl = q->isRightToLeft();
@@ -352,6 +360,7 @@ void QMenuBarPrivate::popupAction(QAction *action, bool activateFirst)
if(!defaultPopDown || (fitUp && !fitDown))
pos.setY(qMax(screenRect.y(), q->mapToGlobal(QPoint(0, adjustedActionRect.top()-popup_size.height())).y()));
+ QMenuPrivate::get(activeMenu)->topData()->initialScreenIndex = QGuiApplication::screens().indexOf(popupScreen);
activeMenu->popup(pos);
if(activateFirst)
activeMenu->d_func()->setFirstActionActive();
diff --git a/tests/auto/corelib/animation/qabstractanimation/tst_qabstractanimation.cpp b/tests/auto/corelib/animation/qabstractanimation/tst_qabstractanimation.cpp
index fc09d57692..66a752df5d 100644
--- a/tests/auto/corelib/animation/qabstractanimation/tst_qabstractanimation.cpp
+++ b/tests/auto/corelib/animation/qabstractanimation/tst_qabstractanimation.cpp
@@ -83,6 +83,21 @@ void tst_QAbstractAnimation::destruction()
{
TestableQAbstractAnimation *anim = new TestableQAbstractAnimation;
delete anim;
+
+ // Animations should stop when deleted
+ auto *stopWhenDeleted = new TestableQAbstractAnimation;
+ QAbstractAnimation::State lastOldState, lastNewState;
+ QObject::connect(stopWhenDeleted, &QAbstractAnimation::stateChanged,
+ [&](QAbstractAnimation::State newState, QAbstractAnimation::State oldState) {
+ lastNewState = newState;
+ lastOldState = oldState;
+ });
+ stopWhenDeleted->start();
+ QCOMPARE(lastOldState, QAbstractAnimation::Stopped);
+ QCOMPARE(lastNewState, QAbstractAnimation::Running);
+ delete stopWhenDeleted;
+ QCOMPARE(lastOldState, QAbstractAnimation::Running);
+ QCOMPARE(lastNewState, QAbstractAnimation::Stopped);
}
void tst_QAbstractAnimation::currentLoop()
diff --git a/tests/auto/gui/image/qimagereader/images/qticon16.png b/tests/auto/gui/image/qimagereader/images/qticon16.png
new file mode 100644
index 0000000000..b6b01a4d64
--- /dev/null
+++ b/tests/auto/gui/image/qimagereader/images/qticon16.png
Binary files differ
diff --git a/tests/auto/gui/image/qimagereader/images/qticon16@2x.png b/tests/auto/gui/image/qimagereader/images/qticon16@2x.png
new file mode 100644
index 0000000000..205461daf0
--- /dev/null
+++ b/tests/auto/gui/image/qimagereader/images/qticon16@2x.png
Binary files differ
diff --git a/tests/auto/gui/image/qimagereader/images/qticon16@3x.png b/tests/auto/gui/image/qimagereader/images/qticon16@3x.png
new file mode 100644
index 0000000000..de92658241
--- /dev/null
+++ b/tests/auto/gui/image/qimagereader/images/qticon16@3x.png
Binary files differ
diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
index 1cf01133b2..d17a171728 100644
--- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
+++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
@@ -164,6 +164,9 @@ private slots:
void preserveTexts_data();
void preserveTexts();
+ void devicePixelRatio_data();
+ void devicePixelRatio();
+
private:
QString prefix;
QTemporaryDir m_temporaryDir;
@@ -1976,6 +1979,28 @@ void tst_QImageReader::preserveTexts()
QCOMPARE(r.text(key3), text3.simplified());
}
+void tst_QImageReader::devicePixelRatio_data()
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QSize>("size");
+ QTest::addColumn<qreal>("dpr");
+
+ QTest::newRow("1x") << "qticon16.png" << QSize(16, 16) << 1.0;
+ QTest::newRow("2x") << "qticon16@2x.png" << QSize(32, 32) << 2.0;
+ QTest::newRow("3x") << "qticon16@3x.png" << QSize(48, 48) << 3.0;
+}
+
+void tst_QImageReader::devicePixelRatio()
+{
+ QFETCH(QString, fileName);
+ QFETCH(QSize, size);
+ QFETCH(qreal, dpr);
+
+ QImageReader r(":/images/" + fileName);
+ QImage img = r.read();
+ QCOMPARE(img.size(), size);
+ QCOMPARE(img.devicePixelRatio(), dpr);
+}
QTEST_MAIN(tst_QImageReader)
#include "tst_qimagereader.moc"
diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp
index 53d0e7a694..e24370fc87 100644
--- a/tests/auto/network/access/http2/tst_http2.cpp
+++ b/tests/auto/network/access/http2/tst_http2.cpp
@@ -340,7 +340,7 @@ void tst_Http2::flowControlServerSide()
clearHTTP2State();
serverPort = 0;
- nRequests = 30;
+ nRequests = 10;
const Http2::RawSettings serverSettings = {{Settings::MAX_CONCURRENT_STREAMS_ID, 7}};
diff --git a/tests/auto/network/access/qftp/tst_qftp.cpp b/tests/auto/network/access/qftp/tst_qftp.cpp
index 63de0083f0..a04c2ae01d 100644
--- a/tests/auto/network/access/qftp/tst_qftp.cpp
+++ b/tests/auto/network/access/qftp/tst_qftp.cpp
@@ -2366,7 +2366,7 @@ void tst_QFtp::loginURL()
ftp = newFtp();
addCommand(QFtp::ConnectToHost,
- ftp->connectToHost(QHostInfo::localHostName(), port));
+ ftp->connectToHost("127.0.0.1", port));
addCommand(QFtp::Login, ftp->login(user, password));
QTestEventLoop::instance().enterLoop(5);
@@ -2374,7 +2374,7 @@ void tst_QFtp::loginURL()
ftp = nullptr;
server.stopServer();
if (QTestEventLoop::instance().timeout())
- QFAIL(msgTimedOut(QHostInfo::localHostName(), port));
+ QFAIL(msgTimedOut("127.0.0.1", port));
QCOMPARE(server.getRawUser(), rawUser);
QCOMPARE(server.getRawPassword(), rawPass);
diff --git a/tests/auto/network/access/qnetworkreply/certs/qt-test-server-cacert.pem b/tests/auto/network/access/qnetworkreply/certs/qt-test-server-cacert.pem
index 25bd4046e8..c5aea0d7c9 100644
--- a/tests/auto/network/access/qnetworkreply/certs/qt-test-server-cacert.pem
+++ b/tests/auto/network/access/qnetworkreply/certs/qt-test-server-cacert.pem
@@ -1,17 +1,17 @@
-----BEGIN CERTIFICATE-----
-MIICrTCCAhYCCQCdDn5rci6VDjANBgkqhkiG9w0BAQQFADCBmjEOMAwGA1UEChMF
-Tm9raWExFDASBgNVBAsTC1F0IFNvZnR3YXJlMSIwIAYJKoZIhvcNAQkBFhNub2Jv
-ZHlAbm9kb21haW4ub3JnMQ0wCwYDVQQHEwRPc2xvMQ0wCwYDVQQIEwRPc2xvMQsw
-CQYDVQQGEwJOTzEjMCEGA1UEAxMacXQtdGVzdC1zZXJ2ZXIucXQtdGVzdC1uZXQw
-HhcNMDkwNzEwMDc0MTIzWhcNMTkwNzA4MDc0MTIzWjCBmjEOMAwGA1UEChMFTm9r
-aWExFDASBgNVBAsTC1F0IFNvZnR3YXJlMSIwIAYJKoZIhvcNAQkBFhNub2JvZHlA
-bm9kb21haW4ub3JnMQ0wCwYDVQQHEwRPc2xvMQ0wCwYDVQQIEwRPc2xvMQswCQYD
-VQQGEwJOTzEjMCEGA1UEAxMacXQtdGVzdC1zZXJ2ZXIucXQtdGVzdC1uZXQwgZ8w
-DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM2q22/WNMmn8cC+5EEYGeICySLmp9W6
-Ay6eKHr0Xxp3X3epETuPfvAuxp7rOtkS18EMUegkUj8jw0IMEcbyHKFC/rTCaYOt
-93CxGBXMIChiMPAsFeYzGa/D6xzAkfcRaJRQ+Ek3CDLXPnXfo7xpABXezYcPXAJr
-gsgBfWrwHdxzAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAy7YOLCZABQy2Ygkchq1I
-+TUpvMn+gLwAyW8TNErM1V4lNY2+K78RawzKx3SqM97ymCy4TD45EA3A2gmi32NI
-xSKBNjFyzngUqsXBdcSasALiowlZCiJrGwlGX5qCkBlxXvJeUEbuJLPYVl5FBjXZ
-6o00K4cSPCqtqUez7WSmDZU=
+MIICpzCCAhACCQCzAF1hyRVzAjANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UEBhMC
+Tk8xDTALBgNVBAgTBE9zbG8xDTALBgNVBAcTBE9zbG8xDjAMBgNVBAoTBU5va2lh
+MTUwMwYDVQQLFCxRdCBTb2Z0d2FyZS9lbWFpbEFkZHJlc3M9bm9ib2R5QG5vZG9t
+YWluLm9yZzEjMCEGA1UEAxMacXQtdGVzdC1zZXJ2ZXIucXQtdGVzdC1uZXQwHhcN
+MTkwNjI0MTI0OTIxWhcNMjIwNjIzMTI0OTIxWjCBlzELMAkGA1UEBhMCTk8xDTAL
+BgNVBAgTBE9zbG8xDTALBgNVBAcTBE9zbG8xDjAMBgNVBAoTBU5va2lhMTUwMwYD
+VQQLFCxRdCBTb2Z0d2FyZS9lbWFpbEFkZHJlc3M9bm9ib2R5QG5vZG9tYWluLm9y
+ZzEjMCEGA1UEAxMacXQtdGVzdC1zZXJ2ZXIucXQtdGVzdC1uZXQwgZ8wDQYJKoZI
+hvcNAQEBBQADgY0AMIGJAoGBAM2q22/WNMmn8cC+5EEYGeICySLmp9W6Ay6eKHr0
+Xxp3X3epETuPfvAuxp7rOtkS18EMUegkUj8jw0IMEcbyHKFC/rTCaYOt93CxGBXM
+IChiMPAsFeYzGa/D6xzAkfcRaJRQ+Ek3CDLXPnXfo7xpABXezYcPXAJrgsgBfWrw
+HdxzAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEASCKbqEX5ysC549mq90ydk4jyDW3m
+PUyet01fKpcRqVs+OJxdExFBTra3gho6WzzpTSPsuX2ZKOLF5k6KkCvdCGvhC1Kv
+HHPIExurfzvdlSRzj6HbKyPuSfxyOloH0bBp7/Gg5RIuBPKlbmfbnTLtwEjhhbMU
+SoYI8HZd3HfY87c=
-----END CERTIFICATE-----
diff --git a/tests/auto/network/ssl/qsslsocket/certs/qt-test-server-cacert.pem b/tests/auto/network/ssl/qsslsocket/certs/qt-test-server-cacert.pem
index 25bd4046e8..c5aea0d7c9 100644
--- a/tests/auto/network/ssl/qsslsocket/certs/qt-test-server-cacert.pem
+++ b/tests/auto/network/ssl/qsslsocket/certs/qt-test-server-cacert.pem
@@ -1,17 +1,17 @@
-----BEGIN CERTIFICATE-----
-MIICrTCCAhYCCQCdDn5rci6VDjANBgkqhkiG9w0BAQQFADCBmjEOMAwGA1UEChMF
-Tm9raWExFDASBgNVBAsTC1F0IFNvZnR3YXJlMSIwIAYJKoZIhvcNAQkBFhNub2Jv
-ZHlAbm9kb21haW4ub3JnMQ0wCwYDVQQHEwRPc2xvMQ0wCwYDVQQIEwRPc2xvMQsw
-CQYDVQQGEwJOTzEjMCEGA1UEAxMacXQtdGVzdC1zZXJ2ZXIucXQtdGVzdC1uZXQw
-HhcNMDkwNzEwMDc0MTIzWhcNMTkwNzA4MDc0MTIzWjCBmjEOMAwGA1UEChMFTm9r
-aWExFDASBgNVBAsTC1F0IFNvZnR3YXJlMSIwIAYJKoZIhvcNAQkBFhNub2JvZHlA
-bm9kb21haW4ub3JnMQ0wCwYDVQQHEwRPc2xvMQ0wCwYDVQQIEwRPc2xvMQswCQYD
-VQQGEwJOTzEjMCEGA1UEAxMacXQtdGVzdC1zZXJ2ZXIucXQtdGVzdC1uZXQwgZ8w
-DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM2q22/WNMmn8cC+5EEYGeICySLmp9W6
-Ay6eKHr0Xxp3X3epETuPfvAuxp7rOtkS18EMUegkUj8jw0IMEcbyHKFC/rTCaYOt
-93CxGBXMIChiMPAsFeYzGa/D6xzAkfcRaJRQ+Ek3CDLXPnXfo7xpABXezYcPXAJr
-gsgBfWrwHdxzAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAy7YOLCZABQy2Ygkchq1I
-+TUpvMn+gLwAyW8TNErM1V4lNY2+K78RawzKx3SqM97ymCy4TD45EA3A2gmi32NI
-xSKBNjFyzngUqsXBdcSasALiowlZCiJrGwlGX5qCkBlxXvJeUEbuJLPYVl5FBjXZ
-6o00K4cSPCqtqUez7WSmDZU=
+MIICpzCCAhACCQCzAF1hyRVzAjANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UEBhMC
+Tk8xDTALBgNVBAgTBE9zbG8xDTALBgNVBAcTBE9zbG8xDjAMBgNVBAoTBU5va2lh
+MTUwMwYDVQQLFCxRdCBTb2Z0d2FyZS9lbWFpbEFkZHJlc3M9bm9ib2R5QG5vZG9t
+YWluLm9yZzEjMCEGA1UEAxMacXQtdGVzdC1zZXJ2ZXIucXQtdGVzdC1uZXQwHhcN
+MTkwNjI0MTI0OTIxWhcNMjIwNjIzMTI0OTIxWjCBlzELMAkGA1UEBhMCTk8xDTAL
+BgNVBAgTBE9zbG8xDTALBgNVBAcTBE9zbG8xDjAMBgNVBAoTBU5va2lhMTUwMwYD
+VQQLFCxRdCBTb2Z0d2FyZS9lbWFpbEFkZHJlc3M9bm9ib2R5QG5vZG9tYWluLm9y
+ZzEjMCEGA1UEAxMacXQtdGVzdC1zZXJ2ZXIucXQtdGVzdC1uZXQwgZ8wDQYJKoZI
+hvcNAQEBBQADgY0AMIGJAoGBAM2q22/WNMmn8cC+5EEYGeICySLmp9W6Ay6eKHr0
+Xxp3X3epETuPfvAuxp7rOtkS18EMUegkUj8jw0IMEcbyHKFC/rTCaYOt93CxGBXM
+IChiMPAsFeYzGa/D6xzAkfcRaJRQ+Ek3CDLXPnXfo7xpABXezYcPXAJrgsgBfWrw
+HdxzAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEASCKbqEX5ysC549mq90ydk4jyDW3m
+PUyet01fKpcRqVs+OJxdExFBTra3gho6WzzpTSPsuX2ZKOLF5k6KkCvdCGvhC1Kv
+HHPIExurfzvdlSRzj6HbKyPuSfxyOloH0bBp7/Gg5RIuBPKlbmfbnTLtwEjhhbMU
+SoYI8HZd3HfY87c=
-----END CERTIFICATE-----
diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
index 491f52a66b..b05f989b5c 100644
--- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
+++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
@@ -2755,6 +2755,7 @@ void tst_QSslSocket::encryptWithoutConnecting()
void tst_QSslSocket::resume_data()
{
+ QSKIP("Temporary skip while updating certificates");
QTest::addColumn<bool>("ignoreErrorsAfterPause");
QTest::addColumn<QList<QSslError> >("errorsToIgnore");
QTest::addColumn<bool>("expectSuccess");
@@ -3592,12 +3593,7 @@ protected:
socket = new QSslSocket(this);
socket->setSslConfiguration(config);
socket->setPeerVerifyMode(peerVerifyMode);
- if (QSslSocket::sslLibraryVersionNumber() > 0x10101000L) {
- // FIXME. With OpenSSL 1.1.1 and TLS 1.3 PSK auto-test is broken.
- socket->setProtocol(QSsl::TlsV1_2);
- } else {
- socket->setProtocol(protocol);
- }
+ socket->setProtocol(protocol);
if (ignoreSslErrors)
connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
@@ -3941,11 +3937,6 @@ void tst_QSslSocket::pskServer()
return;
QSslSocket socket;
-#ifdef TLS1_3_VERSION
- // FIXME: with OpenSSL 1.1.1 (thus TLS 1.3) test is known to fail
- // due to the different PSK mechanism (?) - to be investigated ASAP.
- socket.setProtocol(QSsl::TlsV1_2);
-#endif
this->socket = &socket;
QSignalSpy connectedSpy(&socket, SIGNAL(connected()));
diff --git a/tests/auto/other/lancelot/scripts/degeneratebeziers.qps b/tests/auto/other/lancelot/scripts/degeneratebeziers.qps
index 6c069fd82f..948968b0cd 100644
--- a/tests/auto/other/lancelot/scripts/degeneratebeziers.qps
+++ b/tests/auto/other/lancelot/scripts/degeneratebeziers.qps
@@ -34,3 +34,14 @@ setPen blue 40 solidline roundcap
drawPath revbez
setPen red 0
drawPath revbez
+
+resetMatrix
+path_lineTo tightJoin 60 10
+path_cubicTo tightJoin 50 0 100 0 100 50
+
+translate 50 500
+
+setPen green 40 solidline roundcap roundjoin
+drawPath tightJoin
+setPen red 0
+drawPath tightJoin
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index 3aece8746e..fb40674d98 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -180,6 +180,7 @@ private slots:
void tabOrderWithProxy();
void tabOrderWithCompoundWidgets();
void tabOrderNoChange();
+ void tabOrderNoChange2();
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
void activation();
#endif
@@ -1942,6 +1943,24 @@ static QVector<QWidget*> getFocusChain(QWidget *start, bool bForward)
return ret;
}
+//#define DEBUG_FOCUS_CHAIN
+static void dumpFocusChain(QWidget *start, bool bForward, const char *desc = nullptr)
+{
+#ifdef DEBUG_FOCUS_CHAIN
+ qDebug() << "Dump focus chain, start:" << start << "isForward:" << bForward << desc;
+ QWidget *cur = start;
+ do {
+ qDebug() << cur;
+ auto widgetPrivate = static_cast<QWidgetPrivate *>(qt_widget_private(cur));
+ cur = bForward ? widgetPrivate->focus_next : widgetPrivate->focus_prev;
+ } while (cur != start);
+#else
+ Q_UNUSED(start)
+ Q_UNUSED(bForward)
+ Q_UNUSED(desc)
+#endif
+}
+
void tst_QWidget::tabOrderNoChange()
{
QWidget w;
@@ -1953,7 +1972,61 @@ void tst_QWidget::tabOrderNoChange()
const auto focusChainForward = getFocusChain(&w, true);
const auto focusChainBackward = getFocusChain(&w, false);
+ dumpFocusChain(&w, true);
QWidget::setTabOrder(tabWidget, tv);
+ dumpFocusChain(&w, true);
+ QCOMPARE(focusChainForward, getFocusChain(&w, true));
+ QCOMPARE(focusChainBackward, getFocusChain(&w, false));
+}
+
+void tst_QWidget::tabOrderNoChange2()
+{
+ QWidget w;
+ auto *verticalLayout = new QVBoxLayout(&w);
+ auto *tabWidget = new QTabWidget(&w);
+ tabWidget->setObjectName("tabWidget");
+ verticalLayout->addWidget(tabWidget);
+
+ auto *tab1 = new QWidget(tabWidget);
+ tab1->setObjectName("tab1");
+ auto *vLay1 = new QVBoxLayout(tab1);
+ auto *le1 = new QLineEdit(tab1);
+ le1->setObjectName("le1");
+ auto *le2 = new QLineEdit(tab1);
+ le2->setObjectName("le2");
+ vLay1->addWidget(le1);
+ vLay1->addWidget(le2);
+ tabWidget->addTab(tab1, QStringLiteral("Tab 1"));
+
+ auto *tab2 = new QWidget(tabWidget);
+ tab2->setObjectName("tab2");
+ auto *vLay2 = new QVBoxLayout(tab2);
+ auto *le3 = new QLineEdit(tab2);
+ le3->setObjectName("le3");
+ auto *le4 = new QLineEdit(tab2);
+ le4->setObjectName("le4");
+ vLay2->addWidget(le3);
+ vLay2->addWidget(le4);
+ tabWidget->addTab(tab2, QStringLiteral("Tab 2"));
+
+ const auto focusChainForward = getFocusChain(&w, true);
+ const auto focusChainBackward = getFocusChain(&w, false);
+ dumpFocusChain(&w, true);
+ dumpFocusChain(&w, false);
+ // this will screw up the focus chain order without visible changes,
+ // so don't call it here for the simplicity of the test
+ //QWidget::setTabOrder(tabWidget, le1);
+
+ QWidget::setTabOrder(le1, le2);
+ dumpFocusChain(&w, true, "QWidget::setTabOrder(le1, le2)");
+ QWidget::setTabOrder(le2, le3);
+ dumpFocusChain(&w, true, "QWidget::setTabOrder(le2, le3)");
+ QWidget::setTabOrder(le3, le4);
+ dumpFocusChain(&w, true, "QWidget::setTabOrder(le3, le4)");
+ QWidget::setTabOrder(le4, tabWidget);
+ dumpFocusChain(&w, true, "QWidget::setTabOrder(le4, tabWidget)");
+ dumpFocusChain(&w, false);
+
QCOMPARE(focusChainForward, getFocusChain(&w, true));
QCOMPARE(focusChainBackward, getFocusChain(&w, false));
}
diff --git a/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp b/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp
index d744cece9c..8b45ac20b7 100644
--- a/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp
+++ b/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp
@@ -735,6 +735,7 @@ void tst_QSplitter::replaceWidget()
// Configure splitter
QWidget *oldWidget = sp.widget(index);
+ QTest::qWait(100); // Make sure we record the right original size (after the window manager adds the frame)
const QRect oldGeom = oldWidget ? oldWidget->geometry() : QRect();
if (oldWidget) {
// Collapse first, then hide, if necessary