summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmake/QtAndroidHelpers.cmake3
-rw-r--r--cmake/QtPublicCMakeVersionHelpers.cmake36
-rw-r--r--coin/instructions/cmake_regular_test_instructions.yaml2
-rw-r--r--coin/instructions/vxworks_testrunner.yaml95
-rw-r--r--examples/widgets/doc/src/draggableicons.qdoc1
-rw-r--r--examples/widgets/doc/src/draggabletext.qdoc1
-rw-r--r--examples/widgets/doc/src/dropsite.qdoc1
-rw-r--r--examples/widgets/doc/src/tablet.qdoc2
-rw-r--r--examples/widgets/gestures/imagegestures/doc/src/imagegestures.qdoc1
-rw-r--r--examples/widgets/touch/knobs/doc/src/touch-knobs.qdoc1
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtView.java49
-rw-r--r--src/corelib/CMakeLists.txt2
-rw-r--r--src/corelib/doc/src/qtcore.qdoc5
-rw-r--r--src/corelib/global/qfloat16.h9
-rw-r--r--src/corelib/kernel/qmetaassociation.cpp299
-rw-r--r--src/corelib/kernel/qmetacontainer.cpp499
-rw-r--r--src/corelib/kernel/qmetasequence.cpp471
-rw-r--r--src/corelib/kernel/qobject.cpp4
-rw-r--r--src/corelib/kernel/qwinregistry.cpp4
-rw-r--r--src/corelib/serialization/.gitignore1
-rwxr-xr-xsrc/corelib/serialization/make-xml-parser.sh1
-rw-r--r--src/corelib/serialization/qcborstream.h1
-rw-r--r--src/corelib/serialization/qjsonparseerror.h4
-rw-r--r--src/corelib/serialization/qjsonparser.cpp4
-rw-r--r--src/corelib/serialization/qjsonparser_p.h1
-rw-r--r--src/corelib/serialization/qjsonwriter_p.h1
-rw-r--r--src/corelib/text/qcollator.cpp1
-rw-r--r--src/corelib/text/qcollator.h1
-rw-r--r--src/corelib/text/qcollator_icu.cpp1
-rw-r--r--src/corelib/text/qcollator_macx.cpp1
-rw-r--r--src/corelib/text/qcollator_p.h1
-rw-r--r--src/corelib/text/qcollator_posix.cpp1
-rw-r--r--src/corelib/text/qcollator_win.cpp1
-rw-r--r--src/corelib/text/qlocale.qdoc1
-rw-r--r--src/corelib/text/qtliterals.qdoc5
-rw-r--r--src/corelib/thread/qthread.cpp3
-rw-r--r--src/gui/doc/images/plaintext-layout.pngbin46384 -> 0 bytes
-rw-r--r--src/gui/doc/images/plaintext-layout.webpbin0 -> 7714 bytes
-rw-r--r--src/gui/doc/src/qtgui.qdoc5
-rw-r--r--src/gui/doc/src/richtext.qdoc2
-rw-r--r--src/gui/kernel/qkeysequence.cpp5
-rw-r--r--src/gui/kernel/qplatformwindow_p.h12
-rw-r--r--src/gui/painting/qpainter.cpp33
-rw-r--r--src/gui/painting/qpainter_p.h3
-rw-r--r--src/gui/painting/qstroker.cpp6
-rw-r--r--src/gui/text/qtextdocumentfragment.cpp12
-rw-r--r--src/gui/text/qtextformat.cpp4
-rw-r--r--src/gui/util/qundostack.cpp12
-rw-r--r--src/gui/util/qundostack_p.h15
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.cpp2
-rw-r--r--src/plugins/platforms/android/qandroidplatformwindow.cpp39
-rw-r--r--src/plugins/platforms/android/qandroidplatformwindow.h5
-rw-r--r--src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h5
-rw-r--r--src/plugins/platforms/ios/qiosdocumentpickercontroller.h5
-rw-r--r--src/plugins/platforms/ios/qiosplatformaccessibility.h2
-rw-r--r--src/plugins/platforms/ios/qiosplatformaccessibility.mm2
-rw-r--r--src/plugins/platforms/ios/qiostextresponder.h5
-rw-r--r--src/plugins/platforms/ios/qioswindow.h5
-rw-r--r--src/plugins/platforms/ios/quiview.h5
-rw-r--r--src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp193
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.cpp24
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow_p.h10
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp6
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm5
-rw-r--r--src/plugins/styles/modernwindows/qwindows11style.cpp44
-rw-r--r--src/plugins/tls/schannel/qtls_schannel.cpp3
-rw-r--r--src/tools/androidtestrunner/main.cpp51
-rw-r--r--src/widgets/doc/src/qtwidgets-examples.qdoc12
-rw-r--r--src/widgets/doc/src/qtwidgets-toc.qdoc1
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp3
-rw-r--r--src/widgets/kernel/qtooltip.cpp13
-rw-r--r--src/widgets/kernel/qwidget.cpp19
-rw-r--r--src/widgets/util/qcompleter.cpp15
-rw-r--r--src/widgets/widgets/qcombobox.cpp14
-rw-r--r--src/widgets/widgets/qmenu.cpp21
-rw-r--r--tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp8
-rw-r--r--tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp10
-rw-r--r--tests/auto/gui/kernel/qsurfaceformat/tst_qsurfaceformat.cpp4
-rw-r--r--tests/auto/gui/painting/qpainter/tst_qpainter.cpp57
-rw-r--r--tests/auto/gui/rhi/qrhi/tst_qrhi.cpp2
-rw-r--r--tests/auto/gui/rhi/qshader/tst_qshader.cpp5
-rw-r--r--tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp16
-rw-r--r--tests/auto/network/access/qnetworkreply_local/minihttpserver.h2
-rw-r--r--tests/auto/network/access/qnetworkreply_local/tst_qnetworkreply_local.cpp2
-rw-r--r--tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp25
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp2
-rw-r--r--tests/benchmarks/corelib/time/qtimezone/tst_bench_qtimezone.cpp10
87 files changed, 1503 insertions, 772 deletions
diff --git a/cmake/QtAndroidHelpers.cmake b/cmake/QtAndroidHelpers.cmake
index b473c2c331b..59a469b1683 100644
--- a/cmake/QtAndroidHelpers.cmake
+++ b/cmake/QtAndroidHelpers.cmake
@@ -442,8 +442,9 @@ function(qt_internal_create_source_jar)
add_dependencies(android_source_jars ${jar_target})
if(QT_WILL_INSTALL)
+ qt_path_join(destination "${INSTALL_DATADIR}" "android" "${module}")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${jar_name}-${PROJECT_VERSION}.jar"
- DESTINATION "${INSTALL_DATADIR}/android/${module}"
+ DESTINATION "${destination}"
COMPONENT _install_android_source_jar_${module}
EXCLUDE_FROM_ALL
)
diff --git a/cmake/QtPublicCMakeVersionHelpers.cmake b/cmake/QtPublicCMakeVersionHelpers.cmake
index 292d97c84e7..0207c087e1a 100644
--- a/cmake/QtPublicCMakeVersionHelpers.cmake
+++ b/cmake/QtPublicCMakeVersionHelpers.cmake
@@ -107,10 +107,9 @@ endfunction()
# Handle force-assignment of CMP0156 policy when using CMake 3.29+.
#
# For Apple-platforms we set it to NEW, to avoid duplicate linker issues when using -ObjC flag.
+# For Emscripten / WebAssembly we also set it to NEW, to avoid duplicate linker issues.
#
-# For non-Apple platforms we set it to OLD, because we haven't done the necessary testing to
-# see which platforms / linkers can handle the new deduplication behavior, without breaking the
-# various linking techniques that Qt uses for object library propagation.
+# For other platforms, we leave the policy value as-is, without showing any warnings.
function(__qt_internal_set_cmp0156)
# Exit early if not using CMake 3.29+
if(NOT POLICY CMP0156)
@@ -164,29 +163,32 @@ function(__qt_internal_set_cmp0156)
set(default_policy_value NEW)
set(unsupported_policy_value OLD)
else()
- # For non-Apple linkers, we keep the previous behavior of not deduplicating libraries,
- # because we haven't done the necessary testing to identify on which platforms
- # it is safe to deduplicate.
- set(default_policy_value OLD)
- set(unsupported_policy_value NEW)
+ # For other platforms we don't enforce any policy values and keep them as-is.
+ set(default_policy_value "")
+ set(unsupported_policy_value "")
endif()
# Force set the default policy value for the given platform, even if the policy value is
# the same or empty. That's because in the calling function scope, the value can be empty
# due to the cmake_minimum_required call in Qt6Config.cmake resetting the policy value.
- get_cmake_property(debug_message_shown _qt_internal_cmp0156_debug_message_shown)
- if(NOT debug_message_shown)
- message(DEBUG "Force setting the CMP0156 policy to '${default_policy_value}' "
- "for platform '${CMAKE_SYSTEM_NAME}'.")
- set_property(GLOBAL PROPERTY _qt_internal_cmp0156_debug_message_shown TRUE)
- endif()
+ if(default_policy_value)
+ get_cmake_property(debug_message_shown _qt_internal_cmp0156_debug_message_shown)
+ if(NOT debug_message_shown)
+ message(DEBUG "Force setting the CMP0156 policy to '${default_policy_value}' "
+ "for platform '${CMAKE_SYSTEM_NAME}'.")
+ set_property(GLOBAL PROPERTY _qt_internal_cmp0156_debug_message_shown TRUE)
+ endif()
- cmake_policy(SET CMP0156 "${default_policy_value}")
+ cmake_policy(SET CMP0156 "${default_policy_value}")
+ endif()
- # If the policy is explicitly set to a value other than the default, issue a warning.
+ # If the policy is explicitly set to a value other than the (non-empty) default, issue a
+ # warning.
# Don't show the warning if the policy is unset, which would be the default for most
# projects, because it's too much noise. Also don't show it for Qt builds.
- if("${policy_value}" STREQUAL "${unsupported_policy_value}" AND NOT QT_BUILDING_QT)
+ if(unsupported_policy_value
+ AND "${policy_value}" STREQUAL "${unsupported_policy_value}"
+ AND NOT QT_BUILDING_QT)
message(WARNING
"CMP0156 is set to '${policy_value}'. Qt forces the '${default_policy_value}'"
" behavior of this policy for the '${CMAKE_SYSTEM_NAME}' platform by default."
diff --git a/coin/instructions/cmake_regular_test_instructions.yaml b/coin/instructions/cmake_regular_test_instructions.yaml
index 91593df6b4f..60fbd2e8e20 100644
--- a/coin/instructions/cmake_regular_test_instructions.yaml
+++ b/coin/instructions/cmake_regular_test_instructions.yaml
@@ -33,7 +33,7 @@ instructions:
conditions:
- condition: property
property: id
- contains_value: "macos-15"
+ equals_value: "macos-26-arm64-tests"
- condition: runtime
env_var: COIN_CTEST_FORCE_IGNORE_EXIT_CODE
equals_value: null
diff --git a/coin/instructions/vxworks_testrunner.yaml b/coin/instructions/vxworks_testrunner.yaml
index 6979b6807da..e348290d6d4 100644
--- a/coin/instructions/vxworks_testrunner.yaml
+++ b/coin/instructions/vxworks_testrunner.yaml
@@ -5,8 +5,39 @@ instructions:
fileMode: 493
fileContents: |
#!/bin/bash
+
+ # Seconds of serial silence before triggering an SSH probe; also the cadence for repeated probes
+ EMPTY_READ_GRACE=20
+
+ # Maximum time (s) with no output while waiting; exceeding this triggers a timeout failure
+ MAX_WAIT_TIME=700
+
quoted_args=`python3 -c 'import sys, shlex; print(shlex.join(sys.argv[2:]))' "$@"`
+ ssh_cmd() {
+ LD_LIBRARY_PATH=/usr/lib ssh -n -q \
+ -o BatchMode=yes -o ConnectTimeout=1 -o HostKeyAlgorithms=+ssh-rsa \
+ ${VXWORKS_SSH} "$@" </dev/null
+ }
+
+ ssh_probe_status() {
+ # Returns one of: FINISHED | RUNNING | UNRESPONSIVE
+ local out
+ out="$(ssh_cmd 'cmd rtp list; exit' 2>&1 || true)"
+ # If we don't see the normal SSH epilogue ("Au revoir!"), treat as UNRESPONSIVE
+ # (system is probably under a heavy load)
+ if ! printf '%s\n' "$out" | /usr/bin/grep -q 'Au revoir!'; then
+ echo "UNRESPONSIVE"
+ return 0
+ fi
+ # Determine if our RTP is present; currently we match by 'tests' substring in 'rtp list' output
+ if printf '%s\n' "$out" | /usr/bin/grep -Fq "tests"; then
+ echo "RUNNING"
+ else
+ echo "FINISHED"
+ fi
+ }
+
testdir="$(dirname $1)"
testexecutable="$1"
echo RUNNING via serial: "$quoted_args"
@@ -33,8 +64,16 @@ instructions:
read -t 1 testline</tmp/guest.out
fi
- if [[ -z "$testline" ]]; then
- echo "Restarting stuck emulator"
+ probe0="$(ssh_probe_status)"
+
+ if [[ -z "$testline" || "$probe0" != "FINISHED" ]]; then
+ if [[ "$probe0" == "UNRESPONSIVE" ]]; then
+ echo "Restarting stuck emulator (SSH down)"
+ elif [[ "$probe0" == "RUNNING" ]]; then
+ echo "Restarting stuck emulator (RTP still running)"
+ else
+ echo "Restarting stuck emulator (serial down)"
+ fi
pkill qemu-system
rm /tmp/guest.in /tmp/guest.out
mkfifo /tmp/guest.in /tmp/guest.out
@@ -43,37 +82,79 @@ instructions:
/bin/bash /home/qt/work/coin_vxworks_vars.sh
sleep 1
else
- echo "Emulator responding"
+ echo "VxWorks is functional"
fi
- # Empty output
+ # Empty out any pending serial output to start clean
while read -t 1 line; do
echo $line
done < /tmp/guest.out
echo "cmd cd $testdir" > /tmp/guest.in
sleep 1
+
+ # Empty line before result of cd
+ read -t 1 line_cmd </tmp/guest.out
+
+ if read -t 5 cdline </tmp/guest.out; then
+ cdline_clean=$(printf '%s' "$cdline" | tr -d '\r')
+ if printf '%s' "$cdline_clean" | /usr/bin/grep -Eq 'error\s*='; then
+ printf 'entering %s: %s\n' "$testdir" "$cdline_clean"
+ exit 1
+ fi
+ fi
+
echo "</home/qt/work/vx.sh" > /tmp/guest.in
- while read -t 600 line; do
+ silent_seconds=0
+ last_probe_result="NONE"
+
+ while true; do
+ if ! read -t $EMPTY_READ_GRACE line; then
+ silent_seconds=$((silent_seconds + EMPTY_READ_GRACE))
+
+ probe="$(ssh_probe_status)"
+ last_probe_result="$probe"
+ if [[ "$probe" == "UNRESPONSIVE" ]]; then
+ echo "system is under heavy load after ${silent_seconds}s of silence (SSH unresponsive)"
+ elif [[ "$probe" == "FINISHED" ]]; then
+ echo "RTP finished after ${silent_seconds}s of silence, ending"
+ exit 0
+ fi
+ # RUNNING or UNRESPONSIVE - keep waiting
+ if (( silent_seconds >= MAX_WAIT_TIME )); then
+ echo "Timeout: no output for ${MAX_WAIT_TIME}s (last SSH probe: ${last_probe_result})"
+ exit 1
+ fi
+ continue
+ fi
+
+ # We received serial output
+ silent_seconds=0
+
echo "$line"
+
if echo "$line" | /usr/bin/grep -q "qtest_in_vxworks_complete"
then
read -t 1 line</tmp/guest.out
echo "$line"
exitcode=$(echo "$line" | sed -nr 's/qtest_in_vxworks_complete: (-?[0-9]+)/\1/gp' | tr -d '\r')
+ probe="$(ssh_probe_status)"
+ if [[ "$probe" != "FINISHED" ]]; then
+ echo "final SSH probe: ${probe}"
+ fi
exit $exitcode
fi
# Handle crashes
if echo "$line" | /usr/bin/grep -qE "(SIGSEGV)|(SIGABRT)|(S_rtpLib_[A-Z_]+)"
then
- # Empty output pipe
+ # Drain the pipe for context, mark as crashed, and restart emulator next run.
while read -t 1 line; do
echo $line
done < /tmp/guest.out
echo "Test crashed"
- pkill qemu-system # Kill emulator to force restart on next test start
+ pkill qemu-system
exit 1
fi
done < /tmp/guest.out
diff --git a/examples/widgets/doc/src/draggableicons.qdoc b/examples/widgets/doc/src/draggableicons.qdoc
index 0f1feacb7fb..3cf9b9b7266 100644
--- a/examples/widgets/doc/src/draggableicons.qdoc
+++ b/examples/widgets/doc/src/draggableicons.qdoc
@@ -4,6 +4,7 @@
/*!
\example draganddrop/draggableicons
\title Draggable Icons Example
+ \ingroup examples-user-input
\examplecategory {User Interface Components}
\brief The Draggable Icons example shows how to drag and drop image data between widgets
diff --git a/examples/widgets/doc/src/draggabletext.qdoc b/examples/widgets/doc/src/draggabletext.qdoc
index 3609ed5a1a1..f34e166ed89 100644
--- a/examples/widgets/doc/src/draggabletext.qdoc
+++ b/examples/widgets/doc/src/draggabletext.qdoc
@@ -4,6 +4,7 @@
/*!
\example draganddrop/draggabletext
\title Draggable Text Example
+ \ingroup examples-user-input
\examplecategory {User Interface Components}
\brief Illustrates how to drag and drop text between widgets.
diff --git a/examples/widgets/doc/src/dropsite.qdoc b/examples/widgets/doc/src/dropsite.qdoc
index 4c38ffc50d3..baa7b22fa8a 100644
--- a/examples/widgets/doc/src/dropsite.qdoc
+++ b/examples/widgets/doc/src/dropsite.qdoc
@@ -4,6 +4,7 @@
/*!
\example draganddrop/dropsite
\title Drop Site Example
+ \ingroup examples-user-input
\examplecategory {User Interface Components}
\brief The example shows how to distinguish the various MIME formats available
diff --git a/examples/widgets/doc/src/tablet.qdoc b/examples/widgets/doc/src/tablet.qdoc
index a18eb3249e7..f1238238df9 100644
--- a/examples/widgets/doc/src/tablet.qdoc
+++ b/examples/widgets/doc/src/tablet.qdoc
@@ -5,7 +5,7 @@
\example widgets/tablet
\title Tablet Example
\examplecategory {User Interface Components}
- \ingroup examples-widgets
+ \ingroup examples-user-input
\brief This example shows how to use a Wacom tablet in Qt applications.
\image tabletexample.png {Application displaying a drawing area}
diff --git a/examples/widgets/gestures/imagegestures/doc/src/imagegestures.qdoc b/examples/widgets/gestures/imagegestures/doc/src/imagegestures.qdoc
index 03b31edabc5..63ca14787b6 100644
--- a/examples/widgets/gestures/imagegestures/doc/src/imagegestures.qdoc
+++ b/examples/widgets/gestures/imagegestures/doc/src/imagegestures.qdoc
@@ -5,6 +5,7 @@
\example gestures/imagegestures
\title Image Gestures Example
\examplecategory {User Interface Components}
+ \ingroup examples-user-input
\brief Demonstrates the use of simple gestures in a widget.
This example shows how to enable gestures for a widget and use gesture input
diff --git a/examples/widgets/touch/knobs/doc/src/touch-knobs.qdoc b/examples/widgets/touch/knobs/doc/src/touch-knobs.qdoc
index d229f54f5c7..38bd2016cab 100644
--- a/examples/widgets/touch/knobs/doc/src/touch-knobs.qdoc
+++ b/examples/widgets/touch/knobs/doc/src/touch-knobs.qdoc
@@ -6,6 +6,7 @@
\title Touch Knobs Example
\examplecategory {User Interface Components}
\ingroup touchinputexamples
+ \ingroup examples-user-input
\brief Shows how to create custom controls that accept touch input.
The Touch Knobs example shows how to create custom controls that
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtView.java b/src/android/jar/src/org/qtproject/qt/android/QtView.java
index b60c58013f5..e245f731ce8 100644
--- a/src/android/jar/src/org/qtproject/qt/android/QtView.java
+++ b/src/android/jar/src/org/qtproject/qt/android/QtView.java
@@ -25,11 +25,11 @@ abstract class QtView extends ViewGroup implements QtNative.AppStateDetailsListe
void onQtWindowLoaded();
}
- protected QtWindow m_window;
- protected long m_windowReference;
- protected long m_parentWindowReference;
- protected QtWindowListener m_windowListener;
- protected final QtEmbeddedViewInterface m_viewInterface;
+ private QtWindow m_window;
+ private long m_windowReference;
+ private long m_parentWindowReference;
+ private QtWindowListener m_windowListener;
+ private final QtEmbeddedViewInterface m_viewInterface;
// Implement in subclass to handle the creation of the QWindow and its parent container.
// TODO could we take care of the parent window creation and parenting outside of the
// window creation method to simplify things if user would extend this? Preferably without
@@ -164,10 +164,43 @@ abstract class QtView extends ViewGroup implements QtNative.AppStateDetailsListe
m_windowReference = windowReference;
}
- long windowReference() {
+ long getWindowReference() {
return m_windowReference;
}
+ void setQtWindow(QtWindow qtWindow) {
+ m_window = qtWindow;
+ }
+
+ QtWindow getQtWindow() {
+ return m_window;
+ }
+
+ long getParentWindowReference()
+ {
+ return m_parentWindowReference;
+ }
+
+ void setParentWindowReference(long reference)
+ {
+ m_parentWindowReference = reference;
+ }
+
+ QtWindowListener getWindowListener()
+ {
+ return m_windowListener;
+ }
+
+ void setWindowListener(QtWindowListener listner)
+ {
+ m_windowListener = listner;
+ }
+
+ QtEmbeddedViewInterface getViewInterface()
+ {
+ return m_viewInterface;
+ }
+
// Set the visibility of the underlying QWindow. If visible is true, showNormal() is called.
// If false, the window is hidden.
void setWindowVisible(boolean visible) {
@@ -203,10 +236,6 @@ abstract class QtView extends ViewGroup implements QtNative.AppStateDetailsListe
setWindowReference(0L);
}
- QtWindow getQtWindow() {
- return m_window;
- }
-
@Override
public void onAppStateDetailsChanged(QtNative.ApplicationStateDetails details) {
if (!details.isStarted) {
diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt
index d8743a1c976..337703bda3a 100644
--- a/src/corelib/CMakeLists.txt
+++ b/src/corelib/CMakeLists.txt
@@ -175,10 +175,12 @@ qt_internal_add_module(Core
kernel/qfunctions_p.h
kernel/qiterable.cpp kernel/qiterable.h kernel/qiterable_impl.h
kernel/qmath.cpp kernel/qmath.h
+ kernel/qmetaassociation.cpp
kernel/qmetacontainer.cpp kernel/qmetacontainer.h
kernel/qmetaobject.cpp kernel/qmetaobject.h kernel/qmetaobject_p.h
kernel/qmetaobject_moc_p.h
kernel/qmetaobjectbuilder.cpp kernel/qmetaobjectbuilder_p.h
+ kernel/qmetasequence.cpp
kernel/qmetatype.cpp kernel/qmetatype.h kernel/qmetatype_p.h
kernel/qmimedata.cpp kernel/qmimedata.h
kernel/qtmetamacros.h kernel/qtmocconstants.h kernel/qtmochelpers.h
diff --git a/src/corelib/doc/src/qtcore.qdoc b/src/corelib/doc/src/qtcore.qdoc
index ea65d68da58..ec5fa564639 100644
--- a/src/corelib/doc/src/qtcore.qdoc
+++ b/src/corelib/doc/src/qtcore.qdoc
@@ -19,8 +19,7 @@
\module QtCorePrivate
\title Qt Core Private C++ Classes
\qtvariable core-private
- \qtcmakepackage Core
- \qtcmaketargetitem CorePrivate
+ \qtcmakepackage CorePrivate
\preliminary
\brief Provides private core functionality.
@@ -28,7 +27,7 @@
private Qt Core APIs:
\badcode
- find_package(Qt6 REQUIRED COMPONENTS Core)
+ find_package(Qt6 REQUIRED COMPONENTS CorePrivate)
target_link_libraries(mytarget PRIVATE Qt6::CorePrivate)
\endcode
*/
diff --git a/src/corelib/global/qfloat16.h b/src/corelib/global/qfloat16.h
index 01106abf34d..cb8514105a0 100644
--- a/src/corelib/global/qfloat16.h
+++ b/src/corelib/global/qfloat16.h
@@ -354,15 +354,15 @@ inline int qIntCast(qfloat16 f) noexcept
{ return int(static_cast<qfloat16::NearestFloat>(f)); }
#if !defined(Q_QDOC) && !QFLOAT16_IS_NATIVE
-QT_WARNING_PUSH
-QT_WARNING_DISABLE_CLANG("-Wc99-extensions")
-QT_WARNING_DISABLE_GCC("-Wold-style-cast")
inline qfloat16::qfloat16(float f) noexcept
{
#if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__F16C__)
__m128 packsingle = _mm_set_ss(f);
+ QT_WARNING_PUSH
+ QT_WARNING_DISABLE_GCC("-Wold-style-cast") // _mm_cvtps_ph() may be a macro using C-style casts
__m128i packhalf = _mm_cvtps_ph(packsingle, 0);
- b16 = _mm_extract_epi16(packhalf, 0);
+ QT_WARNING_POP
+ b16 = quint16(_mm_extract_epi16(packhalf, 0));
#elif defined (__ARM_FP16_FORMAT_IEEE)
__fp16 f16 = __fp16(f);
memcpy(&b16, &f16, sizeof(quint16));
@@ -393,7 +393,6 @@ inline qfloat16::qfloat16(float f) noexcept
b16 = quint16(base + (mantissa >> shift));
#endif
}
-QT_WARNING_POP
inline qfloat16::operator float() const noexcept
{
diff --git a/src/corelib/kernel/qmetaassociation.cpp b/src/corelib/kernel/qmetaassociation.cpp
new file mode 100644
index 00000000000..dc239424e6d
--- /dev/null
+++ b/src/corelib/kernel/qmetaassociation.cpp
@@ -0,0 +1,299 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <QtCore/qmetacontainer.h>
+#include <QtCore/qmetatype.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMetaAssociation
+ \inmodule QtCore
+ \since 6.0
+ \brief The QMetaAssociation class allows type erased access to associative containers.
+
+ \ingroup objectmodel
+
+ \compares equality
+
+ The class provides a number of primitive container operations, using void*
+ as operands. This way, you can manipulate a generic container retrieved from
+ a Variant without knowing its type.
+
+ QMetaAssociation covers both, containers with mapped values such as QMap or
+ QHash, and containers that only hold keys such as QSet.
+
+ The void* arguments to the various methods are typically created by using
+ a \l QVariant of the respective container or value type, and calling
+ its \l QVariant::data() or \l QVariant::constData() methods. However, you
+ can also pass plain pointers to objects of the container or value type.
+
+ Iterator invalidation follows the rules given by the underlying containers
+ and is not expressed in the API. Therefore, for a truly generic container,
+ any iterators should be considered invalid after any write operation.
+
+ \sa QMetaContainer, QMetaSequence, QIterable, QIterator
+*/
+
+/*!
+ \fn template<typename C> QMetaAssociation QMetaAssociation::fromContainer()
+ \since 6.0
+
+ Returns the QMetaAssociation corresponding to the type given as template parameter.
+*/
+
+/*!
+ Returns the meta type for keys in the container.
+ */
+QMetaType QMetaAssociation::keyMetaType() const
+{
+ if (auto iface = d())
+ return QMetaType(iface->keyMetaType);
+ return QMetaType();
+}
+
+/*!
+ Returns the meta type for mapped values in the container.
+ */
+QMetaType QMetaAssociation::mappedMetaType() const
+{
+ if (auto iface = d())
+ return QMetaType(iface->mappedMetaType);
+ return QMetaType();
+}
+
+/*!
+ \fn bool QMetaAssociation::canInsertKey() const
+
+ Returns \c true if keys can be added to the container using \l insertKey(),
+ otherwise returns \c false.
+
+ \sa insertKey()
+ */
+
+/*!
+ \fn void QMetaAssociation::insertKey(void *container, const void *key) const
+
+ Inserts the \a key into the \a container if possible. If the container has
+ mapped values a default-create mapped value is associated with the \a key.
+
+ \sa canInsertKey()
+ */
+
+/*!
+ \fn bool QMetaAssociation::canRemoveKey() const
+
+ Returns \c true if keys can be removed from the container using
+ \l removeKey(), otherwise returns \c false.
+
+ \sa removeKey()
+ */
+
+/*!
+ \fn void QMetaAssociation::removeKey(void *container, const void *key) const
+
+ Removes the \a key and its associated mapped value from the \a container if
+ possible.
+
+ \sa canRemoveKey()
+ */
+
+/*!
+ \fn bool QMetaAssociation::canContainsKey() const
+
+ Returns \c true if the container can be queried for keys using
+ \l containsKey(), otherwise returns \c false.
+ */
+
+/*!
+ \fn bool QMetaAssociation::containsKey(const void *container, const void *key) const
+
+ Returns \c true if the \a container can be queried for keys and contains the
+ \a key, otherwise returns \c false.
+
+ \sa canContainsKey()
+ */
+
+/*!
+ \fn bool QMetaAssociation::canGetMappedAtKey() const
+
+ Returns \c true if the container can be queried for values using
+ \l mappedAtKey(), otherwise returns \c false.
+ */
+
+/*!
+ \fn void QMetaAssociation::mappedAtKey(const void *container, const void *key, void *mapped) const
+
+ Retrieves the mapped value associated with the \a key in the \a container
+ and places it in the memory location pointed to by \a mapped, if that is
+ possible.
+
+ \sa canGetMappedAtKey()
+ */
+
+/*!
+ \fn bool QMetaAssociation::canSetMappedAtKey() const
+
+ Returns \c true if mapped values can be modified in the container using
+ \l setMappedAtKey(), otherwise returns \c false.
+
+ \sa setMappedAtKey()
+ */
+
+/*!
+ \fn void QMetaAssociation::setMappedAtKey(void *container, const void *key, const void *mapped) const
+
+ Overwrites the value associated with the \a key in the \a container using
+ the \a mapped value passed as argument if that is possible.
+
+ \sa canSetMappedAtKey()
+ */
+
+/*!
+ \fn bool QMetaAssociation::canGetKeyAtIterator() const
+
+ Returns \c true if a key can be retrieved from a non-const iterator using
+ \l keyAtIterator(), otherwise returns \c false.
+
+ \sa keyAtIterator()
+ */
+
+/*!
+ \fn void QMetaAssociation::keyAtIterator(const void *iterator, void *key) const
+
+ Retrieves the key pointed to by the non-const \a iterator and stores it
+ in the memory location pointed to by \a key, if possible.
+
+ \sa canGetKeyAtIterator(), begin(), end(), createIteratorAtKey()
+ */
+
+/*!
+ \fn bool QMetaAssociation::canGetKeyAtConstIterator() const
+
+ Returns \c true if a key can be retrieved from a const iterator using
+ \l keyAtConstIterator(), otherwise returns \c false.
+
+ \sa keyAtConstIterator()
+ */
+
+/*!
+ \fn void QMetaAssociation::keyAtConstIterator(const void *iterator, void *key) const
+
+ Retrieves the key pointed to by the const \a iterator and stores it
+ in the memory location pointed to by \a key, if possible.
+
+ \sa canGetKeyAtConstIterator(), constBegin(), constEnd(), createConstIteratorAtKey()
+ */
+
+/*!
+ \fn bool QMetaAssociation::canGetMappedAtIterator() const
+
+ Returns \c true if a mapped value can be retrieved from a non-const
+ iterator using \l mappedAtIterator(), otherwise returns \c false.
+
+ \sa mappedAtIterator()
+ */
+
+/*!
+ \fn void QMetaAssociation::mappedAtIterator(const void *iterator, void *mapped) const
+
+ Retrieves the mapped value pointed to by the non-const \a iterator and
+ stores it in the memory location pointed to by \a mapped, if possible.
+
+ \sa canGetMappedAtIterator(), begin(), end(), createIteratorAtKey()
+ */
+
+/*!
+ \fn bool QMetaAssociation::canGetMappedAtConstIterator() const
+
+ Returns \c true if a mapped value can be retrieved from a const iterator
+ using \l mappedAtConstIterator(), otherwise returns \c false.
+
+ \sa mappedAtConstIterator()
+ */
+
+/*!
+ \fn void QMetaAssociation::mappedAtConstIterator(const void *iterator, void *mapped) const
+
+ Retrieves the mapped value pointed to by the const \a iterator and
+ stores it in the memory location pointed to by \a mapped, if possible.
+
+ \sa canGetMappedAtConstIterator(), constBegin(), constEnd(), createConstIteratorAtKey()
+ */
+
+/*!
+ \fn bool QMetaAssociation::canSetMappedAtIterator() const
+
+ Returns \c true if a mapped value can be set via a non-const iterator using
+ \l setMappedAtIterator(), otherwise returns \c false.
+
+ \sa setMappedAtIterator()
+ */
+
+/*!
+ \fn void QMetaAssociation::setMappedAtIterator(const void *iterator, const void *mapped) const
+
+ Writes the \a mapped value to the container location pointed to by the
+ non-const \a iterator, if possible.
+
+ \sa canSetMappedAtIterator(), begin(), end(), createIteratorAtKey()
+ */
+
+/*!
+ \fn bool QMetaAssociation::canCreateIteratorAtKey() const
+
+ Returns \c true if an iterator pointing to an entry in the container can be
+ created using \l createIteratorAtKey(), otherwise returns false.
+
+ \sa createIteratorAtKey()
+ */
+
+/*!
+ \fn void *QMetaAssociation::createIteratorAtKey(void *container, const void *key) const
+
+ Returns a non-const iterator pointing to the entry of \a key in the
+ \a container, if possible. If the entry doesn't exist, creates a non-const
+ iterator pointing to the end of the \a container. If no non-const iterator
+ can be created, returns \c nullptr.
+
+ The non-const iterator has to be destroyed using destroyIterator().
+
+ \sa canCreateIteratorAtKey(), begin(), end(), destroyIterator()
+ */
+
+/*!
+ \fn bool QMetaAssociation::canCreateConstIteratorAtKey() const
+
+ Returns \c true if a const iterator pointing to an entry in the container
+ can be created using \l createConstIteratorAtKey(), otherwise returns false.
+ */
+
+/*!
+ \fn void *QMetaAssociation::createConstIteratorAtKey(const void *container, const void *key) const
+
+ Returns a const iterator pointing to the entry of \a key in the
+ \a container, if possible. If the entry doesn't exist, creates a const
+ iterator pointing to the end of the \a container. If no const iterator can
+ be created, returns \c nullptr.
+
+ The const iterator has to be destroyed using destroyConstIterator().
+
+ \sa canCreateConstIteratorAtKey(), constBegin(), constEnd(), destroyConstIterator()
+ */
+
+/*!
+ \fn bool QMetaAssociation::operator==(const QMetaAssociation &lhs, const QMetaAssociation &rhs)
+
+ Returns \c true if the QMetaAssociation \a lhs represents the same container type
+ as the QMetaAssociation \a rhs, otherwise returns \c false.
+*/
+
+/*!
+ \fn bool QMetaAssociation::operator!=(const QMetaAssociation &lhs, const QMetaAssociation &rhs)
+
+ Returns \c true if the QMetaAssociation \a lhs represents a different container
+ type than the QMetaAssociation \a rhs, otherwise returns \c false.
+*/
+
+
+QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qmetacontainer.cpp b/src/corelib/kernel/qmetacontainer.cpp
index 3a1a33a478a..4b4ea06d8b9 100644
--- a/src/corelib/kernel/qmetacontainer.cpp
+++ b/src/corelib/kernel/qmetacontainer.cpp
@@ -7,37 +7,6 @@
QT_BEGIN_NAMESPACE
/*!
- \class QMetaSequence
- \inmodule QtCore
- \since 6.0
- \brief The QMetaSequence class allows type erased access to sequential containers.
-
- \ingroup objectmodel
-
- \compares equality
-
- The class provides a number of primitive container operations, using void*
- as operands. This way, you can manipulate a generic container retrieved from
- a Variant without knowing its type.
-
- The void* arguments to the various methods are typically created by using
- a \l QVariant of the respective container or value type, and calling
- its \l QVariant::data() or \l QVariant::constData() methods. However, you
- can also pass plain pointers to objects of the container or value type.
-
- Iterator invalidation follows the rules given by the underlying containers
- and is not expressed in the API. Therefore, for a truly generic container,
- any iterators should be considered invalid after any write operation.
-*/
-
-/*!
- \fn template<typename C> QMetaSequence QMetaSequence::fromContainer()
- \since 6.0
-
- Returns the QMetaSequence corresponding to the type given as template parameter.
-*/
-
-/*!
\class QMetaContainer
\inmodule QtCore
\since 6.0
@@ -66,7 +35,7 @@ QT_BEGIN_NAMESPACE
specializations of input iterators. This method will also return
\c true if the container provides one of those.
- QMetaSequence assumes that const and non-const iterators for the same
+ QMetaContainer assumes that const and non-const iterators for the same
container have the same iterator traits.
*/
bool QMetaContainer::hasInputIterator() const
@@ -83,7 +52,7 @@ bool QMetaContainer::hasInputIterator() const
specializations of forward iterators. This method will also return
\c true if the container provides one of those.
- QMetaSequence assumes that const and non-const iterators for the same
+ QMetaContainer assumes that const and non-const iterators for the same
container have the same iterator traits.
*/
bool QMetaContainer::hasForwardIterator() const
@@ -99,7 +68,7 @@ bool QMetaContainer::hasForwardIterator() const
std::bidirectional_iterator_tag and std::random_access_iterator_tag,
respectively. Otherwise returns \c false.
- QMetaSequence assumes that const and non-const iterators for the same
+ QMetaContainer assumes that const and non-const iterators for the same
container have the same iterator traits.
*/
bool QMetaContainer::hasBidirectionalIterator() const
@@ -114,7 +83,7 @@ bool QMetaContainer::hasBidirectionalIterator() const
iterator as defined by std::random_access_iterator_tag, otherwise returns
\c false.
- QMetaSequence assumes that const and non-const iterators for the same
+ QMetaContainer assumes that const and non-const iterators for the same
container have the same iterator traits.
*/
bool QMetaContainer::hasRandomAccessIterator() const
@@ -125,147 +94,6 @@ bool QMetaContainer::hasRandomAccessIterator() const
}
/*!
- Returns the meta type for values stored in the container.
- */
-QMetaType QMetaSequence::valueMetaType() const
-{
- if (auto iface = d())
- return QMetaType(iface->valueMetaType);
- return QMetaType();
-}
-
-/*!
- Returns \c true if the underlying container is sortable, otherwise returns
- \c false. A container is considered sortable if values added to it are
- placed in a defined location. Inserting into or adding to a sortable
- container will always succeed. Inserting into or adding to an unsortable
- container may not succeed, for example if the container is a QSet that
- already contains the value being inserted.
-
- \sa addValue(), insertValueAtIterator(), canAddValueAtBegin(),
- canAddValueAtEnd(), canRemoveValueAtBegin(), canRemoveValueAtEnd()
- */
-bool QMetaSequence::isSortable() const
-{
- if (auto iface = d()) {
- return (iface->addRemoveCapabilities
- & (QtMetaContainerPrivate::CanAddAtBegin | QtMetaContainerPrivate::CanAddAtEnd))
- && (iface->addRemoveCapabilities
- & (QtMetaContainerPrivate::CanRemoveAtBegin
- | QtMetaContainerPrivate::CanRemoveAtEnd));
- }
- return false;
-}
-
-/*!
- Returns \c true if values added using \l addValue() can be placed at the
- beginning of the container, otherwise returns \c false.
-
- \sa addValueAtBegin(), canAddValueAtEnd()
- */
-bool QMetaSequence::canAddValueAtBegin() const
-{
- if (auto iface = d()) {
- return iface->addValueFn
- && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanAddAtBegin;
- }
- return false;
-}
-
-/*!
- Adds \a value to the beginning of \a container if possible. If
- \l canAddValueAtBegin() returns \c false, the \a value is not added.
-
- \sa canAddValueAtBegin(), isSortable(), removeValueAtBegin()
- */
-void QMetaSequence::addValueAtBegin(void *container, const void *value) const
-{
- if (canAddValueAtBegin())
- d()->addValueFn(container, value, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin);
-}
-
-/*!
- Returns \c true if values can be removed from the beginning of the container
- using \l removeValue(), otherwise returns \c false.
-
- \sa removeValueAtBegin(), canRemoveValueAtEnd()
- */
-bool QMetaSequence::canRemoveValueAtBegin() const
-{
- if (auto iface = d()) {
- return iface->removeValueFn
- && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanRemoveAtBegin;
- }
- return false;
-}
-
-/*!
- Removes a value from the beginning of \a container if possible. If
- \l canRemoveValueAtBegin() returns \c false, the value is not removed.
-
- \sa canRemoveValueAtBegin(), isSortable(), addValueAtBegin()
- */
-void QMetaSequence::removeValueAtBegin(void *container) const
-{
- if (canRemoveValueAtBegin())
- d()->removeValueFn(container, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin);
-}
-
-/*!
- Returns \c true if values added using \l addValue() can be placed at the
- end of the container, otherwise returns \c false.
-
- \sa addValueAtEnd(), canAddValueAtBegin()
- */
-bool QMetaSequence::canAddValueAtEnd() const
-{
- if (auto iface = d()) {
- return iface->addValueFn
- && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanAddAtEnd;
- }
- return false;
-}
-
-/*!
- Adds \a value to the end of \a container if possible. If
- \l canAddValueAtEnd() returns \c false, the \a value is not added.
-
- \sa canAddValueAtEnd(), isSortable(), removeValueAtEnd()
- */
-void QMetaSequence::addValueAtEnd(void *container, const void *value) const
-{
- if (canAddValueAtEnd())
- d()->addValueFn(container, value, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd);
-}
-
-/*!
- Returns \c true if values can be removed from the end of the container
- using \l removeValue(), otherwise returns \c false.
-
- \sa removeValueAtEnd(), canRemoveValueAtBegin()
- */
-bool QMetaSequence::canRemoveValueAtEnd() const
-{
- if (auto iface = d()) {
- return iface->removeValueFn
- && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanRemoveAtEnd;
- }
- return false;
-}
-
-/*!
- Removes a value from the end of \a container if possible. If
- \l canRemoveValueAtEnd() returns \c false, the value is not removed.
-
- \sa canRemoveValueAtEnd(), isSortable(), addValueAtEnd()
- */
-void QMetaSequence::removeValueAtEnd(void *container) const
-{
- if (canRemoveValueAtEnd())
- d()->removeValueFn(container, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd);
-}
-
-/*!
Returns \c true if the container can be queried for its size, \c false
otherwise.
@@ -309,122 +137,6 @@ void QMetaContainer::clear(void *container) const
}
/*!
- Returns \c true if values can be retrieved from the container by index,
- otherwise \c false.
-
- \sa valueAtIndex()
- */
-bool QMetaSequence::canGetValueAtIndex() const
-{
- if (auto iface = d())
- return iface->valueAtIndexFn;
- return false;
-}
-
-/*!
- Retrieves the value at \a index in the \a container and places it in the
- memory location pointed to by \a result, if that is possible.
-
- \sa canGetValueAtIndex()
- */
-void QMetaSequence::valueAtIndex(const void *container, qsizetype index, void *result) const
-{
- if (canGetValueAtIndex())
- d()->valueAtIndexFn(container, index, result);
-}
-
-/*!
- Returns \c true if a value can be written to the container by index,
- otherwise \c false.
-
- \sa setValueAtIndex()
-*/
-bool QMetaSequence::canSetValueAtIndex() const
-{
- if (auto iface = d())
- return iface->setValueAtIndexFn;
- return false;
-}
-
-/*!
- Overwrites the value at \a index in the \a container using the \a value
- passed as parameter if that is possible.
-
- \sa canSetValueAtIndex()
- */
-void QMetaSequence::setValueAtIndex(void *container, qsizetype index, const void *value) const
-{
- if (canSetValueAtIndex())
- d()->setValueAtIndexFn(container, index, value);
-}
-
-/*!
- Returns \c true if values can be added to the container, \c false
- otherwise.
-
- \sa addValue(), isSortable()
- */
-bool QMetaSequence::canAddValue() const
-{
- if (auto iface = d())
- return iface->addValueFn;
- return false;
-}
-
-/*!
- Adds \a value to the \a container if possible. If \l canAddValue()
- returns \c false, the \a value is not added. Else, if
- \l canAddValueAtEnd() returns \c true, the \a value is added
- to the end of the \a container. Else, if
- \l canAddValueAtBegin() returns \c true, the \a value is added to
- the beginning of the container. Else, the value is added in an unspecified
- place or not at all. The latter is the case for adding values to an
- unordered container, for example \l QSet.
-
- \sa canAddValue(), canAddValueAtBegin(),
- canAddValueAtEnd(), isSortable(), removeValue()
- */
-void QMetaSequence::addValue(void *container, const void *value) const
-{
- if (canAddValue()) {
- d()->addValueFn(container, value,
- QtMetaContainerPrivate::QMetaSequenceInterface::Unspecified);
- }
-}
-
-/*!
- Returns \c true if values can be removed from the container, \c false
- otherwise.
-
- \sa removeValue(), isSortable()
- */
-bool QMetaSequence::canRemoveValue() const
-{
- if (auto iface = d())
- return iface->removeValueFn;
- return false;
-}
-
-/*!
- Removes a value from the \a container if possible. If
- \l canRemoveValue() returns \c false, no value is removed. Else, if
- \l canRemoveValueAtEnd() returns \c true, the last value in
- the \a container is removed. Else, if \l canRemoveValueAtBegin()
- returns \c true, the first value in the \a container is removed. Else,
- an unspecified value or nothing is removed.
-
- \sa canRemoveValue(), canRemoveValueAtBegin(),
- canRemoveValueAtEnd(), isSortable(), addValue()
- */
-void QMetaSequence::removeValue(void *container) const
-{
- if (canRemoveValue()) {
- d()->removeValueFn(container,
- QtMetaContainerPrivate::QMetaSequenceInterface::Unspecified);
- }
-}
-
-/*!
Returns \c true if the underlying container offers a non-const iterator,
\c false otherwise.
@@ -456,7 +168,7 @@ void *QMetaContainer::begin(void *container) const
{
return hasIterator()
? d_ptr->createIteratorFn(
- container, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin)
+ container, QtMetaContainerPrivate::QMetaContainerInterface::AtBegin)
: nullptr;
}
@@ -473,7 +185,7 @@ void *QMetaContainer::end(void *container) const
{
return hasIterator()
? d_ptr->createIteratorFn(
- container, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd)
+ container, QtMetaContainerPrivate::QMetaContainerInterface::AtEnd)
: nullptr;
}
@@ -541,137 +253,6 @@ qsizetype QMetaContainer::diffIterator(const void *i, const void *j) const
}
/*!
- Returns \c true if the underlying container can retrieve the value pointed
- to by a non-const iterator, \c false otherwise.
-
- \sa hasIterator(), valueAtIterator()
- */
-bool QMetaSequence::canGetValueAtIterator() const
-{
- if (auto iface = d())
- return iface->valueAtIteratorFn;
- return false;
-}
-
-/*!
- Retrieves the value pointed to by the non-const \a iterator and stores it
- in the memory location pointed to by \a result, if possible.
-
- \sa canGetValueAtIterator(), begin(), end()
- */
-void QMetaSequence::valueAtIterator(const void *iterator, void *result) const
-{
- if (canGetValueAtIterator())
- d()->valueAtIteratorFn(iterator, result);
-}
-
-/*!
- Returns \c true if the underlying container can write to the value pointed
- to by a non-const iterator, \c false otherwise.
-
- \sa hasIterator(), setValueAtIterator()
- */
-bool QMetaSequence::canSetValueAtIterator() const
-{
- if (auto iface = d())
- return iface->setValueAtIteratorFn;
- return false;
-}
-
-/*!
- Writes \a value to the value pointed to by the non-const \a iterator, if
- possible.
-
- \sa canSetValueAtIterator(), begin(), end()
- */
-void QMetaSequence::setValueAtIterator(const void *iterator, const void *value) const
-{
- if (canSetValueAtIterator())
- d()->setValueAtIteratorFn(iterator, value);
-}
-
-/*!
- Returns \c true if the underlying container can insert a new value, taking
- the location pointed to by a non-const iterator into account.
-
- \sa hasIterator(), insertValueAtIterator()
- */
-bool QMetaSequence::canInsertValueAtIterator() const
-{
- if (auto iface = d())
- return iface->insertValueAtIteratorFn;
- return false;
-}
-
-/*!
- Inserts \a value into the \a container, if possible, taking the non-const
- \a iterator into account. If \l canInsertValueAtIterator() returns
- \c false, the \a value is not inserted. Else if \l isSortable() returns
- \c true, the value is inserted before the value pointed to by
- \a iterator. Else, the \a value is inserted at an unspecified place or not
- at all. In the latter case, the \a iterator is taken as a hint. If it points
- to the correct place for the \a value, the operation may be faster than a
- \l addValue() without iterator.
-
- \sa canInsertValueAtIterator(), isSortable(), begin(), end()
- */
-void QMetaSequence::insertValueAtIterator(void *container, const void *iterator,
- const void *value) const
-{
- if (canInsertValueAtIterator())
- d()->insertValueAtIteratorFn(container, iterator, value);
-}
-
-/*!
- Returns \c true if the value pointed to by a non-const iterator can be
- erased, \c false otherwise.
-
- \sa hasIterator(), eraseValueAtIterator()
- */
-bool QMetaSequence::canEraseValueAtIterator() const
-{
- if (auto iface = d())
- return iface->eraseValueAtIteratorFn;
- return false;
-}
-
-/*!
- Erases the value pointed to by the non-const \a iterator from the
- \a container, if possible.
-
- \sa canEraseValueAtIterator(), begin(), end()
- */
-void QMetaSequence::eraseValueAtIterator(void *container, const void *iterator) const
-{
- if (canEraseValueAtIterator())
- d()->eraseValueAtIteratorFn(container, iterator);
-}
-
-/*!
- Returns \c true if a range between two iterators can be erased from the
- container, \c false otherwise.
- */
-bool QMetaSequence::canEraseRangeAtIterator() const
-{
- if (auto iface = d())
- return iface->eraseRangeAtIteratorFn;
- return false;
-}
-
-/*!
- Erases the range of values between the iterators \a iterator1 and
- \a iterator2 from the \a container, if possible.
-
- \sa canEraseValueAtIterator(), begin(), end()
- */
-void QMetaSequence::eraseRangeAtIterator(void *container, const void *iterator1,
- const void *iterator2) const
-{
- if (canEraseRangeAtIterator())
- d()->eraseRangeAtIteratorFn(container, iterator1, iterator2);
-}
-
-/*!
Returns \c true if the underlying container offers a const iterator,
\c false otherwise.
@@ -704,7 +285,7 @@ void *QMetaContainer::constBegin(const void *container) const
{
return hasConstIterator()
? d_ptr->createConstIteratorFn(
- container, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin)
+ container, QtMetaContainerPrivate::QMetaContainerInterface::AtBegin)
: nullptr;
}
@@ -721,7 +302,7 @@ void *QMetaContainer::constEnd(const void *container) const
{
return hasConstIterator()
? d_ptr->createConstIteratorFn(
- container, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd)
+ container, QtMetaContainerPrivate::QMetaContainerInterface::AtEnd)
: nullptr;
}
@@ -788,68 +369,4 @@ qsizetype QMetaContainer::diffConstIterator(const void *i, const void *j) const
return hasConstIterator() ? d_ptr->diffConstIteratorFn(i, j) : 0;
}
-/*!
- Returns \c true if the underlying container can retrieve the value pointed
- to by a const iterator, \c false otherwise.
-
- \sa hasConstIterator(), valueAtConstIterator()
- */
-bool QMetaSequence::canGetValueAtConstIterator() const
-{
- if (auto iface = d())
- return iface->valueAtConstIteratorFn;
- return false;
-}
-
-/*!
- Retrieves the value pointed to by the const \a iterator and stores it
- in the memory location pointed to by \a result, if possible.
-
- \sa canGetValueAtConstIterator(), constBegin(), constEnd()
- */
-void QMetaSequence::valueAtConstIterator(const void *iterator, void *result) const
-{
- if (canGetValueAtConstIterator())
- d()->valueAtConstIteratorFn(iterator, result);
-}
-
-/*!
- \fn bool QMetaSequence::operator==(const QMetaSequence &lhs, const QMetaSequence &rhs)
- \since 6.0
-
- Returns \c true if the QMetaSequence \a lhs represents the same container type
- as the QMetaSequence \a rhs, otherwise returns \c false.
-*/
-
-/*!
- \fn bool QMetaSequence::operator!=(const QMetaSequence &lhs, const QMetaSequence &rhs)
- \since 6.0
-
- Returns \c true if the QMetaSequence \a lhs represents a different container
- type than the QMetaSequence \a rhs, otherwise returns \c false.
-*/
-
-
-/*!
- \internal
- Returns the meta type for keys in the container.
- */
-QMetaType QMetaAssociation::keyMetaType() const
-{
- if (auto iface = d())
- return QMetaType(iface->keyMetaType);
- return QMetaType();
-}
-
-/*!
- \internal
- Returns the meta type for mapped values in the container.
- */
-QMetaType QMetaAssociation::mappedMetaType() const
-{
- if (auto iface = d())
- return QMetaType(iface->mappedMetaType);
- return QMetaType();
-}
-
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qmetasequence.cpp b/src/corelib/kernel/qmetasequence.cpp
new file mode 100644
index 00000000000..1d3f3dfd080
--- /dev/null
+++ b/src/corelib/kernel/qmetasequence.cpp
@@ -0,0 +1,471 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qmetacontainer.h"
+#include "qmetatype.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMetaSequence
+ \inmodule QtCore
+ \since 6.0
+ \brief The QMetaSequence class allows type erased access to sequential containers.
+
+ \ingroup objectmodel
+
+ \compares equality
+
+ The class provides a number of primitive container operations, using void*
+ as operands. This way, you can manipulate a generic container retrieved from
+ a Variant without knowing its type.
+
+ The void* arguments to the various methods are typically created by using
+ a \l QVariant of the respective container or value type, and calling
+ its \l QVariant::data() or \l QVariant::constData() methods. However, you
+ can also pass plain pointers to objects of the container or value type.
+
+ Iterator invalidation follows the rules given by the underlying containers
+ and is not expressed in the API. Therefore, for a truly generic container,
+ any iterators should be considered invalid after any write operation.
+*/
+
+/*!
+ \fn template<typename C> QMetaSequence QMetaSequence::fromContainer()
+ \since 6.0
+
+ Returns the QMetaSequence corresponding to the type given as template parameter.
+*/
+
+/*!
+ Returns the meta type for values stored in the container.
+ */
+QMetaType QMetaSequence::valueMetaType() const
+{
+ if (auto iface = d())
+ return QMetaType(iface->valueMetaType);
+ return QMetaType();
+}
+
+/*!
+ Returns \c true if the underlying container is sortable, otherwise returns
+ \c false. A container is considered sortable if values added to it are
+ placed in a defined location. Inserting into or adding to a sortable
+ container will always succeed. Inserting into or adding to an unsortable
+ container may not succeed, for example if the container is a QSet that
+ already contains the value being inserted.
+
+ \sa addValue(), insertValueAtIterator(), canAddValueAtBegin(),
+ canAddValueAtEnd(), canRemoveValueAtBegin(), canRemoveValueAtEnd()
+ */
+bool QMetaSequence::isSortable() const
+{
+ if (auto iface = d()) {
+ return (iface->addRemoveCapabilities
+ & (QtMetaContainerPrivate::CanAddAtBegin | QtMetaContainerPrivate::CanAddAtEnd))
+ && (iface->addRemoveCapabilities
+ & (QtMetaContainerPrivate::CanRemoveAtBegin
+ | QtMetaContainerPrivate::CanRemoveAtEnd));
+ }
+ return false;
+}
+
+/*!
+ Returns \c true if values added using \l addValue() can be placed at the
+ beginning of the container, otherwise returns \c false.
+
+ \sa addValueAtBegin(), canAddValueAtEnd()
+ */
+bool QMetaSequence::canAddValueAtBegin() const
+{
+ if (auto iface = d()) {
+ return iface->addValueFn
+ && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanAddAtBegin;
+ }
+ return false;
+}
+
+/*!
+ Adds \a value to the beginning of \a container if possible. If
+ \l canAddValueAtBegin() returns \c false, the \a value is not added.
+
+ \sa canAddValueAtBegin(), isSortable(), removeValueAtBegin()
+ */
+void QMetaSequence::addValueAtBegin(void *container, const void *value) const
+{
+ if (canAddValueAtBegin())
+ d()->addValueFn(container, value, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin);
+}
+
+/*!
+ Returns \c true if values can be removed from the beginning of the container
+ using \l removeValue(), otherwise returns \c false.
+
+ \sa removeValueAtBegin(), canRemoveValueAtEnd()
+ */
+bool QMetaSequence::canRemoveValueAtBegin() const
+{
+ if (auto iface = d()) {
+ return iface->removeValueFn
+ && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanRemoveAtBegin;
+ }
+ return false;
+}
+
+/*!
+ Removes a value from the beginning of \a container if possible. If
+ \l canRemoveValueAtBegin() returns \c false, the value is not removed.
+
+ \sa canRemoveValueAtBegin(), isSortable(), addValueAtBegin()
+ */
+void QMetaSequence::removeValueAtBegin(void *container) const
+{
+ if (canRemoveValueAtBegin())
+ d()->removeValueFn(container, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin);
+}
+
+/*!
+ Returns \c true if values added using \l addValue() can be placed at the
+ end of the container, otherwise returns \c false.
+
+ \sa addValueAtEnd(), canAddValueAtBegin()
+ */
+bool QMetaSequence::canAddValueAtEnd() const
+{
+ if (auto iface = d()) {
+ return iface->addValueFn
+ && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanAddAtEnd;
+ }
+ return false;
+}
+
+/*!
+ Adds \a value to the end of \a container if possible. If
+ \l canAddValueAtEnd() returns \c false, the \a value is not added.
+
+ \sa canAddValueAtEnd(), isSortable(), removeValueAtEnd()
+ */
+void QMetaSequence::addValueAtEnd(void *container, const void *value) const
+{
+ if (canAddValueAtEnd())
+ d()->addValueFn(container, value, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd);
+}
+
+/*!
+ Returns \c true if values can be removed from the end of the container
+ using \l removeValue(), otherwise returns \c false.
+
+ \sa removeValueAtEnd(), canRemoveValueAtBegin()
+ */
+bool QMetaSequence::canRemoveValueAtEnd() const
+{
+ if (auto iface = d()) {
+ return iface->removeValueFn
+ && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanRemoveAtEnd;
+ }
+ return false;
+}
+
+/*!
+ Removes a value from the end of \a container if possible. If
+ \l canRemoveValueAtEnd() returns \c false, the value is not removed.
+
+ \sa canRemoveValueAtEnd(), isSortable(), addValueAtEnd()
+ */
+void QMetaSequence::removeValueAtEnd(void *container) const
+{
+ if (canRemoveValueAtEnd())
+ d()->removeValueFn(container, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd);
+}
+
+/*!
+ Returns \c true if values can be retrieved from the container by index,
+ otherwise \c false.
+
+ \sa valueAtIndex()
+ */
+bool QMetaSequence::canGetValueAtIndex() const
+{
+ if (auto iface = d())
+ return iface->valueAtIndexFn;
+ return false;
+}
+
+/*!
+ Retrieves the value at \a index in the \a container and places it in the
+ memory location pointed to by \a result, if that is possible.
+
+ \sa canGetValueAtIndex()
+ */
+void QMetaSequence::valueAtIndex(const void *container, qsizetype index, void *result) const
+{
+ if (canGetValueAtIndex())
+ d()->valueAtIndexFn(container, index, result);
+}
+
+/*!
+ Returns \c true if a value can be written to the container by index,
+ otherwise \c false.
+
+ \sa setValueAtIndex()
+*/
+bool QMetaSequence::canSetValueAtIndex() const
+{
+ if (auto iface = d())
+ return iface->setValueAtIndexFn;
+ return false;
+}
+
+/*!
+ Overwrites the value at \a index in the \a container using the \a value
+ passed as parameter if that is possible.
+
+ \sa canSetValueAtIndex()
+ */
+void QMetaSequence::setValueAtIndex(void *container, qsizetype index, const void *value) const
+{
+ if (canSetValueAtIndex())
+ d()->setValueAtIndexFn(container, index, value);
+}
+
+/*!
+ Returns \c true if values can be added to the container, \c false
+ otherwise.
+
+ \sa addValue(), isSortable()
+ */
+bool QMetaSequence::canAddValue() const
+{
+ if (auto iface = d())
+ return iface->addValueFn;
+ return false;
+}
+
+/*!
+ Adds \a value to the \a container if possible. If \l canAddValue()
+ returns \c false, the \a value is not added. Else, if
+ \l canAddValueAtEnd() returns \c true, the \a value is added
+ to the end of the \a container. Else, if
+ \l canAddValueAtBegin() returns \c true, the \a value is added to
+ the beginning of the container. Else, the value is added in an unspecified
+ place or not at all. The latter is the case for adding values to an
+ unordered container, for example \l QSet.
+
+ \sa canAddValue(), canAddValueAtBegin(),
+ canAddValueAtEnd(), isSortable(), removeValue()
+ */
+void QMetaSequence::addValue(void *container, const void *value) const
+{
+ if (canAddValue()) {
+ d()->addValueFn(container, value,
+ QtMetaContainerPrivate::QMetaSequenceInterface::Unspecified);
+ }
+}
+
+/*!
+ Returns \c true if values can be removed from the container, \c false
+ otherwise.
+
+ \sa removeValue(), isSortable()
+ */
+bool QMetaSequence::canRemoveValue() const
+{
+ if (auto iface = d())
+ return iface->removeValueFn;
+ return false;
+}
+
+/*!
+ Removes a value from the \a container if possible. If
+ \l canRemoveValue() returns \c false, no value is removed. Else, if
+ \l canRemoveValueAtEnd() returns \c true, the last value in
+ the \a container is removed. Else, if \l canRemoveValueAtBegin()
+ returns \c true, the first value in the \a container is removed. Else,
+ an unspecified value or nothing is removed.
+
+ \sa canRemoveValue(), canRemoveValueAtBegin(),
+ canRemoveValueAtEnd(), isSortable(), addValue()
+ */
+void QMetaSequence::removeValue(void *container) const
+{
+ if (canRemoveValue()) {
+ d()->removeValueFn(container,
+ QtMetaContainerPrivate::QMetaSequenceInterface::Unspecified);
+ }
+}
+
+
+/*!
+ Returns \c true if the underlying container can retrieve the value pointed
+ to by a non-const iterator, \c false otherwise.
+
+ \sa hasIterator(), valueAtIterator()
+ */
+bool QMetaSequence::canGetValueAtIterator() const
+{
+ if (auto iface = d())
+ return iface->valueAtIteratorFn;
+ return false;
+}
+
+/*!
+ Retrieves the value pointed to by the non-const \a iterator and stores it
+ in the memory location pointed to by \a result, if possible.
+
+ \sa canGetValueAtIterator(), begin(), end()
+ */
+void QMetaSequence::valueAtIterator(const void *iterator, void *result) const
+{
+ if (canGetValueAtIterator())
+ d()->valueAtIteratorFn(iterator, result);
+}
+
+/*!
+ Returns \c true if the underlying container can write to the value pointed
+ to by a non-const iterator, \c false otherwise.
+
+ \sa hasIterator(), setValueAtIterator()
+ */
+bool QMetaSequence::canSetValueAtIterator() const
+{
+ if (auto iface = d())
+ return iface->setValueAtIteratorFn;
+ return false;
+}
+
+/*!
+ Writes \a value to the value pointed to by the non-const \a iterator, if
+ possible.
+
+ \sa canSetValueAtIterator(), begin(), end()
+ */
+void QMetaSequence::setValueAtIterator(const void *iterator, const void *value) const
+{
+ if (canSetValueAtIterator())
+ d()->setValueAtIteratorFn(iterator, value);
+}
+
+/*!
+ Returns \c true if the underlying container can insert a new value, taking
+ the location pointed to by a non-const iterator into account.
+
+ \sa hasIterator(), insertValueAtIterator()
+ */
+bool QMetaSequence::canInsertValueAtIterator() const
+{
+ if (auto iface = d())
+ return iface->insertValueAtIteratorFn;
+ return false;
+}
+
+/*!
+ Inserts \a value into the \a container, if possible, taking the non-const
+ \a iterator into account. If \l canInsertValueAtIterator() returns
+ \c false, the \a value is not inserted. Else if \l isSortable() returns
+ \c true, the value is inserted before the value pointed to by
+ \a iterator. Else, the \a value is inserted at an unspecified place or not
+ at all. In the latter case, the \a iterator is taken as a hint. If it points
+ to the correct place for the \a value, the operation may be faster than a
+ \l addValue() without iterator.
+
+ \sa canInsertValueAtIterator(), isSortable(), begin(), end()
+ */
+void QMetaSequence::insertValueAtIterator(void *container, const void *iterator,
+ const void *value) const
+{
+ if (canInsertValueAtIterator())
+ d()->insertValueAtIteratorFn(container, iterator, value);
+}
+
+/*!
+ Returns \c true if the value pointed to by a non-const iterator can be
+ erased, \c false otherwise.
+
+ \sa hasIterator(), eraseValueAtIterator()
+ */
+bool QMetaSequence::canEraseValueAtIterator() const
+{
+ if (auto iface = d())
+ return iface->eraseValueAtIteratorFn;
+ return false;
+}
+
+/*!
+ Erases the value pointed to by the non-const \a iterator from the
+ \a container, if possible.
+
+ \sa canEraseValueAtIterator(), begin(), end()
+ */
+void QMetaSequence::eraseValueAtIterator(void *container, const void *iterator) const
+{
+ if (canEraseValueAtIterator())
+ d()->eraseValueAtIteratorFn(container, iterator);
+}
+
+/*!
+ Returns \c true if a range between two iterators can be erased from the
+ container, \c false otherwise.
+ */
+bool QMetaSequence::canEraseRangeAtIterator() const
+{
+ if (auto iface = d())
+ return iface->eraseRangeAtIteratorFn;
+ return false;
+}
+
+/*!
+ Erases the range of values between the iterators \a iterator1 and
+ \a iterator2 from the \a container, if possible.
+
+ \sa canEraseValueAtIterator(), begin(), end()
+ */
+void QMetaSequence::eraseRangeAtIterator(void *container, const void *iterator1,
+ const void *iterator2) const
+{
+ if (canEraseRangeAtIterator())
+ d()->eraseRangeAtIteratorFn(container, iterator1, iterator2);
+}
+
+
+/*!
+ Returns \c true if the underlying container can retrieve the value pointed
+ to by a const iterator, \c false otherwise.
+
+ \sa hasConstIterator(), valueAtConstIterator()
+ */
+bool QMetaSequence::canGetValueAtConstIterator() const
+{
+ if (auto iface = d())
+ return iface->valueAtConstIteratorFn;
+ return false;
+}
+
+/*!
+ Retrieves the value pointed to by the const \a iterator and stores it
+ in the memory location pointed to by \a result, if possible.
+
+ \sa canGetValueAtConstIterator(), constBegin(), constEnd()
+ */
+void QMetaSequence::valueAtConstIterator(const void *iterator, void *result) const
+{
+ if (canGetValueAtConstIterator())
+ d()->valueAtConstIteratorFn(iterator, result);
+}
+
+/*!
+ \fn bool QMetaSequence::operator==(const QMetaSequence &lhs, const QMetaSequence &rhs)
+ \since 6.0
+
+ Returns \c true if the QMetaSequence \a lhs represents the same container type
+ as the QMetaSequence \a rhs, otherwise returns \c false.
+*/
+
+/*!
+ \fn bool QMetaSequence::operator!=(const QMetaSequence &lhs, const QMetaSequence &rhs)
+ \since 6.0
+
+ Returns \c true if the QMetaSequence \a lhs represents a different container
+ type than the QMetaSequence \a rhs, otherwise returns \c false.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index fe510898429..560a8c7d789 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -1894,8 +1894,8 @@ int QObject::startTimer(int interval, Qt::TimerType timerType)
A timer event will occur every \a interval until killTimer()
is called. If \a interval is equal to \c{std::chrono::duration::zero()},
- then the timer event occurs once every time there are no more window
- system events to process.
+ then the timer event occurs once every time control returns to the event
+ loop, that is, there are no more native window system events to process.
\include timers-common.qdocinc negative-intervals-not-allowed
diff --git a/src/corelib/kernel/qwinregistry.cpp b/src/corelib/kernel/qwinregistry.cpp
index fb315cacb7e..37bf3f99ae1 100644
--- a/src/corelib/kernel/qwinregistry.cpp
+++ b/src/corelib/kernel/qwinregistry.cpp
@@ -191,7 +191,9 @@ QVariant QWinRegistryKey::value(const QString &subKey) const
// Otherwise, the resulting string (which may be empty) is returned.
QString QWinRegistryKey::stringValue(const wchar_t *subKey) const
{
- return value<QString>(subKey).value_or(QString());
+ if (auto v = value<QString>(subKey))
+ return std::move(*v);
+ return QString();
}
QString QWinRegistryKey::stringValue(const QString &subKey) const
diff --git a/src/corelib/serialization/.gitignore b/src/corelib/serialization/.gitignore
index 89f9ac04aac..8261c031991 100644
--- a/src/corelib/serialization/.gitignore
+++ b/src/corelib/serialization/.gitignore
@@ -1 +1,2 @@
+# Qt-Security score:insignificant reason:gitignore
out/
diff --git a/src/corelib/serialization/make-xml-parser.sh b/src/corelib/serialization/make-xml-parser.sh
index 18898337003..4174949154c 100755
--- a/src/corelib/serialization/make-xml-parser.sh
+++ b/src/corelib/serialization/make-xml-parser.sh
@@ -1,6 +1,7 @@
#!/bin/sh
# Copyright (C) 2016 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+# Qt-Security score:insignificant reason:build-tool-containing-no-compiled-source
me=$(dirname $0)
mkdir -p $me/out
diff --git a/src/corelib/serialization/qcborstream.h b/src/corelib/serialization/qcborstream.h
index 7850d266639..e51296f3cca 100644
--- a/src/corelib/serialization/qcborstream.h
+++ b/src/corelib/serialization/qcborstream.h
@@ -1,6 +1,7 @@
// Copyright (C) 2019 The Qt Company Ltd.
// Copyright (C) 2018 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:header-decls-only
#ifndef QCBORSTREAM_H
#define QCBORSTREAM_H
diff --git a/src/corelib/serialization/qjsonparseerror.h b/src/corelib/serialization/qjsonparseerror.h
index 803b04c53b6..d8fc94448e6 100644
--- a/src/corelib/serialization/qjsonparseerror.h
+++ b/src/corelib/serialization/qjsonparseerror.h
@@ -7,6 +7,7 @@
#include <QtCore/qtconfigmacros.h>
#include <QtCore/qtcoreexports.h>
+#include <QtCore/qtypes.h>
QT_BEGIN_NAMESPACE
@@ -34,7 +35,8 @@ struct Q_CORE_EXPORT QJsonParseError
QString errorString() const;
- int offset = -1;
+ std::conditional_t<QT_VERSION_MAJOR < 7, int, qint64>
+ offset = -1;
ParseError error = NoError;
};
diff --git a/src/corelib/serialization/qjsonparser.cpp b/src/corelib/serialization/qjsonparser.cpp
index df266a76c79..779287adb1d 100644
--- a/src/corelib/serialization/qjsonparser.cpp
+++ b/src/corelib/serialization/qjsonparser.cpp
@@ -321,7 +321,9 @@ QCborValue Parser::parse(QJsonParseError *error)
error:
container.reset();
if (error) {
- error->offset = json - head;
+ using OffType = decltype(error->offset);
+ error->offset = OffType(json - head);
+ Q_ASSERT(error->offset == json - head);
error->error = lastError;
}
return QCborValue();
diff --git a/src/corelib/serialization/qjsonparser_p.h b/src/corelib/serialization/qjsonparser_p.h
index 6b70af38152..8951bb3129b 100644
--- a/src/corelib/serialization/qjsonparser_p.h
+++ b/src/corelib/serialization/qjsonparser_p.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:header-decls-only
#ifndef QJSONPARSER_P_H
#define QJSONPARSER_P_H
diff --git a/src/corelib/serialization/qjsonwriter_p.h b/src/corelib/serialization/qjsonwriter_p.h
index 446ed906e21..10b89f3c106 100644
--- a/src/corelib/serialization/qjsonwriter_p.h
+++ b/src/corelib/serialization/qjsonwriter_p.h
@@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:header-decls-only
#ifndef QJSONWRITER_P_H
#define QJSONWRITER_P_H
diff --git a/src/corelib/text/qcollator.cpp b/src/corelib/text/qcollator.cpp
index 9ead847843b..6609d17adf4 100644
--- a/src/corelib/text/qcollator.cpp
+++ b/src/corelib/text/qcollator.cpp
@@ -1,6 +1,7 @@
// Copyright (C) 2021 The Qt Company Ltd.
// Copyright (C) 2013 Aleix Pol Gonzalez <[email protected]>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:critical reason:data-parser
#include "qcollator_p.h"
#include "qstringlist.h"
diff --git a/src/corelib/text/qcollator.h b/src/corelib/text/qcollator.h
index 870811fc48e..2b1e3963b0d 100644
--- a/src/corelib/text/qcollator.h
+++ b/src/corelib/text/qcollator.h
@@ -1,6 +1,7 @@
// Copyright (C) 2020 The Qt Company Ltd.
// Copyright (C) 2013 Aleix Pol Gonzalez <[email protected]>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:trivial-impl-only
#ifndef QCOLLATOR_H
#define QCOLLATOR_H
diff --git a/src/corelib/text/qcollator_icu.cpp b/src/corelib/text/qcollator_icu.cpp
index 84f9c515374..e13e96285ef 100644
--- a/src/corelib/text/qcollator_icu.cpp
+++ b/src/corelib/text/qcollator_icu.cpp
@@ -1,6 +1,7 @@
// Copyright (C) 2020 The Qt Company Ltd.
// Copyright (C) 2013 Aleix Pol Gonzalez <[email protected]>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:critical reason:data-parser
#include "qcollator_p.h"
#include "qlocale_p.h"
diff --git a/src/corelib/text/qcollator_macx.cpp b/src/corelib/text/qcollator_macx.cpp
index 23c23bd53a2..c0561877dd1 100644
--- a/src/corelib/text/qcollator_macx.cpp
+++ b/src/corelib/text/qcollator_macx.cpp
@@ -1,5 +1,6 @@
// Copyright (C) 2020 Aleix Pol Gonzalez <[email protected]>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:critical reason:data-parser
#include "qcollator_p.h"
#include "qlocale_p.h"
diff --git a/src/corelib/text/qcollator_p.h b/src/corelib/text/qcollator_p.h
index b96cdbaa32a..400cafc0c8a 100644
--- a/src/corelib/text/qcollator_p.h
+++ b/src/corelib/text/qcollator_p.h
@@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2013 Aleix Pol Gonzalez <[email protected]>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:trivial-impl-only
#ifndef QCOLLATOR_P_H
#define QCOLLATOR_P_H
diff --git a/src/corelib/text/qcollator_posix.cpp b/src/corelib/text/qcollator_posix.cpp
index 5ed80c1b8ea..2712133521c 100644
--- a/src/corelib/text/qcollator_posix.cpp
+++ b/src/corelib/text/qcollator_posix.cpp
@@ -1,6 +1,7 @@
// Copyright (C) 2021 The Qt Company Ltd.
// Copyright (C) 2013 Aleix Pol Gonzalez <[email protected]>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:critical reason:data-parser
#include "qcollator_p.h"
#include "qstringlist.h"
diff --git a/src/corelib/text/qcollator_win.cpp b/src/corelib/text/qcollator_win.cpp
index b588f5ff46a..54228b79b31 100644
--- a/src/corelib/text/qcollator_win.cpp
+++ b/src/corelib/text/qcollator_win.cpp
@@ -1,5 +1,6 @@
// Copyright (C) 2020 Aleix Pol Gonzalez <[email protected]>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:critical reason:data-parser
#include "qcollator_p.h"
#include "qlocale_p.h"
diff --git a/src/corelib/text/qlocale.qdoc b/src/corelib/text/qlocale.qdoc
index 3980e9d9a6d..bc88b27477d 100644
--- a/src/corelib/text/qlocale.qdoc
+++ b/src/corelib/text/qlocale.qdoc
@@ -1,5 +1,6 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+// Qt-Security score:insignificant reason:docs
/*!
\class QLocale
diff --git a/src/corelib/text/qtliterals.qdoc b/src/corelib/text/qtliterals.qdoc
index c4671415ee4..8be03a02236 100644
--- a/src/corelib/text/qtliterals.qdoc
+++ b/src/corelib/text/qtliterals.qdoc
@@ -1,5 +1,6 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+// Qt-Security score:insignificant reason:docs
/*!
\namespace QtLiterals
@@ -43,4 +44,8 @@
// in the Qt namespace
using namespace Qt;
\endcode
+
+ The latter is discouraged, because it doesn't allow you to pick which literal
+ operators you want in case Qt adds conflicting operators in different
+ namespaces within Qt::Literals.
*/
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index ccd944a0824..3e08df2b5ac 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -1291,6 +1291,9 @@ bool QThread::event(QEvent *event)
This function does not stop any event loop running on the thread and
does not terminate it in any way.
+ This function has no effect on the main thread, and does nothing if the thread
+ is not currently running.
+
\sa isInterruptionRequested()
*/
diff --git a/src/gui/doc/images/plaintext-layout.png b/src/gui/doc/images/plaintext-layout.png
deleted file mode 100644
index 9172d7a044d..00000000000
--- a/src/gui/doc/images/plaintext-layout.png
+++ /dev/null
Binary files differ
diff --git a/src/gui/doc/images/plaintext-layout.webp b/src/gui/doc/images/plaintext-layout.webp
new file mode 100644
index 00000000000..b8266ec5a8c
--- /dev/null
+++ b/src/gui/doc/images/plaintext-layout.webp
Binary files differ
diff --git a/src/gui/doc/src/qtgui.qdoc b/src/gui/doc/src/qtgui.qdoc
index dca2f10bf26..f5d60699deb 100644
--- a/src/gui/doc/src/qtgui.qdoc
+++ b/src/gui/doc/src/qtgui.qdoc
@@ -17,8 +17,7 @@
/*!
\module QtGuiPrivate
\title Qt GUI Private C++ Classes
- \qtcmakepackage Gui
- \qtcmaketargetitem GuiPrivate
+ \qtcmakepackage GuiPrivate
\qtvariable gui-private
\brief Provides access to private GUI functionality.
@@ -27,7 +26,7 @@
private Qt GUI APIs:
\badcode
- find_package(Qt6 REQUIRED COMPONENTS Gui)
+ find_package(Qt6 REQUIRED COMPONENTS GuiPrivate)
target_link_libraries(mytarget PRIVATE Qt6::GuiPrivate)
\endcode
*/
diff --git a/src/gui/doc/src/richtext.qdoc b/src/gui/doc/src/richtext.qdoc
index 429233ec8f1..2fa49a31e03 100644
--- a/src/gui/doc/src/richtext.qdoc
+++ b/src/gui/doc/src/richtext.qdoc
@@ -650,7 +650,7 @@
the QTextLayout class, to help developers perform word-wrapping and
layout tasks without the need to create a document first.
- \image plaintext-layout.png {Screenshot of a text that flows around a
+ \image plaintext-layout.webp {Screenshot of a text that flows around a
circle.}
Formatting and drawing a paragraph of plain text is straightforward.
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index c7b6e4ebff3..bb71f8fb6fc 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -1298,7 +1298,10 @@ QString QKeySequencePrivate::keyName(Qt::Key key, QKeySequence::SequenceFormat f
bool nativeText = (format == QKeySequence::NativeText);
QString p;
- if (key && key < Qt::Key_Escape && key != Qt::Key_Space) {
+ if (nativeText && (key > 0x00 && key <= 0x1f)) {
+ // Map C0 control codes to the corresponding Control Pictures
+ p = QChar::fromUcs2(0x2400 + key);
+ } else if (key && key < Qt::Key_Escape && key != Qt::Key_Space) {
if (!QChar::requiresSurrogates(key)) {
p = QChar::fromUcs2(key).toUpper();
} else {
diff --git a/src/gui/kernel/qplatformwindow_p.h b/src/gui/kernel/qplatformwindow_p.h
index c446ac760c0..24c0fd7c431 100644
--- a/src/gui/kernel/qplatformwindow_p.h
+++ b/src/gui/kernel/qplatformwindow_p.h
@@ -125,6 +125,14 @@ struct Q_GUI_EXPORT QWaylandWindow : public QObject
public:
QT_DECLARE_NATIVE_INTERFACE(QWaylandWindow, 1, QWindow)
+ enum WindowType {
+ Default,
+ ToolTip,
+ ComboBox,
+ Menu,
+ SubMenu,
+ };
+
virtual wl_surface *surface() const = 0;
virtual void setCustomMargins(const QMargins &margins) = 0;
virtual void requestXdgActivationToken(uint serial) = 0;
@@ -136,6 +144,10 @@ public:
return role ? *role : nullptr;
}
virtual void setSessionRestoreId(const QString &role) = 0;
+
+ virtual void setExtendedWindowType(WindowType windowType) = 0;
+ virtual void setParentControlGeometry(const QRect &parentAnchor) = 0;
+
Q_SIGNALS:
void surfaceCreated();
void surfaceDestroyed();
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 3b64a8ecf73..a3f9f069b69 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -1527,14 +1527,14 @@ void QPainterPrivate::initFrom(const QPaintDevice *device)
Q_Q(QPainter);
device->initPainter(q);
+}
- if (extended) {
- extended->penChanged();
- } else if (engine) {
- engine->setDirty(QPaintEngine::DirtyPen);
- engine->setDirty(QPaintEngine::DirtyBrush);
- engine->setDirty(QPaintEngine::DirtyFont);
- }
+void QPainterPrivate::setEngineDirtyFlags(QSpan<const QPaintEngine::DirtyFlags> flags)
+{
+ if (!engine)
+ return;
+ for (const QPaintEngine::DirtyFlags f : flags)
+ engine->setDirty(f);
}
/*!
@@ -1801,14 +1801,16 @@ bool QPainter::begin(QPaintDevice *pd)
d->engine->setActive(begun);
}
- // Copy painter properties from original paint device,
- // required for QPixmap::grabWidget()
- if (d->original_device->devType() == QInternal::Widget) {
+ switch (d->original_device->devType()) {
+ case QInternal::Widget:
d->initFrom(d->original_device);
- } else {
+ break;
+
+ default:
d->state->layoutDirection = Qt::LayoutDirectionAuto;
// make sure we have a font compatible with the paintdevice
d->state->deviceFont = d->state->font = QFont(d->state->deviceFont, device());
+ break;
}
QRect systemRect = d->engine->systemRect();
@@ -1834,6 +1836,15 @@ bool QPainter::begin(QPaintDevice *pd)
d->state->emulationSpecifier = 0;
+ switch (d->original_device->devType()) {
+ case QInternal::Widget:
+ // for widgets we've aleady initialized the painter above
+ break;
+ default:
+ d->initFrom(d->original_device);
+ break;
+ }
+
return true;
}
diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h
index dd4653a5788..a6f93134ca0 100644
--- a/src/gui/painting/qpainter_p.h
+++ b/src/gui/painting/qpainter_p.h
@@ -15,6 +15,7 @@
// We mean it.
//
+#include <QtCore/qspan.h>
#include <QtCore/qvarlengtharray.h>
#include <QtGui/private/qtguiglobal_p.h>
#include "QtGui/qbrush.h"
@@ -242,6 +243,8 @@ public:
std::unique_ptr<QEmulationPaintEngine> emulationEngine;
QPaintEngineEx *extended = nullptr;
QBrush colorBrush; // for fill with solid color
+
+ Q_GUI_EXPORT void setEngineDirtyFlags(QSpan<const QPaintEngine::DirtyFlags>);
};
Q_GUI_EXPORT void qt_draw_helper(QPainterPrivate *p, const QPainterPath &path, QPainterPrivate::DrawOperation operation);
diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp
index 79799ca2ece..0d435c95048 100644
--- a/src/gui/painting/qstroker.cpp
+++ b/src/gui/painting/qstroker.cpp
@@ -1154,7 +1154,8 @@ void QDashStroker::processCurrentSubpath()
elen -= std::floor(elen * invSumLength) * sumLength;
// Update dash offset.
while (!done) {
- qreal dpos = pos + dashes[idash] - doffset - estart;
+ // parentheses to avoid float rounding issues: qreal(4) + 0.1 - 0.1 - 4 < 0
+ qreal dpos = (pos + dashes[idash]) - (doffset + estart);
Q_ASSERT(dpos >= 0);
@@ -1189,7 +1190,8 @@ void QDashStroker::processCurrentSubpath()
bool has_offset = doffset > 0;
bool evenDash = (idash & 1) == 0;
- qreal dpos = pos + dashes[idash] - doffset - estart;
+ // parentheses to avoid float rounding issues: qreal(4) + 0.1 - 0.1 - 4 < 0
+ qreal dpos = (pos + dashes[idash]) - (doffset + estart);
Q_ASSERT(dpos >= 0);
diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp
index 1b6e76c2017..5797d1a68b4 100644
--- a/src/gui/text/qtextdocumentfragment.cpp
+++ b/src/gui/text/qtextdocumentfragment.cpp
@@ -16,6 +16,7 @@
#include <qbytearray.h>
#include <qdatastream.h>
#include <qdatetime.h>
+#include <QtCore/private/qstringiterator_p.h>
QT_BEGIN_NAMESPACE
@@ -582,8 +583,11 @@ bool QTextHtmlImporter::appendNodeText()
QString textToInsert;
textToInsert.reserve(text.size());
- for (QChar ch : text) {
- if (ch.isSpace()
+ QStringIterator it(text);
+ while (it.hasNext()) {
+ char32_t ch = it.next();
+
+ if (QChar::isSpace(ch)
&& ch != QChar::Nbsp
&& ch != QChar::ParagraphSeparator) {
@@ -646,12 +650,12 @@ bool QTextHtmlImporter::appendNodeText()
format.setAnchor(true);
format.setAnchorNames(namedAnchors);
- cursor.insertText(ch, format);
+ cursor.insertText(QString::fromUcs4(&ch, 1), format);
namedAnchors.clear();
format.clearProperty(QTextFormat::IsAnchor);
format.clearProperty(QTextFormat::AnchorName);
} else {
- textToInsert += ch;
+ textToInsert += QChar::fromUcs4(ch);
}
}
}
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index 53a984306c6..d722bceb289 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -657,8 +657,8 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextTableCellFormat &
\value FontStyleName
\value FontPointSize
\value FontPixelSize
- \value FontSizeAdjustment Specifies the change in size given to the fontsize already set using
- FontPointSize or FontPixelSize.
+ \value FontSizeAdjustment Specifies an integer adjustment added to the base font size set using
+ \c FontPointSize or \c FontPixelSize.
\value FontFixedPitch
\omitvalue FontSizeIncrement
\value FontWeight
diff --git a/src/gui/util/qundostack.cpp b/src/gui/util/qundostack.cpp
index 3d1d8a2b788..27b131cd733 100644
--- a/src/gui/util/qundostack.cpp
+++ b/src/gui/util/qundostack.cpp
@@ -425,16 +425,16 @@ void QUndoStackPrivate::setIndex(int idx, bool clean)
emit q->indexChanged(index);
}
- const ActionState newUndoState{q->canUndo(), q->undoText()};
- if (indexChanged || newUndoState != undoActionState) {
- undoActionState = newUndoState;
+ if (ActionState newUndoState{q->canUndo(), q->undoText()};
+ indexChanged || newUndoState != undoActionState) {
+ undoActionState = std::move(newUndoState);
emit q->canUndoChanged(undoActionState.enabled);
emit q->undoTextChanged(undoActionState.text);
}
- const ActionState newRedoState{q->canRedo(), q->redoText()};
- if (indexChanged || newRedoState != redoActionState) {
- redoActionState = newRedoState;
+ if (ActionState newRedoState{q->canRedo(), q->redoText()};
+ indexChanged || newRedoState != redoActionState) {
+ redoActionState = std::move(newRedoState);
emit q->canRedoChanged(redoActionState.enabled);
emit q->redoTextChanged(redoActionState.text);
}
diff --git a/src/gui/util/qundostack_p.h b/src/gui/util/qundostack_p.h
index fea201ce62d..6bdcf5fb20b 100644
--- a/src/gui/util/qundostack_p.h
+++ b/src/gui/util/qundostack_p.h
@@ -59,10 +59,17 @@ public:
bool enabled = false;
QString text;
- bool operator!=(const ActionState &other) const noexcept
- {
- return enabled != other.enabled || text != other.text;
- }
+ friend bool operator==(const ActionState &lhs, const ActionState &rhs) noexcept
+#ifdef __cpp_impl_three_way_comparison
+ = default;
+#else
+ { return lhs.enabled == rhs.enabled && lhs.text == rhs.text; }
+ friend bool operator!=(const ActionState &lhs, const ActionState &rhs) noexcept
+ { return !(lhs == rhs); }
+#endif
+ // some compiler's reject seed = 0) = delete, overload instead:
+ friend void qHash(const ActionState &key, size_t seed) = delete;
+ friend void qHash(const ActionState &key) = delete;
};
QList<QUndoCommand*> command_list;
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp
index c8555cdc659..f64742ff133 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.cpp
+++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp
@@ -291,7 +291,7 @@ void QAndroidPlatformScreen::topVisibleWindowChanged()
if (w && w->handle()) {
QAndroidPlatformWindow *platformWindow = static_cast<QAndroidPlatformWindow *>(w->handle());
if (platformWindow) {
- platformWindow->updateSystemUiVisibility();
+ platformWindow->updateSystemUiVisibility(w->windowStates(), w->flags());
platformWindow->updateFocusedEditText();
}
}
diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp
index 96c4bfa06f1..c4245998772 100644
--- a/src/plugins/platforms/android/qandroidplatformwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp
@@ -56,15 +56,12 @@ void QAndroidPlatformWindow::initialize()
isForeignWindow(), m_nativeParentQtWindow, listener);
m_nativeViewId = m_nativeQtWindow.callMethod<jint>("getId");
- m_windowFlags = Qt::Widget;
- m_windowState = Qt::WindowNoState;
// the surfaceType is overwritten in QAndroidPlatformOpenGLWindow ctor so let's save
// the fact that it's a raster window for now
m_isRaster = window->surfaceType() == QSurface::RasterSurface;
- setWindowState(window->windowStates());
// the following is in relation to the virtual geometry
- const bool forceMaximize = m_windowState & (Qt::WindowMaximized | Qt::WindowFullScreen);
+ const bool forceMaximize = window->windowStates() & (Qt::WindowMaximized | Qt::WindowFullScreen);
const QRect nativeScreenGeometry = platformScreen()->availableGeometry();
if (forceMaximize) {
setGeometry(nativeScreenGeometry);
@@ -123,7 +120,7 @@ void QAndroidPlatformWindow::raise()
QWindowSystemInterface::handleFocusWindowChanged(window(), Qt::ActiveWindowFocusReason);
return;
}
- updateSystemUiVisibility();
+ updateSystemUiVisibility(window()->windowStates(), window()->flags());
platformScreen()->raise(this);
}
@@ -167,13 +164,13 @@ void QAndroidPlatformWindow::setVisible(bool visible)
if (!visible && window() == qGuiApp->focusWindow()) {
platformScreen()->topVisibleWindowChanged();
} else {
- updateSystemUiVisibility();
- if ((m_windowState & Qt::WindowFullScreen)
- || (window()->flags() & Qt::ExpandedClientAreaHint)) {
+ const Qt::WindowStates states = window()->windowStates();
+ const Qt::WindowFlags flags = window()->flags();
+ updateSystemUiVisibility(states, flags);
+ if (states & Qt::WindowFullScreen || flags & Qt::ExpandedClientAreaHint)
setGeometry(platformScreen()->geometry());
- } else if (m_windowState & Qt::WindowMaximized) {
+ else if (states & Qt::WindowMaximized)
setGeometry(platformScreen()->availableGeometry());
- }
requestActivateWindow();
}
}
@@ -188,27 +185,18 @@ void QAndroidPlatformWindow::setVisible(bool visible)
void QAndroidPlatformWindow::setWindowState(Qt::WindowStates state)
{
- if (m_windowState == state)
- return;
-
QPlatformWindow::setWindowState(state);
- m_windowState = state;
if (window()->isVisible())
- updateSystemUiVisibility();
+ updateSystemUiVisibility(state, window()->flags());
}
void QAndroidPlatformWindow::setWindowFlags(Qt::WindowFlags flags)
{
- if (m_windowFlags == flags)
- return;
+ QPlatformWindow::setWindowFlags(flags);
- m_windowFlags = flags;
-}
-
-Qt::WindowFlags QAndroidPlatformWindow::windowFlags() const
-{
- return m_windowFlags;
+ if (window()->isVisible())
+ updateSystemUiVisibility(window()->windowStates(), flags);
}
void QAndroidPlatformWindow::setParent(const QPlatformWindow *window)
@@ -256,16 +244,15 @@ void QAndroidPlatformWindow::requestActivateWindow()
raise();
}
-void QAndroidPlatformWindow::updateSystemUiVisibility()
+void QAndroidPlatformWindow::updateSystemUiVisibility(Qt::WindowStates states, Qt::WindowFlags flags)
{
- const int flags = window()->flags();
const bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
if (!isNonRegularWindow) {
auto iface = qGuiApp->nativeInterface<QNativeInterface::QAndroidApplication>();
iface->runOnAndroidMainThread([=]() {
using namespace QtJniTypes;
auto activity = iface->context().object<Activity>();
- if (m_windowState & Qt::WindowFullScreen)
+ if (states & Qt::WindowFullScreen)
QtWindowInsetsController::callStaticMethod("showFullScreen", activity);
else if (flags & Qt::ExpandedClientAreaHint)
QtWindowInsetsController::callStaticMethod("showExpanded", activity);
diff --git a/src/plugins/platforms/android/qandroidplatformwindow.h b/src/plugins/platforms/android/qandroidplatformwindow.h
index 07f4e12b35c..826a8d30ade 100644
--- a/src/plugins/platforms/android/qandroidplatformwindow.h
+++ b/src/plugins/platforms/android/qandroidplatformwindow.h
@@ -43,7 +43,6 @@ public:
void setWindowState(Qt::WindowStates state) override;
void setWindowFlags(Qt::WindowFlags flags) override;
- Qt::WindowFlags windowFlags() const;
void setParent(const QPlatformWindow *window) override;
WId winId() const override;
@@ -58,7 +57,7 @@ public:
void propagateSizeHints() override;
void requestActivateWindow() override;
- void updateSystemUiVisibility();
+ void updateSystemUiVisibility(Qt::WindowStates states, Qt::WindowFlags flags);
void updateFocusedEditText();
inline bool isRaster() const { return m_isRaster; }
bool isExposed() const override;
@@ -82,8 +81,6 @@ protected:
bool isEmbeddingContainer() const;
virtual void clearSurface() {}
- Qt::WindowFlags m_windowFlags;
- Qt::WindowStates m_windowState;
bool m_isRaster;
int m_nativeViewId = -1;
diff --git a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h
index 60b9bc8fc02..8fdcf88293e 100644
--- a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h
+++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h
@@ -2,6 +2,9 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:significant reason:default
+#ifndef QIOSIMAGEPICKERCONTROLLER_H
+#define QIOSIMAGEPICKERCONTROLLER_H
+
#import <UIKit/UIKit.h>
#include "../../qiosfiledialog.h"
@@ -9,3 +12,5 @@
@interface QIOSImagePickerController : UIImagePickerController <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
- (instancetype)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog;
@end
+
+#endif // QIOSIMAGEPICKERCONTROLLER_H
diff --git a/src/plugins/platforms/ios/qiosdocumentpickercontroller.h b/src/plugins/platforms/ios/qiosdocumentpickercontroller.h
index 289c3ee3258..a227312c5b0 100644
--- a/src/plugins/platforms/ios/qiosdocumentpickercontroller.h
+++ b/src/plugins/platforms/ios/qiosdocumentpickercontroller.h
@@ -2,6 +2,9 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:significant reason:default
+#ifndef QIOSDOCUMENTPICKERCONTROLLER_H
+#define QIOSDOCUMENTPICKERCONTROLLER_H
+
#import <UIKit/UIKit.h>
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
@@ -12,3 +15,5 @@
UIAdaptivePresentationControllerDelegate>
- (instancetype)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog;
@end
+
+#endif // QIOSDOCUMENTPICKERCONTROLLER_H
diff --git a/src/plugins/platforms/ios/qiosplatformaccessibility.h b/src/plugins/platforms/ios/qiosplatformaccessibility.h
index 04cddf00f4e..1ccc5bd089a 100644
--- a/src/plugins/platforms/ios/qiosplatformaccessibility.h
+++ b/src/plugins/platforms/ios/qiosplatformaccessibility.h
@@ -23,7 +23,7 @@ public:
private:
QMacNotificationObserver m_focusObserver;
- QMacAccessibilityElement *m_focusElement;
+ QT_MANGLE_NAMESPACE(QMacAccessibilityElement) *m_focusElement;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosplatformaccessibility.mm b/src/plugins/platforms/ios/qiosplatformaccessibility.mm
index 26f48468c45..a63c75757e4 100644
--- a/src/plugins/platforms/ios/qiosplatformaccessibility.mm
+++ b/src/plugins/platforms/ios/qiosplatformaccessibility.mm
@@ -12,6 +12,8 @@
#include "qioswindow.h"
#include "quiaccessibilityelement.h"
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QMacAccessibilityElement);
+
QIOSPlatformAccessibility::QIOSPlatformAccessibility()
{
m_focusObserver = QMacNotificationObserver(
diff --git a/src/plugins/platforms/ios/qiostextresponder.h b/src/plugins/platforms/ios/qiostextresponder.h
index addfae3d748..7d73ed9821a 100644
--- a/src/plugins/platforms/ios/qiostextresponder.h
+++ b/src/plugins/platforms/ios/qiostextresponder.h
@@ -2,6 +2,9 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:significant reason:default
+#ifndef QIOSTEXTRESPONDER_H
+#define QIOSTEXTRESPONDER_H
+
#import <UIKit/UIKit.h>
#include <QtCore/qstring.h>
@@ -50,3 +53,5 @@ QT_END_NAMESPACE
@property(nonatomic, assign) id<UITextInputDelegate> inputDelegate;
@end
+
+#endif // QIOSTEXTRESPONDER_H
diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h
index 23a4c506c24..5024013ba77 100644
--- a/src/plugins/platforms/ios/qioswindow.h
+++ b/src/plugins/platforms/ios/qioswindow.h
@@ -10,9 +10,6 @@
#import <UIKit/UIKit.h>
-class QIOSContext;
-class QIOSWindow;
-
@class QUIView;
QT_BEGIN_NAMESPACE
@@ -84,7 +81,7 @@ private:
QDebug operator<<(QDebug debug, const QIOSWindow *window);
#endif
-QT_MANGLE_NAMESPACE(QUIView) *quiview_cast(UIView *view);
+QUIView *quiview_cast(UIView *view);
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/quiview.h b/src/plugins/platforms/ios/quiview.h
index 84726216021..12ae3646ad9 100644
--- a/src/plugins/platforms/ios/quiview.h
+++ b/src/plugins/platforms/ios/quiview.h
@@ -2,6 +2,9 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:significant reason:default
+#ifndef QUIVIEW_H
+#define QUIVIEW_H
+
#import <UIKit/UIKit.h>
#include <qhash.h>
@@ -39,3 +42,5 @@ QT_END_NAMESPACE
@interface QUIMetalView : QUIView
@end
#endif
+
+#endif // QUIVIEW_H
diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
index 8386b65bdce..17422bd606d 100644
--- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
+++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
@@ -697,108 +697,135 @@ void QWaylandXdgSurface::setWindowPosition(const QPoint &position)
window()->updateExposure();
}
+static QtWayland::xdg_positioner::gravity gravityFromEdge(Qt::Edges edges)
+{
+ switch (edges) {
+ case Qt::Edges():
+ return QtWayland::xdg_positioner::gravity_none;
+ case Qt::TopEdge:
+ return QtWayland::xdg_positioner::gravity_top;
+ case Qt::TopEdge | Qt::RightEdge:
+ return QtWayland::xdg_positioner::gravity_top_right;
+ case Qt::RightEdge:
+ return QtWayland::xdg_positioner::gravity_right;
+ case Qt::BottomEdge | Qt::RightEdge:
+ return QtWayland::xdg_positioner::gravity_bottom_right;
+ case Qt::BottomEdge:
+ return QtWayland::xdg_positioner::gravity_bottom;
+ case Qt::BottomEdge | Qt::LeftEdge:
+ return QtWayland::xdg_positioner::gravity_bottom_left;
+ case Qt::LeftEdge:
+ return QtWayland::xdg_positioner::gravity_left;
+ case Qt::TopEdge | Qt::LeftEdge:
+ return QtWayland::xdg_positioner::gravity_top_left;
+ }
+ qCWarning(lcQpaWayland) << "Cannot map positioner gravity " << edges;
+ return QtWayland::xdg_positioner::gravity_none;
+}
+
+static QtWayland::xdg_positioner::anchor anchorFromEdge(Qt::Edges edges)
+{
+ switch (edges) {
+ case Qt::Edges():
+ return QtWayland::xdg_positioner::anchor_none;
+ case Qt::TopEdge:
+ return QtWayland::xdg_positioner::anchor_top;
+ case Qt::TopEdge | Qt::RightEdge:
+ return QtWayland::xdg_positioner::anchor_top_right;
+ case Qt::RightEdge:
+ return QtWayland::xdg_positioner::anchor_right;
+ case Qt::BottomEdge | Qt::RightEdge:
+ return QtWayland::xdg_positioner::anchor_bottom_right;
+ case Qt::BottomEdge:
+ return QtWayland::xdg_positioner::anchor_bottom;
+ case Qt::BottomEdge | Qt::LeftEdge:
+ return QtWayland::xdg_positioner::anchor_bottom_left;
+ case Qt::LeftEdge:
+ return QtWayland::xdg_positioner::anchor_left;
+ case Qt::TopEdge | Qt::LeftEdge:
+ return QtWayland::xdg_positioner::anchor_top_left;
+ }
+ qCWarning(lcQpaWayland) << "Cannot map positioner anchor" << edges;
+ return QtWayland::xdg_positioner::anchor_none;
+}
+
std::unique_ptr<QWaylandXdgSurface::Positioner> QWaylandXdgSurface::createPositioner(QWaylandWindow *parent)
{
std::unique_ptr<Positioner> positioner(new Positioner(m_shell));
- // set_popup expects a position relative to the parent
- QRect windowGeometry = m_window->windowContentGeometry();
- QMargins windowMargins = m_window->windowContentMargins() - m_window->clientSideMargins();
- QMargins parentMargins = parent->windowContentMargins() - parent->clientSideMargins();
- // These property overrides may be removed when public API becomes available
- QRect placementAnchor = m_window->window()->property("_q_waylandPopupAnchorRect").toRect();
- if (!placementAnchor.isValid()) {
- placementAnchor = QRect(m_window->geometry().topLeft() - parent->geometry().topLeft(), QSize(1,1));
- }
- placementAnchor.translate(windowMargins.left(), windowMargins.top());
- placementAnchor.translate(-parentMargins.left(), -parentMargins.top());
+ // Default case, map the guessed global position to a relative position
+ QRect placementAnchor = QRect(m_window->geometry().topLeft() - parent->geometry().topLeft(), QSize(1,1));
+ Qt::Edges anchor = Qt::TopEdge | Qt::RightEdge;
+ Qt::Edges gravity = Qt::BottomEdge | Qt::RightEdge;
+ uint32_t constraintAdjustment = QtWayland::xdg_positioner::constraint_adjustment_slide_x | QtWayland::xdg_positioner::constraint_adjustment_slide_y;
- uint32_t anchor = QtWayland::xdg_positioner::anchor_top_left;
+ // Override from window type
+ if (m_window->parentControlGeometry().isValid())
+ placementAnchor = m_window->parentControlGeometry();
+
+ switch (m_window->extendedWindowType()) {
+ case QNativeInterface::Private::QWaylandWindow::Menu:
+ case QNativeInterface::Private::QWaylandWindow::WindowType::ComboBox:
+ anchor = Qt::BottomEdge | Qt::LeftEdge;
+ gravity = Qt::BottomEdge | Qt::RightEdge;
+ constraintAdjustment = QtWayland::xdg_positioner::constraint_adjustment_slide_x |
+ QtWayland::xdg_positioner::constraint_adjustment_flip_y | QtWayland::xdg_positioner::constraint_adjustment_slide_y;
+ break;
+ case QNativeInterface::Private::QWaylandWindow::SubMenu:
+ anchor = Qt::TopEdge | Qt::RightEdge;
+ gravity = Qt::BottomEdge | Qt::RightEdge;
+ constraintAdjustment = QtWayland::xdg_positioner::constraint_adjustment_flip_x |
+ QtWayland::xdg_positioner::constraint_adjustment_slide_y;
+ break;
+ case QNativeInterface::Private::QWaylandWindow::ToolTip:
+ anchor = Qt::BottomEdge | Qt::RightEdge;
+ gravity = Qt::BottomEdge | Qt::RightEdge;
+ constraintAdjustment = QtWayland::xdg_positioner::constraint_adjustment_flip_x | QtWayland::xdg_positioner::constraint_adjustment_slide_x |
+ QtWayland::xdg_positioner::constraint_adjustment_flip_y | QtWayland::xdg_positioner::constraint_adjustment_slide_y;
+ break;
+ default:
+ break;
+ }
+
+ if (qApp->layoutDirection() == Qt::RightToLeft) {
+ if (anchor & (Qt::RightEdge | Qt::LeftEdge))
+ anchor ^= (Qt::RightEdge | Qt::LeftEdge);
+ if (gravity & (Qt::RightEdge | Qt::LeftEdge))
+ gravity ^= (Qt::RightEdge | Qt::LeftEdge);
+ }
+
+ // Override with properties fauxAPI
+ const QVariant placementAnchorVariant = m_window->window()->property("_q_waylandPopupAnchorRect");
+ if (placementAnchorVariant.isValid())
+ placementAnchor = placementAnchorVariant.toRect();
const QVariant anchorVariant = m_window->window()->property("_q_waylandPopupAnchor");
- if (anchorVariant.isValid()) {
- switch (anchorVariant.value<Qt::Edges>()) {
- case Qt::Edges():
- anchor = QtWayland::xdg_positioner::anchor_none;
- break;
- case Qt::TopEdge:
- anchor = QtWayland::xdg_positioner::anchor_top;
- break;
- case Qt::TopEdge | Qt::RightEdge:
- anchor = QtWayland::xdg_positioner::anchor_top_right;
- break;
- case Qt::RightEdge:
- anchor = QtWayland::xdg_positioner::anchor_right;
- break;
- case Qt::BottomEdge | Qt::RightEdge:
- anchor = QtWayland::xdg_positioner::anchor_bottom_right;
- break;
- case Qt::BottomEdge:
- anchor = QtWayland::xdg_positioner::anchor_bottom;
- break;
- case Qt::BottomEdge | Qt::LeftEdge:
- anchor = QtWayland::xdg_positioner::anchor_bottom_left;
- break;
- case Qt::LeftEdge:
- anchor = QtWayland::xdg_positioner::anchor_left;
- break;
- case Qt::TopEdge | Qt::LeftEdge:
- anchor = QtWayland::xdg_positioner::anchor_top_left;
- break;
- }
- }
-
- uint32_t gravity = QtWayland::xdg_positioner::gravity_bottom_right;
+ if (anchorVariant.isValid())
+ anchor = anchorVariant.value<Qt::Edges>();
const QVariant popupGravityVariant = m_window->window()->property("_q_waylandPopupGravity");
- if (popupGravityVariant.isValid()) {
- switch (popupGravityVariant.value<Qt::Edges>()) {
- case Qt::Edges():
- gravity = QtWayland::xdg_positioner::gravity_none;
- break;
- case Qt::TopEdge:
- gravity = QtWayland::xdg_positioner::gravity_top;
- break;
- case Qt::TopEdge | Qt::RightEdge:
- gravity = QtWayland::xdg_positioner::gravity_top_right;
- break;
- case Qt::RightEdge:
- gravity = QtWayland::xdg_positioner::gravity_right;
- break;
- case Qt::BottomEdge | Qt::RightEdge:
- gravity = QtWayland::xdg_positioner::gravity_bottom_right;
- break;
- case Qt::BottomEdge:
- gravity = QtWayland::xdg_positioner::gravity_bottom;
- break;
- case Qt::BottomEdge | Qt::LeftEdge:
- gravity = QtWayland::xdg_positioner::gravity_bottom_left;
- break;
- case Qt::LeftEdge:
- gravity = QtWayland::xdg_positioner::gravity_left;
- break;
- case Qt::TopEdge | Qt::LeftEdge:
- gravity = QtWayland::xdg_positioner::gravity_top_left;
- break;
- }
- }
-
- uint32_t constraintAdjustment = QtWayland::xdg_positioner::constraint_adjustment_slide_x | QtWayland::xdg_positioner::constraint_adjustment_slide_y;
+ if (popupGravityVariant.isValid())
+ gravity = popupGravityVariant.value<Qt::Edges>();
const QVariant constraintAdjustmentVariant = m_window->window()->property("_q_waylandPopupConstraintAdjustment");
- if (constraintAdjustmentVariant.isValid()) {
+ if (constraintAdjustmentVariant.isValid())
constraintAdjustment = constraintAdjustmentVariant.toUInt();
- }
+
+ // set_popup expects a position relative to the parent
+ QRect windowGeometry = m_window->windowContentGeometry();
+ QMargins windowMargins = m_window->windowContentMargins() - m_window->clientSideMargins();
+ QMargins parentMargins = parent->windowContentMargins() - parent->clientSideMargins();
+ placementAnchor.translate(windowMargins.left(), windowMargins.top());
+ placementAnchor.translate(-parentMargins.left(), -parentMargins.top());
positioner->set_anchor_rect(placementAnchor.x(),
placementAnchor.y(),
placementAnchor.width(),
placementAnchor.height());
- positioner->set_anchor(anchor);
- positioner->set_gravity(gravity);
+ positioner->set_anchor(anchorFromEdge(anchor));
+ positioner->set_gravity(gravityFromEdge(gravity));
positioner->set_size(windowGeometry.width(), windowGeometry.height());
positioner->set_constraint_adjustment(constraintAdjustment);
return positioner;
}
-
void QWaylandXdgSurface::setIcon(const QIcon &icon)
{
if (!m_shell->m_topLevelIconManager || !m_toplevel)
diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp
index 7c300843518..be527b08f4d 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow.cpp
+++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp
@@ -481,8 +481,9 @@ void QWaylandWindow::setGeometry(const QRect &r)
if (mShellSurface && !mInResizeFromApplyConfigure) {
const QRect frameGeometry = r.marginsAdded(clientSideMargins()).marginsRemoved(windowContentMargins());
- if (qt_window_private(window())->positionAutomatic)
+ if (qt_window_private(window())->positionAutomatic || m_popupInfo.parentControlGeometry.isValid())
mShellSurface->setWindowSize(frameGeometry.size());
+
else
mShellSurface->setWindowGeometry(frameGeometry);
}
@@ -1945,6 +1946,27 @@ QString QWaylandWindow::sessionRestoreId() const
return mSessionRestoreId;
}
+void QWaylandWindow::setExtendedWindowType(QNativeInterface::Private::QWaylandWindow::WindowType windowType) {
+ m_popupInfo.extendedWindowType = windowType;
+}
+
+QNativeInterface::Private::QWaylandWindow::WindowType QWaylandWindow::extendedWindowType() const
+{
+ return m_popupInfo.extendedWindowType;
+}
+
+void QWaylandWindow::setParentControlGeometry(const QRect &parentControlGeometry) {
+ m_popupInfo.parentControlGeometry = parentControlGeometry;
+ if (mExposed) {
+ mShellSurface->setWindowPosition(window()->position());
+ }
+}
+
+QRect QWaylandWindow::parentControlGeometry() const
+{
+ return m_popupInfo.parentControlGeometry;
+}
+
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/qwaylandwindow_p.h b/src/plugins/platforms/wayland/qwaylandwindow_p.h
index 854724daf82..d6b24d0569f 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow_p.h
+++ b/src/plugins/platforms/wayland/qwaylandwindow_p.h
@@ -255,6 +255,11 @@ public:
void setSessionRestoreId(const QString &role) override;
QString sessionRestoreId() const;
+ void setExtendedWindowType(QNativeInterface::Private::QWaylandWindow::WindowType) override;
+ QNativeInterface::Private::QWaylandWindow::WindowType extendedWindowType() const;
+ void setParentControlGeometry(const QRect &parentAnchor) override;
+ QRect parentControlGeometry() const;
+
public Q_SLOTS:
void applyConfigure();
@@ -397,6 +402,11 @@ private:
void handleFrameCallback(struct ::wl_callback* callback);
const QPlatformWindow *lastParent = nullptr;
+ struct {
+ QRect parentControlGeometry;
+ QNativeInterface::Private::QWaylandWindow::WindowType extendedWindowType = QNativeInterface::Private::QWaylandWindow::Default;
+ } m_popupInfo;
+
static QWaylandWindow *mMouseGrab;
static QWaylandWindow *mTopPopup;
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 82a86d6ff3a..01716fba60c 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -4019,9 +4019,11 @@ void QWindowsWindow::requestUpdate()
// request or we are waiting for the event loop to process
// the Posted event on the GUI thread.
if (m_vsyncUpdatePending.testAndSetAcquire(UpdateState::Requested, UpdateState::Posted)) {
- QMetaObject::invokeMethod(w, [w] {
+ QWindowsWindow *oldSelf = this;
+ QMetaObject::invokeMethod(w, [w, oldSelf] {
+ // 'oldSelf' is only used for comparison, don't access it directly!
auto *self = static_cast<QWindowsWindow *>(w->handle());
- if (self) {
+ if (self && self == oldSelf) {
// The platform window is still alive
self->m_vsyncUpdatePending.storeRelease(UpdateState::Ready);
self->deliverUpdateRequest();
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index 5ba6f3e1649..0b05a31ca5c 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -5849,6 +5849,9 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
const auto aquaSize = d->effectiveAquaSizeConstrain(opt, widget);
const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Stepper, aquaSize);
NSStepperCell *cell = static_cast<NSStepperCell *>(d->cocoaCell(cw));
+ const auto controlSize = cell.controlSize;
+ if (qt_apple_runningWithLiquidGlass())
+ cell.controlSize = NSControlSizeMini;
cell.enabled = (sb->state & State_Enabled);
const CGRect newRect = [cell drawingRectForBounds:updown.toCGRect()];
@@ -5869,6 +5872,8 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
[cell stopTracking:pressPoint at:pressPoint inView:d->backingStoreNSView mouseIsUp:NO];
d->restoreNSGraphicsContext(cg);
+ if (qt_apple_runningWithLiquidGlass())
+ cell.controlSize = controlSize;
}
}
break;
diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp
index 28b12bd81f9..25142612c4f 100644
--- a/src/plugins/styles/modernwindows/qwindows11style.cpp
+++ b/src/plugins/styles/modernwindows/qwindows11style.cpp
@@ -1331,11 +1331,12 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
}
}
break;
- case QStyle::CE_ProgressBarGroove:{
- if (const QStyleOptionProgressBar* progbaropt = qstyleoption_cast<const QStyleOptionProgressBar*>(option)) {
- QRect rect = subElementRect(SE_ProgressBarContents, progbaropt, widget);
+#if QT_CONFIG(progressbar)
+ case CE_ProgressBarGroove:
+ if (const auto baropt = qstyleoption_cast<const QStyleOptionProgressBar*>(option)) {
+ QRect rect = option->rect;
QPointF center = rect.center();
- if (progbaropt->state & QStyle::State_Horizontal) {
+ if (baropt->state & QStyle::State_Horizontal) {
rect.setHeight(1);
rect.moveTop(center.y());
} else {
@@ -1347,11 +1348,10 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
painter->drawRect(rect);
}
break;
- }
- case QStyle::CE_ProgressBarContents:
+ case CE_ProgressBarContents:
if (const auto baropt = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
QPainterStateGuard psg(painter);
- QRectF rect = subElementRect(SE_ProgressBarContents, baropt, widget);
+ QRectF rect = option->rect;
painter->translate(rect.topLeft());
rect.translate(-rect.topLeft());
@@ -1411,16 +1411,17 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
drawRoundedRect(painter, rect, Qt::NoPen, baropt->palette.accent());
}
break;
- case QStyle::CE_ProgressBarLabel:
- if (const QStyleOptionProgressBar* progbaropt = qstyleoption_cast<const QStyleOptionProgressBar*>(option)) {
- const bool vertical = !(progbaropt->state & QStyle::State_Horizontal);
+ case CE_ProgressBarLabel:
+ if (const auto baropt = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
+ const bool vertical = !(baropt->state & QStyle::State_Horizontal);
if (!vertical) {
- QRect rect = subElementRect(SE_ProgressBarLabel, progbaropt, widget);
- painter->setPen(progbaropt->palette.text().color());
- painter->drawText(rect, progbaropt->text, progbaropt->textAlignment);
+ proxy()->drawItemText(painter, baropt->rect, Qt::AlignCenter | Qt::TextSingleLine,
+ baropt->palette, baropt->state & State_Enabled, baropt->text,
+ QPalette::Text);
}
}
break;
+#endif // QT_CONFIG(progressbar)
case CE_PushButtonLabel:
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
QRect textRect = btn->rect;
@@ -1914,15 +1915,18 @@ QRect QWindows11Style::subElementRect(QStyle::SubElement element, const QStyleOp
ret = QWindowsVistaStyle::subElementRect(element, option, widget);
}
break;
- case QStyle::SE_ProgressBarLabel:
- if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
- if (pb->textAlignment.testFlags(Qt::AlignVCenter)) {
- ret = option->rect.adjusted(0, 6, 0, 0);
- } else {
- ret = QWindowsVistaStyle::subElementRect(element, option, widget);
- }
+#if QT_CONFIG(progressbar)
+ case SE_ProgressBarGroove:
+ case SE_ProgressBarContents:
+ case SE_ProgressBarLabel:
+ if (const auto *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
+ QStyleOptionProgressBar optCopy(*pb);
+ // we only support label right from content
+ optCopy.textAlignment = Qt::AlignRight;
+ return QWindowsVistaStyle::subElementRect(element, &optCopy, widget);
}
break;
+#endif // QT_CONFIG(progressbar)
case QStyle::SE_HeaderLabel:
case QStyle::SE_HeaderArrow:
ret = QCommonStyle::subElementRect(element, option, widget);
diff --git a/src/plugins/tls/schannel/qtls_schannel.cpp b/src/plugins/tls/schannel/qtls_schannel.cpp
index 12c2625f39d..667f2d8a6c3 100644
--- a/src/plugins/tls/schannel/qtls_schannel.cpp
+++ b/src/plugins/tls/schannel/qtls_schannel.cpp
@@ -1238,9 +1238,10 @@ bool TlsCryptographSchannel::createContext()
};
#endif
+ const QString encodedTargetName = QUrl::fromUserInput(targetName()).host(QUrl::EncodeUnicode);
auto status = InitializeSecurityContext(&credentialHandle, // phCredential
nullptr, // phContext
- const_reinterpret_cast<SEC_WCHAR *>(targetName().utf16()), // pszTargetName
+ const_reinterpret_cast<SEC_WCHAR *>(encodedTargetName.utf16()), // pszTargetName
contextReq, // fContextReq
0, // Reserved1
0, // TargetDataRep (unused)
diff --git a/src/tools/androidtestrunner/main.cpp b/src/tools/androidtestrunner/main.cpp
index 0e04d10e692..b517d85c5fb 100644
--- a/src/tools/androidtestrunner/main.cpp
+++ b/src/tools/androidtestrunner/main.cpp
@@ -328,6 +328,53 @@ static bool processAndroidManifest()
return true;
}
+static QStringList queryDangerousPermissions()
+{
+ QByteArray output;
+ const QStringList args({ "shell"_L1, "dumpsys"_L1, "package"_L1, "permissions"_L1 });
+ if (!execAdbCommand(args, &output, false)) {
+ qWarning("Failed to query permissions via dumpsys");
+ return {};
+ }
+
+ /*
+ * Permissions section from this command look like:
+ *
+ * Permission [android.permission.INTERNET] (c8cafdc):
+ * sourcePackage=android
+ * uid=1000 gids=[3003] type=0 prot=normal|instant
+ * perm=PermissionInfo{5f5bfbb android.permission.INTERNET}
+ * flags=0x0
+ */
+ const static QRegularExpression regex("^\\s*Permission\\s+\\[([^\\]]+)\\]\\s+\\(([^)]+)\\):"_L1);
+ QStringList dangerousPermissions;
+ QString currentPerm;
+
+ const QStringList lines = QString::fromUtf8(output).split(u'\n');
+ for (const QString &line : lines) {
+ QRegularExpressionMatch match = regex.match(line);
+ if (match.hasMatch()) {
+ currentPerm = match.captured(1);
+ continue;
+ }
+
+ if (currentPerm.isEmpty())
+ continue;
+
+ int protIndex = line.indexOf("prot="_L1);
+ if (protIndex == -1)
+ continue;
+
+ QString protectionTypes = line.mid(protIndex + 5).trimmed();
+ if (protectionTypes.contains("dangerous"_L1, Qt::CaseInsensitive)) {
+ dangerousPermissions.append(currentPerm);
+ currentPerm.clear();
+ }
+ }
+
+ return dangerousPermissions;
+}
+
static void setOutputFile(QString file, QString format)
{
if (format.isEmpty())
@@ -938,7 +985,11 @@ int main(int argc, char *argv[])
return EXIT_ERROR;
}
+ const QStringList dangerousPermisisons = queryDangerousPermissions();
for (const auto &permission : g_options.permissions) {
+ if (!dangerousPermisisons.contains(permission))
+ continue;
+
if (!execAdbCommand({ "shell"_L1, "pm"_L1, "grant"_L1, g_options.package, permission },
nullptr)) {
qWarning("Unable to grant '%s' to '%s'. Probably the Android version mismatch.",
diff --git a/src/widgets/doc/src/qtwidgets-examples.qdoc b/src/widgets/doc/src/qtwidgets-examples.qdoc
index 45677c471ba..364c985b310 100644
--- a/src/widgets/doc/src/qtwidgets-examples.qdoc
+++ b/src/widgets/doc/src/qtwidgets-examples.qdoc
@@ -164,3 +164,15 @@
regular expressions for the Widget-based applications.
*/
+/*!
+ \group examples-user-input
+ \ingroup all-examples
+ \title User Input Examples
+ \brief Using user input in Qt Widgets applications.
+
+ \image imagegestures-example.png {Application handling touch gestures}
+
+ Qt provides the functionality for handling user input and drag-and-drop in
+ widget-based applications.
+
+*/
diff --git a/src/widgets/doc/src/qtwidgets-toc.qdoc b/src/widgets/doc/src/qtwidgets-toc.qdoc
index bc447b8bd58..beddf853a22 100644
--- a/src/widgets/doc/src/qtwidgets-toc.qdoc
+++ b/src/widgets/doc/src/qtwidgets-toc.qdoc
@@ -53,6 +53,7 @@
\li \l{Rich Text Examples}
\li \l{Graphics View Examples}
\li \l{Widget Tools Examples}
+ \li \l{User Input Examples}
\endlist
\endlist
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index e4159ad2cf0..51aea4079a1 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -3298,7 +3298,8 @@ void QAbstractItemView::closePersistentEditor(const QModelIndex &index)
bool QAbstractItemView::isPersistentEditorOpen(const QModelIndex &index) const
{
Q_D(const QAbstractItemView);
- return d->editorForIndex(index).widget;
+ QWidget *editor = d->editorForIndex(index).widget;
+ return editor && d->persistent.contains(editor);
}
/*!
diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp
index 9e6aaf4b95f..d989feb7f91 100644
--- a/src/widgets/kernel/qtooltip.cpp
+++ b/src/widgets/kernel/qtooltip.cpp
@@ -20,6 +20,8 @@
#if QT_CONFIG(style_stylesheet)
#include <private/qstylesheetstyle_p.h>
#endif
+#include <qpa/qplatformwindow.h>
+#include <qpa/qplatformwindow_p.h>
#include <qlabel.h>
#include <QtWidgets/private/qlabel_p.h>
@@ -386,6 +388,17 @@ void QTipLabel::placeTip(const QPoint &pos, QWidget *w)
p += offset;
+#if QT_CONFIG(wayland)
+ create();
+ if (auto waylandWindow = dynamic_cast<QNativeInterface::Private::QWaylandWindow*>(windowHandle()->handle())) {
+ // based on the existing code below, by default position at 'p' stored at the bottom right of our rect
+ // then flip to the other arbitrary 4x24 space if constrained
+ const QRect controlGeometry(QRect(p.x() - 4, p.y() - 24, 4, 24));
+ waylandWindow->setParentControlGeometry(controlGeometry);
+ waylandWindow->setExtendedWindowType(QNativeInterface::Private::QWaylandWindow::ToolTip);
+ }
+#endif
+
QRect screenRect = screen->geometry();
if (p.x() + this->width() > screenRect.x() + screenRect.width())
p.rx() -= 4 + this->width();
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 36446c3e5c4..9499c88af12 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -13144,11 +13144,22 @@ int QWidget::metric(PaintDeviceMetric m) const
void QWidget::initPainter(QPainter *painter) const
{
const QPalette &pal = palette();
- painter->d_func()->state->pen = QPen(pal.brush(foregroundRole()), 1);
- painter->d_func()->state->bgBrush = pal.brush(backgroundRole());
+ QPainterPrivate *painterPrivate = QPainterPrivate::get(painter);
+
+ painterPrivate->state->pen = QPen(pal.brush(foregroundRole()), 1);
+ painterPrivate->state->bgBrush = pal.brush(backgroundRole());
QFont f(font(), this);
- painter->d_func()->state->deviceFont = f;
- painter->d_func()->state->font = f;
+ painterPrivate->state->deviceFont = f;
+ painterPrivate->state->font = f;
+
+ painterPrivate->setEngineDirtyFlags({
+ QPaintEngine::DirtyPen,
+ QPaintEngine::DirtyBrush,
+ QPaintEngine::DirtyFont,
+ });
+
+ if (painterPrivate->extended)
+ painterPrivate->extended->penChanged();
}
/*!
diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp
index 220f600ea41..735b574d293 100644
--- a/src/widgets/util/qcompleter.cpp
+++ b/src/widgets/util/qcompleter.cpp
@@ -122,6 +122,8 @@
#include "QtGui/qevent.h"
#include <private/qapplication_p.h>
#include <private/qwidget_p.h>
+#include <qpa/qplatformwindow.h>
+#include <qpa/qplatformwindow_p.h>
#if QT_CONFIG(lineedit)
#include "QtWidgets/qlineedit.h"
#endif
@@ -925,10 +927,15 @@ void QCompleterPrivate::showPopup(const QRect& rect)
popup->setGeometry(pos.x(), pos.y(), w, h);
if (!popup->isVisible()) {
- // Make sure popup has a transient parent set, Wayland needs it. QTBUG-130474
- popup->winId(); // force creation of windowHandle
- popup->windowHandle()->setTransientParent(widget->window()->windowHandle());
-
+#if QT_CONFIG(wayland)
+ popup->createWinId();
+ if (auto waylandWindow = dynamic_cast<QNativeInterface::Private::QWaylandWindow*>(popup->windowHandle()->handle())) {
+ popup->windowHandle()->setTransientParent(widget->window()->windowHandle());
+ const QRect controlGeometry = QRect(widget->mapTo(widget->topLevelWidget(), QPoint(0,0)), widget->size());
+ waylandWindow->setParentControlGeometry(controlGeometry);
+ waylandWindow->setExtendedWindowType(QNativeInterface::Private::QWaylandWindow::ComboBox);
+ }
+#endif
popup->show();
}
}
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index 6f25b8bde67..2f51b83a49d 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -7,6 +7,9 @@
#include <qstylepainter.h>
#include <qpa/qplatformtheme.h>
#include <qpa/qplatformmenu.h>
+#include <qpa/qplatformwindow.h>
+#include <qpa/qplatformwindow_p.h>
+
#include <qlineedit.h>
#include <qapplication.h>
#include <qlistview.h>
@@ -2868,6 +2871,17 @@ void QComboBox::showPopup()
container->hide();
}
}
+
+#if QT_CONFIG(wayland)
+ if (auto waylandWindow = dynamic_cast<QNativeInterface::Private::QWaylandWindow*>(container->windowHandle()->handle())) {
+ const QRect popup(style->subControlRect(QStyle::CC_ComboBox, &opt,
+ QStyle::SC_ComboBoxListBoxPopup, this));
+ const QRect controlGeometry = QRect(mapTo(window(), popup.topLeft()), popup.size());
+ waylandWindow->setParentControlGeometry(controlGeometry);
+ waylandWindow->setExtendedWindowType(QNativeInterface::Private::QWaylandWindow::ComboBox);
+ }
+#endif
+
container->show();
if (!neededHorizontalScrollBar && needHorizontalScrollBar()) {
listRect.adjust(0, 0, 0, sb->height());
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 5cda8f33f4c..3177ed5c2d4 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -40,6 +40,8 @@
#include <private/qaction_p.h>
#include <private/qguiapplication_p.h>
#include <qpa/qplatformtheme.h>
+#include <qpa/qplatformwindow.h>
+#include <qpa/qplatformwindow_p.h>
#include <private/qstyle_p.h>
QT_BEGIN_NAMESPACE
@@ -2535,6 +2537,23 @@ void QMenuPrivate::popup(const QPoint &p, QAction *atAction, PositionFunction po
}
popupScreen = QGuiApplication::screenAt(pos);
q->setGeometry(QRect(pos, size));
+
+#if QT_CONFIG(wayland)
+ q->create();
+ if (auto waylandWindow = dynamic_cast<QNativeInterface::Private::QWaylandWindow*>(q->windowHandle()->handle())) {
+ if (causedButton) {
+ waylandWindow->setExtendedWindowType(QNativeInterface::Private::QWaylandWindow::Menu);
+ waylandWindow->setParentControlGeometry(causedButton->geometry());
+ } else if (caused) {
+ waylandWindow->setExtendedWindowType(QNativeInterface::Private::QWaylandWindow::SubMenu);
+ waylandWindow->setParentControlGeometry(caused->d_func()->actionRect(caused->d_func()->currentAction));
+ } else if (auto menubar = qobject_cast<QMenuBar*>(causedPopup.widget)) {
+ waylandWindow->setExtendedWindowType(QNativeInterface::Private::QWaylandWindow::Menu);
+ waylandWindow->setParentControlGeometry(menubar->actionGeometry(causedPopup.action));
+ }
+ }
+#endif
+
#if QT_CONFIG(effects)
int hGuess = q->isRightToLeft() ? QEffects::LeftScroll : QEffects::RightScroll;
int vGuess = QEffects::DownScroll;
@@ -2952,7 +2971,7 @@ void QMenu::mouseReleaseEvent(QMouseEvent *e)
#endif
d->activateAction(action, QAction::Trigger);
}
- } else if (!action || action->isEnabled()) {
+ } else if ((!action || action->isEnabled()) && !action->isSeparator()) {
d->hideUpToMenuBar();
}
}
diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
index b9e239af31d..fde06d2edd9 100644
--- a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
+++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
@@ -2411,7 +2411,7 @@ void tst_QDateTime::springForward_data()
QTest::newRow("PT from day after")
<< pacific << QDate(2015, 3, 8) << QTime(2, 30) << -1 << -420;
}
- if (const QTimeZone eastern("America/Ottawa"); eastern.isValid()) {
+ if (const QTimeZone eastern("America/Toronto"); eastern.isValid()) {
QTest::newRow("ET from day before")
<< eastern << QDate(2015, 3, 8) << QTime(2, 30) << 1 << -300;
QTest::newRow("ET from day after")
@@ -3500,11 +3500,11 @@ void tst_QDateTime::fromStringStringFormat_localTimeZone_data()
QTest::newRow("local-timezone-ttt-with-zone:Etc/GMT+3")
<< "GMT"_ba << u"2008-10-13 Etc/GMT+3 11.50"_s << u"yyyy-MM-dd ttt hh.mm"_s << 1900
<< QDateTime(); // Zone name not valid when offset expected
- QTimeZone gmtWithOffset("GMT-2");
+ QTimeZone gmtWithOffset("GMT-0");
if (gmtWithOffset.isValid()) {
lacksRows = false;
- QTest::newRow("local-timezone-with-offset:GMT-2")
- << "GMT"_ba << u"2008-10-13 GMT-2 11.50"_s << u"yyyy-MM-dd t hh.mm"_s << 1900
+ QTest::newRow("local-timezone-with-offset:GMT-0")
+ << "GMT"_ba << u"2008-10-13 GMT-0 11.50"_s << u"yyyy-MM-dd t hh.mm"_s << 1900
<< QDateTime(QDate(2008, 10, 13), QTime(11, 50), gmtWithOffset);
}
QTimeZone gmt("GMT");
diff --git a/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
index 3b66ad76a2f..6a72b5ddf38 100644
--- a/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
+++ b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
@@ -1887,12 +1887,14 @@ void tst_QTimeZone::roundtripDisplayNames_data()
"UTC"_ba,
// Those named overtly in tst_QDateTime - special cases first:
"UTC-02:00"_ba, "UTC+02:00"_ba, "UTC+12:00"_ba,
- "Etc/GMT+3"_ba, "GMT-2"_ba, "GMT"_ba,
+ "Etc/GMT+3"_ba, "GMT-0"_ba, "GMT"_ba,
// ... then ordinary names in alphabetic order:
- "America/New_York"_ba, "America/Sao_Paulo"_ba, "America/Vancouver"_ba,
- "Asia/Kathmandu"_ba, "Asia/Singapore"_ba,
+ "America/Anchorage"_ba, "America/Metlakatla"_ba, "America/New_York"_ba,
+ "America/Sao_Paulo"_ba, "America/Toronto"_ba, "America/Vancouver"_ba,
+ "Asia/Kathmandu"_ba, "Asia/Manila"_ba, "Asia/Singapore"_ba,
"Australia/Brisbane"_ba, "Australia/Eucla"_ba, "Australia/Sydney"_ba,
- "Europe/Berlin"_ba, "Europe/Helsinki"_ba, "Europe/Rome"_ba, "Europe/Oslo"_ba,
+ "Europe/Berlin"_ba, "Europe/Helsinki"_ba, "Europe/Lisbon"_ba, "Europe/Oslo"_ba,
+ "Europe/Rome"_ba,
"Pacific/Apia"_ba, "Pacific/Auckland"_ba, "Pacific/Kiritimati"_ba,
"Vulcan/ShiKahr"_ba // Invalid: also worth testing.
};
diff --git a/tests/auto/gui/kernel/qsurfaceformat/tst_qsurfaceformat.cpp b/tests/auto/gui/kernel/qsurfaceformat/tst_qsurfaceformat.cpp
index 3f655bd905d..28085e1405f 100644
--- a/tests/auto/gui/kernel/qsurfaceformat/tst_qsurfaceformat.cpp
+++ b/tests/auto/gui/kernel/qsurfaceformat/tst_qsurfaceformat.cpp
@@ -54,10 +54,10 @@ void tst_QSurfaceFormat::versionCheck()
format.setMinorVersion(formatMinor);
format.setMajorVersion(formatMajor);
- QCOMPARE(format.version() >= qMakePair(compareMajor, compareMinor), expected);
+ QCOMPARE(format.version() >= std::pair(compareMajor, compareMinor), expected);
format.setVersion(formatMajor, formatMinor);
- QCOMPARE(format.version() >= qMakePair(compareMajor, compareMinor), expected);
+ QCOMPARE(format.version() >= std::pair(compareMajor, compareMinor), expected);
}
#include <tst_qsurfaceformat.moc>
diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
index 64add80907a..7dac778d5ff 100644
--- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
+++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
@@ -292,6 +292,8 @@ private slots:
void alphaBlitToNonAlphaFormats_data();
void alphaBlitToNonAlphaFormats();
+ void floatRounding();
+
private:
void fillData();
void setPenColor(QPainter& p);
@@ -3843,26 +3845,23 @@ void tst_QPainter::linearGradientSymmetry_data()
QTest::addColumn<QGradientStops>("stops");
if (sizeof(qreal) != sizeof(float)) {
- QGradientStops stops;
- stops << qMakePair(qreal(0.0), QColor(Qt::blue));
- stops << qMakePair(qreal(0.2), QColor(220, 220, 220, 0));
- stops << qMakePair(qreal(0.6), QColor(Qt::red));
- stops << qMakePair(qreal(0.9), QColor(220, 220, 220, 255));
- stops << qMakePair(qreal(1.0), QColor(Qt::black));
+ QGradientStops stops = {{qreal(0.0), QColor(Qt::blue)},
+ {qreal(0.2), QColor(220, 220, 220, 0)},
+ {qreal(0.6), QColor(Qt::red)},
+ {qreal(0.9), QColor(220, 220, 220, 255)},
+ {qreal(1.0), QColor(Qt::black)}};
QTest::newRow("multiple stops") << stops;
}
{
- QGradientStops stops;
- stops << qMakePair(qreal(0.0), QColor(Qt::blue));
- stops << qMakePair(qreal(1.0), QColor(Qt::black));
+ QGradientStops stops = {{qreal(0.0), QColor(Qt::blue)},
+ {qreal(1.0), QColor(Qt::black)}};
QTest::newRow("two stops") << stops;
}
if (sizeof(qreal) != sizeof(float)) {
- QGradientStops stops;
- stops << qMakePair(qreal(0.3), QColor(Qt::blue));
- stops << qMakePair(qreal(0.6), QColor(Qt::black));
+ QGradientStops stops = {{qreal(0.3), QColor(Qt::blue)},
+ {qreal(0.6), QColor(Qt::black)}};
QTest::newRow("two stops 2") << stops;
}
}
@@ -3913,12 +3912,10 @@ void tst_QPainter::gradientPixelFormat()
QImage a(8, 64, QImage::Format_ARGB32_Premultiplied);
QImage b(8, 64, format);
-
- QGradientStops stops;
- stops << qMakePair(qreal(0.0), QColor(Qt::blue));
- stops << qMakePair(qreal(0.3), QColor(Qt::red));
- stops << qMakePair(qreal(0.6), QColor(Qt::green));
- stops << qMakePair(qreal(1.0), QColor(Qt::black));
+ QGradientStops stops = {{qreal(0.0), QColor(Qt::blue)},
+ {qreal(0.3), QColor(Qt::red)},
+ {qreal(0.6), QColor(Qt::green)},
+ {qreal(1.0), QColor(Qt::black)}};
a.fill(0);
b.fill(0);
@@ -5751,6 +5748,30 @@ void tst_QPainter::alphaBlitToNonAlphaFormats()
}
}
+void tst_QPainter::floatRounding()
+{
+ // oss-fuzz issue 429123947
+ // The following triggered an assert in QDashStroker::processCurrentSubpath(): "dpos >= 0"
+ // when it expected the calculation's result to be zero but it was actually smaller:
+ // qreal(4) + qreal(0.1) - qreal(0.1) - qreal(4)
+ // actual result: -4.440892098500626e-16
+ QImage img(5, 5, QImage::Format_RGB888);
+ QPainter p(&img);
+
+ QList<qreal> pattern {0.1, 0.3, 0.1, 0.1, 0.3, 0.1};
+ QPainterPathStroker stroker;
+ stroker.setDashPattern(pattern);
+
+ QPainterPath pp;
+ pp.moveTo(4.0, 0.0);
+ pp.lineTo(0.1, 0.0);
+ pp.lineTo(0.0, 0.0);
+ pp.lineTo(0.0, 5.0);
+
+ QPolygonF poly = stroker.createStroke(pp).toFillPolygon();
+ p.drawPolygon(poly);
+}
+
QTEST_MAIN(tst_QPainter)
#include "tst_qpainter.moc"
diff --git a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp
index ab0e8693644..511007e0ae4 100644
--- a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp
+++ b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp
@@ -3525,7 +3525,7 @@ void tst_QRhi::renderToTextureMultipleUniformBuffersAndDynamicOffset()
// "see" an all zero matrix and zero opacity, thus leading to different
// rendering output. This way we can verify if using dynamic offsets, and
// more than one at the same time, is functional.
- QVarLengthArray<QPair<int, quint32>, 2> dynamicOffset = {
+ QVarLengthArray<std::pair<int, quint32>, 2> dynamicOffset = {
{ 0, quint32(ubufElemSize * 2) },
{ 1, quint32(ubuf2ElemSize * 3) },
};
diff --git a/tests/auto/gui/rhi/qshader/tst_qshader.cpp b/tests/auto/gui/rhi/qshader/tst_qshader.cpp
index 9e179c95c35..371da0d800c 100644
--- a/tests/auto/gui/rhi/qshader/tst_qshader.cpp
+++ b/tests/auto/gui/rhi/qshader/tst_qshader.cpp
@@ -279,7 +279,7 @@ void tst_QShader::mslResourceMapping()
QCOMPARE(resMap.size(), 2);
QCOMPARE(resMap.value(0).first, 0); // mapped to native buffer index 0
- QCOMPARE(resMap.value(1), qMakePair(0, 0)); // mapped to native texture index 0 and sampler index 0
+ QCOMPARE(resMap.value(1), std::pair(0, 0)); // mapped to native texture index 0 and sampler index 0
}
void tst_QShader::serializeShaderDesc()
@@ -667,7 +667,8 @@ void tst_QShader::loadV7()
QCOMPARE(tese.description().inputBuiltinVariables()[3].type, QShaderDescription::TessCoordBuiltin);
QCOMPARE(tese.nativeResourceBindingMap(QShaderKey(QShader::MslShader, QShaderVersion(12))).size(), 1);
- QCOMPARE(tese.nativeResourceBindingMap(QShaderKey(QShader::MslShader, QShaderVersion(12))).value(0), qMakePair(0, -1));
+ QCOMPARE(tese.nativeResourceBindingMap(QShaderKey(QShader::MslShader, QShaderVersion(12))).value(0),
+ std::pair(0, -1));
QShader frag = getShader(QLatin1String(":/data/metal_enabled_tessellation_v7.frag.qsb"));
QVERIFY(frag.isValid());
diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
index fa1d70a942b..fdc2dde7921 100644
--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -781,7 +781,7 @@ private:
void parseContentLength()
{
- int index = receivedData.indexOf("content-length:");
+ int index = receivedData.toLower().indexOf("content-length:");
if (index == -1)
return;
@@ -3620,7 +3620,7 @@ void tst_QNetworkReply::connectToIPv6Address()
QByteArray content = reply->readAll();
//qDebug() << server.receivedData;
QByteArray hostinfo = "\r\nhost: " + hostfield + ':' + QByteArray::number(server.serverPort()) + "\r\n";
- QVERIFY(server.receivedData.contains(hostinfo));
+ QVERIFY(server.receivedData.toLower().contains(hostinfo));
QCOMPARE(content, dataToSend);
QCOMPARE(reply->url(), request.url());
QCOMPARE(reply->error(), error);
@@ -8793,7 +8793,11 @@ void tst_QNetworkReply::httpUserAgent()
QVERIFY(reply->isFinished());
QCOMPARE(reply->error(), QNetworkReply::NoError);
- QVERIFY(server.receivedData.contains("\r\nuser-agent: abcDEFghi\r\n"));
+ const char userAgentSearch[] = "\r\nuser-agent: ";
+ qsizetype userAgentIndex = server.receivedData.toLower().indexOf(userAgentSearch);
+ QCOMPARE_NE(userAgentIndex, -1);
+ userAgentIndex += sizeof(userAgentSearch) - 1;
+ QVERIFY(server.receivedData.slice(userAgentIndex).startsWith("abcDEFghi\r\n"));
}
void tst_QNetworkReply::synchronousAuthenticationCache()
@@ -8813,7 +8817,7 @@ void tst_QNetworkReply::synchronousAuthenticationCache()
"content-type: text/plain\r\n"
"\r\n"
"auth";
- QRegularExpression rx("authorization: Basic ([^\r\n]*)\r\n");
+ QRegularExpression rx("[Aa]uthorization: Basic ([^\r\n]*)\r\n");
QRegularExpressionMatch match = rx.match(receivedData);
if (match.hasMatch()) {
if (QByteArray::fromBase64(match.captured(1).toLatin1()) == "login:password") {
@@ -9526,7 +9530,7 @@ void tst_QNetworkReply::ioHttpCookiesDuringRedirect()
manager.setRedirectPolicy(oldRedirectPolicy);
QVERIFY(waitForFinish(reply) == Success);
- QVERIFY(target.receivedData.contains("\r\ncookie: hello=world\r\n"));
+ QVERIFY(target.receivedData.toLower().contains("\r\ncookie: hello=world\r\n"));
QVERIFY(validateRedirectedResponseHeaders(reply));
}
@@ -10439,7 +10443,7 @@ void tst_QNetworkReply::contentEncoding()
{
// Check that we included the content encoding method in our Accept-Encoding header
const QByteArray &receivedData = server.receivedData;
- int start = receivedData.indexOf("accept-encoding");
+ int start = receivedData.toLower().indexOf("accept-encoding");
QVERIFY(start != -1);
int end = receivedData.indexOf("\r\n", start);
QVERIFY(end != -1);
diff --git a/tests/auto/network/access/qnetworkreply_local/minihttpserver.h b/tests/auto/network/access/qnetworkreply_local/minihttpserver.h
index daad88cdbcc..ae1069d7a7d 100644
--- a/tests/auto/network/access/qnetworkreply_local/minihttpserver.h
+++ b/tests/auto/network/access/qnetworkreply_local/minihttpserver.h
@@ -152,7 +152,7 @@ private:
void parseContentLength(State &st, QByteArrayView header)
{
- qsizetype index = header.indexOf("\r\ncontent-length:");
+ qsizetype index = header.toByteArray().toLower().indexOf("\r\ncontent-length:");
if (index == -1)
return;
st.foundContentLength = true;
diff --git a/tests/auto/network/access/qnetworkreply_local/tst_qnetworkreply_local.cpp b/tests/auto/network/access/qnetworkreply_local/tst_qnetworkreply_local.cpp
index 8bed904c230..977a047c58e 100644
--- a/tests/auto/network/access/qnetworkreply_local/tst_qnetworkreply_local.cpp
+++ b/tests/auto/network/access/qnetworkreply_local/tst_qnetworkreply_local.cpp
@@ -270,7 +270,7 @@ void tst_QNetworkReply_local::fullServerName()
QVERIFY(receivedData.startsWith(expectedGet));
const QByteArray expectedHost = "host: " % url.host().toUtf8() % "\r\n";
- QVERIFY(receivedData.contains(expectedHost));
+ QVERIFY(receivedData.toLower().contains(expectedHost));
}
#endif
diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
index 805fa046a07..3e5c65cf0be 100644
--- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
+++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
@@ -156,6 +156,7 @@ private slots:
void removeIndexWhileEditing();
void focusNextOnHide();
void shiftSelectionAfterModelSetCurrentIndex();
+ void QTBUG72333_isPersistentEditorOpen();
private:
static QAbstractItemView *viewFromString(const QByteArray &viewType, QWidget *parent = nullptr)
@@ -3604,5 +3605,29 @@ void tst_QAbstractItemView::shiftSelectionAfterModelSetCurrentIndex()
QCOMPARE(selection.first().bottom(), 2);
}
+void tst_QAbstractItemView::QTBUG72333_isPersistentEditorOpen()
+{
+ QStandardItemModel model(1, 1);
+ model.setData(model.index(0, 0), QStringLiteral("Test"));
+
+ QTableView view;
+ view.setModel(&model);
+ view.show();
+
+ const QModelIndex index = model.index(0, 0);
+
+ view.edit(index);
+ QVERIFY(view.state() == QAbstractItemView::EditingState);
+ QVERIFY(!view.isPersistentEditorOpen(index));
+
+ view.closeEditor(view.indexWidget(index), QAbstractItemDelegate::RevertModelCache);
+
+ view.openPersistentEditor(index);
+ QVERIFY(view.isPersistentEditorOpen(index));
+
+ view.closePersistentEditor(index);
+ QVERIFY(!view.isPersistentEditorOpen(index));
+}
+
QTEST_MAIN(tst_QAbstractItemView)
#include "tst_qabstractitemview.moc"
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index 72f5ada4889..8e46876934d 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -11280,7 +11280,7 @@ void tst_QWidget::destroyBackingStore()
#endif // QT_BUILD_INTERNAL
// Helper function
-QWidgetRepaintManager* repaintManager(QWidget &widget)
+QWidgetRepaintManager* repaintManager([[maybe_unused]] QWidget &widget)
{
QWidgetRepaintManager *repaintManager = nullptr;
#ifdef QT_BUILD_INTERNAL
diff --git a/tests/benchmarks/corelib/time/qtimezone/tst_bench_qtimezone.cpp b/tests/benchmarks/corelib/time/qtimezone/tst_bench_qtimezone.cpp
index 3b58b6927ae..fbcce88fe81 100644
--- a/tests/benchmarks/corelib/time/qtimezone/tst_bench_qtimezone.cpp
+++ b/tests/benchmarks/corelib/time/qtimezone/tst_bench_qtimezone.cpp
@@ -41,15 +41,17 @@ static QList<QByteArray> enoughZones()
QByteArray("UTC"),
// Those named overtly in tst_QDateTime - special cases first:
QByteArray("UTC-02:00"), QByteArray("UTC+02:00"), QByteArray("UTC+12:00"),
- QByteArray("Etc/GMT+3"), QByteArray("GMT-2"), QByteArray("GMT"),
+ QByteArray("Etc/GMT+3"), QByteArray("GMT-0"), QByteArray("GMT"),
// ... then ordinary names in alphabetic order:
+ QByteArray("America/Anchorage"), QByteArray("America/Metlakatla"),
QByteArray("America/New_York"), QByteArray("America/Sao_Paulo"),
- QByteArray("America/Vancouver"),
- QByteArray("Asia/Kathmandu"), QByteArray("Asia/Singapore"),
+ QByteArray("America/Toronto"), QByteArray("America/Vancouver"),
+ QByteArray("Asia/Kathmandu"), QByteArray("Asia/Manila"), QByteArray("Asia/Singapore"),
QByteArray("Australia/Brisbane"), QByteArray("Australia/Eucla"),
QByteArray("Australia/Sydney"),
QByteArray("Europe/Berlin"), QByteArray("Europe/Helsinki"),
- QByteArray("Europe/Rome"), QByteArray("Europe/Oslo"),
+ QByteArray("Europe/Lisbon"), QByteArray("Europe/Oslo"),
+ QByteArray("Europe/Rome"),
QByteArray("Pacific/Apia"), QByteArray("Pacific/Auckland"),
QByteArray("Pacific/Kiritimati")
};