summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmake/QtBuildHelpers.cmake1
-rw-r--r--cmake/QtPublicSbomCycloneDXHelpers.cmake4
-rw-r--r--cmake/QtPublicSbomDocumentNamespaceHelpers.cmake456
-rw-r--r--cmake/QtPublicSbomHelpers.cmake105
-rw-r--r--coin/instructions/README.md6
-rw-r--r--coin/instructions/cmake_cross_compilation_module_build_instructions.yaml14
-rw-r--r--coin/instructions/cmake_module_build_instructions.yaml14
-rw-r--r--doc/global/macros.qdocconf8
-rw-r--r--examples/network/doc/src/http.qdoc9
-rw-r--r--examples/network/http/httpwindow.cpp11
-rw-r--r--src/corelib/doc/images/javaiterators1.svg60
-rw-r--r--src/corelib/doc/images/javaiterators2.svg57
-rw-r--r--src/corelib/doc/images/stliterators1.svg90
-rw-r--r--src/corelib/doc/src/cmake/cmake-properties.qdoc1
-rw-r--r--src/corelib/doc/src/containers.qdoc2
-rw-r--r--src/corelib/doc/src/java-style-iterators.qdoc2
-rw-r--r--src/corelib/thread/qfuture.qdoc2
-rw-r--r--src/gui/painting/qcolor.cpp30
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp13
-rw-r--r--src/plugins/styles/modernwindows/qwindows11style.cpp9
-rw-r--r--src/plugins/styles/modernwindows/qwindows11style_p.h1
-rw-r--r--src/testlib/qtestlog.cpp6
-rw-r--r--src/tools/macdeployqt/shared/shared.cpp27
-rw-r--r--src/widgets/widgets/qtabbar.cpp66
-rw-r--r--src/widgets/widgets/qtabbar_p.h3
-rw-r--r--tests/auto/widgets/kernel/qwidget/BLACKLIST5
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp33
27 files changed, 883 insertions, 152 deletions
diff --git a/cmake/QtBuildHelpers.cmake b/cmake/QtBuildHelpers.cmake
index 3ef292b27bc..6a1dc543145 100644
--- a/cmake/QtBuildHelpers.cmake
+++ b/cmake/QtBuildHelpers.cmake
@@ -301,6 +301,7 @@ function(qt_internal_get_qt_build_public_helpers out_var)
QtPublicSbomCommonGenerationHelpers
QtPublicSbomCpeHelpers
QtPublicSbomCycloneDXHelpers
+ QtPublicSbomDocumentNamespaceHelpers
QtPublicSbomDepHelpers
QtPublicSbomFileHelpers
QtPublicSbomGenerationHelpers
diff --git a/cmake/QtPublicSbomCycloneDXHelpers.cmake b/cmake/QtPublicSbomCycloneDXHelpers.cmake
index a3dc52d4e39..92b26bb0525 100644
--- a/cmake/QtPublicSbomCycloneDXHelpers.cmake
+++ b/cmake/QtPublicSbomCycloneDXHelpers.cmake
@@ -226,9 +226,7 @@ function(_qt_internal_sbom_get_cyclone_bom_serial_number)
_qt_internal_sbom_set_default_option_value_and_error_if_empty(SPDX_NAMESPACE "")
- # This is a randomly generated uuid v4 value. To be used for all eternity. Until we change the
- # implementation of the function.
- set(uuid_namespace "c024642f-9853-45b2-9bfd-ab3f061a05bb")
+ _qt_internal_sbom_get_document_namespace_uuid_namespace(uuid_namespace)
string(UUID uuid NAMESPACE "${uuid_namespace}" NAME "${arg_SPDX_NAMESPACE}" TYPE SHA1)
set(cyclone_dx_serial_number "urn:cdx:${uuid}")
diff --git a/cmake/QtPublicSbomDocumentNamespaceHelpers.cmake b/cmake/QtPublicSbomDocumentNamespaceHelpers.cmake
new file mode 100644
index 00000000000..0293c163dec
--- /dev/null
+++ b/cmake/QtPublicSbomDocumentNamespaceHelpers.cmake
@@ -0,0 +1,456 @@
+# Copyright (C) 2025 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+# Computes the SPDX document namespace field.
+# See https://spdx.github.io/spdx-spec/v2.3/document-creation-information/#65-spdx-document-namespace-field
+# The document namespace is used in SPDX external references and dependency relationships.
+function(_qt_internal_sbom_compute_project_namespace out_var)
+ set(opt_args "")
+ set(single_args
+ SUPPLIER_URL
+ PROJECT_NAME
+ VERSION_SUFFIX
+ DOCUMENT_NAMESPACE_INFIX
+ DOCUMENT_NAMESPACE_SUFFIX
+ DOCUMENT_NAMESPACE_URL_PREFIX
+ )
+ set(multi_args "")
+
+ cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ if(NOT arg_PROJECT_NAME)
+ message(FATAL_ERROR "PROJECT_NAME must be set")
+ endif()
+
+ if(NOT arg_SUPPLIER_URL)
+ message(FATAL_ERROR "SUPPLIER_URL must be set")
+ endif()
+
+ string(TOLOWER "${arg_PROJECT_NAME}" project_name_lowercase)
+
+ set(version_suffix "")
+
+ if(arg_VERSION_SUFFIX)
+ set(version_suffix "-${arg_VERSION_SUFFIX}")
+ else()
+ _qt_internal_sbom_get_git_version_vars()
+ if(QT_SBOM_GIT_VERSION)
+ set(version_suffix "-${QT_SBOM_GIT_VERSION}")
+ endif()
+ endif()
+
+ set(namespace "${project_name_lowercase}${version_suffix}")
+
+ if(arg_DOCUMENT_NAMESPACE_INFIX)
+ string(APPEND namespace "${arg_DOCUMENT_NAMESPACE_INFIX}")
+ endif()
+
+ if(arg_DOCUMENT_NAMESPACE_SUFFIX)
+ string(APPEND namespace "${arg_DOCUMENT_NAMESPACE_SUFFIX}")
+ endif()
+
+ if(arg_DOCUMENT_NAMESPACE_URL_PREFIX)
+ set(url_prefix "${arg_DOCUMENT_NAMESPACE_URL_PREFIX}")
+ else()
+ set(url_prefix "${arg_SUPPLIER_URL}/spdxdocs")
+ endif()
+
+ set(repo_spdx_namespace "${url_prefix}/${namespace}")
+
+ set(${out_var} "${repo_spdx_namespace}" PARENT_SCOPE)
+endfunction()
+
+# A document namespace is recommended to be either a URI + v4 random UUID or a URI + v5 UUID
+# generated from a sha1 checksum.
+# It needs to be unique per document.
+# Having randomness is bad for build reproducibility, so the v4 UUID is not a good idea.
+#
+# Collecting enough unique content as part of the build for a checksum is difficult
+# without outside input, and because the final document contents is only available at install time.
+#
+# We currently create a fake URI (that is not hosted on a web service) and a combination of the
+# following info:
+# - project name
+# - project version
+# - document namespace infix, which consists of:
+# - platform and arch info (host + target)
+# - a v5 UUID based on various inputs
+# - extra content provided as input
+# - document namespace suffix (as a last resort)
+#
+# The document namespace infix should make the namespace unique enough, so that different
+# builds don't usually map to the same value, and thus is conformant to the spec.
+function(_qt_internal_sbom_compute_uniqueish_document_namespace_infix)
+ set(opt_args "")
+ set(single_args
+ UUID_EXTRA_CONTENT
+ OUT_VAR_INFIX
+ OUT_VAR_UUID_INFIX
+ OUT_VAR_UUID_INFIX_MERGED
+ )
+ set(multi_args "")
+
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ if(NOT arg_OUT_VAR_INFIX AND NOT arg_OUT_VAR_UUID_INFIX AND NOT arg_OUT_VAR_UUID_INFIX_MERGED)
+ message(FATAL_ERROR "One of OUT_VAR_INFIX, OUT_VAR_UUID_INFIX or "
+ "OUT_VAR_UUID_INFIX_MERGED must be set")
+ endif()
+
+ if(QT_SBOM_NO_UNIQUE_NAMESPACE_INFIX)
+ set(${arg_OUT_VAR_INFIX} "" PARENT_SCOPE)
+
+ if(arg_OUT_VAR_UUID_INFIX)
+ set(${arg_OUT_VAR_UUID_INFIX} "" PARENT_SCOPE)
+ endif()
+
+ if(arg_OUT_VAR_UUID_INFIX_MERGED)
+ set(${arg_OUT_VAR_UUID_INFIX_MERGED} "" PARENT_SCOPE)
+ endif()
+
+ return()
+ endif()
+
+ # Collect the various pieces of information to build the unique-ish infix.
+ set(main_value "")
+
+ _qt_internal_sbom_get_host_platform_name(host_platform_name)
+ if(host_platform_name)
+ string(APPEND main_value "host-${host_platform_name}")
+ endif()
+
+ _qt_internal_sbom_get_host_platform_architecture(host_arch)
+ if(host_arch)
+ string(APPEND main_value "-${host_arch}")
+ endif()
+
+ _qt_internal_sbom_get_target_platform_friendly_name(target_platform_name)
+ if(target_platform_name)
+ string(APPEND main_value "-target-${target_platform_name}")
+ endif()
+
+ _qt_internal_sbom_get_target_platform_architecture(target_arch)
+ if(target_arch)
+ string(APPEND main_value "-${target_arch}")
+ endif()
+
+
+ # Collect the pieces for the infix uuid part.
+ set(uuid_content "<main_value>:${main_value}\n")
+
+ _qt_internal_sbom_get_build_tools_info_for_namespace_infix_uuid(tools_info)
+ if(tools_info)
+ string(APPEND uuid_content "<build_tools_info>:${tools_info}\n")
+ endif()
+
+ if(arg_UUID_EXTRA_CONTENT)
+ string(APPEND uuid_content "<extra_content>:\n${arg_UUID_EXTRA_CONTENT}\n")
+ endif()
+
+ if(QT_SBOM_NAMESPACE_INFIX_UUID_EXTRA_CONTENT)
+ string(APPEND uuid_content
+ "<extra_content_var>:${QT_SBOM_NAMESPACE_INFIX_UUID_EXTRA_CONTENT}\n")
+ endif()
+
+ _qt_internal_sbom_compute_document_namespace_infix_uuid(
+ UUID_CONTENT "${uuid_content}"
+ OUT_VAR_UUID uuid_value
+ )
+
+ if(arg_OUT_VAR_INFIX)
+ set(${arg_OUT_VAR_INFIX} "${main_value}" PARENT_SCOPE)
+ endif()
+
+ if(arg_OUT_VAR_UUID_INFIX)
+ set(${arg_OUT_VAR_UUID_INFIX} "${uuid_value}" PARENT_SCOPE)
+ endif()
+
+ if(arg_OUT_VAR_UUID_INFIX_MERGED)
+ set(${arg_OUT_VAR_UUID_INFIX_MERGED} "${main_value}-${uuid_value}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+# Computes the uuid part of a SPDX document namespace, given the inputs.
+# UUID_CONTENT - should be given enough unique content to ensure the uniqueness of generated the
+# uuid based on the content.
+#
+# Allow various overrides like:
+# - override of the full uuid content via QT_SBOM_FORCE_DOCUMENT_NAMESPACE_INFIX_UUID_CONTENT
+# - allow using a random value via QT_SBOM_FORCE_RANDOM_DOCUMENT_NAMESPACE_INFIX_UUID_CONTENT
+# - allow setting a specific uuid via QT_SBOM_FORCE_DOCUMENT_NAMESPACE_INFIX_UUID
+# - fake deterministic uuid (only useful for development purposes of this code)
+function(_qt_internal_sbom_compute_document_namespace_infix_uuid)
+ set(opt_args "")
+ set(single_args
+ UUID_CONTENT
+ OUT_VAR_UUID
+ )
+ set(multi_args "")
+
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ if(NOT arg_OUT_VAR_UUID)
+ message(FATAL_ERROR "OUT_VAR_UUID must be set")
+ endif()
+
+ set(content "${arg_UUID_CONTENT}")
+
+ _qt_internal_sbom_get_document_namespace_uuid_namespace(uuid_namespace)
+
+ # Allow various overrides.
+ if(QT_SBOM_FAKE_DETERMINISTIC_BUILD
+ # This is to allow developers test a fake build, without a fake uuid
+ AND NOT QT_SBOM_NO_FAKE_DETERMINISTIC_BUILD_DOCUMENT_NAMESPACE_INFIX_UUID
+ )
+ set(uuid_content "<fake_deterministic_build>")
+ elseif(QT_SBOM_FORCE_DOCUMENT_NAMESPACE_INFIX_UUID_CONTENT)
+ set(uuid_content "${QT_SBOM_FORCE_DOCUMENT_NAMESPACE_INFIX_UUID_CONTENT}")
+ elseif(QT_SBOM_FORCE_RANDOM_DOCUMENT_NAMESPACE_INFIX_UUID_CONTENT)
+ string(RANDOM LENGTH 256 uuid_content)
+ else()
+ set(uuid_content "${content}")
+ endif()
+
+ # Also allow direct override of uuid.
+ if(QT_SBOM_FORCE_DOCUMENT_NAMESPACE_INFIX_UUID)
+ set(namespace_infix_uuid "${QT_SBOM_FORCE_DOCUMENT_NAMESPACE_INFIX_UUID}")
+ else()
+ string(UUID namespace_infix_uuid
+ NAMESPACE "${uuid_namespace}" NAME "${uuid_content}" TYPE SHA1)
+ endif()
+
+ set(${arg_OUT_VAR_UUID} "${namespace_infix_uuid}" PARENT_SCOPE)
+endfunction()
+
+# A v4 uuid to be used as a namespace value for generating v5 uuids.
+function(_qt_internal_sbom_get_document_namespace_uuid_namespace out_var)
+ # This is a randomly generated uuid v4 value. To be used for all eternity. Until we change the
+ # implementation of the function.
+ set(uuid_namespace "c024642f-9853-45b2-9bfd-ab3f061a05bb")
+ set(${out_var} "${uuid_namespace}" PARENT_SCOPE)
+endfunction()
+
+# Collects extra uuid content for generating a more unique document namespace uuid for qt repos.
+function(_qt_internal_sbom_compute_qt_uniqueish_document_namespace_infix)
+ set(opt_args "")
+ set(single_args
+ OUT_VAR_INFIX
+ OUT_VAR_UUID_INFIX
+ OUT_VAR_UUID_INFIX_MERGED
+ )
+ set(multi_args "")
+
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ if(NOT arg_OUT_VAR_INFIX AND NOT arg_OUT_VAR_UUID_INFIX AND NOT arg_OUT_VAR_UUID_INFIX_MERGED)
+ message(FATAL_ERROR "One of OUT_VAR_INFIX, OUT_VAR_UUID_INFIX or "
+ "OUT_VAR_UUID_INFIX_MERGED must be set")
+ endif()
+
+ if(QT_SBOM_NO_UNIQUE_QT_NAMESPACE_INFIX)
+ set(${arg_OUT_VAR_INFIX} "" PARENT_SCOPE)
+
+ if(arg_OUT_VAR_UUID_INFIX)
+ set(${arg_OUT_VAR_UUID_INFIX} "" PARENT_SCOPE)
+ endif()
+
+ if(arg_OUT_VAR_UUID_INFIX_MERGED)
+ set(${arg_OUT_VAR_UUID_INFIX_MERGED} "" PARENT_SCOPE)
+ endif()
+
+ return()
+ endif()
+
+ set(uuid_extra_content "")
+
+ if(APPLE AND (CMAKE_OSX_ARCHITECTURES MATCHES ";"))
+ string(CONCAT building_for
+ "${QT_QMAKE_TARGET_MKSPEC} (${CMAKE_OSX_ARCHITECTURES}), ${TEST_architecture_arch} "
+ "features: ${subarch_summary})")
+ else()
+ string(CONCAT building_for
+ "${QT_QMAKE_TARGET_MKSPEC} (${TEST_architecture_arch}, "
+ "CPU features: ${subarch_summary})")
+ endif()
+
+ string(APPEND uuid_extra_content "<building_for>:${building_for}\n")
+
+ _qt_internal_get_configure_line(configure_line)
+ if(configure_line)
+ string(APPEND uuid_extra_content "<configure_line>:${configure_line}\n")
+ endif()
+
+ _qt_internal_sbom_compute_uniqueish_document_namespace_infix(
+ UUID_EXTRA_CONTENT "${uuid_extra_content}"
+ OUT_VAR_INFIX infix
+ OUT_VAR_UUID_INFIX uuid_infix
+ OUT_VAR_UUID_INFIX_MERGED uuid_infix_merged
+ )
+
+ if(arg_OUT_VAR_INFIX)
+ set(${arg_OUT_VAR_INFIX} "${infix}" PARENT_SCOPE)
+ endif()
+
+ if(arg_OUT_VAR_UUID_INFIX)
+ set(${arg_OUT_VAR_UUID_INFIX} "${uuid_infix}" PARENT_SCOPE)
+ endif()
+
+ if(arg_OUT_VAR_UUID_INFIX_MERGED)
+ set(${arg_OUT_VAR_UUID_INFIX_MERGED} "${uuid_infix_merged}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+# Returns a lower case host platform name for sbom document namespace purposes.
+function(_qt_internal_sbom_get_host_platform_name out_var)
+ string(TOLOWER "${CMAKE_HOST_SYSTEM_NAME}" main_value)
+ if(NOT main_value)
+ set(main_value "unknown-platform")
+ endif()
+
+ set(${out_var} "${main_value}" PARENT_SCOPE)
+endfunction()
+
+# Returns a lower case target platform name for sbom document namespace purposes.
+function(_qt_internal_sbom_get_target_platform_friendly_name out_var)
+ string(TOLOWER "${CMAKE_SYSTEM_NAME}" lower_system_name)
+ set(friendly_name "${lower_system_name}")
+
+ if(NOT friendly_name)
+ set(friendly_name "unknown-platform")
+ endif()
+
+ if(MSVC)
+ string(APPEND friendly_name "-msvc")
+ endif()
+
+ if(MINGW)
+ string(APPEND friendly_name "-mingw")
+ endif()
+
+ if(CYGWIN)
+ string(APPEND friendly_name "-cygwin")
+ endif()
+
+ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ set(friendly_name "linux")
+ endif()
+
+ if(CMAKE_SYSTEM_NAME STREQUAL "HPUX")
+ set(friendly_name "hpux")
+ endif()
+
+ if(CMAKE_SYSTEM_NAME STREQUAL "Android")
+ set(friendly_name "android")
+ endif()
+
+ if(CMAKE_SYSTEM_NAME STREQUAL "Integrity")
+ set(friendly_name "integrity")
+ endif()
+
+ if(CMAKE_SYSTEM_NAME STREQUAL "VxWorks")
+ set(friendly_name "vxworks")
+ endif()
+
+ if(CMAKE_SYSTEM_NAME STREQUAL "QNX")
+ set(friendly_name "qnx")
+ endif()
+
+ if(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
+ set(friendly_name "openbsd")
+ endif()
+
+ if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
+ set(friendly_name "freebsd")
+ endif()
+
+ if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
+ set(friendly_name "netbsd")
+ endif()
+
+ if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten" OR EMSCRIPTEN)
+ set(friendly_name "wasm")
+ endif()
+
+ if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+ set(friendly_name "sunos")
+ endif()
+
+ if(CMAKE_SYSTEM_NAME STREQUAL "GNU")
+ set(friendly_name "hurd")
+ endif()
+
+ if(CMAKE_CXX_FLAGS MATCHES "-D__WEBOS__")
+ set(friendly_name "webos")
+ endif()
+
+ if(APPLE)
+ if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
+ set(friendly_name "ios")
+ elseif(CMAKE_SYSTEM_NAME STREQUAL "tvOS")
+ set(friendly_name "tvos")
+ elseif(CMAKE_SYSTEM_NAME STREQUAL "watchOS")
+ set(friendly_name "watchos")
+ elseif(CMAKE_SYSTEM_NAME STREQUAL "visionOS")
+ set(friendly_name "visionos")
+ else()
+ set(friendly_name "macos")
+ endif()
+ endif()
+
+ set(${out_var} "${friendly_name}" PARENT_SCOPE)
+endfunction()
+
+# Returns the host architecture for sbom document namespace purposes.
+function(_qt_internal_sbom_get_host_platform_architecture out_var)
+ set(main_value "${CMAKE_HOST_SYSTEM_PROCESSOR}")
+
+ if(QT_SBOM_HOST_PLATFORM_ARCHITECTURE)
+ set(main_value "${QT_SBOM_HOST_PLATFORM_ARCHITECTURE}")
+ endif()
+
+ string(TOLOWER "${main_value}" main_value)
+
+ set(${out_var} "${main_value}" PARENT_SCOPE)
+endfunction()
+
+# Returns the target architecture for sbom document namespace purposes.
+function(_qt_internal_sbom_get_target_platform_architecture out_var)
+ set(main_value "")
+ if(APPLE)
+ set(main_value "${CMALE_OSX_ARCHITECTURES}")
+ string(REPLACE ";" "_" main_value "${main_value}")
+ endif()
+
+ if(NOT main_value)
+ set(main_value "${CMAKE_SYSTEM_PROCESSOR}")
+ endif()
+
+ if(QT_SBOM_TARGET_PLATFORM_ARCHITECTURE)
+ set(main_value "${QT_SBOM_TARGET_PLATFORM_ARCHITECTURE}")
+ endif()
+
+ string(TOLOWER "${main_value}" main_value)
+
+ set(${out_var} "${main_value}" PARENT_SCOPE)
+endfunction()
+
+# Returns various build tool information ofr document namespace purposes.
+function(_qt_internal_sbom_get_build_tools_info_for_namespace_infix_uuid out_var)
+ set(content "")
+
+ string(APPEND content "<cmake_version>: ${CMAKE_VERSION}\n")
+ string(APPEND content "<cmake_generator>: ${CMAKE_GENERATOR}\n")
+ string(APPEND content "<compiler>: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}\n")
+
+ if(CMAKE_CXX_COMPILER_LINKER_ID)
+ string(APPEND content "<linker>: ${CMAKE_CXX_COMPILER_LINKER_ID} "
+ "${CMAKE_CXX_COMPILER_LINKER_VERSION} "
+ "${CMAKE_CXX_COMPILER_LINKER_FRONTEND_VARIANT}\n")
+ endif()
+
+ set(${out_var} "${content}" PARENT_SCOPE)
+endfunction()
diff --git a/cmake/QtPublicSbomHelpers.cmake b/cmake/QtPublicSbomHelpers.cmake
index 3d66e7ff783..45342c2efb6 100644
--- a/cmake/QtPublicSbomHelpers.cmake
+++ b/cmake/QtPublicSbomHelpers.cmake
@@ -30,6 +30,7 @@ function(_qt_internal_sbom_begin_project)
set(opt_args
USE_GIT_VERSION
__QT_INTERNAL_HANDLE_QT_REPO
+ NO_AUTO_DOCUMENT_NAMESPACE_INFIX
)
set(single_args
INSTALL_PREFIX
@@ -39,6 +40,9 @@ function(_qt_internal_sbom_begin_project)
SUPPLIER_URL
DOWNLOAD_LOCATION
DOCUMENT_NAMESPACE
+ DOCUMENT_NAMESPACE_INFIX
+ DOCUMENT_NAMESPACE_SUFFIX
+ DOCUMENT_NAMESPACE_URL_PREFIX
VERSION
SBOM_PROJECT_NAME
QT_REPO_PROJECT_NAME
@@ -110,13 +114,72 @@ function(_qt_internal_sbom_begin_project)
)
_qt_internal_handle_sbom_project_version(${sbom_project_version_args})
+ if(arg___QT_INTERNAL_HANDLE_QT_REPO)
+ _qt_internal_sbom_compute_qt_uniqueish_document_namespace_infix(
+ OUT_VAR_UUID_INFIX_MERGED document_namespace_infix
+ )
+ if(document_namespace_infix)
+ set(arg_DOCUMENT_NAMESPACE_INFIX "-${document_namespace_infix}")
+ endif()
+ endif()
+
if(arg_DOCUMENT_NAMESPACE)
set(repo_spdx_namespace "${arg_DOCUMENT_NAMESPACE}")
+
+ if(QT_SBOM_DOCUMENT_NAMESPACE_INFIX)
+ string(APPEND repo_spdx_namespace "${QT_SBOM_DOCUMENT_NAMESPACE_INFIX}")
+ elseif(arg_DOCUMENT_NAMESPACE_INFIX)
+ string(APPEND repo_spdx_namespace "${arg_DOCUMENT_NAMESPACE_INFIX}")
+ elseif(NOT arg_NO_AUTO_DOCUMENT_NAMESPACE_INFIX
+ AND NOT QT_SBOM_NO_AUTO_DOCUMENT_NAMESPACE_INFIX)
+ _qt_internal_sbom_compute_uniqueish_document_namespace_infix(
+ OUT_VAR_UUID_INFIX_MERGED document_namespace_infix
+ )
+ string(APPEND repo_spdx_namespace "-${document_namespace_infix}")
+ endif()
+
+ if(QT_SBOM_DOCUMENT_NAMESPACE_SUFFIX)
+ string(APPEND repo_spdx_namespace "${QT_SBOM_DOCUMENT_NAMESPACE_SUFFIX}")
+ elseif(arg_DOCUMENT_NAMESPACE_SUFFIX)
+ string(APPEND repo_spdx_namespace "${arg_DOCUMENT_NAMESPACE_SUFFIX}")
+ endif()
else()
set(compute_project_namespace_args "")
if(repo_supplier_url)
list(APPEND compute_project_namespace_args SUPPLIER_URL "${repo_supplier_url}")
endif()
+
+ if(QT_SBOM_DOCUMENT_NAMESPACE_INFIX)
+ list(APPEND compute_project_namespace_args
+ DOCUMENT_NAMESPACE_INFIX "${QT_SBOM_DOCUMENT_NAMESPACE_INFIX}")
+ elseif(arg_DOCUMENT_NAMESPACE_INFIX)
+ list(APPEND compute_project_namespace_args
+ DOCUMENT_NAMESPACE_INFIX "${arg_DOCUMENT_NAMESPACE_INFIX}")
+ elseif(NOT arg_NO_AUTO_DOCUMENT_NAMESPACE_INFIX
+ AND NOT QT_SBOM_NO_AUTO_DOCUMENT_NAMESPACE_INFIX)
+ _qt_internal_sbom_compute_uniqueish_document_namespace_infix(
+ OUT_VAR_UUID_INFIX_MERGED document_namespace_infix
+ )
+ list(APPEND compute_project_namespace_args
+ DOCUMENT_NAMESPACE_INFIX "-${document_namespace_infix}")
+ endif()
+
+ if(QT_SBOM_DOCUMENT_NAMESPACE_SUFFIX)
+ list(APPEND compute_project_namespace_args
+ DOCUMENT_NAMESPACE_SUFFIX "${QT_SBOM_DOCUMENT_NAMESPACE_SUFFIX}")
+ elseif(arg_DOCUMENT_NAMESPACE_SUFFIX)
+ list(APPEND compute_project_namespace_args
+ DOCUMENT_NAMESPACE_SUFFIX "${arg_DOCUMENT_NAMESPACE_SUFFIX}")
+ endif()
+
+ if(QT_SBOM_DOCUMENT_NAMESPACE_URL_PREFIX)
+ list(APPEND compute_project_namespace_args
+ DOCUMENT_NAMESPACE_URL_PREFIX "${QT_SBOM_DOCUMENT_NAMESPACE_URL_PREFIX}")
+ elseif(arg_DOCUMENT_NAMESPACE_URL_PREFIX)
+ list(APPEND compute_project_namespace_args
+ DOCUMENT_NAMESPACE_URL_PREFIX "${arg_DOCUMENT_NAMESPACE_URL_PREFIX}")
+ endif()
+
_qt_internal_sbom_compute_project_namespace(repo_spdx_namespace
PROJECT_NAME "${repo_project_name_lowercase}"
${compute_project_namespace_args}
@@ -2332,48 +2395,6 @@ function(_qt_internal_get_configure_line out_var)
set(${out_var} "${content}" PARENT_SCOPE)
endfunction()
-function(_qt_internal_sbom_compute_project_namespace out_var)
- set(opt_args "")
- set(single_args
- SUPPLIER_URL
- PROJECT_NAME
- VERSION_SUFFIX
- )
- set(multi_args "")
-
- cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
- _qt_internal_validate_all_args_are_parsed(arg)
-
- if(NOT arg_PROJECT_NAME)
- message(FATAL_ERROR "PROJECT_NAME must be set")
- endif()
-
- if(NOT arg_SUPPLIER_URL)
- message(FATAL_ERROR "SUPPLIER_URL must be set")
- endif()
-
- string(TOLOWER "${arg_PROJECT_NAME}" project_name_lowercase)
-
- set(version_suffix "")
-
- if(arg_VERSION_SUFFIX)
- set(version_suffix "-${arg_VERSION_SUFFIX}")
- else()
- _qt_internal_sbom_get_git_version_vars()
- if(QT_SBOM_GIT_VERSION)
- set(version_suffix "-${QT_SBOM_GIT_VERSION}")
- endif()
- endif()
-
- # Used in external refs, it should be either aa URI + UUID or a URI + checksum.
- # We currently use a URI + git version, which is probably not conformant to the spec.
- set(repo_name_and_version "${project_name_lowercase}${version_suffix}")
- set(repo_spdx_namespace
- "${arg_SUPPLIER_URL}/spdxdocs/${repo_name_and_version}")
-
- set(${out_var} "${repo_spdx_namespace}" PARENT_SCOPE)
-endfunction()
-
function(_qt_internal_sbom_compute_project_file_name out_var)
set(opt_args
SPDX_TAG_VALUE
diff --git a/coin/instructions/README.md b/coin/instructions/README.md
index f366642395d..86a46efe051 100644
--- a/coin/instructions/README.md
+++ b/coin/instructions/README.md
@@ -32,6 +32,10 @@ The following environment variables are used in Coin instructions when building
that will be passed to a non-qtbase qt-configure-module call
`NON_QTBASE_CMAKE_ARGS` - contains platform-specific ``CMake-style`` arguments
that will be passed to a non-qtbase qt-configure-module call
+`<MODULE>_CONFIGURE_ARGS` - contains platform-specific ``configure-style`` arguments
+ that will be passed to the specified module's qt-configure-module call
+`<MODULE>_CMAKE_ARGS` - contains platform-specific ``CMake-style`` arguments
+ that will be passed to the specified module's qt-configure-module call
`COMMON_CMAKE_ARGS` - platform-independent ``CMake-style`` args set in
`prepare_building_env.yaml` that apply to qtbase configurations
only.
@@ -51,6 +55,8 @@ mirror the ones above. They are:
`TARGET_CMAKE_ARGS`
`NON_QTBASE_TARGET_CONFIGURE_ARGS`
`NON_QTBASE_TARGET_CMAKE_ARGS`
+`<MODULE>_TARGET_CONFIGURE_ARGS`
+`<MODULE>_TARGET_CMAKE_ARGS`
`COMMON_TARGET_CMAKE_ARGS`
`COMMON_NON_QTBASE_TARGET_CMAKE_ARGS`
diff --git a/coin/instructions/cmake_cross_compilation_module_build_instructions.yaml b/coin/instructions/cmake_cross_compilation_module_build_instructions.yaml
index cf308fc7836..1d60af72831 100644
--- a/coin/instructions/cmake_cross_compilation_module_build_instructions.yaml
+++ b/coin/instructions/cmake_cross_compilation_module_build_instructions.yaml
@@ -36,6 +36,20 @@ instructions:
- type: EnvironmentVariable
variableName: COIN_CMAKE_ARGS
variableValue: "{{.Env.NON_QTBASE_TARGET_CMAKE_ARGS}} {{.Env.COMMON_NON_QTBASE_TARGET_CMAKE_ARGS}}"
+ - type: AppendToEnvironmentVariable
+ variableName: COIN_CONFIGURE_ARGS
+ variableValue: " ${{ToUpper .Env.TESTED_MODULE_COIN}}_TARGET_CONFIGURE_ARGS"
+ enable_if:
+ condition: runtime
+ env_var: "{{ToUpper .Env.TESTED_MODULE_COIN}}_TARGET_CONFIGURE_ARGS"
+ not_equals_value: null
+ - type: AppendToEnvironmentVariable
+ variableName: COIN_CMAKE_ARGS
+ variableValue: " ${{ToUpper .Env.TESTED_MODULE_COIN}}_TARGET_CMAKE_ARGS"
+ enable_if:
+ condition: runtime
+ env_var: "{{ToUpper .Env.TESTED_MODULE_COIN}}_TARGET_CMAKE_ARGS"
+ not_equals_value: null
- type: EnvironmentVariable
variableName: CONFIGURE_ENV_PREFIX
variableValue: "{{.Env.TARGET_ENV_PREFIX}}"
diff --git a/coin/instructions/cmake_module_build_instructions.yaml b/coin/instructions/cmake_module_build_instructions.yaml
index 788074a4bf6..3d83d4ac0dc 100644
--- a/coin/instructions/cmake_module_build_instructions.yaml
+++ b/coin/instructions/cmake_module_build_instructions.yaml
@@ -17,6 +17,20 @@ instructions:
- type: EnvironmentVariable
variableName: COIN_CMAKE_ARGS
variableValue: "{{.Env.NON_QTBASE_CMAKE_ARGS}} {{.Env.COMMON_NON_QTBASE_CMAKE_ARGS}}"
+ - type: AppendToEnvironmentVariable
+ variableName: CONFIGURE_ARGS
+ variableValue: " ${{ToUpper .Env.TESTED_MODULE_COIN}}_CONFIGURE_ARGS"
+ enable_if:
+ condition: runtime
+ env_var: "{{ToUpper .Env.TESTED_MODULE_COIN}}_CONFIGURE_ARGS"
+ not_equals_value: null
+ - type: AppendToEnvironmentVariable
+ variableName: COIN_CMAKE_ARGS
+ variableValue: " ${{ToUpper .Env.TESTED_MODULE_COIN}}_CMAKE_ARGS"
+ enable_if:
+ condition: runtime
+ env_var: "{{ToUpper .Env.TESTED_MODULE_COIN}}_CMAKE_ARGS"
+ not_equals_value: null
- type: EnvironmentVariable
variableName: CONFIGURE_ENV_PREFIX
variableValue: "{{.Env.ENV_PREFIX}}"
diff --git a/doc/global/macros.qdocconf b/doc/global/macros.qdocconf
index ae08c76ad93..f414b3fed18 100644
--- a/doc/global/macros.qdocconf
+++ b/doc/global/macros.qdocconf
@@ -91,11 +91,11 @@ macro.NdkFullVer = "27.2.12479018"
macro.NdkCompilerVer = "Clang 17.0.2"
macro.JdkVer = "17"
macro.AndroidMinApiVer = "28"
-macro.AndroidMaxApiVer = "35"
+macro.AndroidMaxApiVer = "36"
macro.AndroidMinVer = "9"
-macro.AndroidMaxVer = "15"
-macro.AndroidPlatformVer = "35"
-macro.AndroidBuildToolsVer = "35.0.1"
+macro.AndroidMaxVer = "16"
+macro.AndroidPlatformVer = "36"
+macro.AndroidBuildToolsVer = "36.0.0"
macro.GradleVer = "8.14.3"
macro.AGPVer = "8.10.1"
macro.AAOSVer = "10 to 13"
diff --git a/examples/network/doc/src/http.qdoc b/examples/network/doc/src/http.qdoc
index a07d0fe73b0..e8ebc907e92 100644
--- a/examples/network/doc/src/http.qdoc
+++ b/examples/network/doc/src/http.qdoc
@@ -18,6 +18,15 @@
The main work of this example is done in the HttpWindow class.
Thus we will focus on that.
+ \snippet http/httpwindow.cpp qnam-tcpkeepalive
+
+ Since Qt 6.11, it is possible to explicitly specify the TCP keepalive
+ parameters for a QNetworkRequest. In the snippet above, we are overriding
+ the defaults used by QNetworkAccessManager to follow a more aggressive
+ strategy. This can be useful, for example, in early detection of network
+ hangs caused by network changes on Linux. In this particular example, the
+ connection will be closed after thirty seconds of inactivity.
+
\snippet http/httpwindow.cpp qnam-download
Using QNetworkAccessManager, we begin the download of a resource as
diff --git a/examples/network/http/httpwindow.cpp b/examples/network/http/httpwindow.cpp
index 3d1c2467d84..3a4ae098321 100644
--- a/examples/network/http/httpwindow.cpp
+++ b/examples/network/http/httpwindow.cpp
@@ -10,6 +10,8 @@
#include <QUrl>
#include <memory>
+#include <chrono>
+using namespace std::chrono_literals;
#if QT_CONFIG(ssl)
const char defaultUrl[] = "https://www.qt.io/";
@@ -95,8 +97,15 @@ void HttpWindow::startRequest(const QUrl &requestedUrl)
url = requestedUrl;
httpRequestAborted = false;
+ //! [qnam-tcpkeepalive]
+ QNetworkRequest networkRequest(url);
+ networkRequest.setTcpKeepAliveIdleTimeBeforeProbes(20s);
+ networkRequest.setTcpKeepAliveIntervalBetweenProbes(2s);
+ networkRequest.setTcpKeepAliveProbeCount(5);
+ //! [qnam-tcpkeepalive]
+
//! [qnam-download]
- reply.reset(qnam.get(QNetworkRequest(url)));
+ reply.reset(qnam.get(networkRequest));
//! [qnam-download]
//! [connecting-reply-to-slots]
connect(reply.get(), &QNetworkReply::finished, this, &HttpWindow::httpFinished);
diff --git a/src/corelib/doc/images/javaiterators1.svg b/src/corelib/doc/images/javaiterators1.svg
index 468dbe5371c..c10329ab480 100644
--- a/src/corelib/doc/images/javaiterators1.svg
+++ b/src/corelib/doc/images/javaiterators1.svg
@@ -12,6 +12,11 @@
svg .text-style { font: 20px arial; fill: black }
svg .fill-style { stroke: none; fill: red }
+ svg.dark .box-style { stroke: #f2f2f2; fill: black }
+ svg.dark .line-style { stroke: red; fill: none }
+ svg.dark .text-style { font: 20px arial; fill: #f2f2f2 }
+ svg.dark .fill-style { stroke: none; fill: red }
+
[data-theme="dark"] svg .box-style { stroke: #f2f2f2; fill: black }
[data-theme="dark"] svg .line-style { stroke: red; fill: none }
[data-theme="dark"] svg .text-style { font: 20px arial; fill: #f2f2f2 }
@@ -24,36 +29,53 @@
</style>
<g transform="translate(10.5, 10.5)">
-<path d="m 0,0 h 80 v 60 h -80 z" class="box-style" />
-<text x="35" y="36" class="text-style">A</text>
-<path d="M 0,60 v 30" class="line-style" />
-<path d="M 0,60 l -5,10 l 10,0 z" class="fill-style" />
+<path d="m 0,0 h 80 v 60 h -80 z" stroke="black" fill="white"
+ class="box-style" />
+<text x="35" y="36" font-family="arial" font-size="20px"
+ class="text-style">A</text>
+<path d="M 0,60 v 30" stroke="red"
+ class="line-style" />
+<path d="M 0,60 l -5,10 l 10,0 z" stroke="red" fill="red"
+ class="fill-style" />
</g>
<g transform="translate(90.5, 10.5)">
-<path d="m 0,0 h 80 v 60 h -80 z" class="box-style" />
-<text x="35" y="36" class="text-style">B</text>
-<path d="M 0,60 v 30" class="line-style" />
-<path d="M 0,60 l -5,10 l 10,0 z" class="fill-style" />
+<path d="m 0,0 h 80 v 60 h -80 z" stroke="black" fill="white"
+ class="box-style" />
+<text x="35" y="36" font-family="arial" font-size="20px"
+ class="text-style">B</text>
+<path d="M 0,60 v 30" stroke="red"
+ class="line-style" />
+<path d="M 0,60 l -5,10 l 10,0 z" stroke="red" fill="red"
+ class="fill-style" />
</g>
<g transform="translate(170.5, 10.5)">
-<path d="m 0,0 h 80 v 60 h -80 z" class="box-style" />
-<text x="35" y="36" class="text-style">C</text>
-<path d="M 0,60 v 30" class="line-style" />
-<path d="M 0,60 l -5,10 l 10,0 z" class="fill-style" />
+<path d="m 0,0 h 80 v 60 h -80 z" stroke="black" fill="white"
+ class="box-style" />
+<text x="35" y="36" font-family="arial" font-size="20px"
+ class="text-style">C</text>
+<path d="M 0,60 v 30" stroke="red"
+ class="line-style" />
+<path d="M 0,60 l -5,10 l 10,0 z" stroke="red" fill="red"
+ class="fill-style" />
</g>
<g transform="translate(250.5, 10.5)">
-<path d="m 0,0 h 80 v 60 h -80 z" class="box-style" />
-<text x="35" y="36" class="text-style">D</text>
-<path d="M 0,60 v 30" class="line-style" />
-<path d="M 0,60 l -5,10 l 10,0 z" class="fill-style" />
+<path d="m 0,0 h 80 v 60 h -80 z" stroke="black" fill="white"
+ class="box-style" />
+<text x="35" y="36" font-family="arial" font-size="20px"
+ class="text-style">D</text>
+<path d="M 0,60 v 30" stroke="red"
+ class="line-style" />
+<path d="M 0,60 l -5,10 l 10,0 z" stroke="red" fill="red"
+ class="fill-style" />
</g>
<g transform="translate(330.5, 10.5)">
-<path d="M 0,60 v 30" class="line-style" />
-<path d="M 0,60 l -5,10 l 10,0 z" class="fill-style" />
+<path d="M 0,60 v 30" stroke="red"
+ class="line-style" />
+<path d="M 0,60 l -5,10 l 10,0 z" stroke="red" fill="red"
+ class="fill-style" />
</g>
-
</svg>
diff --git a/src/corelib/doc/images/javaiterators2.svg b/src/corelib/doc/images/javaiterators2.svg
index df4c6b352a6..3b41b3f8730 100644
--- a/src/corelib/doc/images/javaiterators2.svg
+++ b/src/corelib/doc/images/javaiterators2.svg
@@ -15,6 +15,14 @@
svg .text-style { font: 20px arial; fill: black }
svg .small-text-style { font: 12px monospace; fill: black }
+ svg.dark .box-style { stroke: #f2f2f2; fill: black }
+ svg.dark .line-style { stroke: red; fill: none }
+ svg.dark .fill-style { stroke: none; fill: red }
+ svg.dark .np-line-style { stroke: #4080ff; fill: none; stroke-width: 1.5 }
+ svg.dark .np-fill-style { stroke: none; fill: #4080ff }
+ svg.dark .text-style { font: 20px arial; fill: #f2f2f2 }
+ svg.dark .small-text-style { font: 12px monospace; fill: #f2f2f2 }
+
[data-theme="dark"] svg .box-style { stroke: #f2f2f2; fill: black }
[data-theme="dark"] svg .line-style { stroke: red; fill: none }
[data-theme="dark"] svg .fill-style { stroke: none; fill: red }
@@ -33,31 +41,46 @@
</style>
<g transform="translate(10.5, 10.5)">
-<path d="m 0,0 h 80 v 60 h -80 z" class="box-style" />
-<text x="35" y="36" class="text-style">A</text>
+<path d="m 0,0 h 80 v 60 h -80 z" stroke="black" fill="white"
+ class="box-style" />
+<text x="35" y="36" font-family="arial" font-size="20px"
+ class="text-style">A</text>
</g>
<g transform="translate(90.5, 10.5)">
-<path d="m 0,0 h 80 v 60 h -80 z" class="box-style" />
-<text x="35" y="36" class="text-style">B</text>
-<path d="M 0,60 c 0,30 50,40 80,30" class="np-line-style" />
-<path d="M 0,60 l -2,14 l 11,-4 z" class="np-fill-style" />
-<text x="-15" y="110" class="small-text-style">previous()</text>
+<path d="m 0,0 h 80 v 60 h -80 z" stroke="black" fill="white"
+ class="box-style" />
+<text x="35" y="36" font-family="arial" font-size="20px"
+ class="text-style">B</text>
+<path d="M 0,60 c 0,30 50,40 80,30" stroke="blue" fill="none"
+ class="np-line-style" />
+<path d="M 0,60 l -2,14 l 11,-4 z" stroke="none" fill="blue"
+ class="np-fill-style" />
+<text x="-15" y="110"
+ class="small-text-style">previous()</text>
</g>
<g transform="translate(170.5, 10.5)">
-<path d="m 0,0 h 80 v 60 h -80 z" class="box-style" />
-<text x="35" y="36" class="text-style">C</text>
-<path d="M 0,60 v 50" class="line-style" />
-<path d="M 0,60 l -5,10 l 10,0 z" class="fill-style" />
-<text x="30" y="110" class="small-text-style">next()</text>
+<path d="m 0,0 h 80 v 60 h -80 z" stroke="black" fill="white"
+ class="box-style" />
+<text x="35" y="36" font-family="arial" font-size="20px"
+ class="text-style">C</text>
+<path d="M 0,60 v 50" stroke="red"
+ class="line-style" />
+<path d="M 0,60 l -5,10 l 10,0 z" stroke="none" fill="red"
+ class="fill-style" />
+<text x="30" y="110"
+ class="small-text-style">next()</text>
</g>
<g transform="translate(250.5, 10.5)">
-<path d="m 0,0 h 80 v 60 h -80 z" class="box-style" />
-<text x="35" y="36" class="text-style">D</text>
-<path d="M 0,60 c 0,30 -50,40 -80,30" class="np-line-style" />
-<path d="M 0,60 l 2,14 l -11,-4 z" class="np-fill-style" />
+<path d="m 0,0 h 80 v 60 h -80 z" stroke="black" fill="white"
+ class="box-style" />
+<text x="35" y="36" font-family="arial" font-size="20px"
+ class="text-style">D</text>
+<path d="M 0,60 c 0,30 -50,40 -80,30" stroke="blue" fill="none"
+ class="np-line-style" />
+<path d="M 0,60 l 2,14 l -11,-4 z" stroke="none" fill="blue"
+ class="np-fill-style" />
</g>
-
</svg>
diff --git a/src/corelib/doc/images/stliterators1.svg b/src/corelib/doc/images/stliterators1.svg
new file mode 100644
index 00000000000..478211c78d7
--- /dev/null
+++ b/src/corelib/doc/images/stliterators1.svg
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ version="1.1"
+ width="420"
+ height="110"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+
+<style>
+ svg .box-style { stroke: black; fill: white }
+ svg .line-style { stroke: red; fill: none }
+ svg .text-style { font: 20px arial; fill: black }
+ svg .fill-style { stroke: none; fill: red }
+ svg .fn-text-style { font: 14px monospace; fill: black }
+
+ svg.dark .box-style { stroke: #f2f2f2; fill: black }
+ svg.dark .line-style { stroke: red; fill: none }
+ svg.dark .text-style { font: 20px arial; fill: #f2f2f2 }
+ svg.dark .fill-style { stroke: none; fill: red }
+ svg.dark .fn-text-style { font: 14px monospace; fill: #f2f2f2 }
+
+ [data-theme="dark"] svg .box-style { stroke: #f2f2f2; fill: black }
+ [data-theme="dark"] svg .line-style { stroke: red; fill: none }
+ [data-theme="dark"] svg .text-style { font: 20px arial; fill: #f2f2f2 }
+ [data-theme="dark"] svg .fill-style { stroke: none; fill: red }
+ [data-theme="dark"] svg .fn-text-style { font: 14px monospace; fill: #f2f2f2 }
+
+ [data-theme="light"] svg .box-style { stroke: black; fill: white }
+ [data-theme="light"] svg .line-style { stroke: red; fill: none }
+ [data-theme="light"] svg .text-style { font: 20px arial; fill: black }
+ [data-theme="light"] svg .fill-style { stroke: none; fill: red }
+ [data-theme="light"] svg .fn-text-style { font: 14px monospace; fill: black }
+</style>
+
+<g transform="translate(10.5, 10.5)">
+<path d="m 0,0 h 80 v 60 h -80 z" stroke="black" fill="white"
+ class="box-style" />
+<text x="35" y="36" font-family="arial" font-size="20px"
+ class="text-style">A</text>
+<path d="M 40,60 v 30" stroke="red"
+ class="line-style" />
+<path d="M 40,60 l -5,10 l 10,0 z" stroke="none" fill="red"
+ class="fill-style" />
+</g>
+
+<g transform="translate(90.5, 10.5)">
+<path d="m 0,0 h 80 v 60 h -80 z" stroke="black" fill="white"
+ class="box-style" />
+<text x="35" y="36" font-family="arial" font-size="20px"
+ class="text-style">B</text>
+<path d="M 40,60 v 30" stroke="red"
+ class="line-style" />
+<path d="M 40,60 l -5,10 l 10,0 z" stroke="none" fill="red"
+ class="fill-style" />
+</g>
+
+<g transform="translate(170.5, 10.5)">
+<path d="m 0,0 h 80 v 60 h -80 z" stroke="black" fill="white"
+ class="box-style" />
+<text x="35" y="36" font-family="arial" font-size="20px"
+ class="text-style">C</text>
+<path d="M 40,60 v 30" stroke="red"
+ class="line-style" />
+<path d="M 40,60 l -5,10 l 10,0 z" stroke="none" fill="red"
+ class="fill-style" />
+</g>
+
+<g transform="translate(250.5, 10.5)">
+<path d="m 0,0 h 80 v 60 h -80 z" stroke="black" fill="white"
+ class="box-style" />
+<text x="35" y="36" font-family="arial" font-size="20px"
+ class="text-style">D</text>
+<path d="M 40,60 v 30" stroke="red"
+ class="line-style" />
+<path d="M 40,60 l -5,10 l 10,0 z" stroke="none" fill="red"
+ class="fill-style" />
+</g>
+
+<g transform="translate(330.5, 10.5)">
+<path d="m 0,0 h 80 v 60 h -80 z" stroke="black" fill="white"
+ stroke-dasharray="3,3"
+ class="box-style" />
+<text x="20" y="36" font-family="monospace" font-size="14px"
+ class="fn-text-style">end()</text>
+<path d="M 40,60 v 30" stroke="red"
+ class="line-style" />
+<path d="M 40,60 l -5,10 l 10,0 z" stroke="none" fill="red"
+ class="fill-style" />
+</g>
+</svg>
diff --git a/src/corelib/doc/src/cmake/cmake-properties.qdoc b/src/corelib/doc/src/cmake/cmake-properties.qdoc
index d248257021c..c7b1a27a4b4 100644
--- a/src/corelib/doc/src/cmake/cmake-properties.qdoc
+++ b/src/corelib/doc/src/cmake/cmake-properties.qdoc
@@ -772,7 +772,6 @@ CMake properties:
\brief Sets the FOLDER property for Qt-internal targets.
\cmakepropertysince 6.5
-\preliminarycmakeproperty
Name of the \l FOLDER for internal targets that are added by Qt's CMake
commands.
diff --git a/src/corelib/doc/src/containers.qdoc b/src/corelib/doc/src/containers.qdoc
index 874ab807609..38ce2188e13 100644
--- a/src/corelib/doc/src/containers.qdoc
+++ b/src/corelib/doc/src/containers.qdoc
@@ -275,7 +275,7 @@
The diagram below shows the valid iterator positions as red
arrows for a list containing four items:
- \image stliterators1.png
+ \image stliterators1.svg STL-style iterators point to items
Iterating backward with an STL-style iterator is done with reverse iterators:
diff --git a/src/corelib/doc/src/java-style-iterators.qdoc b/src/corelib/doc/src/java-style-iterators.qdoc
index a0e5c53d633..fc1378bb718 100644
--- a/src/corelib/doc/src/java-style-iterators.qdoc
+++ b/src/corelib/doc/src/java-style-iterators.qdoc
@@ -70,7 +70,7 @@
\l{QListIterator::next()}{next()} and
\l{QListIterator::previous()}{previous()} on an iterator:
- \image javaiterators2.png Iterating to the next and previous items
+ \image javaiterators2.svg Iterating to the next and previous items
The following table summarizes the QListIterator API:
diff --git a/src/corelib/thread/qfuture.qdoc b/src/corelib/thread/qfuture.qdoc
index f3f32e20adc..5e97086694b 100644
--- a/src/corelib/thread/qfuture.qdoc
+++ b/src/corelib/thread/qfuture.qdoc
@@ -786,7 +786,7 @@
between the second and third result, and returns the second result; and
so on.
- \image javaiterators1.png
+ \image javaiterators1.svg
Here's how to iterate over the elements in reverse order:
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index fe79490f54b..d63da38b747 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -2196,29 +2196,27 @@ QColor QColor::toHsv() const noexcept
color.ct.ahsv.alpha = ct.argb.alpha;
color.ct.ahsv.pad = 0;
- const float r = ct.argb.red / float(USHRT_MAX);
- const float g = ct.argb.green / float(USHRT_MAX);
- const float b = ct.argb.blue / float(USHRT_MAX);
- const float max = Q_MAX_3(r, g, b);
- const float min = Q_MIN_3(r, g, b);
- const float delta = max - min;
- color.ct.ahsv.value = qRound(max * USHRT_MAX);
- if (qFuzzyIsNull(delta)) {
+ const ushort r = ct.argb.red;
+ const ushort g = ct.argb.green;
+ const ushort b = ct.argb.blue;
+ const auto [min, max] = std::minmax({r, g, b});
+ color.ct.ahsv.value = max;
+ if (max == min) {
// achromatic case, hue is undefined
color.ct.ahsv.hue = USHRT_MAX;
color.ct.ahsv.saturation = 0;
} else {
// chromatic case
- float hue = 0;
+ const float delta = max - min; // cannot overflow
+ float hue;
color.ct.ahsv.saturation = qRound((delta / max) * USHRT_MAX);
- if (qFuzzyCompare(r, max)) {
- hue = ((g - b) /delta);
- } else if (qFuzzyCompare(g, max)) {
- hue = (2.0f + (b - r) / delta);
- } else if (qFuzzyCompare(b, max)) {
- hue = (4.0f + (r - g) / delta);
+ if (max == r) {
+ hue = 0 + (g - b) / delta;
+ } else if (max == g) {
+ hue = 2 + (b - r) / delta;
} else {
- Q_ASSERT_X(false, "QColor::toHsv", "internal error");
+ Q_ASSERT(max == b); // max({r,g,b}) must be one of r, g, and b!
+ hue = 4 + (r - g) / delta;
}
hue *= 60.0f;
if (hue < 0.0f)
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 6428653de26..66bb65685fa 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -216,6 +216,19 @@ static void ensureInitialized()
can be:
\snippet code/src_network_access_qnetworkaccessmanager.cpp 1
+ Since Qt 6.11 the defaults of the TCP Keepalive parameters used by
+ QNetworkAccessManager have been changed. With the current settings
+ the connection will be terminated after 2 minutes of inactivity.
+
+ These settings can be changed the individual requests, to make
+ them more lenient, or even more aggressive via the QNetworkRequest API.
+ \snippet http/httpwindow.cpp qnam-tcpkeepalive
+
+ In the above snippet we are picking a more aggressive strategy, to
+ terminate the connection after thirty seconds of inactivity. This can
+ be useful, for example, in early detection of network hangs caused
+ by network changes on Linux.
+
\sa QNetworkRequest, QNetworkReply, QNetworkProxy
*/
diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp
index e9b90d787bc..98e51397c17 100644
--- a/src/plugins/styles/modernwindows/qwindows11style.cpp
+++ b/src/plugins/styles/modernwindows/qwindows11style.cpp
@@ -2622,6 +2622,7 @@ void QWindows11Style::polish(QPalette& result)
d->m_titleBarNormalIcon = QIcon();
d->m_toolbarExtensionButton = QIcon();
d->m_lineEditClearButton = QIcon();
+ d->m_tabCloseButton = QIcon();
}
QPixmap QWindows11Style::standardPixmap(StandardPixmap standardPixmap,
@@ -2662,6 +2663,14 @@ QIcon QWindows11Style::standardIcon(StandardPixmap standardIcon,
}
return d->m_toolbarExtensionButton;
}
+ case SP_TabCloseButton: {
+ if (d->m_tabCloseButton.isNull()) {
+ auto e = new WinFontIconEngine(fluentIcon(Icon::ChromeClose), d->assetFont);
+ e->setScale(0.6);
+ d->m_tabCloseButton = QIcon(e);
+ }
+ return d->m_tabCloseButton;
+ }
default:
break;
}
diff --git a/src/plugins/styles/modernwindows/qwindows11style_p.h b/src/plugins/styles/modernwindows/qwindows11style_p.h
index 9d0cdda3e33..43a344a6ac9 100644
--- a/src/plugins/styles/modernwindows/qwindows11style_p.h
+++ b/src/plugins/styles/modernwindows/qwindows11style_p.h
@@ -125,6 +125,7 @@ class QWindows11StylePrivate : public QWindowsVistaStylePrivate {
protected:
QIcon m_toolbarExtensionButton;
QIcon m_lineEditClearButton;
+ QIcon m_tabCloseButton;
};
QT_END_NAMESPACE
diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp
index 29cafe9aea4..f3db4ece49e 100644
--- a/src/testlib/qtestlog.cpp
+++ b/src/testlib/qtestlog.cpp
@@ -305,9 +305,7 @@ namespace QTest {
{
static QBasicAtomicInt counter = Q_BASIC_ATOMIC_INITIALIZER(QTest::maxWarnings);
- auto loggerCapture = loggers->allLoggers();
-
- if (loggerCapture.isEmpty()) {
+ if (loggers.isDestroyed() || loggers->allLoggers().isEmpty()) {
// the message handler may be called from a worker thread, after the main thread stopped
// logging. Forwarding to original message handler to avoid swallowing the message
Q_ASSERT(oldMessageHandler);
@@ -326,6 +324,8 @@ namespace QTest {
return;
}
+ auto loggerCapture = loggers->allLoggers();
+
if (type != QtFatalMsg) {
if (counter.loadRelaxed() <= 0)
return;
diff --git a/src/tools/macdeployqt/shared/shared.cpp b/src/tools/macdeployqt/shared/shared.cpp
index 0731fb616ed..7f8590ae894 100644
--- a/src/tools/macdeployqt/shared/shared.cpp
+++ b/src/tools/macdeployqt/shared/shared.cpp
@@ -1008,6 +1008,31 @@ DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks,
rpathsUsed.append(framework.rpathUsed);
}
+ // To properly find all dependencies of the current framework / library further down in
+ // getQtFrameworks, we need to get its rpaths, resolve them in the context of its original
+ // location before it is copied, and add them as candidate rpaths.
+ //
+ // This is necessary to handle cases like
+ // (1) QtNetwork.framework -> (2) libbrotlidec.dylib -> (3) libbrotlicommon.1.dylib
+ // to correctly resolve the path to (3) when it is referenced as
+ // '@rpath/libbrotlicommon.1.dylib' and (2) has an LC_RPATH of '@loader_path/../lib', and
+ // no other absolute rpaths. So the '@loader_path/../lib' will be resolved relative
+ // to (2)'s original location and its LC_RPATH.
+ //
+ // Otherwise we'd only have the Qt prefix and the current bundle app dir as rpath
+ // candidates, and once (2) is copied into the app bundle, there's no way
+ // '@rpath/libbrotlicommon.1.dylib' could resolve to the real path on disk from the two
+ // candidates above.
+ if (!framework.sourceFilePath.isEmpty()) {
+ const QList<QString> sourceRPaths = getBinaryRPaths(framework.sourceFilePath, true);
+ for (const QString &sourceRPath : sourceRPaths) {
+ const QDir sourceRPathDir(sourceRPath);
+ if (sourceRPathDir.exists() && !rpathsUsed.contains(sourceRPath)) {
+ rpathsUsed.append(sourceRPath);
+ }
+ }
+ }
+
// Copy the framework/dylib to the app bundle.
const QString deployedBinaryPath = framework.isDylib ? copyDylib(framework, bundlePath)
: copyFramework(framework, bundlePath);
@@ -1032,7 +1057,7 @@ DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks,
for (const FrameworkInfo &dependency : dependencies) {
if (dependency.rpathUsed.isEmpty()) {
changeInstallName(bundlePath, dependency, QStringList() << deployedBinaryPath, useLoaderPath);
- } else {
+ } else if (!rpathsUsed.contains(dependency.rpathUsed)) {
rpathsUsed.append(dependency.rpathUsed);
}
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index 0f0abb6e1d5..44218d41ded 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -52,6 +52,14 @@ public:
void enterEvent(QEnterEvent *event) override;
void leaveEvent(QEvent *event) override;
void paintEvent(QPaintEvent *event) override;
+
+ void setParentClipRect(const QRect &clipRect)
+ {
+ m_parentClipRect = clipRect;
+ }
+
+protected:
+ QRect m_parentClipRect;
};
}
@@ -598,10 +606,11 @@ QRect QTabBarPrivate::normalizedScrollRect(int index)
q->initStyleOption(&opt, currentIndex);
opt.rect = q->rect();
- QRect scrollButtonLeftRect = q->style()->subElementRect(QStyle::SE_TabBarScrollLeftButton, &opt, q);
- QRect scrollButtonRightRect = q->style()->subElementRect(QStyle::SE_TabBarScrollRightButton, &opt, q);
- QRect tearLeftRect = q->style()->subElementRect(QStyle::SE_TabBarTearIndicatorLeft, &opt, q);
- QRect tearRightRect = q->style()->subElementRect(QStyle::SE_TabBarTearIndicatorRight, &opt, q);
+ const auto style = q->style();
+ QRect scrollButtonLeftRect = style->subElementRect(QStyle::SE_TabBarScrollLeftButton, &opt, q);
+ QRect scrollButtonRightRect = style->subElementRect(QStyle::SE_TabBarScrollRightButton, &opt, q);
+ QRect tearLeftRect = style->subElementRect(QStyle::SE_TabBarTearIndicatorLeft, &opt, q);
+ QRect tearRightRect = style->subElementRect(QStyle::SE_TabBarTearIndicatorRight, &opt, q);
if (verticalTabs(shape)) {
int topEdge, bottomEdge;
@@ -739,7 +748,7 @@ void QTabBarPrivate::layoutTab(int index)
if (tab->leftWidget) {
QRect rect = q->style()->subElementRect(QStyle::SE_TabBarTabLeftButton, &opt, q);
QPoint p = rect.topLeft();
- if ((index == pressedIndex) || paintWithOffsets) {
+ if (index == pressedIndex) {
if (vertical)
p.setY(p.y() + tab->dragOffset);
else
@@ -750,7 +759,7 @@ void QTabBarPrivate::layoutTab(int index)
if (tab->rightWidget) {
QRect rect = q->style()->subElementRect(QStyle::SE_TabBarTabRightButton, &opt, q);
QPoint p = rect.topLeft();
- if ((index == pressedIndex) || paintWithOffsets) {
+ if (index == pressedIndex) {
if (vertical)
p.setY(p.y() + tab->dragOffset);
else
@@ -1004,8 +1013,13 @@ int QTabBar::insertTab(int index, const QIcon& icon, const QString &text)
}
if (isVisible() && tabAt(d->mousePosition) == index) {
- d->hoverIndex = index;
- d->hoverRect = tabRect(index);
+ if (d->normalizedScrollRect(index).contains(d->mousePosition)) {
+ d->hoverIndex = index;
+ d->hoverRect = tabRect(index);
+ } else {
+ d->hoverIndex = -1;
+ d->hoverRect = QRect();
+ }
}
tabInserted(index);
@@ -1096,11 +1110,13 @@ void QTabBar::removeTab(int index)
if (d->hoverRect.isValid()) {
update(d->hoverRect);
d->hoverIndex = tabAt(d->mousePosition);
- if (d->validIndex(d->hoverIndex)) {
+ if (d->validIndex(d->hoverIndex)
+ && d->normalizedScrollRect(d->hoverIndex).contains(d->mousePosition)) {
d->hoverRect = tabRect(d->hoverIndex);
update(d->hoverRect);
} else {
d->hoverRect = QRect();
+ d->hoverIndex = -1;
}
}
tabRemoved(index);
@@ -1692,15 +1708,18 @@ bool QTabBar::event(QEvent *event)
case QEvent::HoverEnter: {
QHoverEvent *he = static_cast<QHoverEvent *>(event);
d->mousePosition = he->position().toPoint();
- if (!d->hoverRect.contains(d->mousePosition)) {
+ const auto sr = d->normalizedScrollRect();
+ const auto oldHoverRect = d->hoverRect & sr;
+ if (!oldHoverRect.contains(d->mousePosition)) {
if (d->hoverRect.isValid())
update(d->hoverRect);
d->hoverIndex = tabAt(d->mousePosition);
- if (d->validIndex(d->hoverIndex)) {
+ if (d->validIndex(d->hoverIndex) && sr.contains(d->mousePosition)) {
d->hoverRect = tabRect(d->hoverIndex);
update(d->hoverRect);
} else {
d->hoverRect = QRect();
+ d->hoverIndex = -1;
}
}
return true;
@@ -1845,10 +1864,14 @@ void QTabBar::paintEvent(QPaintEvent *)
QStyleOption opt;
opt.initFrom(this);
QRegion buttonRegion;
- if (d->leftB->isVisible())
- buttonRegion |= style()->subElementRect(QStyle::SE_TabBarScrollLeftButton, &opt, this);
- if (d->rightB->isVisible())
- buttonRegion |= style()->subElementRect(QStyle::SE_TabBarScrollRightButton, &opt, this);
+ if (d->leftB->isVisible()) {
+ const auto r = style()->subElementRect(QStyle::SE_TabBarScrollLeftButton, &opt, this);
+ buttonRegion |= r;
+ }
+ if (d->rightB->isVisible()) {
+ const auto r = style()->subElementRect(QStyle::SE_TabBarScrollRightButton, &opt, this);
+ buttonRegion |= r;
+ }
if (!buttonRegion.isEmpty())
p.setClipRegion(QRegion(rect()) - buttonRegion);
}
@@ -1857,9 +1880,13 @@ void QTabBar::paintEvent(QPaintEvent *)
const auto tab = d->tabList.at(i);
if (!tab->visible)
continue;
+ for (const auto side : { QTabBar::LeftSide, QTabBar::RightSide }) {
+ if (auto closeButton = qobject_cast<CloseButton *>(tabButton(i, side)))
+ closeButton->setParentClipRect(scrollRect);
+ }
QStyleOptionTab tabOption;
initStyleOption(&tabOption, i);
- if (d->paintWithOffsets && tab->dragOffset != 0) {
+ if (tab->dragOffset != 0) {
if (vertical) {
tabOption.rect.moveTop(tabOption.rect.y() + tab->dragOffset);
} else {
@@ -1901,7 +1928,7 @@ void QTabBar::paintEvent(QPaintEvent *)
const auto tab = d->tabList.at(selected);
initStyleOption(&tabOption, selected);
- if (d->paintWithOffsets && tab->dragOffset != 0) {
+ if (tab->dragOffset != 0) {
// if the drag offset is != 0, a move is in progress (drag or animation)
// => set the tab position to Moving to preserve the rect
tabOption.position = QStyleOptionTab::TabPosition::Moving;
@@ -2934,6 +2961,11 @@ void CloseButton::paintEvent(QPaintEvent *)
opt.state |= QStyle::State_Selected;
}
+ if (m_parentClipRect.isValid()) {
+ auto tl = mapFromParent(m_parentClipRect.topLeft());
+ auto br = mapFromParent(m_parentClipRect.bottomRight());
+ p.setClipRect(QRect(tl, br));
+ }
style()->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, &p, this);
}
diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h
index 38fbde76470..5b31926253f 100644
--- a/src/widgets/widgets/qtabbar_p.h
+++ b/src/widgets/widgets/qtabbar_p.h
@@ -56,7 +56,7 @@ public:
QTabBarPrivate()
: layoutDirty(false), drawBase(true), elideModeSetByUser(false), useScrollButtons(false),
useScrollButtonsSetByUser(false), expanding(true), closeButtonOnTabs(false),
- paintWithOffsets(true), movable(false), dragInProgress(false), documentMode(false),
+ movable(false), dragInProgress(false), documentMode(false),
autoHide(false), changeCurrentOnDrag(false)
{}
~QTabBarPrivate()
@@ -95,7 +95,6 @@ public:
bool useScrollButtonsSetByUser : 1;
bool expanding : 1;
bool closeButtonOnTabs : 1;
- bool paintWithOffsets : 1;
bool movable : 1;
bool dragInProgress : 1;
bool documentMode : 1;
diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST
index 9651c1480c8..12da5b423ab 100644
--- a/tests/auto/widgets/kernel/qwidget/BLACKLIST
+++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST
@@ -4,11 +4,6 @@ osx
macos arm
[render_systemClip]
osx
-[multipleToplevelFocusCheck]
-centos
-opensuse-leap
-ubuntu
-sles-15
# QTBUG-87668
[showMinimizedKeepsFocus]
android
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index e3d172c60c0..359a0946474 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -6931,9 +6931,13 @@ class TopLevelFocusCheck: public QWidget
Q_OBJECT
public:
QLineEdit* edit;
- explicit TopLevelFocusCheck(QWidget *parent = nullptr)
+ explicit TopLevelFocusCheck(const QString &name, QWidget *parent = nullptr)
: QWidget(parent), edit(new QLineEdit(this))
{
+ const QString title = QLatin1String(QTest::currentTestFunction()) + "_"_L1 + name;
+ setWindowTitle(title);
+ setObjectName(title);
+ edit->setObjectName(QString("%1_edit"_L1).arg(title));
edit->hide();
edit->installEventFilter(this);
}
@@ -6943,7 +6947,7 @@ public slots:
{
edit->show();
edit->setFocus(Qt::OtherFocusReason);
- QCoreApplication::processEvents();
+ QVERIFY(QTest::qWaitForWindowFocused(edit));
}
bool eventFilter(QObject *obj, QEvent *event) override
{
@@ -6963,49 +6967,42 @@ void tst_QWidget::multipleToplevelFocusCheck()
if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))
QSKIP("Window activation is not supported");
- TopLevelFocusCheck w1;
- TopLevelFocusCheck w2;
+ TopLevelFocusCheck w1("Widget-1"_L1);
+ TopLevelFocusCheck w2("Widget-2"_L1);
- const QString title = QLatin1String(QTest::currentTestFunction());
- w1.setWindowTitle(title + QLatin1String("_W1"));
w1.move(m_availableTopLeft + QPoint(20, 20));
w1.resize(200, 200);
w1.show();
QVERIFY(QTest::qWaitForWindowExposed(&w1));
- w2.setWindowTitle(title + QLatin1String("_W2"));
w2.move(w1.frameGeometry().topRight() + QPoint(20, 0));
w2.resize(200,200);
w2.show();
QVERIFY(QTest::qWaitForWindowExposed(&w2));
w1.activateWindow();
- QApplicationPrivate::setActiveWindow(&w1);
QVERIFY(QTest::qWaitForWindowActive(&w1));
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w1));
+ QTRY_COMPARE(QApplication::activeWindow(), &w1);
QTest::mouseDClick(&w1, Qt::LeftButton);
- QTRY_COMPARE(QApplication::focusWidget(), static_cast<QWidget *>(w1.edit));
+ QTRY_COMPARE(QApplication::focusWidget(), w1.edit);
w2.activateWindow();
- QApplicationPrivate::setActiveWindow(&w2);
QVERIFY(QTest::qWaitForWindowActive(&w2));
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w2));
+ QTRY_COMPARE(QApplication::activeWindow(), &w2);
QTest::mouseClick(&w2, Qt::LeftButton);
QTRY_COMPARE(QApplication::focusWidget(), nullptr);
QTest::mouseDClick(&w2, Qt::LeftButton);
- QTRY_COMPARE(QApplication::focusWidget(), static_cast<QWidget *>(w2.edit));
+ QTRY_COMPARE(QApplication::focusWidget(), w2.edit);
w1.activateWindow();
- QApplicationPrivate::setActiveWindow(&w1);
QVERIFY(QTest::qWaitForWindowActive(&w1));
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w1));
+ QTRY_COMPARE(QApplication::activeWindow(), &w1);
QTest::mouseDClick(&w1, Qt::LeftButton);
- QTRY_COMPARE(QApplication::focusWidget(), static_cast<QWidget *>(w1.edit));
+ QTRY_COMPARE(QApplication::focusWidget(), w1.edit);
w2.activateWindow();
- QApplicationPrivate::setActiveWindow(&w2);
QVERIFY(QTest::qWaitForWindowActive(&w2));
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w2));
+ QTRY_COMPARE(QApplication::activeWindow(), &w2);
QTest::mouseClick(&w2, Qt::LeftButton);
QTRY_COMPARE(QApplication::focusWidget(), nullptr);
}