summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/android/jar/build.gradle2
-rw-r--r--src/corelib/Qt6AndroidGradleHelpers.cmake2
-rw-r--r--src/corelib/doc/images/modelindex-no-parent.svg99
-rw-r--r--src/corelib/doc/src/cmake/cmake-properties.qdoc4
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.cpp2
-rw-r--r--src/network/android/jar/build.gradle2
-rw-r--r--src/plugins/networkinformation/android/jar/build.gradle2
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm17
-rw-r--r--src/tools/androiddeployqt/main.cpp2
-rw-r--r--src/tools/bootstrap/CMakeLists.txt2
-rw-r--r--src/tools/rcc/rcc.cpp93
-rw-r--r--src/widgets/kernel/qapplication.cpp13
-rw-r--r--src/widgets/styles/qfusionstyle_p_p.h3
13 files changed, 217 insertions, 26 deletions
diff --git a/src/android/jar/build.gradle b/src/android/jar/build.gradle
index 74ecff6b75f..54512f6f4b3 100644
--- a/src/android/jar/build.gradle
+++ b/src/android/jar/build.gradle
@@ -23,7 +23,7 @@ repositories {
}
android {
- compileSdk 35
+ compileSdk 36
namespace = "org.qtproject.qt.android"
defaultConfig {
diff --git a/src/corelib/Qt6AndroidGradleHelpers.cmake b/src/corelib/Qt6AndroidGradleHelpers.cmake
index f71bac4e08a..fc8e009b9da 100644
--- a/src/corelib/Qt6AndroidGradleHelpers.cmake
+++ b/src/corelib/Qt6AndroidGradleHelpers.cmake
@@ -193,7 +193,7 @@ function(_qt_internal_android_generate_target_build_gradle target)
QT_ANDROID_MIN_SDK_VERSION "28")
_qt_internal_android_get_gradle_property(target_sdk_version ${target}
- QT_ANDROID_TARGET_SDK_VERSION "34")
+ QT_ANDROID_TARGET_SDK_VERSION "36")
set(target_abis "$<TARGET_PROPERTY:${target},_qt_android_abis>")
set(target_abi_list "$<JOIN:${target_abis};${CMAKE_ANDROID_ARCH_ABI},'$<COMMA> '>")
diff --git a/src/corelib/doc/images/modelindex-no-parent.svg b/src/corelib/doc/images/modelindex-no-parent.svg
new file mode 100644
index 00000000000..4ce4b86b1f2
--- /dev/null
+++ b/src/corelib/doc/images/modelindex-no-parent.svg
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ width="300"
+ height="160"
+ version="1.1"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+
+<style>
+ svg .line-style { stroke: black; fill: none }
+ svg .fill-style { stroke: black; fill: #c0c0c0 }
+ svg .text-style { font: 12px arial; fill: black }
+ svg .italic-style { font: 12px arial; fill: black; font-style: italic }
+ svg .bold-style { font: 12px arial; fill: black; font-weight: bold }
+
+ svg.dark .line-style { stroke: #f2f2f2; fill: none }
+ svg.dark .fill-style { stroke: #f2f2f2; fill: #606060 }
+ svg.dark .text-style { font: 12px arial; fill: #f2f2f2 }
+ svg.dark .italic-style { font: 12px arial; fill: #f2f2f2; font-style: italic }
+ svg.dark .bold-style { font: 12px arial; fill: #f2f2f2; font-weight: bold }
+
+ [data-theme="dark"] svg .line-style { stroke: #f2f2f2; fill: none }
+ [data-theme="dark"] svg .fill-style { stroke: #f2f2f2; fill: #606060 }
+ [data-theme="dark"] svg .text-style { font: 12px arial; fill: #f2f2f2 }
+ [data-theme="dark"] svg .italic-style { font: 12px arial; fill: #f2f2f2; font-style: italic }
+ [data-theme="dark"] svg .bold-style { font: 12px arial; fill: #f2f2f2; font-weight: bold }
+
+ [data-theme="light"] svg .line-style { stroke: black; fill: none }
+ [data-theme="light"] svg .fill-style { stroke: black; fill: #c0c0c0 }
+ [data-theme="light"] svg .text-style { font: 12px arial; fill: black }
+ [data-theme="light"] svg .italic-style { font: 12px arial; fill: black; font-style: italic }
+ [data-theme="light"] svg .bold-style { font: 12px arial; fill: black; font-weight: bold }
+</style>
+
+<text x="25" y="49" font-family="arial" font-size="12px"
+ class="text-style">0</text>
+<text x="25" y="79" font-family="arial" font-size="12px"
+ class="text-style">1</text>
+<text x="25" y="109" font-family="arial" font-size="12px"
+ class="text-style">2</text>
+<g transform="translate(30,139)">
+<text x="0" y="0" font-family="arial" font-size="12px"
+ class="text-style" transform="rotate(270)">...</text>
+</g>
+
+<path d="m 40.5,30.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" />
+<path d="m 70.5,30.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" />
+<path d="m 100.5,30.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" />
+<path d="m 130.5,30.5 h 30 v 30" stroke="black" fill="none"
+ class="line-style" stroke-dasharray="3, 3" />
+<path d="m 40.5,60.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" />
+<path d="m 70.5,60.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" />
+<path d="m 100.5,60.5 h 30 v 30 h -30 z" stroke="black" fill="#c0c0c0"
+ class="fill-style" />
+<path d="m 130.5,60.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" stroke-dasharray="3, 3" />
+<path d="m 40.5,90.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" />
+<path d="m 70.5,90.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" />
+<path d="m 100.5,90.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" />
+<path d="m 70.5,120.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" stroke-dasharray="3, 3" />
+<path d="m 40.5,120.5 v 30 h 30" stroke="black" fill="none"
+ class="line-style" stroke-dasharray="3, 3" />
+<path d="m 100.5,150.5 h 30" stroke="black"
+ class="line-style" stroke-dasharray="3, 3" />
+<path d="m 130.5,120.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" stroke-dasharray="3, 3" />
+<path d="m 160.5,90.5 v 30" stroke="black"
+ class="line-style" stroke-dasharray="3, 3" />
+
+<text x="50" y="20" font-family="arial" font-size="12px"
+ class="text-style">0</text>
+<text x="80" y="20" font-family="arial" font-size="12px"
+ class="text-style">1</text>
+<text x="110" y="20" font-family="arial" font-size="12px"
+ class="text-style">2</text>
+<text x="140" y="20" font-family="arial" font-size="12px"
+ class="text-style">...</text>
+
+<text x="190" y="55" font-family="arial" font-size="12px" font-weight="bold"
+ class="bold-style">Model index</text>
+<rect x="185.5" y="60.5" width="77" height="37" stroke="black" fill="none"
+ class="line-style" />
+<text x="190" y="75" font-family="arial" font-size="12px"
+ class="text-style">row = 1</text>
+<text x="190" y="92" font-family="arial" font-size="12px"
+ class="text-style">column = 2</text>
+
+<path d="m 185.5,85.5 c -35,0 -35,-10 -70,-10" stroke="black" fill="none"
+ stroke-dasharray="2, 2" class="line-style" />
+</svg>
diff --git a/src/corelib/doc/src/cmake/cmake-properties.qdoc b/src/corelib/doc/src/cmake/cmake-properties.qdoc
index c7b1a27a4b4..310debf7edc 100644
--- a/src/corelib/doc/src/cmake/cmake-properties.qdoc
+++ b/src/corelib/doc/src/cmake/cmake-properties.qdoc
@@ -239,7 +239,7 @@ precedence over this CMake property.
\badcode
set_target_properties(${target} PROPERTIES
- QT_ANDROID_COMPILE_SDK_VERSION 35
+ QT_ANDROID_COMPILE_SDK_VERSION 36
)
\endcode
@@ -247,7 +247,7 @@ The following format also works:
\badcode
set_target_properties(${target} PROPERTIES
- QT_ANDROID_COMPILE_SDK_VERSION "android-35"
+ QT_ANDROID_COMPILE_SDK_VERSION "android-36"
)
\endcode
diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp
index 58a057009ff..8b0a05ee6ed 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.cpp
+++ b/src/corelib/itemmodels/qabstractitemmodel.cpp
@@ -1390,7 +1390,7 @@ void QAbstractItemModel::resetInternalData()
simple table of rows and columns. Each item has a unique index specified by
a QModelIndex.
- \image modelindex-no-parent.png {Screenshot showing a 3x3 grid with numbered
+ \image modelindex-no-parent.svg {Diagram showing a 3x3 grid with numbered
rows and columns that shows the cell at row 1, column 2 highlighted.}
Every item of data that can be accessed via a model has an associated model
diff --git a/src/network/android/jar/build.gradle b/src/network/android/jar/build.gradle
index f1f470b6635..580e15b92f6 100644
--- a/src/network/android/jar/build.gradle
+++ b/src/network/android/jar/build.gradle
@@ -23,7 +23,7 @@ repositories {
}
android {
- compileSdk 35
+ compileSdk 36
defaultConfig {
minSdkVersion 28
diff --git a/src/plugins/networkinformation/android/jar/build.gradle b/src/plugins/networkinformation/android/jar/build.gradle
index f1f470b6635..580e15b92f6 100644
--- a/src/plugins/networkinformation/android/jar/build.gradle
+++ b/src/plugins/networkinformation/android/jar/build.gradle
@@ -23,7 +23,7 @@ repositories {
}
android {
- compileSdk 35
+ compileSdk 36
defaultConfig {
minSdkVersion 28
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index a6d96df0fbb..b00e6375e1a 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -269,6 +269,23 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSViewMenuHelper);
qCDebug(lcQpaWindow) << "Done moving" << self << "to" << self.window;
}
+// QWindow::setParent() promises that the child window will be clipped
+// to its parent, which we rely on in e.g. Qt Widgets when a native window
+// is added to a scroll area. We try to be smart and only enable clipping
+// if we have potential child QWindows that rely on this behavior.
+// FIXME: Be even smarter, and only consider QWindow based subviews,
+// in a way that also includes foreign windows.
+
+- (void)didAddSubview:(NSView *)subview
+{
+ self.clipsToBounds = YES;
+}
+
+- (void)willRemoveSubview:(NSView *)subview
+{
+ self.clipsToBounds = self.subviews.count > 1;
+}
+
// ----------------------------------------------------------------------------
- (QWindow *)topLevelWindow
diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp
index 7f24df7eac2..c4e7101b372 100644
--- a/src/tools/androiddeployqt/main.cpp
+++ b/src/tools/androiddeployqt/main.cpp
@@ -173,7 +173,7 @@ struct Options
QString versionName;
QString versionCode;
QByteArray minSdkVersion{"28"};
- QByteArray targetSdkVersion{"35"};
+ QByteArray targetSdkVersion{"36"};
// lib c++ path
QString stdCppPath;
diff --git a/src/tools/bootstrap/CMakeLists.txt b/src/tools/bootstrap/CMakeLists.txt
index f9161fa6404..c12475d69af 100644
--- a/src/tools/bootstrap/CMakeLists.txt
+++ b/src/tools/bootstrap/CMakeLists.txt
@@ -221,6 +221,8 @@ qt_internal_apply_gc_binaries(Bootstrap PUBLIC)
set_target_properties(Bootstrap PROPERTIES AUTOMOC OFF AUTOUIC OFF AUTORCC OFF)
qt_internal_add_target_aliases(Bootstrap)
qt_internal_add_target_optimized_flags_for_debug_config_in_current_scope(Bootstrap)
+qt_internal_enable_optimized_tools_lto(Bootstrap)
+qt_internal_workaround_static_lib_gcc_lto_issue(Bootstrap)
qt_set_msvc_cplusplus_options(Bootstrap PUBLIC)
qt_set_common_target_properties(Bootstrap)
diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp
index 40bfa9c2863..6a6027d44f2 100644
--- a/src/tools/rcc/rcc.cpp
+++ b/src/tools/rcc/rcc.cpp
@@ -1,10 +1,12 @@
// Copyright (C) 2018 The Qt Company Ltd.
// Copyright (C) 2018 Intel Corporation.
+// Copyright (C) 2024 Christoph Cullmann <[email protected]>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "rcc.h"
#include <qbytearray.h>
+#include <qcryptographichash.h>
#include <qdatetime.h>
#include <qdebug.h>
#include <qdir.h>
@@ -90,8 +92,28 @@ public:
QString resourceName() const;
+ struct DeduplicationKey {
+ RCCResourceLibrary::CompressionAlgorithm compressAlgo;
+ int compressLevel;
+ int compressThreshold;
+ QByteArray hash;
+
+ bool operator==(const DeduplicationKey &other) const
+ {
+ return compressAlgo == other.compressAlgo &&
+ compressLevel == other.compressLevel &&
+ compressThreshold == other.compressThreshold &&
+ hash == other.hash;
+ }
+ };
+
+ typedef QMultiHash<DeduplicationKey, RCCFileInfo*> DeduplicationMultiHash;
+
public:
- qint64 writeDataBlob(RCCResourceLibrary &lib, qint64 offset, QString *errorMessage);
+ qint64 writeDataBlob(RCCResourceLibrary &lib,
+ qint64 offset,
+ DeduplicationMultiHash &dedupByContent,
+ QString *errorMessage);
qint64 writeDataName(RCCResourceLibrary &, qint64 offset);
void writeDataInfo(RCCResourceLibrary &lib);
@@ -114,6 +136,11 @@ public:
qint64 m_childOffset = 0;
};
+static size_t qHash(const RCCFileInfo::DeduplicationKey &key, size_t seed) noexcept
+{
+ return qHashMulti(seed, key.compressAlgo, key.compressLevel, key.compressThreshold, key.hash);
+}
+
RCCFileInfo::RCCFileInfo(const QString &name, const QFileInfo &fileInfo, QLocale::Language language,
QLocale::Territory territory, uint flags,
RCCResourceLibrary::CompressionAlgorithm compressAlgo, int compressLevel,
@@ -217,8 +244,10 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
}
}
-qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
- QString *errorMessage)
+qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib,
+ qint64 offset,
+ DeduplicationMultiHash &dedupByContent,
+ QString *errorMessage)
{
const bool text = lib.m_format == RCCResourceLibrary::C_Code;
const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
@@ -230,24 +259,58 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
m_dataOffset = offset;
QByteArray data;
+ // determine compession algorithm & level early as used in de-duplication keys
+ // this avoid corruption for the two pass variants (QTBUG-137546)
+#if QT_CONFIG(zstd)
+ if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Best && !m_noZstd) {
+ m_compressAlgo = RCCResourceLibrary::CompressionAlgorithm::Zstd;
+ m_compressLevel = 19; // not ZSTD_maxCLevel(), as 20+ are experimental
+ }
+#endif
+#ifndef QT_NO_COMPRESS
+ if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Best) {
+ m_compressAlgo = RCCResourceLibrary::CompressionAlgorithm::Zlib;
+ m_compressLevel = 9;
+ }
+#endif
+
if (!m_isEmpty) {
- //find the data to be written
- QFile file(m_fileInfo.absoluteFilePath());
+ // find the data to be written
+ const QString absoluteFilePath = m_fileInfo.absoluteFilePath();
+ QFile file(absoluteFilePath);
if (!file.open(QFile::ReadOnly)) {
- *errorMessage = msgOpenReadFailed(m_fileInfo.absoluteFilePath(), file.errorString());
+ *errorMessage = msgOpenReadFailed(absoluteFilePath, file.errorString());
return 0;
}
-
data = file.readAll();
+
+ // de-duplicate the same file content, we can re-use already written data
+ // we only do that if we have the same compression settings
+ const QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Sha256);
+ const DeduplicationKey key{m_compressAlgo, m_compressLevel, m_compressThreshold, hash};
+ const QList<RCCFileInfo *> potentialCandidates = dedupByContent.values(key);
+ for (const RCCFileInfo *candidate : potentialCandidates) {
+ // check real content, we can have collisions
+ QFile candidateFile(candidate->m_fileInfo.absoluteFilePath());
+ if (!candidateFile.open(QFile::ReadOnly)) {
+ *errorMessage = msgOpenReadFailed(candidate->m_fileInfo.absoluteFilePath(),
+ candidateFile.errorString());
+ return 0;
+ }
+ if (data != candidateFile.readAll())
+ continue;
+ // just remember the offset & flags with final compression state
+ // of the already written data and be done
+ m_dataOffset = candidate->m_dataOffset;
+ m_flags = candidate->m_flags;
+ return offset;
+ }
+ dedupByContent.insert(key, this);
}
// Check if compression is useful for this file
if (data.size() != 0) {
#if QT_CONFIG(zstd)
- if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Best && !m_noZstd) {
- m_compressAlgo = RCCResourceLibrary::CompressionAlgorithm::Zstd;
- m_compressLevel = 19; // not ZSTD_maxCLevel(), as 20+ are experimental
- }
if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Zstd && !m_noZstd) {
if (lib.m_zstdCCtx == nullptr)
lib.m_zstdCCtx = ZSTD_createCCtx();
@@ -292,10 +355,6 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
}
#endif
#ifndef QT_NO_COMPRESS
- if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Best) {
- m_compressAlgo = RCCResourceLibrary::CompressionAlgorithm::Zlib;
- m_compressLevel = 9;
- }
if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Zlib) {
QByteArray compressed =
qCompress(reinterpret_cast<uchar *>(data.data()), data.size(), m_compressLevel);
@@ -1168,6 +1227,7 @@ bool RCCResourceLibrary::writeDataBlobs()
QStack<RCCFileInfo*> pending;
pending.push(m_root);
qint64 offset = 0;
+ RCCFileInfo::DeduplicationMultiHash dedupByContent;
QString errorMessage;
while (!pending.isEmpty()) {
RCCFileInfo *file = pending.pop();
@@ -1176,7 +1236,8 @@ bool RCCResourceLibrary::writeDataBlobs()
if (child->m_flags & RCCFileInfo::Directory)
pending.push(child);
else {
- offset = child->writeDataBlob(*this, offset, &errorMessage);
+ offset = child->writeDataBlob(*this, offset,
+ dedupByContent, &errorMessage);
if (offset == 0) {
m_errorDevice->write(errorMessage.toUtf8());
return false;
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index d2b0fb724ac..a735696adcb 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -3741,6 +3741,14 @@ void QApplicationPrivate::cleanupMultitouch_sys()
{
}
+/*! \internal
+ Check the target widgets of the active touchpoints of the given \a device,
+ and choose the widget that is closest to any of the points. This widget
+ will then get all the touchpoints, even if it would not otherwise be the
+ target for some of them.
+
+ \sa translateRawTouchEvent()
+*/
QWidget *QApplicationPrivate::findClosestTouchPointTarget(const QPointingDevice *device, const QEventPoint &touchPoint)
{
const QPointF globalPos = touchPoint.globalPosition();
@@ -3754,7 +3762,10 @@ QWidget *QApplicationPrivate::findClosestTouchPointTarget(const QPointingDevice
qreal dx = globalPos.x() - pt.globalPosition().x();
qreal dy = globalPos.y() - pt.globalPosition().y();
qreal distance = dx * dx + dy * dy;
- if (closestTouchPointId == -1 || distance < closestDistance) {
+ // closestTouchPointId is -1 at the beginning.
+ // closestTouchPointId may be 0 if
+ // a synth-mouse eventPoint was found in activePoints: that's not relevant here.
+ if (closestTouchPointId <= 0 || distance < closestDistance) {
closestTouchPointId = pt.id();
closestDistance = distance;
closestTarget = QMutableEventPoint::target(pt);
diff --git a/src/widgets/styles/qfusionstyle_p_p.h b/src/widgets/styles/qfusionstyle_p_p.h
index dcb79f9e93c..821be49b2fa 100644
--- a/src/widgets/styles/qfusionstyle_p_p.h
+++ b/src/widgets/styles/qfusionstyle_p_p.h
@@ -94,7 +94,8 @@ public:
QColor buttonColor = pal.button().color();
int val = qGray(buttonColor.rgb());
buttonColor = buttonColor.lighter(100 + qMax(1, (180 - val)/6));
- buttonColor.setHsv(buttonColor.hue(), buttonColor.saturation() * 0.75, buttonColor.value());
+ buttonColor.setHsv(buttonColor.hue(), buttonColor.saturation() * 0.75,
+ buttonColor.value(), buttonColor.alpha());
return buttonColor;
}