summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmake/QtPublicAppleHelpers.cmake16
-rw-r--r--configure.cmake2
-rw-r--r--mkspecs/common/msvc-based-version.conf6
-rw-r--r--mkspecs/common/msvc-version.conf6
-rw-r--r--qmake/generators/win32/msvc_objectmodel.cpp2
-rw-r--r--qmake/generators/win32/msvc_objectmodel.h3
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp8
-rw-r--r--src/3rdparty/libjpeg/COPYRIGHT.txt2
-rw-r--r--src/3rdparty/libjpeg/ChangeLog.md43
-rw-r--r--src/3rdparty/libjpeg/qt_attribution.json4
-rw-r--r--src/3rdparty/libjpeg/src/jconfig.h4
-rw-r--r--src/3rdparty/libjpeg/src/jconfigint.h2
-rw-r--r--src/corelib/doc/src/cmake/cmake-configure-variables.qdoc2
-rw-r--r--src/corelib/doc/src/cmake/cmake-properties.qdoc2
-rw-r--r--src/corelib/doc/src/cmake/qt_deploy_translations.qdoc1
-rw-r--r--src/corelib/doc/src/cmake/qt_extract_metatypes.qdoc1
-rw-r--r--src/corelib/doc/src/cmake/qt_finalize_project.qdoc1
-rw-r--r--src/corelib/kernel/qmetacontainer.h9
-rw-r--r--src/corelib/kernel/qmetasequence.cpp40
-rw-r--r--src/corelib/kernel/qmetasequence.h21
-rw-r--r--src/plugins/styles/modernwindows/qwindows11style.cpp9
-rw-r--r--src/plugins/styles/modernwindows/qwindows11style_p.h1
-rw-r--r--src/testlib/qtestlog.cpp6
-rw-r--r--src/widgets/widgets/qtabbar.cpp66
-rw-r--r--src/widgets/widgets/qtabbar_p.h3
-rw-r--r--tests/auto/widgets/kernel/qwidget/BLACKLIST5
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp33
27 files changed, 162 insertions, 136 deletions
diff --git a/cmake/QtPublicAppleHelpers.cmake b/cmake/QtPublicAppleHelpers.cmake
index 3ffe53c6f34..b8f3fb4818e 100644
--- a/cmake/QtPublicAppleHelpers.cmake
+++ b/cmake/QtPublicAppleHelpers.cmake
@@ -1028,7 +1028,6 @@ function(_qt_internal_check_apple_sdk_and_xcode_versions)
endif()
_qt_internal_get_cached_apple_sdk_version(sdk_version)
- _qt_internal_get_cached_xcode_version(xcode_version)
if(NOT max_sdk_version MATCHES "^[0-9]+$")
message(FATAL_ERROR
@@ -1075,12 +1074,15 @@ function(_qt_internal_check_apple_sdk_and_xcode_versions)
)
endif()
- if(xcode_version VERSION_LESS min_xcode_version AND NOT QT_NO_XCODE_MIN_VERSION_CHECK)
- message(${message_type}
- "Qt requires at least version ${min_xcode_version} of Xcode, "
- "you're building against version ${xcode_version}. Please upgrade."
- ${extra_message}
- )
+ if(NOT QT_NO_XCODE_MIN_VERSION_CHECK)
+ _qt_internal_get_cached_xcode_version(xcode_version)
+ if(xcode_version VERSION_LESS min_xcode_version)
+ message(${message_type}
+ "Qt requires at least version ${min_xcode_version} of Xcode, "
+ "you're building against version ${xcode_version}. Please upgrade."
+ ${extra_message}
+ )
+ endif()
endif()
if(QT_NO_APPLE_SDK_MAX_VERSION_CHECK)
diff --git a/configure.cmake b/configure.cmake
index e89922f76f8..0d4e5b04688 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -621,7 +621,7 @@ qt_feature("private_tests" PRIVATE
)
qt_feature("doc_snippets" PRIVATE
LABEL "Developer build: doc_snippets"
- AUTODETECT QT_FEATURE_developer_build
+ AUTODETECT QT_BUILD_DOC_SNIPPETS
CONDITION QT_FEATURE_shared
)
qt_feature_definition("developer-build" "QT_BUILD_INTERNAL")
diff --git a/mkspecs/common/msvc-based-version.conf b/mkspecs/common/msvc-based-version.conf
index adc893836a9..a687fa5f449 100644
--- a/mkspecs/common/msvc-based-version.conf
+++ b/mkspecs/common/msvc-based-version.conf
@@ -42,4 +42,10 @@ greaterThan(QMAKE_MSC_VER, 1929) {
MSVC_TOOLSET_VER = 143
}
+greaterThan(QMAKE_MSC_VER, 1949) {
+ # Visual Studio 2026 (18.0) / Visual C++ 19.50 and up
+ MSVC_VER = 18.0
+ MSVC_TOOLSET_VER = 145
+}
+
!isEmpty(COMPAT_MKSPEC):!$$COMPAT_MKSPEC: CONFIG += $$COMPAT_MKSPEC
diff --git a/mkspecs/common/msvc-version.conf b/mkspecs/common/msvc-version.conf
index 0130542ddb9..8270f02e890 100644
--- a/mkspecs/common/msvc-version.conf
+++ b/mkspecs/common/msvc-version.conf
@@ -147,4 +147,10 @@ greaterThan(QMAKE_MSC_VER, 1929) {
MSVC_TOOLSET_VER = 143
}
+greaterThan(QMAKE_MSC_VER, 1949) {
+ # Visual Studio 2026 (18.0) / Visual C++ 19.50 and up
+ MSVC_VER = 18.0
+ MSVC_TOOLSET_VER = 145
+}
+
!isEmpty(COMPAT_MKSPEC):!$$COMPAT_MKSPEC: CONFIG += $$COMPAT_MKSPEC
diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp
index 6517e5c4516..0776a4a5267 100644
--- a/qmake/generators/win32/msvc_objectmodel.cpp
+++ b/qmake/generators/win32/msvc_objectmodel.cpp
@@ -25,6 +25,8 @@ DotNET vsVersionFromString(const ProString &versionString)
int versionMajor = versionView.left(idx).toInt();
int versionMinor = versionView.mid(idx + 1).toInt();
+ if (versionMajor == 18)
+ return NET2026;
if (versionMajor == 17)
return NET2022;
if (versionMajor == 16)
diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h
index 190d6c727fa..58f818a3bc5 100644
--- a/qmake/generators/win32/msvc_objectmodel.h
+++ b/qmake/generators/win32/msvc_objectmodel.h
@@ -29,7 +29,8 @@ enum DotNET {
NET2015 = 0xd0,
NET2017 = 0xe0,
NET2019,
- NET2022
+ NET2022,
+ NET2026
};
DotNET vsVersionFromString(const ProString &versionString);
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index 1566f72ba66..7c2e0562aa7 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -56,6 +56,8 @@ const char _slnHeader142[] = "Microsoft Visual Studio Solution File, Format
"\n# Visual Studio Version 16";
const char _slnHeader143[] = "Microsoft Visual Studio Solution File, Format Version 12.00"
"\n# Visual Studio Version 17";
+const char _slnHeader145[] = "Microsoft Visual Studio Solution File, Format Version 12.00"
+ "\n# Visual Studio Version 18";
// The following UUID _may_ change for later servicepacks...
// If so we need to search through the registry at
// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0\Projects
@@ -502,6 +504,9 @@ void VcprojGenerator::writeSubDirs(QTextStream &t)
}
switch (vcProject.Configuration.CompilerVersion) {
+ case NET2026:
+ t << _slnHeader145;
+ break;
case NET2022:
t << _slnHeader143;
break;
@@ -882,6 +887,9 @@ void VcprojGenerator::initProject()
// Own elements -----------------------------
vcProject.Name = project->first("QMAKE_ORIG_TARGET").toQString();
switch (vcProject.Configuration.CompilerVersion) {
+ case NET2026:
+ vcProject.Version = "18.00";
+ break;
case NET2022:
vcProject.Version = "17.00";
break;
diff --git a/src/3rdparty/libjpeg/COPYRIGHT.txt b/src/3rdparty/libjpeg/COPYRIGHT.txt
index f5eae868466..ce9d95bfebc 100644
--- a/src/3rdparty/libjpeg/COPYRIGHT.txt
+++ b/src/3rdparty/libjpeg/COPYRIGHT.txt
@@ -1,4 +1,4 @@
-Copyright (C) 2009-2025 D. R. Commander
+Copyright (C) 2009-2024 D. R. Commander
Copyright (C) 2015, 2020 Google, Inc.
Copyright (C) 2019-2020 Arm Limited
Copyright (C) 2015-2016, 2018 Matthieu Darbois
diff --git a/src/3rdparty/libjpeg/ChangeLog.md b/src/3rdparty/libjpeg/ChangeLog.md
index 4bdbf53dd34..17390d80bd0 100644
--- a/src/3rdparty/libjpeg/ChangeLog.md
+++ b/src/3rdparty/libjpeg/ChangeLog.md
@@ -1,3 +1,34 @@
+3.1.3
+=====
+
+### Significant changes relative to 3.1.2:
+
+1. Hardened the TurboJPEG API against hypothetical applications that may
+erroneously call `tj*Compress*()` or `tj*Transform()` with a reused JPEG
+destination buffer pointer while specifying a destination buffer size of 0.
+
+2. Hardened the TurboJPEG API against hypothetical applications that may
+erroneously set `TJPARAM_LOSSLESS` or `TJPARAM_COLORSPACE` prior to calling
+`tj3EncodeYUV*8()` or `tj3CompressFromYUV*8()`. `tj3EncodeYUV*8()` and
+`tj3CompressFromYUV*8()` now ignore `TJPARAM_LOSSLESS` and
+`TJPARAM_COLORSPACE`.
+
+3. Hardened the TurboJPEG Java API against hypothetical applications that may
+erroneously pass huge X or Y offsets to one of the compression, YUV encoding,
+decompression, or YUV decoding methods, leading to signed integer overflow in
+the JNI wrapper's buffer size checks that rendered those checks ineffective.
+
+4. Fixed an issue in the TurboJPEG Java API whereby
+`TJCompressor.getSourceBuf()` sometimes returned the buffer from a previous
+invocation of `TJCompressor.loadSourceImage()` if the target data precision was
+changed before the most recent invocation.
+
+5. Fixed an issue in the PPM reader that caused incorrect pixels to be
+generated when using `tj3LoadImage*()` or `TJCompressor.loadSourceImage()` to
+load a PBMPLUS (PPM/PGM) file into a CMYK buffer with a different data
+precision than that of the file.
+
+
3.1.2
=====
@@ -962,9 +993,9 @@ storage.
64-bit libjpeg-turbo SDK for Visual C++ were installed on the same system, only
one of them could be uninstalled.
-2. Fixed a signed integer overflow and subsequent segfault that occurred when
-attempting to decompress images with more than 715827882 pixels using the
-64-bit C version of TJBench.
+2. Fixed a signed integer overflow and subsequent segfault (CVE-2019-2201) that
+occurred when attempting to decompress images with more than 715827882 pixels
+using the 64-bit C version of TJBench.
3. Fixed out-of-bounds write in `tjDecompressToYUV2()` and
`tjDecompressToYUVPlanes()` (sometimes manifesting as a double free) that
@@ -1016,9 +1047,9 @@ regardless of whether a 4:2:2 JPEG image is rotated or transposed prior to
decompression (in the frequency domain) or after decompression (in the spatial
domain), the final image will be similar.
-4. Fixed an integer overflow and subsequent segfault that occurred when
-attempting to compress or decompress images with more than 1 billion pixels
-using the TurboJPEG API.
+4. Fixed an integer overflow and subsequent segfault (CVE-2019-2201) that
+occurred when attempting to compress or decompress images with more than 1
+billion pixels using the TurboJPEG API.
5. Fixed a regression introduced by 2.0 beta1[15] whereby attempting to
generate a progressive JPEG image on an SSE2-capable CPU using a scan script
diff --git a/src/3rdparty/libjpeg/qt_attribution.json b/src/3rdparty/libjpeg/qt_attribution.json
index fe38aec1f68..5ac811a12b4 100644
--- a/src/3rdparty/libjpeg/qt_attribution.json
+++ b/src/3rdparty/libjpeg/qt_attribution.json
@@ -7,8 +7,8 @@
"Description": "The Independent JPEG Group's JPEG software",
"Homepage": "http://libjpeg-turbo.virtualgl.org/",
- "Version": "3.1.2",
- "DownloadLocation": "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/3.1.2/libjpeg-turbo-3.1.2.tar.gz",
+ "Version": "3.1.3",
+ "DownloadLocation": "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/3.1.3/libjpeg-turbo-3.1.3.tar.gz",
"PURL": "pkg:github/libjpeg-turbo/libjpeg-turbo@$<VERSION>",
"CPE": "cpe:2.3:a:libjpeg-turbo:libjpeg-turbo:$<VERSION>:*:*:*:*:*:*:*",
diff --git a/src/3rdparty/libjpeg/src/jconfig.h b/src/3rdparty/libjpeg/src/jconfig.h
index e81574b9a48..85a1509fb68 100644
--- a/src/3rdparty/libjpeg/src/jconfig.h
+++ b/src/3rdparty/libjpeg/src/jconfig.h
@@ -2,9 +2,9 @@
#define JPEG_LIB_VERSION 80
-#define LIBJPEG_TURBO_VERSION 3.0.3
+#define LIBJPEG_TURBO_VERSION 3.1.3
-#define LIBJPEG_TURBO_VERSION_NUMBER 3000003
+#define LIBJPEG_TURBO_VERSION_NUMBER 3001003
#define C_ARITH_CODING_SUPPORTED 1
diff --git a/src/3rdparty/libjpeg/src/jconfigint.h b/src/3rdparty/libjpeg/src/jconfigint.h
index 6e7dbd75a1e..6d5f9633928 100644
--- a/src/3rdparty/libjpeg/src/jconfigint.h
+++ b/src/3rdparty/libjpeg/src/jconfigint.h
@@ -10,7 +10,7 @@
#define PACKAGE_NAME "libjpeg-turbo"
-#define VERSION "3.0.3"
+#define VERSION "3.1.3"
#if SIZE_MAX == 0xffffffff
#define SIZEOF_SIZE_T 4
diff --git a/src/corelib/doc/src/cmake/cmake-configure-variables.qdoc b/src/corelib/doc/src/cmake/cmake-configure-variables.qdoc
index b8e5e038a33..7cd3f91b901 100644
--- a/src/corelib/doc/src/cmake/cmake-configure-variables.qdoc
+++ b/src/corelib/doc/src/cmake/cmake-configure-variables.qdoc
@@ -525,7 +525,6 @@ To prevent this, set \c QT_NO_SET_XCODE_BUNDLE_IDENTIFIER to \c TRUE.
\summary {Enables verbose mode of deployment tools.}
\cmakevariablesince 6.3
-\preliminarycmakevariable
Enables verbose mode of the \l androiddeployqt deployment tool when it is called
internally at build time, usually during target finalization.
@@ -545,7 +544,6 @@ must be set before the first \c{find_package(Qt6)} call to have that effect.
\summary {Name of the file to include for setting up deployment support.}
\cmakevariablesince 6.3
-\preliminarycmakevariable
\note The value of this variable should never be modified by project code.
This configure-phase variable is set by the Core package. It is intended to be
diff --git a/src/corelib/doc/src/cmake/cmake-properties.qdoc b/src/corelib/doc/src/cmake/cmake-properties.qdoc
index 821862494a2..c7b1a27a4b4 100644
--- a/src/corelib/doc/src/cmake/cmake-properties.qdoc
+++ b/src/corelib/doc/src/cmake/cmake-properties.qdoc
@@ -665,7 +665,6 @@ UTF-8 input). Use the \l QT_NO_CAST_FROM_ASCII and
\summary {Specifies the default Qt resource prefix.}
\cmakepropertysince 6.0
-\preliminarycmakeproperty
When using \l{qt6_add_resources}{qt_add_resources} without a \c PREFIX
argument, then the value of this target property will be used as
@@ -773,7 +772,6 @@ CMake properties:
\brief Sets the FOLDER property for Qt-internal targets.
\cmakepropertysince 6.5
-\preliminarycmakeproperty
Name of the \l FOLDER for internal targets that are added by Qt's CMake
commands.
diff --git a/src/corelib/doc/src/cmake/qt_deploy_translations.qdoc b/src/corelib/doc/src/cmake/qt_deploy_translations.qdoc
index 43ff23a35a1..e6d3edbbdc4 100644
--- a/src/corelib/doc/src/cmake/qt_deploy_translations.qdoc
+++ b/src/corelib/doc/src/cmake/qt_deploy_translations.qdoc
@@ -17,7 +17,6 @@ can only be called from a deployment script. It cannot be called directly by the
project during the configure stage.
\cmakecommandsince 6.5
-\preliminarycmakecommand
\note This command does not usually need to be called directly. It is used
internally by other higher level commands, but projects wishing to
implement more customized deployment logic may find it useful.
diff --git a/src/corelib/doc/src/cmake/qt_extract_metatypes.qdoc b/src/corelib/doc/src/cmake/qt_extract_metatypes.qdoc
index 7ec8d90f9b1..24112b1cf87 100644
--- a/src/corelib/doc/src/cmake/qt_extract_metatypes.qdoc
+++ b/src/corelib/doc/src/cmake/qt_extract_metatypes.qdoc
@@ -11,7 +11,6 @@
\summary {Extracts metatypes from a Qt target and generates an associated metatypes.json file.}
\cmakecommandsince 6.0
-\preliminarycmakecommand
\section1 Synopsis
diff --git a/src/corelib/doc/src/cmake/qt_finalize_project.qdoc b/src/corelib/doc/src/cmake/qt_finalize_project.qdoc
index 5506712691e..f60b850fcdb 100644
--- a/src/corelib/doc/src/cmake/qt_finalize_project.qdoc
+++ b/src/corelib/doc/src/cmake/qt_finalize_project.qdoc
@@ -9,7 +9,6 @@
\keyword qt6_finalize_project
\summary {Handles various common platform-specific tasks associated with a Qt project.}
-\preliminarycmakecommand
\include cmake-find-package-core.qdocinc
diff --git a/src/corelib/kernel/qmetacontainer.h b/src/corelib/kernel/qmetacontainer.h
index c9d3a6bf9c6..66047afefd4 100644
--- a/src/corelib/kernel/qmetacontainer.h
+++ b/src/corelib/kernel/qmetacontainer.h
@@ -971,18 +971,11 @@ public:
Iterator mutableEnd();
QVariant at(qsizetype idx) const;
- void set(qsizetype idx, const QVariant &value);
+ void setAt(qsizetype idx, const QVariant &value);
void append(const QVariant &value);
void prepend(const QVariant &value);
void removeLast();
void removeFirst();
-
-#if QT_DEPRECATED_SINCE(6, 11)
- enum Position: quint8 { Unspecified, AtBegin, AtEnd };
- void addValue(const QVariant &value, Position position = Unspecified);
- void removeValue(Position position = Unspecified);
- QMetaType valueMetaType() const;
-#endif // QT_DEPRECATED_SINCE(6, 11)
};
#else
using Iterable = QtMetaContainerPrivate::Sequence;
diff --git a/src/corelib/kernel/qmetasequence.cpp b/src/corelib/kernel/qmetasequence.cpp
index 2a3a923d5ca..018dd610146 100644
--- a/src/corelib/kernel/qmetasequence.cpp
+++ b/src/corelib/kernel/qmetasequence.cpp
@@ -531,39 +531,6 @@ void QMetaSequence::valueAtConstIterator(const void *iterator, void *result) con
*/
/*!
- \enum QMetaSequence::Iterable::Position
- \deprecated [6.11] Use append(), prepend(), removeFirst(), or removeLast()
-
- Specifies the position at which an element shall be added to or removed from
- the iterable.
-
- \value AtBegin
- Add or remove at the beginning of the iterable.
- \value AtEnd
- Add or remove at the end of the iterable.
- \value Unspecified
- Add or remove at an unspecified position in the iterable.
- */
-
-/*!
- \fn void QMetaSequence::Iterable::addValue(const QVariant &value, Position position)
- \deprecated [6.11] Use append() or prepend()
- Adds \a value to the container, at \a position, if possible.
- */
-
-/*!
- \deprecated [6.11] Use removeFirst() or removeLast()
- \fn void QMetaSequence::Iterable::removeValue(Position position)
- Removes a value from the container, at \a position, if possible.
- */
-
-/*!
- \deprecated [6.11] Use QMetaSequence::valueMetaType()
- \fn QMetaType QMetaSequence::Iterable::valueMetaType() const
- Returns the meta type for values stored in the underlying container.
- */
-
-/*!
\fn QVariant QMetaSequence::Iterable::at(qsizetype idx) const
Returns the value at position \a idx in the container.
@@ -574,13 +541,8 @@ void QMetaSequence::valueAtConstIterator(const void *iterator, void *result) con
*/
/*!
- \fn void QMetaSequence::Iterable::set(qsizetype idx, const QVariant &value)
+ \fn void QMetaSequence::Iterable::setAt(qsizetype idx, const QVariant &value)
Sets the element at position \a idx in the container to \a value.
-
- \note If the underlying container does not provide a native way to assign
- an element at an index, this method will synthesize the assignment
- using iterators. This behavior is deprecated and will be removed in a
- future version of Qt.
*/
/*!
diff --git a/src/corelib/kernel/qmetasequence.h b/src/corelib/kernel/qmetasequence.h
index 26156e7924f..f8052476d79 100644
--- a/src/corelib/kernel/qmetasequence.h
+++ b/src/corelib/kernel/qmetasequence.h
@@ -196,25 +196,11 @@ public:
});
}
- void set(qsizetype idx, const QVariant &value)
+ void setAt(qsizetype idx, const QVariant &value)
{
const QMetaSequence meta = metaContainer();
QtPrivate::QVariantTypeCoercer coercer;
- const void *dataPtr = coercer.coerce(value, meta.valueMetaType());
- if (meta.canSetValueAtIndex()) {
- meta.setValueAtIndex(mutableIterable(), idx, dataPtr);
- return;
- }
-
-#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
- // We shouldn't second-guess the underlying container
- QtPrivate::warnSynthesizedAccess(
- "set() called on an iterable without native indexed accessors. This is slow");
- void *it = meta.begin(m_iterable.mutablePointer());
- meta.advanceIterator(it, idx);
- meta.setValueAtIterator(it, dataPtr);
- meta.destroyIterator(it);
-#endif
+ meta.setValueAtIndex(mutableIterable(), idx, coercer.coerce(value, meta.valueMetaType()));
}
void append(const QVariant &value)
@@ -261,6 +247,9 @@ public:
QMetaType valueMetaType() const
Q_DECL_EQ_DELETE_X("Use QMetaSequence::valueMetaType() instead.");
+ void set(qsizetype idx, const QVariant &value)
+ Q_DECL_EQ_DELETE_X("Use setAt() instead.");
+
QT_WARNING_POP
#endif // QT_DEPRECATED_SINCE(6, 11)
};
diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp
index e9b90d787bc..98e51397c17 100644
--- a/src/plugins/styles/modernwindows/qwindows11style.cpp
+++ b/src/plugins/styles/modernwindows/qwindows11style.cpp
@@ -2622,6 +2622,7 @@ void QWindows11Style::polish(QPalette& result)
d->m_titleBarNormalIcon = QIcon();
d->m_toolbarExtensionButton = QIcon();
d->m_lineEditClearButton = QIcon();
+ d->m_tabCloseButton = QIcon();
}
QPixmap QWindows11Style::standardPixmap(StandardPixmap standardPixmap,
@@ -2662,6 +2663,14 @@ QIcon QWindows11Style::standardIcon(StandardPixmap standardIcon,
}
return d->m_toolbarExtensionButton;
}
+ case SP_TabCloseButton: {
+ if (d->m_tabCloseButton.isNull()) {
+ auto e = new WinFontIconEngine(fluentIcon(Icon::ChromeClose), d->assetFont);
+ e->setScale(0.6);
+ d->m_tabCloseButton = QIcon(e);
+ }
+ return d->m_tabCloseButton;
+ }
default:
break;
}
diff --git a/src/plugins/styles/modernwindows/qwindows11style_p.h b/src/plugins/styles/modernwindows/qwindows11style_p.h
index 9d0cdda3e33..43a344a6ac9 100644
--- a/src/plugins/styles/modernwindows/qwindows11style_p.h
+++ b/src/plugins/styles/modernwindows/qwindows11style_p.h
@@ -125,6 +125,7 @@ class QWindows11StylePrivate : public QWindowsVistaStylePrivate {
protected:
QIcon m_toolbarExtensionButton;
QIcon m_lineEditClearButton;
+ QIcon m_tabCloseButton;
};
QT_END_NAMESPACE
diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp
index 29cafe9aea4..f3db4ece49e 100644
--- a/src/testlib/qtestlog.cpp
+++ b/src/testlib/qtestlog.cpp
@@ -305,9 +305,7 @@ namespace QTest {
{
static QBasicAtomicInt counter = Q_BASIC_ATOMIC_INITIALIZER(QTest::maxWarnings);
- auto loggerCapture = loggers->allLoggers();
-
- if (loggerCapture.isEmpty()) {
+ if (loggers.isDestroyed() || loggers->allLoggers().isEmpty()) {
// the message handler may be called from a worker thread, after the main thread stopped
// logging. Forwarding to original message handler to avoid swallowing the message
Q_ASSERT(oldMessageHandler);
@@ -326,6 +324,8 @@ namespace QTest {
return;
}
+ auto loggerCapture = loggers->allLoggers();
+
if (type != QtFatalMsg) {
if (counter.loadRelaxed() <= 0)
return;
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index 0f0abb6e1d5..44218d41ded 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -52,6 +52,14 @@ public:
void enterEvent(QEnterEvent *event) override;
void leaveEvent(QEvent *event) override;
void paintEvent(QPaintEvent *event) override;
+
+ void setParentClipRect(const QRect &clipRect)
+ {
+ m_parentClipRect = clipRect;
+ }
+
+protected:
+ QRect m_parentClipRect;
};
}
@@ -598,10 +606,11 @@ QRect QTabBarPrivate::normalizedScrollRect(int index)
q->initStyleOption(&opt, currentIndex);
opt.rect = q->rect();
- QRect scrollButtonLeftRect = q->style()->subElementRect(QStyle::SE_TabBarScrollLeftButton, &opt, q);
- QRect scrollButtonRightRect = q->style()->subElementRect(QStyle::SE_TabBarScrollRightButton, &opt, q);
- QRect tearLeftRect = q->style()->subElementRect(QStyle::SE_TabBarTearIndicatorLeft, &opt, q);
- QRect tearRightRect = q->style()->subElementRect(QStyle::SE_TabBarTearIndicatorRight, &opt, q);
+ const auto style = q->style();
+ QRect scrollButtonLeftRect = style->subElementRect(QStyle::SE_TabBarScrollLeftButton, &opt, q);
+ QRect scrollButtonRightRect = style->subElementRect(QStyle::SE_TabBarScrollRightButton, &opt, q);
+ QRect tearLeftRect = style->subElementRect(QStyle::SE_TabBarTearIndicatorLeft, &opt, q);
+ QRect tearRightRect = style->subElementRect(QStyle::SE_TabBarTearIndicatorRight, &opt, q);
if (verticalTabs(shape)) {
int topEdge, bottomEdge;
@@ -739,7 +748,7 @@ void QTabBarPrivate::layoutTab(int index)
if (tab->leftWidget) {
QRect rect = q->style()->subElementRect(QStyle::SE_TabBarTabLeftButton, &opt, q);
QPoint p = rect.topLeft();
- if ((index == pressedIndex) || paintWithOffsets) {
+ if (index == pressedIndex) {
if (vertical)
p.setY(p.y() + tab->dragOffset);
else
@@ -750,7 +759,7 @@ void QTabBarPrivate::layoutTab(int index)
if (tab->rightWidget) {
QRect rect = q->style()->subElementRect(QStyle::SE_TabBarTabRightButton, &opt, q);
QPoint p = rect.topLeft();
- if ((index == pressedIndex) || paintWithOffsets) {
+ if (index == pressedIndex) {
if (vertical)
p.setY(p.y() + tab->dragOffset);
else
@@ -1004,8 +1013,13 @@ int QTabBar::insertTab(int index, const QIcon& icon, const QString &text)
}
if (isVisible() && tabAt(d->mousePosition) == index) {
- d->hoverIndex = index;
- d->hoverRect = tabRect(index);
+ if (d->normalizedScrollRect(index).contains(d->mousePosition)) {
+ d->hoverIndex = index;
+ d->hoverRect = tabRect(index);
+ } else {
+ d->hoverIndex = -1;
+ d->hoverRect = QRect();
+ }
}
tabInserted(index);
@@ -1096,11 +1110,13 @@ void QTabBar::removeTab(int index)
if (d->hoverRect.isValid()) {
update(d->hoverRect);
d->hoverIndex = tabAt(d->mousePosition);
- if (d->validIndex(d->hoverIndex)) {
+ if (d->validIndex(d->hoverIndex)
+ && d->normalizedScrollRect(d->hoverIndex).contains(d->mousePosition)) {
d->hoverRect = tabRect(d->hoverIndex);
update(d->hoverRect);
} else {
d->hoverRect = QRect();
+ d->hoverIndex = -1;
}
}
tabRemoved(index);
@@ -1692,15 +1708,18 @@ bool QTabBar::event(QEvent *event)
case QEvent::HoverEnter: {
QHoverEvent *he = static_cast<QHoverEvent *>(event);
d->mousePosition = he->position().toPoint();
- if (!d->hoverRect.contains(d->mousePosition)) {
+ const auto sr = d->normalizedScrollRect();
+ const auto oldHoverRect = d->hoverRect & sr;
+ if (!oldHoverRect.contains(d->mousePosition)) {
if (d->hoverRect.isValid())
update(d->hoverRect);
d->hoverIndex = tabAt(d->mousePosition);
- if (d->validIndex(d->hoverIndex)) {
+ if (d->validIndex(d->hoverIndex) && sr.contains(d->mousePosition)) {
d->hoverRect = tabRect(d->hoverIndex);
update(d->hoverRect);
} else {
d->hoverRect = QRect();
+ d->hoverIndex = -1;
}
}
return true;
@@ -1845,10 +1864,14 @@ void QTabBar::paintEvent(QPaintEvent *)
QStyleOption opt;
opt.initFrom(this);
QRegion buttonRegion;
- if (d->leftB->isVisible())
- buttonRegion |= style()->subElementRect(QStyle::SE_TabBarScrollLeftButton, &opt, this);
- if (d->rightB->isVisible())
- buttonRegion |= style()->subElementRect(QStyle::SE_TabBarScrollRightButton, &opt, this);
+ if (d->leftB->isVisible()) {
+ const auto r = style()->subElementRect(QStyle::SE_TabBarScrollLeftButton, &opt, this);
+ buttonRegion |= r;
+ }
+ if (d->rightB->isVisible()) {
+ const auto r = style()->subElementRect(QStyle::SE_TabBarScrollRightButton, &opt, this);
+ buttonRegion |= r;
+ }
if (!buttonRegion.isEmpty())
p.setClipRegion(QRegion(rect()) - buttonRegion);
}
@@ -1857,9 +1880,13 @@ void QTabBar::paintEvent(QPaintEvent *)
const auto tab = d->tabList.at(i);
if (!tab->visible)
continue;
+ for (const auto side : { QTabBar::LeftSide, QTabBar::RightSide }) {
+ if (auto closeButton = qobject_cast<CloseButton *>(tabButton(i, side)))
+ closeButton->setParentClipRect(scrollRect);
+ }
QStyleOptionTab tabOption;
initStyleOption(&tabOption, i);
- if (d->paintWithOffsets && tab->dragOffset != 0) {
+ if (tab->dragOffset != 0) {
if (vertical) {
tabOption.rect.moveTop(tabOption.rect.y() + tab->dragOffset);
} else {
@@ -1901,7 +1928,7 @@ void QTabBar::paintEvent(QPaintEvent *)
const auto tab = d->tabList.at(selected);
initStyleOption(&tabOption, selected);
- if (d->paintWithOffsets && tab->dragOffset != 0) {
+ if (tab->dragOffset != 0) {
// if the drag offset is != 0, a move is in progress (drag or animation)
// => set the tab position to Moving to preserve the rect
tabOption.position = QStyleOptionTab::TabPosition::Moving;
@@ -2934,6 +2961,11 @@ void CloseButton::paintEvent(QPaintEvent *)
opt.state |= QStyle::State_Selected;
}
+ if (m_parentClipRect.isValid()) {
+ auto tl = mapFromParent(m_parentClipRect.topLeft());
+ auto br = mapFromParent(m_parentClipRect.bottomRight());
+ p.setClipRect(QRect(tl, br));
+ }
style()->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, &p, this);
}
diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h
index 38fbde76470..5b31926253f 100644
--- a/src/widgets/widgets/qtabbar_p.h
+++ b/src/widgets/widgets/qtabbar_p.h
@@ -56,7 +56,7 @@ public:
QTabBarPrivate()
: layoutDirty(false), drawBase(true), elideModeSetByUser(false), useScrollButtons(false),
useScrollButtonsSetByUser(false), expanding(true), closeButtonOnTabs(false),
- paintWithOffsets(true), movable(false), dragInProgress(false), documentMode(false),
+ movable(false), dragInProgress(false), documentMode(false),
autoHide(false), changeCurrentOnDrag(false)
{}
~QTabBarPrivate()
@@ -95,7 +95,6 @@ public:
bool useScrollButtonsSetByUser : 1;
bool expanding : 1;
bool closeButtonOnTabs : 1;
- bool paintWithOffsets : 1;
bool movable : 1;
bool dragInProgress : 1;
bool documentMode : 1;
diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST
index 9651c1480c8..12da5b423ab 100644
--- a/tests/auto/widgets/kernel/qwidget/BLACKLIST
+++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST
@@ -4,11 +4,6 @@ osx
macos arm
[render_systemClip]
osx
-[multipleToplevelFocusCheck]
-centos
-opensuse-leap
-ubuntu
-sles-15
# QTBUG-87668
[showMinimizedKeepsFocus]
android
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index e3d172c60c0..359a0946474 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -6931,9 +6931,13 @@ class TopLevelFocusCheck: public QWidget
Q_OBJECT
public:
QLineEdit* edit;
- explicit TopLevelFocusCheck(QWidget *parent = nullptr)
+ explicit TopLevelFocusCheck(const QString &name, QWidget *parent = nullptr)
: QWidget(parent), edit(new QLineEdit(this))
{
+ const QString title = QLatin1String(QTest::currentTestFunction()) + "_"_L1 + name;
+ setWindowTitle(title);
+ setObjectName(title);
+ edit->setObjectName(QString("%1_edit"_L1).arg(title));
edit->hide();
edit->installEventFilter(this);
}
@@ -6943,7 +6947,7 @@ public slots:
{
edit->show();
edit->setFocus(Qt::OtherFocusReason);
- QCoreApplication::processEvents();
+ QVERIFY(QTest::qWaitForWindowFocused(edit));
}
bool eventFilter(QObject *obj, QEvent *event) override
{
@@ -6963,49 +6967,42 @@ void tst_QWidget::multipleToplevelFocusCheck()
if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))
QSKIP("Window activation is not supported");
- TopLevelFocusCheck w1;
- TopLevelFocusCheck w2;
+ TopLevelFocusCheck w1("Widget-1"_L1);
+ TopLevelFocusCheck w2("Widget-2"_L1);
- const QString title = QLatin1String(QTest::currentTestFunction());
- w1.setWindowTitle(title + QLatin1String("_W1"));
w1.move(m_availableTopLeft + QPoint(20, 20));
w1.resize(200, 200);
w1.show();
QVERIFY(QTest::qWaitForWindowExposed(&w1));
- w2.setWindowTitle(title + QLatin1String("_W2"));
w2.move(w1.frameGeometry().topRight() + QPoint(20, 0));
w2.resize(200,200);
w2.show();
QVERIFY(QTest::qWaitForWindowExposed(&w2));
w1.activateWindow();
- QApplicationPrivate::setActiveWindow(&w1);
QVERIFY(QTest::qWaitForWindowActive(&w1));
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w1));
+ QTRY_COMPARE(QApplication::activeWindow(), &w1);
QTest::mouseDClick(&w1, Qt::LeftButton);
- QTRY_COMPARE(QApplication::focusWidget(), static_cast<QWidget *>(w1.edit));
+ QTRY_COMPARE(QApplication::focusWidget(), w1.edit);
w2.activateWindow();
- QApplicationPrivate::setActiveWindow(&w2);
QVERIFY(QTest::qWaitForWindowActive(&w2));
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w2));
+ QTRY_COMPARE(QApplication::activeWindow(), &w2);
QTest::mouseClick(&w2, Qt::LeftButton);
QTRY_COMPARE(QApplication::focusWidget(), nullptr);
QTest::mouseDClick(&w2, Qt::LeftButton);
- QTRY_COMPARE(QApplication::focusWidget(), static_cast<QWidget *>(w2.edit));
+ QTRY_COMPARE(QApplication::focusWidget(), w2.edit);
w1.activateWindow();
- QApplicationPrivate::setActiveWindow(&w1);
QVERIFY(QTest::qWaitForWindowActive(&w1));
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w1));
+ QTRY_COMPARE(QApplication::activeWindow(), &w1);
QTest::mouseDClick(&w1, Qt::LeftButton);
- QTRY_COMPARE(QApplication::focusWidget(), static_cast<QWidget *>(w1.edit));
+ QTRY_COMPARE(QApplication::focusWidget(), w1.edit);
w2.activateWindow();
- QApplicationPrivate::setActiveWindow(&w2);
QVERIFY(QTest::qWaitForWindowActive(&w2));
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w2));
+ QTRY_COMPARE(QApplication::activeWindow(), &w2);
QTest::mouseClick(&w2, Qt::LeftButton);
QTRY_COMPARE(QApplication::focusWidget(), nullptr);
}