diff options
89 files changed, 2584 insertions, 235 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 62f12110d0..2bc704bc73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ if(NOT QT_BUILD_STANDALONE_TESTS) "${CMAKE_CURRENT_SOURCE_DIR}/cmake/3rdparty/kwin" ) - if(APPLE_OSX) + if(MACOS) # Add module directory to pick up custom Info.plist template list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos") endif() diff --git a/cmake/FindGLESv2.cmake b/cmake/FindGLESv2.cmake index 49e757ef55..3ba7b85d68 100644 --- a/cmake/FindGLESv2.cmake +++ b/cmake/FindGLESv2.cmake @@ -54,9 +54,9 @@ find_package_handle_standard_args(GLESv2 DEFAULT_MSG ${package_args}) mark_as_advanced(${package_args}) if(GLESv2_FOUND AND NOT TARGET GLESv2::GLESv2) - if(EMSCRIPTEN OR APPLE_UIKIT) + if(EMSCRIPTEN OR UIKIT) add_library(GLESv2::GLESv2 INTERFACE IMPORTED) - if(APPLE_UIKIT) + if(UIKIT) # For simulator_and_device builds we can't specify the full library path, because # it's specific to either the device or the simulator. Resort to passing a link # flag instead. diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake index 47f9a1afd7..5b2dd5bfda 100644 --- a/cmake/QtBaseGlobalTargets.cmake +++ b/cmake/QtBaseGlobalTargets.cmake @@ -95,7 +95,7 @@ list(APPEND init_platform "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\" CACHE ST if(APPLE) # For simulator_and_device build, we should not explicitly set the sysroot. list(LENGTH CMAKE_OSX_ARCHITECTURES _qt_osx_architectures_count) - if(CMAKE_OSX_SYSROOT AND NOT _qt_osx_architectures_count GREATER 1 AND APPLE_UIKIT) + if(CMAKE_OSX_SYSROOT AND NOT _qt_osx_architectures_count GREATER 1 AND UIKIT) list(APPEND init_platform "set(CMAKE_OSX_SYSROOT \"${CMAKE_OSX_SYSROOT}\" CACHE PATH \"\")") endif() unset(_qt_osx_architectures_count) @@ -105,7 +105,7 @@ if(APPLE) "set(CMAKE_OSX_DEPLOYMENT_TARGET \"${CMAKE_OSX_DEPLOYMENT_TARGET}\" CACHE STRING \"\")") endif() - if(APPLE_UIKIT) + if(UIKIT) list(APPEND init_platform "set(CMAKE_SYSTEM_NAME \"${CMAKE_SYSTEM_NAME}\" CACHE STRING \"\")") set(_qt_osx_architectures_escaped "${CMAKE_OSX_ARCHITECTURES}") @@ -177,7 +177,7 @@ include("${CMAKE_CURRENT_SOURCE_DIR}/configure.cmake") # Do what mkspecs/features/uikit/default_pre.prf does, aka enable sse2 for # simulator_and_device_builds. -if(APPLE_UIKIT AND NOT QT_UIKIT_SDK) +if(UIKIT AND NOT QT_UIKIT_SDK) set(__QtFeature_custom_enabled_cache_variables TEST_subarch_sse2 FEATURE_sse2 @@ -267,7 +267,7 @@ qt_copy_or_install(DIRECTORY cmake/ PATTERN "3rdparty" EXCLUDE ) -if(APPLE_OSX) +if(MACOS) qt_copy_or_install(FILES cmake/macos/MacOSXBundleInfo.plist.in DESTINATION "${__GlobalConfig_install_dir}/macos" diff --git a/cmake/QtBuild.cmake b/cmake/QtBuild.cmake index c32678a5cf..c8163ebdea 100644 --- a/cmake/QtBuild.cmake +++ b/cmake/QtBuild.cmake @@ -3407,33 +3407,15 @@ function(qt_add_simd_part target) endif() string(TOUPPER "QT_CFLAGS_${arg_SIMD}" simd_flags) - if (NOT TARGET "${name}") - add_library("${name}" OBJECT) - endif() - target_sources("${name}" PRIVATE ${arg_SOURCES}) - target_include_directories("${name}" PRIVATE - ${arg_INCLUDE_DIRECTORIES} - $<TARGET_PROPERTY:${target},INCLUDE_DIRECTORIES>) - target_compile_options("${name}" PRIVATE - ${${simd_flags}} - ${arg_COMPILE_FLAGS} - $<TARGET_PROPERTY:${target},COMPILE_OPTIONS>) - target_compile_definitions("${name}" PRIVATE - $<TARGET_PROPERTY:${target},COMPILE_DEFINITIONS>) - - target_link_libraries("${target}" PRIVATE "${name}") - - # Add a link-only dependency on the parent library, to force copying of framework headers - # before trying to compile a source file. - target_link_libraries("${name}" PRIVATE - $<FILTER:$<TARGET_PROPERTY:${target},LINK_LIBRARIES>,EXCLUDE,^${target}_simd_>) - - if(NOT BUILD_SHARED_LIBS) - qt_install( - TARGETS ${name} - EXPORT "${INSTALL_CMAKE_NAMESPACE}Targets" + foreach(source IN LISTS arg_SOURCES) + set_property(SOURCE "${source}" APPEND + PROPERTY COMPILE_OPTIONS + ${${simd_flags}} + ${arg_COMPILE_FLAGS} ) - endif() + endforeach() + set_source_files_properties(${arg_SOURCES} PROPERTIES SKIP_PRECOMPILE_HEADERS TRUE) + target_sources(${target} PRIVATE ${arg_SOURCES}) else() if(QT_CMAKE_DEBUG_EXTEND_TARGET) message("qt_add_simd_part(${target} SIMD ${arg_SIMD} ...): Skipped") diff --git a/cmake/QtCompilerOptimization.cmake b/cmake/QtCompilerOptimization.cmake index 1f50044a6f..42206368d9 100644 --- a/cmake/QtCompilerOptimization.cmake +++ b/cmake/QtCompilerOptimization.cmake @@ -62,7 +62,7 @@ if(GCC OR CLANG) set(QT_CFLAGS_AVX512VBMI "-mavx512vbmi") set(QT_CFLAGS_AESNI "-maes") set(QT_CFLAGS_SHANI "-msha") - if(NOT APPLE_UIKIT AND NOT QT_64BIT) + if(NOT UIKIT AND NOT QT_64BIT) set(QT_CFLAGS_NEON "-mfpu=neon") endif() set(QT_CFLAGS_MIPS_DSP "-mdsp") diff --git a/cmake/QtConfig.cmake.in b/cmake/QtConfig.cmake.in index e9d2d7f2dc..b63dca8732 100644 --- a/cmake/QtConfig.cmake.in +++ b/cmake/QtConfig.cmake.in @@ -34,7 +34,7 @@ list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}") list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}/3rdparty/extra-cmake-modules/find-modules") list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}/3rdparty/kwin") -if(APPLE_OSX) +if(MACOS) # Add module directory to pick up custom Info.plist template list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}/macos") endif() diff --git a/cmake/QtFeature.cmake b/cmake/QtFeature.cmake index 34ae83b55d..c48e13833e 100644 --- a/cmake/QtFeature.cmake +++ b/cmake/QtFeature.cmake @@ -722,7 +722,7 @@ function(qt_get_platform_try_compile_vars out_var) endforeach() # Pass darwin specific options. - if(APPLE_UIKIT) + if(UIKIT) if(CMAKE_OSX_ARCHITECTURES) list(GET CMAKE_OSX_ARCHITECTURES 0 osx_first_arch) diff --git a/cmake/QtInternalTargets.cmake b/cmake/QtInternalTargets.cmake index ff42e726dc..d1c383d697 100644 --- a/cmake/QtInternalTargets.cmake +++ b/cmake/QtInternalTargets.cmake @@ -99,13 +99,13 @@ endif() target_compile_definitions(PlatformCommonInternal INTERFACE $<$<NOT:$<CONFIG:Debug>>:QT_NO_DEBUG>) -if(APPLE_OSX) +if(MACOS) target_compile_definitions(PlatformCommonInternal INTERFACE GL_SILENCE_DEPRECATION) -elseif(APPLE_UIKIT) +elseif(UIKIT) target_compile_definitions(PlatformCommonInternal INTERFACE GLES_SILENCE_DEPRECATION) endif() -if(APPLE_UIKIT) +if(UIKIT) # Do what mkspecs/features/uikit/default_pre.prf does, aka enable sse2 for # simulator_and_device_builds. if(FEATURE_simulator_and_device) diff --git a/cmake/QtPlatformSupport.cmake b/cmake/QtPlatformSupport.cmake index b54d52eba4..7d057b2ca4 100644 --- a/cmake/QtPlatformSupport.cmake +++ b/cmake/QtPlatformSupport.cmake @@ -22,11 +22,11 @@ qt_set01(BSD APPLE OR OPENBSD OR FREEBSD OR NETBSD) qt_set01(WINRT WIN32 AND CMAKE_VS_PLATFORM_TOOSLET STREQUAL "winrt") # FIXME: How to identify this? -qt_set01(APPLE_IOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "iOS") -qt_set01(APPLE_TVOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "tvOS") -qt_set01(APPLE_WATCHOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "watchOS") -qt_set01(APPLE_UIKIT APPLE AND (APPLE_IOS OR APPLE_TVOS OR APPLE_WATCHOS)) -qt_set01(APPLE_OSX APPLE AND NOT APPLE_UIKIT) +qt_set01(IOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "iOS") +qt_set01(TVOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "tvOS") +qt_set01(WATCHOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "watchOS") +qt_set01(UIKIT APPLE AND (IOS OR TVOS OR WATCHOS)) +qt_set01(MACOS APPLE AND NOT UIKIT) qt_set01(GCC CMAKE_CXX_COMPILER_ID STREQUAL "GNU") qt_set01(CLANG CMAKE_CXX_COMPILER_ID MATCHES "Clang") diff --git a/cmake/QtSetup.cmake b/cmake/QtSetup.cmake index 6e057e4e66..3b43f44bdd 100644 --- a/cmake/QtSetup.cmake +++ b/cmake/QtSetup.cmake @@ -93,7 +93,7 @@ if(FEATURE_developer_build) # Tests are not built by default with qmake for iOS and friends, and thus the overall build # tends to fail. Disable them by default when targeting uikit. - if(APPLE_UIKIT OR ANDROID) + if(UIKIT OR ANDROID) set(QT_BUILD_TESTING OFF) endif() @@ -129,7 +129,7 @@ enable_testing() set(QT_BUILD_EXAMPLES ON) # Examples are not built by default with qmake for iOS and friends, and thus the overall build # tends to fail. Disable them by default when targeting uikit. -if(APPLE_UIKIT OR ANDROID) +if(UIKIT OR ANDROID) set(QT_BUILD_EXAMPLES OFF) endif() diff --git a/configure.cmake b/configure.cmake index 6458264a61..99ec9e7b33 100644 --- a/configure.cmake +++ b/configure.cmake @@ -129,8 +129,8 @@ int main(int argc, char **argv) qt_config_compile_test("separate_debug_info" - LABEL "separate debug information support" - PROJECT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/config.tests/separate_debug_info") + LABEL "separate debug information support" + PROJECT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/config.tests/separate_debug_info") # signaling_nan qt_config_compile_test(signaling_nan LABEL "Signaling NaN for doubles" @@ -318,7 +318,7 @@ qt_feature("android-style-assets" PRIVATE ) qt_feature("shared" PUBLIC LABEL "Building shared libraries" - AUTODETECT NOT APPLE_UIKIT + AUTODETECT NOT UIKIT CONDITION BUILD_SHARED_LIBS ) qt_feature_config("shared" QMAKE_PUBLIC_QT_CONFIG) @@ -380,11 +380,11 @@ qt_feature_config("separate_debug_info" QMAKE_PUBLIC_QT_CONFIG) qt_feature("appstore-compliant" PUBLIC LABEL "App store compliance" PURPOSE "Disables code that is not allowed in platform app stores" - AUTODETECT APPLE_UIKIT OR ANDROID OR WINRT + AUTODETECT UIKIT OR ANDROID OR WINRT ) qt_feature("simulator_and_device" PUBLIC LABEL "Build for both simulator and device" - CONDITION APPLE_UIKIT AND NOT QT_UIKIT_SDK + CONDITION UIKIT AND NOT QT_UIKIT_SDK ) qt_feature_config("simulator_and_device" QMAKE_PUBLIC_QT_CONFIG) qt_feature("force_asserts" PUBLIC @@ -685,7 +685,7 @@ qt_feature("concurrent" PUBLIC qt_feature_definition("concurrent" "QT_NO_CONCURRENT" NEGATE VALUE "1") qt_feature("dbus" PUBLIC PRIVATE LABEL "Qt D-Bus" - AUTODETECT NOT APPLE_UIKIT AND NOT ANDROID AND NOT WINRT + AUTODETECT NOT UIKIT AND NOT ANDROID AND NOT WINRT CONDITION QT_FEATURE_thread ) qt_feature_definition("dbus" "QT_NO_DBUS" NEGATE VALUE "1") @@ -712,7 +712,7 @@ qt_feature("testlib" PRIVATE ) qt_feature("widgets" PRIVATE LABEL "Qt Widgets" - AUTODETECT NOT APPLE_TVOS AND NOT APPLE_WATCHOS + AUTODETECT NOT TVOS AND NOT WATCHOS CONDITION QT_FEATURE_gui ) qt_feature_definition("widgets" "QT_NO_WIDGETS" NEGATE) @@ -868,7 +868,7 @@ qt_configure_add_report_entry( qt_configure_add_report_entry( TYPE ERROR MESSAGE "Debug build wihtout Release build is not currently supported on ios see QTBUG-71990. Use -debug-and-release." - CONDITION APPLE_IOS AND QT_FEATURE_debug AND NOT QT_FEATURE_debug_and_release + CONDITION IOS AND QT_FEATURE_debug AND NOT QT_FEATURE_debug_and_release ) qt_configure_add_report_entry( TYPE WARNING diff --git a/examples/widgets/CMakeLists.txt b/examples/widgets/CMakeLists.txt index 1b18fc8622..a710f75207 100644 --- a/examples/widgets/CMakeLists.txt +++ b/examples/widgets/CMakeLists.txt @@ -28,6 +28,6 @@ if(QT_FEATURE_cursor) # special case add_subdirectory(mainwindows) endif() -if(APPLE_OSX) +if(MACOS) add_subdirectory(mac) endif() diff --git a/examples/widgets/mac/CMakeLists.txt b/examples/widgets/mac/CMakeLists.txt index 82038acfae..39003dc4c8 100644 --- a/examples/widgets/mac/CMakeLists.txt +++ b/examples/widgets/mac/CMakeLists.txt @@ -1,7 +1,7 @@ # Generated from mac.pro. -if(APPLE_OSX) +if(MACOS) add_subdirectory(qmaccocoaviewcontainer) add_subdirectory(qmacnativewidget) endif() diff --git a/qmake/.prev_CMakeLists.txt b/qmake/.prev_CMakeLists.txt index 3f30387fd4..5d32aa4251 100644 --- a/qmake/.prev_CMakeLists.txt +++ b/qmake/.prev_CMakeLists.txt @@ -162,7 +162,7 @@ qt_extend_target(qmake CONDITION UNIX qlocale_unix.cpp-NOTFOUND ) -qt_extend_target(qmake CONDITION APPLE_OSX +qt_extend_target(qmake CONDITION MACOS SOURCES qcore_foundation.mm qcore_mac.cpp diff --git a/qmake/CMakeLists.txt b/qmake/CMakeLists.txt index fb370eda4a..4c8160eda5 100644 --- a/qmake/CMakeLists.txt +++ b/qmake/CMakeLists.txt @@ -165,7 +165,7 @@ qt_extend_target(qmake CONDITION UNIX ../src/corelib/text/qlocale_unix.cpp ) -qt_extend_target(qmake CONDITION APPLE_OSX +qt_extend_target(qmake CONDITION MACOS SOURCES ../src/corelib/kernel/qcore_foundation.mm # special case ../src/corelib/kernel/qcore_mac.cpp # special case diff --git a/src/3rdparty/harfbuzz-ng/.prev_CMakeLists.txt b/src/3rdparty/harfbuzz-ng/.prev_CMakeLists.txt index 9da792e15a..1cdc8bafc0 100644 --- a/src/3rdparty/harfbuzz-ng/.prev_CMakeLists.txt +++ b/src/3rdparty/harfbuzz-ng/.prev_CMakeLists.txt @@ -158,13 +158,13 @@ qt_extend_target(BundledHarfbuzz CONDITION SHAPERS___contains___opentype HAVE_OT ) -qt_extend_target(BundledHarfbuzz CONDITION APPLE_UIKIT +qt_extend_target(BundledHarfbuzz CONDITION UIKIT LIBRARIES ${FWCoreGraphics} ${FWCoreText} ) -qt_extend_target(BundledHarfbuzz CONDITION APPLE AND NOT APPLE_UIKIT +qt_extend_target(BundledHarfbuzz CONDITION APPLE AND NOT UIKIT LIBRARIES ${FWApplicationServices} ) diff --git a/src/3rdparty/harfbuzz-ng/CMakeLists.txt b/src/3rdparty/harfbuzz-ng/CMakeLists.txt index 8abff4d076..07e0fdf836 100644 --- a/src/3rdparty/harfbuzz-ng/CMakeLists.txt +++ b/src/3rdparty/harfbuzz-ng/CMakeLists.txt @@ -159,13 +159,13 @@ qt_extend_target(BundledHarfbuzz CONDITION TRUE # special case HAVE_OT ) -qt_extend_target(BundledHarfbuzz CONDITION APPLE_UIKIT +qt_extend_target(BundledHarfbuzz CONDITION UIKIT LIBRARIES ${FWCoreGraphics} ${FWCoreText} ) -qt_extend_target(BundledHarfbuzz CONDITION APPLE AND NOT APPLE_UIKIT +qt_extend_target(BundledHarfbuzz CONDITION APPLE AND NOT UIKIT LIBRARIES ${FWApplicationServices} ) @@ -175,4 +175,4 @@ qt_extend_target(BundledHarfbuzz CONDITION SHAPERS_ISEMPTY OR SHAPERS___contains src/hb-fallback-shape.cc DEFINES HAVE_FALLBACK -)
\ No newline at end of file +) diff --git a/src/3rdparty/pcre2/CMakeLists.txt b/src/3rdparty/pcre2/CMakeLists.txt index 76cddc83bc..d32073dab5 100644 --- a/src/3rdparty/pcre2/CMakeLists.txt +++ b/src/3rdparty/pcre2/CMakeLists.txt @@ -56,7 +56,7 @@ qt_extend_target(BundledPcre2 CONDITION WIN32 PCRE2_STATIC ) -qt_extend_target(BundledPcre2 CONDITION APPLE_UIKIT OR QNX OR WINRT +qt_extend_target(BundledPcre2 CONDITION QNX OR UIKIT OR WINRT DEFINES PCRE2_DISABLE_JIT ) diff --git a/src/corelib/.prev_CMakeLists.txt b/src/corelib/.prev_CMakeLists.txt index 8bdc2debd3..b9b9e8eb92 100644 --- a/src/corelib/.prev_CMakeLists.txt +++ b/src/corelib/.prev_CMakeLists.txt @@ -102,6 +102,9 @@ qt_add_module(Core kernel/qobjectdefs.h kernel/qobjectdefs_impl.h kernel/qpointer.cpp kernel/qpointer.h + kernel/qproperty.cpp kernel/qproperty.h kernel/qproperty_p.h + kernel/qpropertybinding.cpp kernel/qpropertybinding_p.h + kernel/qpropertyprivate.h kernel/qsharedmemory.cpp kernel/qsharedmemory.h kernel/qsharedmemory_p.h kernel/qsignalmapper.cpp kernel/qsignalmapper.h kernel/qsocketnotifier.cpp kernel/qsocketnotifier.h @@ -398,7 +401,7 @@ qt_extend_target(Core CONDITION APPLE ${FWFoundation} ) -qt_extend_target(Core CONDITION APPLE_OSX +qt_extend_target(Core CONDITION MACOS LIBRARIES ${FWAppKit} ${FWApplicationServices} @@ -658,7 +661,7 @@ qt_extend_target(Core CONDITION QT_FEATURE_easingcurve tools/qtimeline.cpp tools/qtimeline.h ) -qt_extend_target(Core CONDITION UNIX AND NOT HAIKU AND NOT INTEGRITY AND NOT VXWORKS AND NOT WASM AND (NOT APPLE_OSX OR NOT ICC) +qt_extend_target(Core CONDITION UNIX AND NOT HAIKU AND NOT INTEGRITY AND NOT VXWORKS AND NOT WASM AND (NOT ICC OR NOT MACOS) LIBRARIES m ) @@ -692,12 +695,12 @@ qt_extend_target(Core CONDITION WIN32 AND NOT QT_FEATURE_icu text/qcollator_win.cpp ) -qt_extend_target(Core CONDITION APPLE_OSX AND NOT QT_FEATURE_icu +qt_extend_target(Core CONDITION MACOS AND NOT QT_FEATURE_icu SOURCES text/qcollator_macx.cpp ) -qt_extend_target(Core CONDITION UNIX AND NOT APPLE_OSX AND NOT QT_FEATURE_icu +qt_extend_target(Core CONDITION UNIX AND NOT MACOS AND NOT QT_FEATURE_icu SOURCES text/qcollator_posix.cpp ) @@ -784,17 +787,17 @@ qt_extend_target(Core CONDITION QT_FEATURE_filesystemwatcher AND WIN32 io/qfilesystemwatcher_win.cpp io/qfilesystemwatcher_win_p.h ) -qt_extend_target(Core CONDITION APPLE_OSX AND QT_FEATURE_filesystemwatcher +qt_extend_target(Core CONDITION MACOS AND QT_FEATURE_filesystemwatcher SOURCES io/qfilesystemwatcher_fsevents.mm io/qfilesystemwatcher_fsevents_p.h ) -qt_extend_target(Core CONDITION QT_FEATURE_filesystemwatcher AND QT_FEATURE_inotify AND UNIX AND NOT APPLE_OSX +qt_extend_target(Core CONDITION QT_FEATURE_filesystemwatcher AND QT_FEATURE_inotify AND UNIX AND NOT MACOS SOURCES io/qfilesystemwatcher_inotify.cpp io/qfilesystemwatcher_inotify_p.h ) -qt_extend_target(Core CONDITION QT_FEATURE_filesystemwatcher AND UNIX AND NOT APPLE_OSX AND NOT QT_FEATURE_inotify AND (APPLE OR FREEBSD OR NETBSD OR OPENBSD) +qt_extend_target(Core CONDITION QT_FEATURE_filesystemwatcher AND UNIX AND NOT MACOS AND NOT QT_FEATURE_inotify AND (APPLE OR FREEBSD OR NETBSD OR OPENBSD) SOURCES io/qfilesystemwatcher_kqueue.cpp io/qfilesystemwatcher_kqueue_p.h ) @@ -866,7 +869,7 @@ qt_extend_target(Core CONDITION APPLE AND QT_FEATURE_processenvironment io/qprocess_darwin.mm ) -qt_extend_target(Core CONDITION APPLE AND NOT APPLE_OSX +qt_extend_target(Core CONDITION APPLE AND NOT MACOS PUBLIC_LIBRARIES ${FWMobileCoreServices} ) @@ -946,12 +949,12 @@ qt_extend_target(Core CONDITION QT_FEATURE_dlopen AND QT_FEATURE_library ${CMAKE_DL_LIBS} ) -qt_extend_target(Core CONDITION APPLE AND (APPLE_IOS OR APPLE_TVOS) +qt_extend_target(Core CONDITION APPLE AND (IOS OR TVOS) LIBRARIES ${FWUIKit} ) -qt_extend_target(Core CONDITION APPLE_WATCHOS +qt_extend_target(Core CONDITION WATCHOS LIBRARIES ${FWWatchKit} ) @@ -1100,20 +1103,23 @@ qt_extend_target(Core CONDITION QT_FEATURE_mimetype AND QT_FEATURE_mimetype_data # mimedb.output = "$$outpath/qmimeprovider_database.cpp" # mimedb.variable_out = "INCLUDED_SOURCES" -#### Keys ignored in scope 200:.:mimetypes:mimetypes/mimetypes.pri:(CMAKE_BUILD_TYPE STREQUAL Debug): -# outpath = ".rcc/debug" +#### Keys ignored in scope 199:.:mimetypes:mimetypes/mimetypes.pri:ANDROID: +# outpath = "$$outpath/$${QT_ARCH}" -#### Keys ignored in scope 201:.:mimetypes:mimetypes/mimetypes.pri:else: -# outpath = ".rcc/release" +#### Keys ignored in scope 201:.:mimetypes:mimetypes/mimetypes.pri:(CMAKE_BUILD_TYPE STREQUAL Debug): +# outpath = "$$outpath/debug" -#### Keys ignored in scope 202:.:mimetypes:mimetypes/mimetypes.pri:MAKEFILE_GENERATOR___equals___MSVC.NET OR MAKEFILE_GENERATOR___equals___MSBUILD OR QMAKE_SH_ISEMPTY: +#### Keys ignored in scope 202:.:mimetypes:mimetypes/mimetypes.pri:else: +# outpath = "$$outpath/release" + +#### Keys ignored in scope 203:.:mimetypes:mimetypes/mimetypes.pri:MAKEFILE_GENERATOR___equals___MSVC.NET OR MAKEFILE_GENERATOR___equals___MSBUILD OR QMAKE_SH_ISEMPTY: # mimedb.commands = "cmd" "/c" "$$shell_path($$PWD/mime/generate.bat)" # mimedb.depends = "$$PWD/mime/generate.bat" "$$PWD/mime/hexdump.ps1" -#### Keys ignored in scope 203:.:mimetypes:mimetypes/mimetypes.pri:else: +#### Keys ignored in scope 204:.:mimetypes:mimetypes/mimetypes.pri:else: # mimedb.commands = "perl" "$${mimedb.depends}" -#### Keys ignored in scope 204:.:mimetypes:mimetypes/mimetypes.pri:QT_FEATURE_zstd: +#### Keys ignored in scope 205:.:mimetypes:mimetypes/mimetypes.pri:QT_FEATURE_zstd: # mimedb.commands = "--zstd" qt_extend_target(Core CONDITION WASM diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt index 783346578b..4f53ab02f0 100644 --- a/src/corelib/CMakeLists.txt +++ b/src/corelib/CMakeLists.txt @@ -118,6 +118,9 @@ qt_add_module(Core kernel/qobjectdefs.h kernel/qobjectdefs_impl.h kernel/qpointer.cpp kernel/qpointer.h + kernel/qproperty.cpp kernel/qproperty.h kernel/qproperty_p.h + kernel/qpropertybinding.cpp kernel/qpropertybinding_p.h + kernel/qpropertyprivate.h kernel/qsharedmemory.cpp kernel/qsharedmemory.h kernel/qsharedmemory_p.h kernel/qsignalmapper.cpp kernel/qsignalmapper.h kernel/qsocketnotifier.cpp kernel/qsocketnotifier.h @@ -508,7 +511,7 @@ qt_extend_target(Core CONDITION APPLE ${FWFoundation} ) -qt_extend_target(Core CONDITION APPLE_OSX +qt_extend_target(Core CONDITION MACOS LIBRARIES ${FWAppKit} ${FWApplicationServices} @@ -761,7 +764,7 @@ qt_extend_target(Core CONDITION QT_FEATURE_easingcurve tools/qtimeline.cpp tools/qtimeline.h ) -qt_extend_target(Core CONDITION UNIX AND NOT HAIKU AND NOT INTEGRITY AND NOT VXWORKS AND NOT WASM AND (NOT APPLE_OSX OR NOT ICC) +qt_extend_target(Core CONDITION UNIX AND NOT HAIKU AND NOT INTEGRITY AND NOT VXWORKS AND NOT WASM AND (NOT ICC OR NOT MACOS) LIBRARIES m ) @@ -795,12 +798,12 @@ qt_extend_target(Core CONDITION WIN32 AND NOT QT_FEATURE_icu text/qcollator_win.cpp ) -qt_extend_target(Core CONDITION APPLE_OSX AND NOT QT_FEATURE_icu +qt_extend_target(Core CONDITION MACOS AND NOT QT_FEATURE_icu SOURCES text/qcollator_macx.cpp ) -qt_extend_target(Core CONDITION UNIX AND NOT APPLE_OSX AND NOT QT_FEATURE_icu +qt_extend_target(Core CONDITION UNIX AND NOT MACOS AND NOT QT_FEATURE_icu SOURCES text/qcollator_posix.cpp ) @@ -887,17 +890,17 @@ qt_extend_target(Core CONDITION QT_FEATURE_filesystemwatcher AND WIN32 io/qfilesystemwatcher_win.cpp io/qfilesystemwatcher_win_p.h ) -qt_extend_target(Core CONDITION APPLE_OSX AND QT_FEATURE_filesystemwatcher +qt_extend_target(Core CONDITION MACOS AND QT_FEATURE_filesystemwatcher SOURCES io/qfilesystemwatcher_fsevents.mm io/qfilesystemwatcher_fsevents_p.h ) -qt_extend_target(Core CONDITION QT_FEATURE_filesystemwatcher AND QT_FEATURE_inotify AND UNIX AND NOT APPLE_OSX +qt_extend_target(Core CONDITION QT_FEATURE_filesystemwatcher AND QT_FEATURE_inotify AND UNIX AND NOT MACOS SOURCES io/qfilesystemwatcher_inotify.cpp io/qfilesystemwatcher_inotify_p.h ) -qt_extend_target(Core CONDITION QT_FEATURE_filesystemwatcher AND UNIX AND NOT APPLE_OSX AND NOT QT_FEATURE_inotify AND (APPLE OR FREEBSD OR NETBSD OR OPENBSD) +qt_extend_target(Core CONDITION QT_FEATURE_filesystemwatcher AND UNIX AND NOT MACOS AND NOT QT_FEATURE_inotify AND (APPLE OR FREEBSD OR NETBSD OR OPENBSD) SOURCES io/qfilesystemwatcher_kqueue.cpp io/qfilesystemwatcher_kqueue_p.h ) @@ -969,7 +972,7 @@ qt_extend_target(Core CONDITION APPLE AND QT_FEATURE_processenvironment io/qprocess_darwin.mm ) -qt_extend_target(Core CONDITION APPLE AND NOT APPLE_OSX +qt_extend_target(Core CONDITION APPLE AND NOT MACOS PUBLIC_LIBRARIES ${FWMobileCoreServices} ) @@ -1049,12 +1052,12 @@ qt_extend_target(Core CONDITION QT_FEATURE_dlopen AND QT_FEATURE_library ${CMAKE_DL_LIBS} ) -qt_extend_target(Core CONDITION APPLE AND (APPLE_IOS OR APPLE_TVOS) +qt_extend_target(Core CONDITION APPLE AND (IOS OR TVOS) LIBRARIES ${FWUIKit} ) -qt_extend_target(Core CONDITION APPLE_WATCHOS +qt_extend_target(Core CONDITION WATCHOS LIBRARIES ${FWWatchKit} ) @@ -1205,20 +1208,23 @@ qt_extend_target(Core CONDITION QT_FEATURE_mimetype # mimedb.output = "$$outpath/qmimeprovider_database.cpp" # mimedb.variable_out = "INCLUDED_SOURCES" -#### Keys ignored in scope 200:.:mimetypes:mimetypes/mimetypes.pri:(CMAKE_BUILD_TYPE STREQUAL Debug): -# outpath = ".rcc/debug" +#### Keys ignored in scope 199:.:mimetypes:mimetypes/mimetypes.pri:ANDROID: +# outpath = "$$outpath/$${QT_ARCH}" -#### Keys ignored in scope 201:.:mimetypes:mimetypes/mimetypes.pri:else: -# outpath = ".rcc/release" +#### Keys ignored in scope 201:.:mimetypes:mimetypes/mimetypes.pri:(CMAKE_BUILD_TYPE STREQUAL Debug): +# outpath = "$$outpath/debug" -#### Keys ignored in scope 202:.:mimetypes:mimetypes/mimetypes.pri:MAKEFILE_GENERATOR___equals___MSVC.NET OR MAKEFILE_GENERATOR___equals___MSBUILD OR QMAKE_SH_ISEMPTY: +#### Keys ignored in scope 202:.:mimetypes:mimetypes/mimetypes.pri:else: +# outpath = "$$outpath/release" + +#### Keys ignored in scope 203:.:mimetypes:mimetypes/mimetypes.pri:MAKEFILE_GENERATOR___equals___MSVC.NET OR MAKEFILE_GENERATOR___equals___MSBUILD OR QMAKE_SH_ISEMPTY: # mimedb.commands = "cmd" "/c" "$$shell_path($$PWD/mime/generate.bat)" # mimedb.depends = "$$PWD/mime/generate.bat" "$$PWD/mime/hexdump.ps1" -#### Keys ignored in scope 203:.:mimetypes:mimetypes/mimetypes.pri:else: +#### Keys ignored in scope 204:.:mimetypes:mimetypes/mimetypes.pri:else: # mimedb.commands = "perl" "$${mimedb.depends}" -#### Keys ignored in scope 204:.:mimetypes:mimetypes/mimetypes.pri:QT_FEATURE_zstd: +#### Keys ignored in scope 205:.:mimetypes:mimetypes/mimetypes.pri:QT_FEATURE_zstd: # mimedb.commands = "--zstd" # Resources: # special case begin diff --git a/src/corelib/configure.cmake b/src/corelib/configure.cmake index 811030bd38..eaeb7862c4 100644 --- a/src/corelib/configure.cmake +++ b/src/corelib/configure.cmake @@ -782,7 +782,7 @@ qt_feature("process" PUBLIC SECTION "File I/O" LABEL "QProcess" PURPOSE "Supports external process invocation." - CONDITION QT_FEATURE_processenvironment AND ( QT_FEATURE_thread OR NOT UNIX ) AND NOT WINRT AND NOT APPLE_UIKIT AND NOT INTEGRITY AND NOT VXWORKS AND NOT rtems + CONDITION QT_FEATURE_processenvironment AND ( QT_FEATURE_thread OR NOT UNIX ) AND NOT WINRT AND NOT UIKIT AND NOT INTEGRITY AND NOT VXWORKS AND NOT rtems ) qt_feature_definition("process" "QT_NO_PROCESS" NEGATE VALUE "1") qt_feature("processenvironment" PUBLIC diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index 749672c899..76609894ba 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -43,7 +43,11 @@ HEADERS += \ kernel/qsystemerror_p.h \ kernel/qmetatype_p.h \ kernel/qmetatypeswitcher_p.h \ - kernel/qtestsupport_core.h + kernel/qtestsupport_core.h \ + kernel/qproperty.h \ + kernel/qpropertyprivate.h \ + kernel/qproperty_p.h \ + kernel/qpropertybinding_p.h SOURCES += \ kernel/qabstracteventdispatcher.cpp \ @@ -71,7 +75,9 @@ SOURCES += \ kernel/qpointer.cpp \ kernel/qmath.cpp \ kernel/qsystemerror.cpp \ - kernel/qtestsupport_core.cpp + kernel/qtestsupport_core.cpp \ + kernel/qproperty.cpp \ + kernel/qpropertybinding.cpp win32 { SOURCES += \ diff --git a/src/corelib/kernel/qproperty.cpp b/src/corelib/kernel/qproperty.cpp new file mode 100644 index 0000000000..75110fa031 --- /dev/null +++ b/src/corelib/kernel/qproperty.cpp @@ -0,0 +1,671 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qproperty.h" +#include "qproperty_p.h" +#include "qpropertybinding_p.h" + +#include <qscopedvaluerollback.h> + +QT_BEGIN_NAMESPACE + +using namespace QtPrivate; + +QPropertyBase::QPropertyBase(QPropertyBase &&other, void *propertyDataPtr) +{ + std::swap(d_ptr, other.d_ptr); + QPropertyBasePointer d{this}; + d.firstObserverPtr().set(nullptr); + if (auto binding = d.bindingPtr()) + binding->propertyDataPtr = propertyDataPtr; +} + +void QPropertyBase::moveAssign(QPropertyBase &&other, void *propertyDataPtr) +{ + if (&other == this) + return; + + QPropertyBasePointer d{this}; + auto observer = d.firstObserver(); + d.firstObserverPtr().set(nullptr); + + if (auto binding = d.bindingPtr()) { + binding->unlinkAndDeref(); + d_ptr &= FlagMask; + } + + std::swap(d_ptr, other.d_ptr); + + if (auto binding = d.bindingPtr()) + binding->propertyDataPtr = propertyDataPtr; + + d.firstObserverPtr().set(const_cast<QPropertyObserver*>(observer.ptr)); + + // The caller will have to notify observers. +} + +QPropertyBase::~QPropertyBase() +{ + QPropertyBasePointer d{this}; + if (auto observer = d.firstObserver()) + observer.unlink(); + if (auto binding = d.bindingPtr()) + binding->unlinkAndDeref(); +} + +QUntypedPropertyBinding QPropertyBase::setBinding(const QUntypedPropertyBinding &binding, void *propertyDataPtr) +{ + QPropertyBindingPrivatePtr oldBinding; + QPropertyBindingPrivatePtr newBinding = binding.d; + + QPropertyBasePointer d{this}; + + auto observer = d.firstObserver(); + if (observer) + observer.unlink(); + + if (auto *existingBinding = d.bindingPtr()) { + if (existingBinding == newBinding.data()) + return QUntypedPropertyBinding(oldBinding); + oldBinding = QPropertyBindingPrivatePtr(existingBinding); + oldBinding->unlinkAndDeref(); + d_ptr &= FlagMask; + } + if (newBinding) { + newBinding.data()->ref.ref(); + d_ptr = (d_ptr & FlagMask) | reinterpret_cast<quintptr>(newBinding.data()); + d_ptr |= BindingBit; + newBinding->dirty = true; + newBinding->propertyDataPtr = propertyDataPtr; + if (observer) + observer.prependToBinding(newBinding.data()); + } else { + d_ptr &= ~BindingBit; + } + + return QUntypedPropertyBinding(oldBinding); +} + +QPropertyBindingPrivatePtr QPropertyBase::binding() +{ + QPropertyBasePointer d{this}; + if (auto binding = d.bindingPtr()) + return QPropertyBindingPrivatePtr(binding); + return QPropertyBindingPrivatePtr(); +} + +QPropertyBindingPrivate *QPropertyBasePointer::bindingPtr() const +{ + if (ptr->d_ptr & QPropertyBase::BindingBit) + return reinterpret_cast<QPropertyBindingPrivate*>(ptr->d_ptr & ~QPropertyBase::FlagMask); + return nullptr; +} + +QtPrivate::QPropertyTagPreservingPointerToPointer<QPropertyObserver> QPropertyBasePointer::firstObserverPtr() const +{ + if (auto *binding = bindingPtr()) + return const_cast<QPropertyObserver**>(&binding->firstObserver.ptr); + return &ptr->d_ptr; +} + +QPropertyObserverPointer QPropertyBasePointer::firstObserver() const +{ + if (auto *binding = bindingPtr()) + return binding->firstObserver; + return {reinterpret_cast<QPropertyObserver*>(ptr->d_ptr & ~QPropertyBase::FlagMask)}; +} + +static thread_local BindingEvaluationState *currentBindingEvaluationState = nullptr; + +BindingEvaluationState::BindingEvaluationState(QPropertyBindingPrivate *binding) + : binding(binding) + , dependencyObservers(&binding->dependencyObservers) +{ + previousState = currentBindingEvaluationState; + currentBindingEvaluationState = this; + dependencyObservers->clear(); +} + +BindingEvaluationState::~BindingEvaluationState() +{ + currentBindingEvaluationState = previousState; +} + +void QPropertyBase::evaluateIfDirty() +{ + QPropertyBasePointer d{this}; + QPropertyBindingPrivate *binding = d.bindingPtr(); + if (!binding) + return; + binding->evaluateIfDirtyAndReturnTrueIfValueChanged(); +} + +void QPropertyBase::removeBinding() +{ + QPropertyBasePointer d{this}; + + auto observer = d.firstObserver(); + if (observer) + observer.unlink(); + + if (auto *existingBinding = d.bindingPtr()) { + existingBinding->unlinkAndDeref(); + d_ptr &= FlagMask; + } + d_ptr &= ~BindingBit; + + if (observer) + observer.observeProperty(d); +} + +void QPropertyBase::registerWithCurrentlyEvaluatingBinding() const +{ + auto currentState = currentBindingEvaluationState; + if (!currentState) + return; + + QPropertyBasePointer d{this}; + + currentState->dependencyObservers->append(QPropertyObserver()); + QPropertyObserverPointer dependencyObserver{&(*currentState->dependencyObservers)[currentState->dependencyObservers->size() - 1]}; + dependencyObserver.setBindingToMarkDirty(currentState->binding); + dependencyObserver.observeProperty(d); +} + +void QPropertyBase::notifyObservers() +{ + QPropertyBasePointer d{this}; + if (QPropertyObserverPointer observer = d.firstObserver()) + observer.notify(d.bindingPtr()); +} + +int QPropertyBasePointer::observerCount() const +{ + int count = 0; + for (auto observer = firstObserver(); observer; observer = observer.nextObserver()) + ++count; + return count; +} + +QPropertyObserver::QPropertyObserver(void (*callback)(QPropertyObserver*)) +{ + QPropertyObserverPointer d{this}; + d.setChangeHandler(callback); +} + +void QPropertyObserver::setSource(QPropertyBase &property) +{ + QPropertyObserverPointer d{this}; + QPropertyBasePointer propPrivate{&property}; + d.observeProperty(propPrivate); +} + + +QPropertyObserver::~QPropertyObserver() +{ + QPropertyObserverPointer d{this}; + d.unlink(); +} + +QPropertyObserver::QPropertyObserver(QPropertyObserver &&other) +{ + std::swap(bindingToMarkDirty, other.bindingToMarkDirty); + std::swap(next, other.next); + std::swap(prev, other.prev); + if (next) + next->prev = reinterpret_cast<quintptr*>(&next); + if (prev) + prev.set(this); +} + +QPropertyObserver &QPropertyObserver::operator=(QPropertyObserver &&other) +{ + if (this == &other) + return *this; + + QPropertyObserverPointer d{this}; + d.unlink(); + bindingToMarkDirty = nullptr; + + std::swap(bindingToMarkDirty, other.bindingToMarkDirty); + std::swap(next, other.next); + std::swap(prev, other.prev); + if (next) + next->prev = reinterpret_cast<quintptr*>(&next); + if (prev) + prev.set(this); + + return *this; +} + +void QPropertyObserverPointer::unlink() +{ + if (ptr->next) + ptr->next->prev = ptr->prev; + if (ptr->prev) + ptr->prev.set(ptr->next.data()); + ptr->next = nullptr; + ptr->prev.clear(); +} + +void QPropertyObserverPointer::setChangeHandler(void (*changeHandler)(QPropertyObserver *)) +{ + ptr->changeHandler = changeHandler; + ptr->next.setFlag(true); +} + +void QPropertyObserverPointer::setBindingToMarkDirty(QPropertyBindingPrivate *binding) +{ + ptr->bindingToMarkDirty = binding; + ptr->next.setFlag(false); +} + +void QPropertyObserverPointer::notify(QPropertyBindingPrivate *triggeringBinding) +{ + bool knownIfPropertyChanged = false; + bool propertyChanged =true; + + auto observer = const_cast<QPropertyObserver*>(ptr); + while (observer) { + auto * const next = observer->next.data(); + if (observer->next.flag()) { + if (!knownIfPropertyChanged && triggeringBinding) { + knownIfPropertyChanged = true; + + propertyChanged = triggeringBinding->evaluateIfDirtyAndReturnTrueIfValueChanged(); + } + if (!propertyChanged) + return; + + if (auto handlerToCall = std::exchange(observer->changeHandler, nullptr)) { + handlerToCall(observer); + observer->changeHandler = handlerToCall; + } + } else { + if (observer->bindingToMarkDirty) + observer->bindingToMarkDirty->markDirtyAndNotifyObservers(); + } + observer = next; + } +} + +void QPropertyObserverPointer::observeProperty(QPropertyBasePointer property) +{ + unlink(); + auto firstObserverPtr = property.firstObserverPtr(); + ptr->prev = firstObserverPtr; + ptr->next = firstObserverPtr.get(); + if (ptr->next) + ptr->next->prev = &ptr->next; + firstObserverPtr.set(ptr); +} + +void QPropertyObserverPointer::prependToBinding(QPropertyBindingPrivate *binding) +{ + ptr->prev = const_cast<QPropertyObserver **>(&binding->firstObserver.ptr); + binding->firstObserver = *this; +} + +QPropertyBindingError::QPropertyBindingError(Type type) +{ + if (type != NoError) { + d = new QPropertyBindingErrorPrivate; + d->type = type; + } +} + +QPropertyBindingError::QPropertyBindingError(const QPropertyBindingError &other) + : d(other.d) +{ +} + +QPropertyBindingError &QPropertyBindingError::operator=(const QPropertyBindingError &other) +{ + d = other.d; + return *this; +} + +QPropertyBindingError::QPropertyBindingError(QPropertyBindingError &&other) + : d(std::move(other.d)) +{ +} + +QPropertyBindingError &QPropertyBindingError::operator=(QPropertyBindingError &&other) +{ + d = std::move(other.d); + return *this; +} + +QPropertyBindingError::~QPropertyBindingError() +{ +} + +QPropertyBindingError::Type QPropertyBindingError::type() const +{ + if (!d) + return QPropertyBindingError::NoError; + return d->type; +} + +void QPropertyBindingError::setDescription(const QString &description) +{ + if (!d) + d = new QPropertyBindingErrorPrivate; + d->description = description; +} + +QString QPropertyBindingError::description() const +{ + if (!d) + return QString(); + return d->description; +} + +QPropertyBindingSourceLocation QPropertyBindingError::location() const +{ + if (!d) + return QPropertyBindingSourceLocation(); + return d->location; +} + +/*! + \class QProperty + \inmodule QtCore + \brief The QProperty class is a template class that enables automatic property bindings. + + \ingroup tools + + QProperty\<T\> is a generic container that holds an instance of T. You can assign + a value to it and you can read it via the value() function or the T conversion + operator. You can also tie the property to an expression that computes the value + dynamically, the binding expression. It is represented as a C++ lambda and + can be used to express relationships between different properties in your + application. + + The binding expression computes the value by reading other QProperty values. + Behind the scenes this dependency is tracked. Whenever a change in any property's + dependency is detected, the binding expression is re-evaluated and the new + result is applied to the property. This happens lazily, by marking the binding + as dirty and evaluating it only when the property's value is requested. For example: + + \code + QProperty<QString> firstname("John"); + QProperty<QString> lastname("Smith"); + QProperty<int> age(41); + + QProperty<QString> fullname; + fullname.setBinding([&]() { return firstname.value() + " " + lastname.value() + " age:" + QString::number(age.value()); }); + + qDebug() << fullname.value(); // Prints "John Smith age: 41" + + firstname = "Emma"; // Marks binding expression as dirty + + qDebug() << fullname.value(); // Re-evaluates the binding expression and prints "Emma Smith age: 41" + + // Birthday is coming up + age.setValue(age.value() + 1); + + qDebug() << fullname.value(); // Re-evaluates the binding expression and prints "Emma Smith age: 42" + \endcode + + When a new value is assigned to the \c firstname property, the binding + expression for \c fullname is marked as dirty. So when the last \c qDebug() statement + tries to read the name value of the \c fullname property, the expression is + evaluated again, \c firstname() will be called again and return the new value. + + Since bindings are C++ lambda expressions, they may do anything that's possible + in C++. This includes calling other functions. If those functions access values + held by QProperty, they automatically become dependencies to the binding. + + Binding expressions may use properties of any type, so in the above example the age + is an integer and folded into the string value using conversion to integer, but + the dependency is fully tracked. + + \section1 Tracking properties + + Sometimes the relationships between properties cannot be expressed using + bindings. Instead you may need to run custom code whenever the value of a property + changes and instead of assigning the value to another property, pass it to + other parts of your application. For example writing data into a network socket + or printing debug output. QProperty provides two mechanisms for tracking. + + You can register for a callback function to be called whenever the value of + a property changes, by using onValueChanged(). If you want the callback to also + be called for the current value of the property, register your callback using + subscribe() instead. +*/ + +/*! + \fn template <typename T> QProperty<T>::QProperty() + + Constructs a property with a default constructed instance of T. +*/ + +/*! + \fn template <typename T> explicit QProperty<T>::QProperty(const T &initialValue) + + Constructs a property with the provided \a initialValue. +*/ + +/*! + \fn template <typename T> explicit QProperty<T>::QProperty(T &&initialValue) + + Move-Constructs a property with the provided \a initialValue. +*/ + +/*! + \fn template <typename T> QProperty<T>::QProperty(QProperty<T> &&other) + + Move-constructs a QProperty instance, making it point at the same object that + \a other was pointing to. +*/ + +/*! + \fn template <typename T> QProperty<T> &QProperty<T>::operator=(QProperty &&other) + + Move-assigns \a other to this QProperty instance. +*/ + +/*! + \fn template <typename T> QProperty<T>::QProperty(const QPropertyBinding<T> &binding) + + Constructs a property that is tied to the provided \a binding expression. The + first time the property value is read, the binding is evaluated. Whenever a + dependency of the binding changes, the binding will be re-evaluated the next + time the value of this property is read. +*/ + +/*! + \fn template <typename T> template <typename Functor> QProperty<T>::QProperty(Functor &&f) + + Constructs a property that is tied to the provided binding expression \a f. The + first time the property value is read, the binding is evaluated. Whenever a + dependency of the binding changes, the binding will be re-evaluated the next + time the value of this property is read. +*/ + +/*! + \fn template <typename T> QProperty<T>::~QProperty() + + Destroys the property. +*/ + +/*! + \fn template <typename T> T QProperty<T>::value() const + + Returns the value of the property. This may evaluate a binding expression that + is tied to this property, before returning the value. +*/ + +/*! + \fn template <typename T> QProperty<T>::operator T() const + + Returns the value of the property. This may evaluate a binding expression that + is tied to this property, before returning the value. +*/ + +/*! + \fn template <typename T> void QProperty<T>::setValue(const T &newValue) + + Assigns \a newValue to this property and removes the property's associated + binding, if present. +*/ + +/*! + \fn template <typename T> void QProperty<T>::setValue(T &&newValue) + \overload + + Assigns \a newValue to this property and removes the property's associated + binding, if present. +*/ + +/*! + \fn template <typename T> QProperty<T> &QProperty<T>::operator=(const T &newValue) + + Assigns \a newValue to this property and returns a reference to this QProperty. +*/ + +/*! + \fn template <typename T> QProperty<T> &QProperty<T>::operator=(T &&newValue) + \overload + + Assigns \a newValue to this property and returns a reference to this QProperty. +*/ + +/*! + \fn template <typename T> QProperty<T> &QProperty<T>::operator=(const QPropertyBinding<T> &newBinding) + + Associates the value of this property with the provided \a newBinding + expression and returns a reference to this property. The first time the + property value is read, the binding is evaluated. Whenever a dependency of the + binding changes, the binding will be re-evaluated the next time the value of + this property is read. +*/ + +/*! + \fn template <typename T> QPropertyBinding<T> QProperty<T>::setBinding(const QPropertyBinding<T> &newBinding) + + Associates the value of this property with the provided \a newBinding + expression and returns the previously associated binding. The first time the + property value is read, the binding is evaluated. Whenever a dependency of the + binding changes, the binding will be re-evaluated the next time the value of + this property is read. +*/ + +/*! + \fn template <typename T> template <typename Functor> QPropertyBinding<T> QProperty<T>::setBinding(Functor f) + \overload + + Associates the value of this property with the provided functor \a f and + returns the previously associated binding. The first time the property value + is read, the binding is evaluated by invoking the call operator () of \a f. + Whenever a dependency of the binding changes, the binding will be re-evaluated + the next time the value of this property is read. +*/ + +/*! + \fn template <typename T> QPropertyBinding<T> QProperty<T>::setBinding(QPropertyBinding<T> &&newBinding) + \overload + + Associates the value of this property with the provided \a newBinding + expression and returns the previously associated binding. The first time the + property value is read, the binding is evaluated. Whenever a dependency of the + binding changes, the binding will be re-evaluated the next time the value of + this property is read. +*/ + +/*! + \fn template <typename T> QPropertyBinding<T> QProperty<T>::binding() const + + Returns the binding expression that is associated with this property. A + default constructed QPropertyBinding<T> will be returned if no such + association exists. +*/ + +/*! + \fn template <typename T> QPropertyBinding<T> QProperty<T>::takeBinding() + + Disassociates the binding expression from this property and returns it. After + calling this function, the value of the property will only change if you + assign a new value to it, or when a new binding is set. +*/ + +/*! + \fn template <typename T> template <typename Functor> QPropertyChangeHandler<T, Functor> QProperty<T>::onValueChanged(Functor f) + + Registers the given functor \a f as a callback that shall be called whenever + the value of the property changes. + + The callback \a f is expected to be a type that has a plain call operator () without any + parameters. This means that you can provide a C++ lambda expression, an std::function + or even a custom struct with a call operator. + + The returned property change handler object keeps track of the registration. When it + goes out of scope, the callback is de-registered. +*/ + +/*! + \fn template <typename T> template <typename Functor> QPropertyChangeHandler<T, Functor> QProperty<T>::subscribe(Functor f) + + Subscribes the given functor \a f as a callback that is called immediately and whenever + the value of the property changes in the future. + + The callback \a f is expected to be a type that has a plain call operator () without any + parameters. This means that you can provide a C++ lambda expression, an std::function + or even a custom struct with a call operator. + + The returned property change handler object keeps track of the subscription. When it + goes out of scope, the callback is unsubscribed. +*/ + +/*! + \class QPropertyChangeHandler + \inmodule QtCore + \brief The QPropertyChangeHandler class controls the lifecycle of change callback installed on a QProperty. + + \ingroup tools + + QPropertyChangeHandler\<PropertyType, Functor\> is created when registering a + callback on a QProperty to listen to changes to the property's value, using QProperty::onValueChanged + and QProperty::subscribe. As long as the change handler is alive, the callback remains installed. + + A handler instance can be transferred between C++ scopes using move semantics. +*/ + +QT_END_NAMESPACE diff --git a/src/corelib/kernel/qproperty.h b/src/corelib/kernel/qproperty.h new file mode 100644 index 0000000000..45acfadd50 --- /dev/null +++ b/src/corelib/kernel/qproperty.h @@ -0,0 +1,451 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPROPERTY_H +#define QPROPERTY_H + +#include <QtCore/qglobal.h> +#include <QtCore/QSharedDataPointer> +#include <QtCore/QString> +#include <functional> +#include <type_traits> +#include <variant> + +#include <QtCore/qpropertyprivate.h> + +#if __has_include(<source_location>) && __cplusplus >= 202002L && !defined(Q_CLANG_QDOC) +#include <experimental/source_location> +#define QT_PROPERTY_COLLECT_BINDING_LOCATION +#define QT_PROPERTY_DEFAULT_BINDING_LOCATION QPropertyBindingSourceLocation(std::source_location::current()) +#elif __has_include(<experimental/source_location>) && __cplusplus >= 201703L && !defined(Q_CLANG_QDOC) +#include <experimental/source_location> +#define QT_PROPERTY_COLLECT_BINDING_LOCATION +#define QT_PROPERTY_DEFAULT_BINDING_LOCATION QPropertyBindingSourceLocation(std::experimental::source_location::current()) +#else +#define QT_PROPERTY_DEFAULT_BINDING_LOCATION QPropertyBindingSourceLocation() +#endif + +QT_BEGIN_NAMESPACE + +struct Q_CORE_EXPORT QPropertyBindingSourceLocation +{ + const char *fileName = nullptr; + const char *functionName = nullptr; + quint32 line = 0; + quint32 column = 0; + QPropertyBindingSourceLocation() = default; +#ifdef QT_PROPERTY_COLLECT_BINDING_LOCATION + QPropertyBindingSourceLocation(const std::experimental::source_location &cppLocation) + { + fileName = cppLocation.file_name(); + functionName = cppLocation.function_name(); + line = cppLocation.line(); + column = cppLocation.column(); + } +#endif +}; + +template <typename Functor> class QPropertyChangeHandler; + +template <typename T> class QProperty; + +class QPropertyBindingErrorPrivate; + +class Q_CORE_EXPORT QPropertyBindingError +{ +public: + enum Type { + NoError, + BindingLoop, + EvaluationError, + UnknownError + }; + + QPropertyBindingError(Type type = NoError); + QPropertyBindingError(const QPropertyBindingError &other); + QPropertyBindingError &operator=(const QPropertyBindingError &other); + QPropertyBindingError(QPropertyBindingError &&other); + QPropertyBindingError &operator=(QPropertyBindingError &&other); + ~QPropertyBindingError(); + + Type type() const; + void setDescription(const QString &description); + QString description() const; + QPropertyBindingSourceLocation location() const; + +private: + QSharedDataPointer<QPropertyBindingErrorPrivate> d; +}; + +class Q_CORE_EXPORT QUntypedPropertyBinding +{ +public: + // Returns either a boolean to indicate value change or an error. + using BindingEvaluationResult = std::variant<bool, QPropertyBindingError>; + // returns true if value changed, false if the binding evaluation lead to the same value as the property + // already has. + using BindingEvaluationFunction = std::function<BindingEvaluationResult(int version, void *propertyStoragePtr)>; + + QUntypedPropertyBinding() = default; + QUntypedPropertyBinding(BindingEvaluationFunction function, const QPropertyBindingSourceLocation &location); + QUntypedPropertyBinding(QUntypedPropertyBinding &&other); + QUntypedPropertyBinding(const QUntypedPropertyBinding &other); + QUntypedPropertyBinding &operator=(const QUntypedPropertyBinding &other); + QUntypedPropertyBinding &operator=(QUntypedPropertyBinding &&other); + ~QUntypedPropertyBinding(); + + bool isNull() const; + + QPropertyBindingError error() const; + +private: + explicit QUntypedPropertyBinding(const QPropertyBindingPrivatePtr &priv); + friend class QtPrivate::QPropertyBase; + friend struct QPropertyBindingPrivate; + template <typename> friend class QPropertyBinding; + QPropertyBindingPrivatePtr d; +}; + +template <typename PropertyType> +class QPropertyBinding : public QUntypedPropertyBinding +{ + template <typename Functor> + struct BindingAdaptor + { + Functor impl; + QUntypedPropertyBinding::BindingEvaluationResult operator()(int /*version*/, void *propertyStoragePtr) + { + std::variant<PropertyType, QPropertyBindingError> result(impl()); + if (auto errorPtr = std::get_if<QPropertyBindingError>(&result)) + return *errorPtr; + + if (auto valuePtr = std::get_if<PropertyType>(&result)) { + auto storagePtr = reinterpret_cast<QtPrivate::QPropertyValueStorage<PropertyType>*>(propertyStoragePtr); + return storagePtr->setValueAndReturnTrueIfChanged(std::move(*valuePtr)); + } + + return false; + } + }; + +public: + QPropertyBinding() = default; + + template<typename Functor> + QPropertyBinding(Functor &&f, const QPropertyBindingSourceLocation &location) + : QUntypedPropertyBinding(BindingAdaptor<Functor>{std::forward<Functor>(f)}, location) + {} + + QPropertyBinding(const QProperty<PropertyType> &property) + : QUntypedPropertyBinding(property.d.priv.binding()) + {} + +private: + // Internal + explicit QPropertyBinding(const QUntypedPropertyBinding &binding) + : QUntypedPropertyBinding(binding) + {} + friend class QProperty<PropertyType>; +}; + +namespace QtPrivate { + template<typename... Ts> + constexpr auto is_variant_v = false; + template<typename... Ts> + constexpr auto is_variant_v<std::variant<Ts...>> = true; +} + +namespace Qt { + template <typename Functor> + auto makePropertyBinding(Functor &&f, const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION, + std::enable_if_t<std::is_invocable_v<Functor>> * = 0) + { + if constexpr (QtPrivate::is_variant_v<std::invoke_result_t<Functor>>) { + return QPropertyBinding<std::variant_alternative_t<0, std::invoke_result_t<Functor>>>(std::forward<Functor>(f), location); + } else { + return QPropertyBinding<std::invoke_result_t<Functor>>(std::forward<Functor>(f), location); + } + // Work around bogus warning + Q_UNUSED(QtPrivate::is_variant_v<bool>) + } +} + +struct QPropertyBasePointer; + +template <typename T> +class QProperty +{ +public: + QProperty() = default; + explicit QProperty(const T &initialValue) : d(initialValue) {} + explicit QProperty(T &&initialValue) : d(std::move(initialValue)) {} + QProperty(QProperty &&other) : d(std::move(other.d)) { notify(); } + QProperty &operator=(QProperty &&other) { d = std::move(other.d); notify(); return *this; } + QProperty(const QPropertyBinding<T> &binding) + : QProperty() + { operator=(binding); } + QProperty(QPropertyBinding<T> &&binding) + : QProperty() + { operator=(std::move(binding)); } +#ifndef Q_CLANG_QDOC + template <typename Functor> + explicit QProperty(Functor &&f, const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION, + typename std::enable_if_t<std::is_invocable_r_v<T, Functor&>> * = 0); +#else + template <typename Functor> + explicit QProperty(Functor &&f); +#endif + ~QProperty() = default; + + T value() const + { + if (d.priv.hasBinding()) + d.priv.evaluateIfDirty(); + d.priv.registerWithCurrentlyEvaluatingBinding(); + return d.getValue(); + } + + operator T() const + { + return value(); + } + + void setValue(T &&newValue) + { + if (d.setValueAndReturnTrueIfChanged(std::move(newValue))) + notify(); + d.priv.removeBinding(); + } + + void setValue(const T &newValue) + { + if (d.setValueAndReturnTrueIfChanged(newValue)) + notify(); + d.priv.removeBinding(); + } + + QProperty<T> &operator=(T &&newValue) + { + setValue(std::move(newValue)); + return *this; + } + + QProperty<T> &operator=(const T &newValue) + { + setValue(newValue); + return *this; + } + + QProperty<T> &operator=(const QPropertyBinding<T> &newBinding) + { + setBinding(newBinding); + return *this; + } + + QProperty<T> &operator=(QPropertyBinding<T> &&newBinding) + { + setBinding(std::move(newBinding)); + return *this; + } + + QPropertyBinding<T> setBinding(const QPropertyBinding<T> &newBinding) + { + QPropertyBinding<T> oldBinding(d.priv.setBinding(newBinding, &d)); + notify(); + return oldBinding; + } + + QPropertyBinding<T> setBinding(QPropertyBinding<T> &&newBinding) + { + QPropertyBinding<T> b(std::move(newBinding)); + QPropertyBinding<T> oldBinding(d.priv.setBinding(b, &d)); + notify(); + return oldBinding; + } + +#ifndef Q_CLANG_QDOC + template <typename Functor> + QPropertyBinding<T> setBinding(Functor f, + const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION) + { + return setBinding(Qt::makePropertyBinding(f, location)); + } +#else + template <typename Functor> + QPropertyBinding<T> setBinding(Functor f); +#endif + + bool hasBinding() const { return d.priv.hasBinding(); } + + QPropertyBinding<T> binding() const + { + return QPropertyBinding<T>(*this); + } + + QPropertyBinding<T> takeBinding() + { + return QPropertyBinding<T>(d.priv.setBinding(QUntypedPropertyBinding(), &d)); + } + + template<typename Functor> + QPropertyChangeHandler<Functor> onValueChanged(Functor f); + template<typename Functor> + QPropertyChangeHandler<Functor> subscribe(Functor f); + +private: + void notify() + { + d.priv.notifyObservers(); + } + + Q_DISABLE_COPY(QProperty) + + friend struct QPropertyBasePointer; + friend struct QPropertyBinding<T>; + friend struct QPropertyObserver; + // Mutable because querying for the value may require evalating the binding expression, calling + // non-const functions on QPropertyBase. + mutable QtPrivate::QPropertyValueStorage<T> d; +}; + +#ifndef Q_CLANG_QDOC +template <typename PropertyType> +template <typename Functor> +QProperty<PropertyType>::QProperty(Functor &&f, const QPropertyBindingSourceLocation &location, + typename std::enable_if_t<std::is_invocable_r_v<PropertyType, Functor&>> *) + : QProperty(QPropertyBinding<PropertyType>(std::forward<Functor>(f), location)) +{} +#endif + +namespace Qt { + template <typename PropertyType> + QPropertyBinding<PropertyType> makePropertyBinding(const QProperty<PropertyType> &otherProperty, + const QPropertyBindingSourceLocation &location = + QT_PROPERTY_DEFAULT_BINDING_LOCATION) + { + return Qt::makePropertyBinding([&otherProperty]() -> PropertyType { return otherProperty; }, location); + } +} + +struct QPropertyObserverPrivate; +struct QPropertyObserverPointer; + +struct Q_CORE_EXPORT QPropertyObserver +{ + QPropertyObserver() = default; + QPropertyObserver(QPropertyObserver &&other); + QPropertyObserver &operator=(QPropertyObserver &&other); + ~QPropertyObserver(); + + template <typename PropertyType> + void setSource(const QProperty<PropertyType> &property) + { setSource(property.d.priv); } + +protected: + QPropertyObserver(void (*callback)(QPropertyObserver*)); + +private: + void setSource(QtPrivate::QPropertyBase &property); + + QtPrivate::QTaggedPointer<QPropertyObserver> next; + // prev is a pointer to the "next" element within the previous node, or to the "firstObserverPtr" if it is the + // first node. + QtPrivate::QPropertyTagPreservingPointerToPointer<QPropertyObserver> prev; + + union { + QPropertyBindingPrivate *bindingToMarkDirty = nullptr; + void (*changeHandler)(QPropertyObserver*); + }; + + QPropertyObserver(const QPropertyObserver &) = delete; + QPropertyObserver &operator=(const QPropertyObserver &) = delete; + + friend struct QPropertyObserverPointer; +}; + +template <typename Functor> +class QPropertyChangeHandler : public QPropertyObserver +{ + Functor m_handler; +public: + QPropertyChangeHandler(Functor handler) + : QPropertyObserver([](QPropertyObserver *self) { + auto This = static_cast<QPropertyChangeHandler<Functor>*>(self); + This->m_handler(); + }) + , m_handler(handler) + { + } + + template <typename PropertyType> + QPropertyChangeHandler(const QProperty<PropertyType> &property, Functor handler) + : QPropertyObserver([](QPropertyObserver *self) { + auto This = static_cast<QPropertyChangeHandler<Functor>*>(self); + This->m_handler(); + }) + , m_handler(handler) + { + setSource(property); + } +}; + +template <typename T> +template<typename Functor> +QPropertyChangeHandler<Functor> QProperty<T>::onValueChanged(Functor f) +{ +#if defined(__cpp_lib_is_invocable) && (__cpp_lib_is_invocable >= 201703L) + static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters"); +#endif + return QPropertyChangeHandler<Functor>(*this, f); +} + +template <typename T> +template<typename Functor> +QPropertyChangeHandler<Functor> QProperty<T>::subscribe(Functor f) +{ +#if defined(__cpp_lib_is_invocable) && (__cpp_lib_is_invocable >= 201703L) + static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters"); +#endif + f(); + return onValueChanged(f); +} + +QT_END_NAMESPACE + +#endif // QPROPERTY_H diff --git a/src/corelib/kernel/qproperty_p.h b/src/corelib/kernel/qproperty_p.h new file mode 100644 index 0000000000..1b96e09d58 --- /dev/null +++ b/src/corelib/kernel/qproperty_p.h @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPROPERTY_P_H +#define QPROPERTY_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#include <qglobal.h> +#include <qvarlengtharray.h> + +#include "qproperty.h" + +QT_BEGIN_NAMESPACE + +// This is a helper "namespace" +struct Q_AUTOTEST_EXPORT QPropertyBasePointer +{ + const QtPrivate::QPropertyBase *ptr = nullptr; + + QPropertyBindingPrivate *bindingPtr() const; + + QtPrivate::QPropertyTagPreservingPointerToPointer<QPropertyObserver> firstObserverPtr() const; + QPropertyObserverPointer firstObserver() const; + + int observerCount() const; + + template <typename T> + static QPropertyBasePointer get(QProperty<T> &property) + { + return QPropertyBasePointer{&property.d.priv}; + } +}; + +// This is a helper "namespace" +struct QPropertyObserverPointer +{ + QPropertyObserver *ptr = nullptr; + + void unlink(); + + void setBindingToMarkDirty(QPropertyBindingPrivate *binding); + void setChangeHandler(void (*changeHandler)(QPropertyObserver*)); + + void notify(QPropertyBindingPrivate *triggeringBinding); + void observeProperty(QPropertyBasePointer property); + void prependToBinding(QPropertyBindingPrivate *binding); + + explicit operator bool() const { return ptr != nullptr; } + + QPropertyObserverPointer nextObserver() const { return {ptr->next.data()}; } +}; + +class QPropertyBindingErrorPrivate : public QSharedData +{ +public: + QPropertyBindingError::Type type = QPropertyBindingError::NoError; + QString description; + QPropertyBindingSourceLocation location; +}; + +struct BindingEvaluationState +{ + BindingEvaluationState(QPropertyBindingPrivate *binding); + ~BindingEvaluationState(); + QPropertyBindingPrivate *binding; + QVarLengthArray<QPropertyObserver, 4> *dependencyObservers = nullptr; + BindingEvaluationState *previousState = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QPROPERTY_P_H diff --git a/src/corelib/kernel/qpropertybinding.cpp b/src/corelib/kernel/qpropertybinding.cpp new file mode 100644 index 0000000000..23f7075998 --- /dev/null +++ b/src/corelib/kernel/qpropertybinding.cpp @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qpropertybinding_p.h" +#include "qproperty_p.h" + +#include <QScopedValueRollback> + +QT_BEGIN_NAMESPACE + +using namespace QtPrivate; + +QPropertyBindingPrivate::~QPropertyBindingPrivate() +{ + if (firstObserver) + firstObserver.unlink(); +} + +void QPropertyBindingPrivate::unlinkAndDeref() +{ + propertyDataPtr = nullptr; + if (!ref.deref()) + delete this; +} + +void QPropertyBindingPrivate::markDirtyAndNotifyObservers() +{ + dirty = true; + if (firstObserver) + firstObserver.notify(this); +} + +bool QPropertyBindingPrivate::evaluateIfDirtyAndReturnTrueIfValueChanged() +{ + if (!dirty) + return false; + + if (updating) { + error = QPropertyBindingError(QPropertyBindingError::BindingLoop); + return false; + } + + QScopedValueRollback<bool> updateGuard(updating, true); + + BindingEvaluationState evaluationFrame(this); + bool changed = false; + auto result = evaluationFunction(/*version*/1, propertyDataPtr); + if (auto changedPtr = std::get_if<bool>(&result)) + changed = *changedPtr; + else if (auto errorPtr = std::get_if<QPropertyBindingError>(&result)) + error = std::move(*errorPtr); + dirty = false; + return changed; +} + +QUntypedPropertyBinding::QUntypedPropertyBinding(QUntypedPropertyBinding::BindingEvaluationFunction function, + const QPropertyBindingSourceLocation &location) +{ + d = new QPropertyBindingPrivate(std::move(function), std::move(location)); +} + +QUntypedPropertyBinding::QUntypedPropertyBinding(QUntypedPropertyBinding &&other) + : d(std::move(other.d)) +{ +} + +QUntypedPropertyBinding::QUntypedPropertyBinding(const QUntypedPropertyBinding &other) + : d(other.d) +{ +} + +QUntypedPropertyBinding &QUntypedPropertyBinding::operator=(const QUntypedPropertyBinding &other) +{ + d = other.d; + return *this; +} + +QUntypedPropertyBinding &QUntypedPropertyBinding::operator=(QUntypedPropertyBinding &&other) +{ + d = std::move(other.d); + return *this; +} + +QUntypedPropertyBinding::QUntypedPropertyBinding(const QPropertyBindingPrivatePtr &priv) + : d(priv) +{ +} + +QUntypedPropertyBinding::~QUntypedPropertyBinding() +{ +} + +bool QUntypedPropertyBinding::isNull() const +{ + return !d; +} + +QPropertyBindingError QUntypedPropertyBinding::error() const +{ + if (!d) + return QPropertyBindingError(); + return d->error; +} + +QT_END_NAMESPACE diff --git a/src/corelib/kernel/qpropertybinding_p.h b/src/corelib/kernel/qpropertybinding_p.h new file mode 100644 index 0000000000..12913b3088 --- /dev/null +++ b/src/corelib/kernel/qpropertybinding_p.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPROPERTYBINDING_P_H +#define QPROPERTYBINDING_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> +#include <QtCore/qshareddata.h> +#include <QtCore/qvarlengtharray.h> +#include <memory> +#include <vector> +#include <functional> + +#include "qproperty_p.h" + +QT_BEGIN_NAMESPACE + +struct QPropertyBindingPrivate : public QSharedData +{ + QUntypedPropertyBinding::BindingEvaluationFunction evaluationFunction; + + QPropertyObserverPointer firstObserver; + QVarLengthArray<QPropertyObserver, 4> dependencyObservers; + + void *propertyDataPtr = nullptr; + + QPropertyBindingSourceLocation location; + QPropertyBindingError error; + + bool dirty = false; + bool updating = false; + + QPropertyBindingPrivate(QUntypedPropertyBinding::BindingEvaluationFunction evaluationFunction, + const QPropertyBindingSourceLocation &location) + : evaluationFunction(std::move(evaluationFunction)) + , location(location) + {} + virtual ~QPropertyBindingPrivate(); + + void unlinkAndDeref(); + + void markDirtyAndNotifyObservers(); + bool evaluateIfDirtyAndReturnTrueIfValueChanged(); + + static QPropertyBindingPrivate *get(const QUntypedPropertyBinding &binding) + { return binding.d.data(); } +}; + +QT_END_NAMESPACE + +#endif // QPROPERTYBINDING_P_H diff --git a/src/corelib/kernel/qpropertyprivate.h b/src/corelib/kernel/qpropertyprivate.h new file mode 100644 index 0000000000..6d4a729845 --- /dev/null +++ b/src/corelib/kernel/qpropertyprivate.h @@ -0,0 +1,249 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPROPERTYPRIVATE_H +#define QPROPERTYPRIVATE_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> +#include <QtCore/QExplicitlySharedDataPointer> + +QT_BEGIN_NAMESPACE + +class QUntypedPropertyBinding; +struct QPropertyBindingPrivate; +using QPropertyBindingPrivatePtr = QExplicitlySharedDataPointer<QPropertyBindingPrivate>; +struct QPropertyBasePointer; + +namespace QtPrivate { + +class Q_CORE_EXPORT QPropertyBase +{ + // Mutable because the address of the observer of the currently evaluating binding is stored here, for + // notification later when the value changes. + mutable quintptr d_ptr = 0; + friend struct QT_PREPEND_NAMESPACE(QPropertyBasePointer); +public: + QPropertyBase() = default; + Q_DISABLE_COPY(QPropertyBase) + QPropertyBase(QPropertyBase &&other) = delete; + QPropertyBase(QPropertyBase &&other, void *propertyDataPtr); + QPropertyBase &operator=(QPropertyBase &&other) = delete; + ~QPropertyBase(); + + void moveAssign(QPropertyBase &&other, void *propertyDataPtr); + + bool hasBinding() const { return d_ptr & BindingBit; } + + QUntypedPropertyBinding setBinding(const QUntypedPropertyBinding &newBinding, void *propertyDataPtr); + QPropertyBindingPrivatePtr binding(); + + void evaluateIfDirty(); + void removeBinding(); + + void registerWithCurrentlyEvaluatingBinding() const; + void notifyObservers(); + + void setExtraBit(bool b) + { + if (b) + d_ptr |= ExtraBit; + else + d_ptr &= ~ExtraBit; + } + + bool extraBit() const { return d_ptr & ExtraBit; } + + static const quintptr ExtraBit = 0x1; // Used for QProperty<bool> specialization + static const quintptr BindingBit = 0x2; // Is d_ptr pointing to a binding (1) or list of notifiers (0)? + static const quintptr FlagMask = BindingBit | ExtraBit; +}; + +template <typename T> +struct QPropertyValueStorage +{ +private: + T value; +public: + QPropertyBase priv; + + QPropertyValueStorage() : value() {} + Q_DISABLE_COPY(QPropertyValueStorage) + explicit QPropertyValueStorage(const T &initialValue) : value(initialValue) {} + QPropertyValueStorage &operator=(const T &newValue) { value = newValue; return *this; } + explicit QPropertyValueStorage(T &&initialValue) : value(std::move(initialValue)) {} + QPropertyValueStorage &operator=(T &&newValue) { value = std::move(newValue); return *this; } + QPropertyValueStorage(QPropertyValueStorage &&other) : value(std::move(other.value)), priv(std::move(other.priv), this) {} + QPropertyValueStorage &operator=(QPropertyValueStorage &&other) { value = std::move(other.value); priv.moveAssign(std::move(other.priv), &value); return *this; } + + T getValue() const { return value; } + bool setValueAndReturnTrueIfChanged(T &&v) + { + if (v == value) + return false; + value = std::move(v); + return true; + } + bool setValueAndReturnTrueIfChanged(const T &v) + { + if (v == value) + return false; + value = v; + return true; + } +}; + +template<> +struct QPropertyValueStorage<bool> +{ + QPropertyBase priv; + + QPropertyValueStorage() = default; + Q_DISABLE_COPY(QPropertyValueStorage) + explicit QPropertyValueStorage(bool initialValue) { priv.setExtraBit(initialValue); } + QPropertyValueStorage &operator=(bool newValue) { priv.setExtraBit(newValue); return *this; } + QPropertyValueStorage(QPropertyValueStorage &&other) : priv(std::move(other.priv), this) {} + QPropertyValueStorage &operator=(QPropertyValueStorage &&other) { priv.moveAssign(std::move(other.priv), this); return *this; } + + bool getValue() const { return priv.extraBit(); } + bool setValueAndReturnTrueIfChanged(bool v) + { + if (v == priv.extraBit()) + return false; + priv.setExtraBit(v); + return true; + } +}; + +template <typename T> class QTaggedPointer; + +template <typename T, quintptr Mask = 0x3> +class QPropertyTagPreservingPointerToPointer +{ + quintptr *data = nullptr; + +public: + QPropertyTagPreservingPointerToPointer() = default; + QPropertyTagPreservingPointerToPointer(T **ptr) + : data(reinterpret_cast<quintptr*>(ptr)) + {} + QPropertyTagPreservingPointerToPointer(quintptr *ptr) + : data(ptr) + {} + + QPropertyTagPreservingPointerToPointer<T> &operator=(T **ptr) + { + data = reinterpret_cast<quintptr*>(ptr); + return *this; + } + + QPropertyTagPreservingPointerToPointer<T> &operator=(QTaggedPointer<T> *ptr) + { + data = reinterpret_cast<quintptr*>(ptr); + return *this; + } + + void clear() + { + data = nullptr; + } + + void set(T *ptr) + { + *data = (*data & Mask) | (reinterpret_cast<quintptr>(ptr) & ~Mask); + } + + T *get() const + { + return reinterpret_cast<T*>(*data & ~Mask); + } + + explicit operator bool() const { return data != nullptr; } +}; + +template <typename T> +class QTaggedPointer +{ +public: + QTaggedPointer() = default; + QTaggedPointer(T *ptr) : tagAndPointer(reinterpret_cast<quintptr>(ptr)) {} + + void setFlag(bool b) + { + if (b) + tagAndPointer |= Flag1Mask; + else + tagAndPointer &= ~Flag1Mask; + } + + bool flag() const { return tagAndPointer & Flag1Mask; } + + QTaggedPointer &operator=(T *ptr) + { + quintptr tag = tagAndPointer & TagMask; + tagAndPointer = reinterpret_cast<quintptr>(ptr) | tag; + return *this; + } + + T *data() const { return reinterpret_cast<T*>(tagAndPointer & ~TagMask); } + + explicit operator bool() const { return tagAndPointer & ~TagMask; } + T *operator->() const { return data(); } + +private: + quintptr tagAndPointer = 0; + static const quintptr Flag1Mask = 0x1; + static const quintptr TagMask = 0x3; +}; + +} // namespace QtPrivate + +QT_END_NAMESPACE + +#endif // QPROPERTYPRIVATE_H diff --git a/src/gui/.prev_CMakeLists.txt b/src/gui/.prev_CMakeLists.txt index fe6ed3d80a..bd066e833f 100644 --- a/src/gui/.prev_CMakeLists.txt +++ b/src/gui/.prev_CMakeLists.txt @@ -273,7 +273,7 @@ qt_extend_target(Gui CONDITION QT_FEATURE_opengl #### Keys ignored in scope 3:.:.:gui.pro:QT_FEATURE_angle: # MODULE_AUX_INCLUDES = "\$\$QT_MODULE_INCLUDE_BASE/QtANGLE" -qt_extend_target(Gui CONDITION APPLE_OSX +qt_extend_target(Gui CONDITION MACOS LIBRARIES ${FWAppKit} PUBLIC_LIBRARIES @@ -517,12 +517,12 @@ qt_extend_target(Gui CONDITION QT_FEATURE_cssparser text/qcssparser.cpp text/qcssparser_p.h ) -qt_extend_target(Gui CONDITION UNIX AND NOT ANDROID AND NOT APPLE_UIKIT AND NOT INTEGRITY AND NOT (TEST_architecture_arch STREQUAL "arm64") +qt_extend_target(Gui CONDITION UNIX AND NOT ANDROID AND NOT INTEGRITY AND NOT (TEST_architecture_arch STREQUAL "arm64") AND NOT UIKIT DEFINES ENABLE_PIXMAN_DRAWHELPERS ) -if(UNIX AND NOT ANDROID AND NOT APPLE_UIKIT AND NOT INTEGRITY AND NOT (TEST_architecture_arch STREQUAL "arm64")) +if(UNIX AND NOT ANDROID AND NOT INTEGRITY AND NOT (TEST_architecture_arch STREQUAL "arm64") AND NOT UIKIT) qt_add_simd_part(Gui SIMD neon SOURCES ../3rdparty/pixman/pixman-arm-neon-asm.S @@ -633,7 +633,7 @@ qt_extend_target(Gui CONDITION WASM platform/wasm/qwasmlocalfileaccess.cpp platform/wasm/qwasmlocalfileaccess_p.h ) -qt_extend_target(Gui CONDITION APPLE_IOS OR APPLE_OSX +qt_extend_target(Gui CONDITION IOS OR MACOS SOURCES rhi/qrhimetal.mm rhi/qrhimetal_p.h rhi/qrhimetal_p_p.h diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index f89881210b..67a6465b75 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -18,11 +18,11 @@ if (QT_FEATURE_gui) set(_default_platform "windows") elseif(ANDROID) set(_default_platform "android") - elseif(APPLE_OSX) + elseif(MACOS) set(_default_platform "cocoa") - elseif(APPLE_TVOS OR APPLE_IOS) + elseif(TVOS OR IOS) set(_default_platform "ios") - elseif(APPLE_WATCHOS) + elseif(WATCHOS) set(_default_platform "minimal") elseif(QNX) set(_default_platform "qnx") @@ -359,7 +359,7 @@ qt_extend_target(Gui CONDITION QT_FEATURE_opengl #### Keys ignored in scope 3:.:.:gui.pro:QT_FEATURE_angle: # MODULE_AUX_INCLUDES = "\$\$QT_MODULE_INCLUDE_BASE/QtANGLE" -qt_extend_target(Gui CONDITION APPLE_OSX +qt_extend_target(Gui CONDITION MACOS LIBRARIES ${FWAppKit} PUBLIC_LIBRARIES @@ -578,7 +578,7 @@ qt_extend_target(Gui CONDITION QT_FEATURE_harfbuzz # Replicate what src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro does, which is link CoreText # when targeting uikit. -qt_extend_target(Gui CONDITION QT_FEATURE_harfbuzz AND APPLE_UIKIT +qt_extend_target(Gui CONDITION QT_FEATURE_harfbuzz AND UIKIT LIBRARIES ${FWCoreText} ) @@ -622,12 +622,12 @@ qt_extend_target(Gui CONDITION QT_FEATURE_cssparser text/qcssparser.cpp text/qcssparser_p.h ) -qt_extend_target(Gui CONDITION UNIX AND NOT ANDROID AND NOT APPLE_UIKIT AND NOT INTEGRITY AND NOT (TEST_architecture_arch STREQUAL "arm64") +qt_extend_target(Gui CONDITION UNIX AND NOT ANDROID AND NOT INTEGRITY AND NOT (TEST_architecture_arch STREQUAL "arm64") AND NOT UIKIT DEFINES ENABLE_PIXMAN_DRAWHELPERS ) -if(UNIX AND NOT ANDROID AND NOT APPLE_UIKIT AND NOT INTEGRITY AND NOT (TEST_architecture_arch STREQUAL "arm64")) +if(UNIX AND NOT ANDROID AND NOT INTEGRITY AND NOT (TEST_architecture_arch STREQUAL "arm64") AND NOT UIKIT) qt_add_simd_part(Gui SIMD neon SOURCES ../3rdparty/pixman/pixman-arm-neon-asm.S @@ -778,7 +778,7 @@ qt_extend_target(Gui CONDITION WASM platform/wasm/qwasmlocalfileaccess.cpp platform/wasm/qwasmlocalfileaccess_p.h ) -qt_extend_target(Gui CONDITION APPLE_IOS OR APPLE_OSX +qt_extend_target(Gui CONDITION IOS OR MACOS SOURCES rhi/qrhimetal.mm rhi/qrhimetal_p.h rhi/qrhimetal_p_p.h diff --git a/src/gui/configure.cmake b/src/gui/configure.cmake index b338cf7dc8..f17949bc53 100644 --- a/src/gui/configure.cmake +++ b/src/gui/configure.cmake @@ -706,7 +706,7 @@ qt_feature("mtdev" PRIVATE ) qt_feature("opengles2" PUBLIC LABEL "OpenGL ES 2.0" - CONDITION NOT WIN32 AND ( NOT APPLE_WATCHOS AND NOT QT_FEATURE_opengl_desktop AND GLESv2_FOUND ) + CONDITION NOT WIN32 AND ( NOT WATCHOS AND NOT QT_FEATURE_opengl_desktop AND GLESv2_FOUND ) ENABLE INPUT_opengl STREQUAL 'es2' OR INPUT_angle STREQUAL 'yes' DISABLE INPUT_opengl STREQUAL 'desktop' OR INPUT_opengl STREQUAL 'dynamic' OR INPUT_opengl STREQUAL 'no' ) @@ -730,7 +730,7 @@ qt_feature("opengles32" PUBLIC qt_feature_definition("opengles32" "QT_OPENGL_ES_3_2") qt_feature("opengl-desktop" LABEL "Desktop OpenGL" - CONDITION ( WIN32 AND NOT WINRT AND NOT QT_FEATURE_opengles2 AND ( MSVC OR OpenGL_OpenGL_FOUND ) ) OR ( NOT APPLE_WATCHOS AND NOT WIN32 AND NOT WASM AND OpenGL_OpenGL_FOUND ) + CONDITION ( WIN32 AND NOT WINRT AND NOT QT_FEATURE_opengles2 AND ( MSVC OR OpenGL_OpenGL_FOUND ) ) OR ( NOT WATCHOS AND NOT WIN32 AND NOT WASM AND OpenGL_OpenGL_FOUND ) ENABLE INPUT_opengl STREQUAL 'desktop' DISABLE INPUT_opengl STREQUAL 'es2' OR INPUT_opengl STREQUAL 'dynamic' OR INPUT_opengl STREQUAL 'no' ) @@ -1279,7 +1279,7 @@ qt_configure_add_report_entry( qt_configure_add_report_entry( TYPE ERROR MESSAGE "The OpenGL functionality tests failed! You might need to modify the include and library search paths by editing QMAKE_INCDIR_OPENGL[_ES2], QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your platform." - CONDITION QT_FEATURE_gui AND NOT APPLE_WATCHOS AND ( NOT INPUT_opengl STREQUAL 'no' ) AND NOT QT_FEATURE_opengl_desktop AND NOT QT_FEATURE_opengles2 AND NOT QT_FEATURE_opengl_dynamic + CONDITION QT_FEATURE_gui AND NOT WATCHOS AND ( NOT INPUT_opengl STREQUAL 'no' ) AND NOT QT_FEATURE_opengl_desktop AND NOT QT_FEATURE_opengles2 AND NOT QT_FEATURE_opengl_dynamic ) qt_configure_add_report_entry( TYPE WARNING diff --git a/src/network/.prev_CMakeLists.txt b/src/network/.prev_CMakeLists.txt index 8f38d07e93..a1d30b6c83 100644 --- a/src/network/.prev_CMakeLists.txt +++ b/src/network/.prev_CMakeLists.txt @@ -231,25 +231,25 @@ qt_extend_target(Network CONDITION QT_FEATURE_dnslookup AND WINRT kernel/qdnslookup_winrt.cpp ) -qt_extend_target(Network CONDITION APPLE AND NOT APPLE_UIKIT +qt_extend_target(Network CONDITION APPLE AND NOT UIKIT LIBRARIES ${FWCoreServices} ${FWSystemConfiguration} ) -qt_extend_target(Network CONDITION APPLE_IOS OR APPLE_OSX +qt_extend_target(Network CONDITION IOS OR MACOS SOURCES kernel/qnetconmonitor_darwin.mm LIBRARIES ${FWSystemConfiguration} ) -qt_extend_target(Network CONDITION QT_FEATURE_netlistmgr AND NOT APPLE_IOS AND NOT APPLE_OSX +qt_extend_target(Network CONDITION QT_FEATURE_netlistmgr AND NOT IOS AND NOT MACOS SOURCES kernel/qnetconmonitor_win.cpp ) -qt_extend_target(Network CONDITION NOT APPLE_IOS AND NOT APPLE_OSX AND NOT QT_FEATURE_netlistmgr +qt_extend_target(Network CONDITION NOT IOS AND NOT MACOS AND NOT QT_FEATURE_netlistmgr SOURCES kernel/qnetconmonitor_stub.cpp ) @@ -259,17 +259,17 @@ qt_extend_target(Network CONDITION QT_FEATURE_gssapi GSSAPI::GSSAPI ) -qt_extend_target(Network CONDITION APPLE_UIKIT +qt_extend_target(Network CONDITION UIKIT SOURCES kernel/qnetworkinterface_uikit_p.h ) -qt_extend_target(Network CONDITION APPLE_OSX +qt_extend_target(Network CONDITION MACOS SOURCES kernel/qnetworkproxy_mac.cpp ) -qt_extend_target(Network CONDITION QT_FEATURE_libproxy AND NOT APPLE_OSX AND (UNIX OR WINRT) +qt_extend_target(Network CONDITION QT_FEATURE_libproxy AND NOT MACOS AND (UNIX OR WINRT) SOURCES kernel/qnetworkproxy_libproxy.cpp LIBRARIES @@ -277,7 +277,7 @@ qt_extend_target(Network CONDITION QT_FEATURE_libproxy AND NOT APPLE_OSX AND (UN PkgConfig::Libproxy ) -qt_extend_target(Network CONDITION NOT APPLE_OSX AND NOT QT_FEATURE_libproxy AND (UNIX OR WINRT) +qt_extend_target(Network CONDITION NOT MACOS AND NOT QT_FEATURE_libproxy AND (UNIX OR WINRT) SOURCES kernel/qnetworkproxy_generic.cpp ) diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index baea85ea99..86eadf653c 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -231,25 +231,25 @@ qt_extend_target(Network CONDITION QT_FEATURE_dnslookup AND WINRT kernel/qdnslookup_winrt.cpp ) -qt_extend_target(Network CONDITION APPLE AND NOT APPLE_UIKIT +qt_extend_target(Network CONDITION APPLE AND NOT UIKIT LIBRARIES ${FWCoreServices} ${FWSystemConfiguration} ) -qt_extend_target(Network CONDITION APPLE_IOS OR APPLE_OSX +qt_extend_target(Network CONDITION IOS OR MACOS SOURCES kernel/qnetconmonitor_darwin.mm LIBRARIES ${FWSystemConfiguration} ) -qt_extend_target(Network CONDITION QT_FEATURE_netlistmgr AND NOT APPLE_IOS AND NOT APPLE_OSX +qt_extend_target(Network CONDITION QT_FEATURE_netlistmgr AND NOT IOS AND NOT MACOS SOURCES kernel/qnetconmonitor_win.cpp ) -qt_extend_target(Network CONDITION NOT APPLE_IOS AND NOT APPLE_OSX AND NOT QT_FEATURE_netlistmgr +qt_extend_target(Network CONDITION NOT IOS AND NOT MACOS AND NOT QT_FEATURE_netlistmgr SOURCES kernel/qnetconmonitor_stub.cpp ) @@ -259,17 +259,17 @@ qt_extend_target(Network CONDITION QT_FEATURE_gssapi GSSAPI::GSSAPI ) -qt_extend_target(Network CONDITION APPLE_UIKIT +qt_extend_target(Network CONDITION UIKIT SOURCES kernel/qnetworkinterface_uikit_p.h ) -qt_extend_target(Network CONDITION APPLE_OSX +qt_extend_target(Network CONDITION MACOS SOURCES kernel/qnetworkproxy_mac.cpp ) -qt_extend_target(Network CONDITION QT_FEATURE_libproxy AND NOT APPLE_OSX AND (UNIX OR WINRT) +qt_extend_target(Network CONDITION QT_FEATURE_libproxy AND NOT MACOS AND (UNIX OR WINRT) SOURCES kernel/qnetworkproxy_libproxy.cpp LIBRARIES @@ -277,7 +277,7 @@ qt_extend_target(Network CONDITION QT_FEATURE_libproxy AND NOT APPLE_OSX AND (UN PkgConfig::Libproxy ) -qt_extend_target(Network CONDITION NOT APPLE_OSX AND NOT QT_FEATURE_libproxy AND (UNIX OR WINRT) +qt_extend_target(Network CONDITION NOT MACOS AND NOT QT_FEATURE_libproxy AND (UNIX OR WINRT) SOURCES kernel/qnetworkproxy_generic.cpp ) diff --git a/src/network/configure.cmake b/src/network/configure.cmake index 086acc5e72..e4699b7213 100644 --- a/src/network/configure.cmake +++ b/src/network/configure.cmake @@ -444,7 +444,7 @@ qt_configure_end_summary_section() # end of "Qt Network" section qt_configure_add_report_entry( TYPE NOTE MESSAGE "When linking against OpenSSL, you can override the default library names through OPENSSL_LIBS. For example: OPENSSL_LIBS='-L/opt/ssl/lib -lssl -lcrypto' ./configure -openssl-linked" - CONDITION NOT ANDROID AND QT_FEATURE_openssl_linked AND OpenSSL_FOUND.source NOT = 0 AND INPUT_openssl.prefix STREQUAL '' AND INPUT_openssl.libs STREQUAL '' AND INPUT_openssl.libs.debug STREQUAL '' OR FIXME + CONDITION NOT ANDROID AND QT_FEATURE_openssl_linked AND TEST_openssl.source NOT = 0 AND INPUT_openssl.prefix STREQUAL '' AND INPUT_openssl.libs STREQUAL '' AND INPUT_openssl.libs.debug STREQUAL '' OR FIXME ) qt_configure_add_report_entry( TYPE WARNING diff --git a/src/platformsupport/CMakeLists.txt b/src/platformsupport/CMakeLists.txt index fc980f3707..9e91754ac8 100644 --- a/src/platformsupport/CMakeLists.txt +++ b/src/platformsupport/CMakeLists.txt @@ -16,7 +16,7 @@ endif() if(QT_FEATURE_evdev OR QT_FEATURE_integrityhid OR QT_FEATURE_libinput OR QT_FEATURE_tslib) add_subdirectory(input) endif() -if(QT_FEATURE_xcb OR (UNIX AND NOT APPLE_UIKIT)) +if(QT_FEATURE_xcb OR (UNIX AND NOT UIKIT)) add_subdirectory(services) endif() if(QT_FEATURE_opengl) diff --git a/src/platformsupport/clipboard/CMakeLists.txt b/src/platformsupport/clipboard/CMakeLists.txt index 52022903aa..d5b6835a54 100644 --- a/src/platformsupport/clipboard/CMakeLists.txt +++ b/src/platformsupport/clipboard/CMakeLists.txt @@ -23,7 +23,7 @@ qt_add_module(ClipboardSupport ## Scopes: ##################################################################### -qt_extend_target(ClipboardSupport CONDITION APPLE_OSX +qt_extend_target(ClipboardSupport CONDITION MACOS LIBRARIES ${FWAppKit} ) diff --git a/src/platformsupport/fontdatabases/.prev_CMakeLists.txt b/src/platformsupport/fontdatabases/.prev_CMakeLists.txt index 56cf076bd9..b30b04824a 100644 --- a/src/platformsupport/fontdatabases/.prev_CMakeLists.txt +++ b/src/platformsupport/fontdatabases/.prev_CMakeLists.txt @@ -33,12 +33,12 @@ qt_extend_target(FontDatabaseSupport CONDITION APPLE ${FWFoundation} ) -qt_extend_target(FontDatabaseSupport CONDITION APPLE_OSX +qt_extend_target(FontDatabaseSupport CONDITION MACOS LIBRARIES ${FWAppKit} ) -qt_extend_target(FontDatabaseSupport CONDITION APPLE AND NOT APPLE_OSX +qt_extend_target(FontDatabaseSupport CONDITION APPLE AND NOT MACOS LIBRARIES ${FWUIKit} ) diff --git a/src/platformsupport/fontdatabases/CMakeLists.txt b/src/platformsupport/fontdatabases/CMakeLists.txt index b613d6cf6a..46919116da 100644 --- a/src/platformsupport/fontdatabases/CMakeLists.txt +++ b/src/platformsupport/fontdatabases/CMakeLists.txt @@ -36,12 +36,12 @@ qt_extend_target(FontDatabaseSupport CONDITION APPLE ${FWFoundation} ) -qt_extend_target(FontDatabaseSupport CONDITION APPLE_OSX +qt_extend_target(FontDatabaseSupport CONDITION MACOS LIBRARIES ${FWAppKit} ) -qt_extend_target(FontDatabaseSupport CONDITION APPLE AND NOT APPLE_OSX +qt_extend_target(FontDatabaseSupport CONDITION APPLE AND NOT MACOS LIBRARIES ${FWUIKit} ) diff --git a/src/platformsupport/themes/CMakeLists.txt b/src/platformsupport/themes/CMakeLists.txt index a7be78d0e0..3b1ad022b8 100644 --- a/src/platformsupport/themes/CMakeLists.txt +++ b/src/platformsupport/themes/CMakeLists.txt @@ -22,12 +22,12 @@ qt_add_module(ThemeSupport ## Scopes: ##################################################################### -qt_extend_target(ThemeSupport CONDITION QT_FEATURE_xcb OR (UNIX AND NOT APPLE_UIKIT) +qt_extend_target(ThemeSupport CONDITION QT_FEATURE_xcb OR (UNIX AND NOT UIKIT) SOURCES genericunix/qgenericunixthemes.cpp genericunix/qgenericunixthemes_p.h ) -qt_extend_target(ThemeSupport CONDITION QT_FEATURE_dbus AND (QT_FEATURE_xcb OR UNIX) AND (QT_FEATURE_xcb OR NOT APPLE_UIKIT) +qt_extend_target(ThemeSupport CONDITION QT_FEATURE_dbus AND (QT_FEATURE_xcb OR UNIX) AND (QT_FEATURE_xcb OR NOT UIKIT) SOURCES genericunix/dbusmenu/qdbusmenuadaptor.cpp genericunix/dbusmenu/qdbusmenuadaptor_p.h genericunix/dbusmenu/qdbusmenubar.cpp genericunix/dbusmenu/qdbusmenubar_p.h @@ -41,7 +41,7 @@ qt_extend_target(ThemeSupport CONDITION QT_FEATURE_dbus AND (QT_FEATURE_xcb OR U Qt::DBus ) -qt_extend_target(ThemeSupport CONDITION QT_FEATURE_dbus AND QT_FEATURE_systemtrayicon AND (QT_FEATURE_xcb OR UNIX) AND (QT_FEATURE_xcb OR NOT APPLE_UIKIT) +qt_extend_target(ThemeSupport CONDITION QT_FEATURE_dbus AND QT_FEATURE_systemtrayicon AND (QT_FEATURE_xcb OR UNIX) AND (QT_FEATURE_xcb OR NOT UIKIT) SOURCES genericunix/dbustray/qdbustrayicon.cpp genericunix/dbustray/qdbustrayicon_p.h genericunix/dbustray/qdbustraytypes.cpp genericunix/dbustray/qdbustraytypes_p.h diff --git a/src/plugins/platforminputcontexts/CMakeLists.txt b/src/plugins/platforminputcontexts/CMakeLists.txt index 155f5161f2..b5150df4f3 100644 --- a/src/plugins/platforminputcontexts/CMakeLists.txt +++ b/src/plugins/platforminputcontexts/CMakeLists.txt @@ -3,6 +3,6 @@ if(QT_FEATURE_xkbcommon) add_subdirectory(compose) endif() -if(QT_FEATURE_xkbcommon AND TARGET Qt::DBus AND UNIX AND NOT APPLE_OSX) +if(QT_FEATURE_xkbcommon AND TARGET Qt::DBus AND UNIX AND NOT MACOS) add_subdirectory(ibus) endif() diff --git a/src/plugins/platforms/.prev_CMakeLists.txt b/src/plugins/platforms/.prev_CMakeLists.txt index 5797b07233..c58fb31aea 100644 --- a/src/plugins/platforms/.prev_CMakeLists.txt +++ b/src/plugins/platforms/.prev_CMakeLists.txt @@ -12,10 +12,10 @@ endif() if(QT_FEATURE_xcb) add_subdirectory(xcb) endif() -if(APPLE_UIKIT AND NOT APPLE_WATCHOS) +if(UIKIT AND NOT WATCHOS) add_subdirectory(ios) endif() -if(APPLE_OSX) +if(MACOS) add_subdirectory(cocoa) endif() if(QT_FEATURE_direct3d9 AND WIN32 AND NOT WINRT) diff --git a/src/plugins/platforms/CMakeLists.txt b/src/plugins/platforms/CMakeLists.txt index 57c3952e4c..442596286a 100644 --- a/src/plugins/platforms/CMakeLists.txt +++ b/src/plugins/platforms/CMakeLists.txt @@ -12,10 +12,10 @@ endif() if(QT_FEATURE_xcb) add_subdirectory(xcb) endif() -if(APPLE_UIKIT AND NOT APPLE_WATCHOS) +if(UIKIT AND NOT WATCHOS) add_subdirectory(ios) endif() -if(APPLE_OSX) +if(MACOS) add_subdirectory(cocoa) endif() if(WIN32 AND NOT WINRT) # special case TODO fix direct3d9 test diff --git a/src/plugins/platforms/ios/.prev_CMakeLists.txt b/src/plugins/platforms/ios/.prev_CMakeLists.txt index d7ff160ee0..3a330e2b7b 100644 --- a/src/plugins/platforms/ios/.prev_CMakeLists.txt +++ b/src/plugins/platforms/ios/.prev_CMakeLists.txt @@ -49,7 +49,7 @@ extend_target(QIOSIntegrationPlugin CONDITION TARGET Qt::PlatformCompositorSuppo Qt::PlatformCompositorSupportPrivate ) -extend_target(QIOSIntegrationPlugin CONDITION NOT APPLE_TVOS +extend_target(QIOSIntegrationPlugin CONDITION NOT TVOS SOURCES qiosclipboard.h qiosclipboard.mm qiosfiledialog.h qiosfiledialog.mm diff --git a/src/plugins/platforms/ios/CMakeLists.txt b/src/plugins/platforms/ios/CMakeLists.txt index d7ff160ee0..3a330e2b7b 100644 --- a/src/plugins/platforms/ios/CMakeLists.txt +++ b/src/plugins/platforms/ios/CMakeLists.txt @@ -49,7 +49,7 @@ extend_target(QIOSIntegrationPlugin CONDITION TARGET Qt::PlatformCompositorSuppo Qt::PlatformCompositorSupportPrivate ) -extend_target(QIOSIntegrationPlugin CONDITION NOT APPLE_TVOS +extend_target(QIOSIntegrationPlugin CONDITION NOT TVOS SOURCES qiosclipboard.h qiosclipboard.mm qiosfiledialog.h qiosfiledialog.mm diff --git a/src/plugins/platforms/ios/optional/CMakeLists.txt b/src/plugins/platforms/ios/optional/CMakeLists.txt index 3c84e61f26..6f5d754d4a 100644 --- a/src/plugins/platforms/ios/optional/CMakeLists.txt +++ b/src/plugins/platforms/ios/optional/CMakeLists.txt @@ -1,5 +1,5 @@ # Generated from optional.pro. -if(APPLE_IOS) +if(IOS) add_subdirectory(nsphotolibrarysupport) endif() diff --git a/src/plugins/printsupport/.prev_CMakeLists.txt b/src/plugins/printsupport/.prev_CMakeLists.txt index 5853d82c6a..a1f39cb843 100644 --- a/src/plugins/printsupport/.prev_CMakeLists.txt +++ b/src/plugins/printsupport/.prev_CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from printsupport.pro. -if(APPLE_OSX) +if(MACOS) add_subdirectory(cocoa) endif() if(WIN32) diff --git a/src/plugins/printsupport/CMakeLists.txt b/src/plugins/printsupport/CMakeLists.txt index 22b753f5c0..1e7013bc1c 100644 --- a/src/plugins/printsupport/CMakeLists.txt +++ b/src/plugins/printsupport/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from printsupport.pro. -if(APPLE_OSX) +if(MACOS) add_subdirectory(cocoa) endif() if(WIN32) diff --git a/src/printsupport/CMakeLists.txt b/src/printsupport/CMakeLists.txt index c11b9d8b15..9c73d78267 100644 --- a/src/printsupport/CMakeLists.txt +++ b/src/printsupport/CMakeLists.txt @@ -143,7 +143,7 @@ if(QT_FEATURE_printdialog) ) endif() -qt_extend_target(PrintSupport CONDITION APPLE_OSX AND QT_FEATURE_printdialog +qt_extend_target(PrintSupport CONDITION MACOS AND QT_FEATURE_printdialog SOURCES dialogs/qpagesetupdialog_mac.mm dialogs/qprintdialog_mac.mm diff --git a/src/printsupport/configure.cmake b/src/printsupport/configure.cmake index 145a4b05d7..d9f63140af 100644 --- a/src/printsupport/configure.cmake +++ b/src/printsupport/configure.cmake @@ -32,7 +32,7 @@ qt_feature("printer" PUBLIC SECTION "Painting" LABEL "QPrinter" PURPOSE "Provides a printer backend of QPainter." - CONDITION NOT APPLE_UIKIT AND NOT WINRT AND QT_FEATURE_picture AND QT_FEATURE_temporaryfile AND QT_FEATURE_pdf + CONDITION NOT UIKIT AND NOT WINRT AND QT_FEATURE_picture AND QT_FEATURE_temporaryfile AND QT_FEATURE_pdf ) qt_feature_definition("printer" "QT_NO_PRINTER" NEGATE VALUE "1") qt_feature("printpreviewwidget" PUBLIC diff --git a/src/testlib/.prev_CMakeLists.txt b/src/testlib/.prev_CMakeLists.txt index 8279b0719b..a56048240a 100644 --- a/src/testlib/.prev_CMakeLists.txt +++ b/src/testlib/.prev_CMakeLists.txt @@ -101,7 +101,7 @@ qt_extend_target(Test CONDITION APPLE ${FWSecurity} ) -qt_extend_target(Test CONDITION APPLE_OSX +qt_extend_target(Test CONDITION MACOS SOURCES qtestutil_macos.mm qtestutil_macos_p.h PUBLIC_LIBRARIES diff --git a/src/testlib/CMakeLists.txt b/src/testlib/CMakeLists.txt index 8e2a3caafa..0f80af42c9 100644 --- a/src/testlib/CMakeLists.txt +++ b/src/testlib/CMakeLists.txt @@ -99,7 +99,7 @@ qt_extend_target(Test CONDITION APPLE ${FWSecurity} ) -qt_extend_target(Test CONDITION APPLE_OSX +qt_extend_target(Test CONDITION MACOS SOURCES qtestutil_macos.mm qtestutil_macos_p.h PUBLIC_LIBRARIES @@ -111,8 +111,8 @@ qt_extend_target(Test CONDITION APPLE_OSX # special case begin # Do not bother with disabled stuff: -# extend_target(Test CONDITION (APPLE_OSX) AND (OFF AND NOT lessThan(QMAKE_XCODE_VERSION, "6.0")) ... -# extend_target(Test CONDITION ((APPLE_OSX) AND (OFF AND NOT lessThan(QMAKE_XCODE_VERSION, "6.0"))) AND (NOT QMAKE_MAC_SDK_PLATFORM_PATH_ISEMPTY) ... +# extend_target(Test CONDITION (MACOS) AND (OFF AND NOT lessThan(QMAKE_XCODE_VERSION, "6.0")) ... +# extend_target(Test CONDITION ((MACOS) AND (OFF AND NOT lessThan(QMAKE_XCODE_VERSION, "6.0"))) AND (NOT QMAKE_MAC_SDK_PLATFORM_PATH_ISEMPTY) ... # special case end #### Keys ignored in scope 9:.:.:testlib.pro:NOT QMAKE_MAC_SDK_PLATFORM_PATH_ISEMPTY: diff --git a/src/tools/bootstrap/.prev_CMakeLists.txt b/src/tools/bootstrap/.prev_CMakeLists.txt index be8c0e22d8..d4df972715 100644 --- a/src/tools/bootstrap/.prev_CMakeLists.txt +++ b/src/tools/bootstrap/.prev_CMakeLists.txt @@ -174,19 +174,19 @@ qt_extend_target(Bootstrap CONDITION APPLE ${FWFoundation} ) -qt_extend_target(Bootstrap CONDITION APPLE_OSX +qt_extend_target(Bootstrap CONDITION MACOS SOURCES ../../corelib/io/qstandardpaths_mac.mm LIBRARIES ${FWCoreServices} ) -qt_extend_target(Bootstrap CONDITION APPLE_UIKIT +qt_extend_target(Bootstrap CONDITION UIKIT LIBRARIES ${FWUIKit} ) -qt_extend_target(Bootstrap CONDITION UNIX AND NOT APPLE_OSX +qt_extend_target(Bootstrap CONDITION UNIX AND NOT MACOS SOURCES ../../corelib/io/qstandardpaths_unix.cpp ) diff --git a/src/tools/bootstrap/CMakeLists.txt b/src/tools/bootstrap/CMakeLists.txt index c9deb2c4f5..627847bd7f 100644 --- a/src/tools/bootstrap/CMakeLists.txt +++ b/src/tools/bootstrap/CMakeLists.txt @@ -174,19 +174,19 @@ qt_extend_target(Bootstrap CONDITION APPLE ${FWFoundation} ) -qt_extend_target(Bootstrap CONDITION APPLE_OSX +qt_extend_target(Bootstrap CONDITION MACOS SOURCES ../../corelib/io/qstandardpaths_mac.mm LIBRARIES ${FWCoreServices} ) -qt_extend_target(Bootstrap CONDITION APPLE_UIKIT +qt_extend_target(Bootstrap CONDITION UIKIT LIBRARIES ${FWUIKit} ) -qt_extend_target(Bootstrap CONDITION UNIX AND NOT APPLE_OSX +qt_extend_target(Bootstrap CONDITION UNIX AND NOT MACOS SOURCES ../../corelib/io/qstandardpaths_unix.cpp ) diff --git a/src/widgets/.prev_CMakeLists.txt b/src/widgets/.prev_CMakeLists.txt index 51e8f8064d..df76fe30c2 100644 --- a/src/widgets/.prev_CMakeLists.txt +++ b/src/widgets/.prev_CMakeLists.txt @@ -296,7 +296,7 @@ qt_extend_target(Widgets CONDITION MSVC AND (TEST_architecture_arch STREQUAL "i3 "/BASE:0x65000000" ) -qt_extend_target(Widgets CONDITION APPLE_OSX +qt_extend_target(Widgets CONDITION MACOS SOURCES kernel/qmacgesturerecognizer.cpp kernel/qmacgesturerecognizer_p.h widgets/qmaccocoaviewcontainer_mac.h widgets/qmaccocoaviewcontainer_mac.mm @@ -594,7 +594,7 @@ qt_extend_target(Widgets CONDITION QT_FEATURE_widgettextcontrol widgets/qwidgettextcontrol_p_p.h ) -qt_extend_target(Widgets CONDITION APPLE_OSX AND (QT_FEATURE_menu OR QT_FEATURE_menubar) +qt_extend_target(Widgets CONDITION MACOS AND (QT_FEATURE_menu OR QT_FEATURE_menubar) SOURCES widgets/qmenu_mac.mm ) diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index b3c015f3db..f3c04ac4c7 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -298,7 +298,7 @@ qt_extend_target(Widgets CONDITION MSVC AND (TEST_architecture_arch STREQUAL "i3 "/BASE:0x65000000" ) -qt_extend_target(Widgets CONDITION APPLE_OSX +qt_extend_target(Widgets CONDITION MACOS SOURCES kernel/qmacgesturerecognizer.cpp kernel/qmacgesturerecognizer_p.h widgets/qmaccocoaviewcontainer_mac.h widgets/qmaccocoaviewcontainer_mac.mm @@ -596,7 +596,7 @@ qt_extend_target(Widgets CONDITION QT_FEATURE_widgettextcontrol widgets/qwidgettextcontrol_p_p.h ) -qt_extend_target(Widgets CONDITION APPLE_OSX AND (QT_FEATURE_menu OR QT_FEATURE_menubar) +qt_extend_target(Widgets CONDITION MACOS AND (QT_FEATURE_menu OR QT_FEATURE_menubar) SOURCES widgets/qmenu_mac.mm ) diff --git a/src/widgets/configure.cmake b/src/widgets/configure.cmake index 88b1f3e650..9d79ddb788 100644 --- a/src/widgets/configure.cmake +++ b/src/widgets/configure.cmake @@ -25,7 +25,7 @@ qt_feature("style-fusion" PRIVATE ) qt_feature("style-mac" PRIVATE LABEL "macOS" - CONDITION APPLE_OSX AND QT_FEATURE_animation + CONDITION MACOS AND QT_FEATURE_animation ) qt_feature("style-windows" PRIVATE LABEL "Windows" diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt index 64996503eb..480f986830 100644 --- a/tests/auto/CMakeLists.txt +++ b/tests/auto/CMakeLists.txt @@ -31,7 +31,7 @@ endif() # special case begin # Build only corelib and gui tests when targeting uikit (iOS), # because the script can't handle the SUBDIRS assignment well. -if (APPLE_UIKIT) +if (UIKIT) return() endif() # special case end diff --git a/tests/auto/corelib/.prev_CMakeLists.txt b/tests/auto/corelib/.prev_CMakeLists.txt index 1029b14654..2019a771c0 100644 --- a/tests/auto/corelib/.prev_CMakeLists.txt +++ b/tests/auto/corelib/.prev_CMakeLists.txt @@ -1,7 +1,7 @@ # Generated from corelib.pro. add_subdirectory(kernel) -if(NOT APPLE_UIKIT) +if(NOT UIKIT) add_subdirectory(animation) add_subdirectory(codecs) add_subdirectory(global) diff --git a/tests/auto/corelib/CMakeLists.txt b/tests/auto/corelib/CMakeLists.txt index 1029b14654..2019a771c0 100644 --- a/tests/auto/corelib/CMakeLists.txt +++ b/tests/auto/corelib/CMakeLists.txt @@ -1,7 +1,7 @@ # Generated from corelib.pro. add_subdirectory(kernel) -if(NOT APPLE_UIKIT) +if(NOT UIKIT) add_subdirectory(animation) add_subdirectory(codecs) add_subdirectory(global) diff --git a/tests/auto/corelib/io/qdir/CMakeLists.txt b/tests/auto/corelib/io/qdir/CMakeLists.txt index 84136283c1..f77185bc2b 100644 --- a/tests/auto/corelib/io/qdir/CMakeLists.txt +++ b/tests/auto/corelib/io/qdir/CMakeLists.txt @@ -37,7 +37,7 @@ add_qt_resource(tst_qdir "qdir" ## Scopes: ##################################################################### -#### Keys ignored in scope 2:.:.:qdir.pro:APPLE_IOS: +#### Keys ignored in scope 2:.:.:qdir.pro:IOS: # QMAKE_INFO_PLIST = "Info.plist" extend_target(tst_qdir CONDITION CONFIG___contains___builtin_testdata diff --git a/tests/auto/corelib/kernel/.prev_CMakeLists.txt b/tests/auto/corelib/kernel/.prev_CMakeLists.txt index 5415a23a98..515720e282 100644 --- a/tests/auto/corelib/kernel/.prev_CMakeLists.txt +++ b/tests/auto/corelib/kernel/.prev_CMakeLists.txt @@ -17,11 +17,11 @@ add_subdirectory(qmetaenum) if(TARGET Qt::Gui) add_subdirectory(qmimedata) endif() -if(TARGET Qt::Network AND NOT ANDROID AND NOT APPLE_UIKIT) +if(TARGET Qt::Network AND NOT ANDROID AND NOT UIKIT) add_subdirectory(qobject) endif() add_subdirectory(qpointer) -if(QT_FEATURE_private_tests AND NOT ANDROID AND NOT APPLE_UIKIT) +if(QT_FEATURE_private_tests AND NOT ANDROID AND NOT UIKIT) add_subdirectory(qsharedmemory) endif() add_subdirectory(qsignalblocker) @@ -29,7 +29,7 @@ add_subdirectory(qsignalmapper) if(QT_FEATURE_private_tests AND TARGET Qt::Network) add_subdirectory(qsocketnotifier) endif() -if(QT_FEATURE_systemsemaphore AND NOT ANDROID AND NOT APPLE_UIKIT) +if(QT_FEATURE_systemsemaphore AND NOT ANDROID AND NOT UIKIT) add_subdirectory(qsystemsemaphore) endif() add_subdirectory(qtimer) diff --git a/tests/auto/corelib/kernel/CMakeLists.txt b/tests/auto/corelib/kernel/CMakeLists.txt index 9fbe2b8b7a..c72018db6c 100644 --- a/tests/auto/corelib/kernel/CMakeLists.txt +++ b/tests/auto/corelib/kernel/CMakeLists.txt @@ -17,11 +17,11 @@ add_subdirectory(qmetaenum) if(TARGET Qt::Gui) add_subdirectory(qmimedata) endif() -if(TARGET Qt::Network AND NOT ANDROID AND NOT APPLE_UIKIT) +if(TARGET Qt::Network AND NOT ANDROID AND NOT UIKIT) # add_subdirectory(qobject) # special case endif() add_subdirectory(qpointer) -if(QT_FEATURE_private_tests AND NOT ANDROID AND NOT APPLE_UIKIT) +if(QT_FEATURE_private_tests AND NOT ANDROID AND NOT UIKIT) add_subdirectory(qsharedmemory) endif() add_subdirectory(qsignalblocker) @@ -29,7 +29,7 @@ add_subdirectory(qsignalmapper) if(QT_FEATURE_private_tests AND TARGET Qt::Network) add_subdirectory(qsocketnotifier) endif() -if(QT_FEATURE_systemsemaphore AND NOT ANDROID AND NOT APPLE_UIKIT) +if(QT_FEATURE_systemsemaphore AND NOT ANDROID AND NOT UIKIT) add_subdirectory(qsystemsemaphore) endif() # add_subdirectory(qtimer) # special case diff --git a/tests/auto/corelib/kernel/kernel.pro b/tests/auto/corelib/kernel/kernel.pro index 09074a9e8a..26cc00ea40 100644 --- a/tests/auto/corelib/kernel/kernel.pro +++ b/tests/auto/corelib/kernel/kernel.pro @@ -23,7 +23,8 @@ SUBDIRS=\ qtimer \ qtranslator \ qvariant \ - qwineventnotifier + qwineventnotifier \ + qproperty !qtHaveModule(gui): SUBDIRS -= \ qmimedata @@ -35,7 +36,8 @@ SUBDIRS=\ !qtConfig(private_tests): SUBDIRS -= \ qsocketnotifier \ - qsharedmemory + qsharedmemory \ + qproperty # This test is only applicable on Windows !win32*|winrt: SUBDIRS -= qwineventnotifier diff --git a/tests/auto/corelib/kernel/qproperty/qproperty.pro b/tests/auto/corelib/kernel/qproperty/qproperty.pro new file mode 100644 index 0000000000..bae67e70a4 --- /dev/null +++ b/tests/auto/corelib/kernel/qproperty/qproperty.pro @@ -0,0 +1,4 @@ +CONFIG += testcase +TARGET = tst_qproperty +QT = core core-private testlib +SOURCES = tst_qproperty.cpp diff --git a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp new file mode 100644 index 0000000000..7f64072df6 --- /dev/null +++ b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp @@ -0,0 +1,615 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QObject> +#include <qtest.h> +#include <qproperty.h> +#include <private/qproperty_p.h> +#include <private/qpropertybinding_p.h> + +using namespace QtPrivate; + +class tst_QProperty : public QObject +{ + Q_OBJECT +private slots: + void functorBinding(); + void basicDependencies(); + void multipleDependencies(); + void bindingWithDeletedDependency(); + void recursiveDependency(); + void bindingAfterUse(); + void switchBinding(); + void avoidDependencyAllocationAfterFirstEval(); + void propertyArrays(); + void boolProperty(); + void takeBinding(); + void replaceBinding(); + void swap(); + void moveNotifies(); + void moveCtor(); + void changeHandler(); + void propertyChangeHandlerApi(); + void subscribe(); + void changeHandlerThroughBindings(); + void dontTriggerDependenciesIfUnchangedValue(); + void bindingSourceLocation(); + void bindingError(); + void bindingLoop(); + void changePropertyFromWithinChangeHandler(); + void changePropertyFromWithinChangeHandlerThroughDependency(); + void changePropertyFromWithinChangeHandler2(); + void settingPropertyValueDoesRemoveBinding(); +}; + +void tst_QProperty::functorBinding() +{ + QProperty<int> property([]() { return 42; }); + QCOMPARE(property.value(), int(42)); + property = Qt::makePropertyBinding([]() { return 100; }); + QCOMPARE(property.value(), int(100)); + property.setBinding([]() { return 50; }); + QCOMPARE(property.value(), int(50)); +} + +void tst_QProperty::basicDependencies() +{ + QProperty<int> right(100); + + QProperty<int> left = Qt::makePropertyBinding(right); + + QCOMPARE(left.value(), int(100)); + + right = 42; + + QCOMPARE(left.value(), int(42)); +} + +void tst_QProperty::multipleDependencies() +{ + QProperty<int> firstDependency(1); + QProperty<int> secondDependency(2); + + QProperty<int> sum; + sum = Qt::makePropertyBinding([&]() { return firstDependency + secondDependency; }); + + QCOMPARE(QPropertyBasePointer::get(firstDependency).observerCount(), 0); + QCOMPARE(QPropertyBasePointer::get(secondDependency).observerCount(), 0); + + QCOMPARE(sum.value(), int(3)); + QCOMPARE(QPropertyBasePointer::get(firstDependency).observerCount(), 1); + QCOMPARE(QPropertyBasePointer::get(secondDependency).observerCount(), 1); + + firstDependency = 10; + + QCOMPARE(sum.value(), int(12)); + QCOMPARE(QPropertyBasePointer::get(firstDependency).observerCount(), 1); + QCOMPARE(QPropertyBasePointer::get(secondDependency).observerCount(), 1); + + secondDependency = 20; + + QCOMPARE(sum.value(), int(30)); + QCOMPARE(QPropertyBasePointer::get(firstDependency).observerCount(), 1); + QCOMPARE(QPropertyBasePointer::get(secondDependency).observerCount(), 1); + + firstDependency = 1; + secondDependency = 1; + QCOMPARE(sum.value(), int(2)); + QCOMPARE(QPropertyBasePointer::get(firstDependency).observerCount(), 1); + QCOMPARE(QPropertyBasePointer::get(secondDependency).observerCount(), 1); +} + +void tst_QProperty::bindingWithDeletedDependency() +{ + QScopedPointer<QProperty<int>> dynamicProperty(new QProperty<int>(100)); + + QProperty<int> staticProperty(1000); + + QProperty<bool> bindingReturnsDynamicProperty(false); + + QProperty<int> propertySelector; + propertySelector = Qt::makePropertyBinding([&]() { + if (bindingReturnsDynamicProperty && !dynamicProperty.isNull()) + return dynamicProperty->value(); + else + return staticProperty.value(); + }); + + QCOMPARE(propertySelector.value(), staticProperty.value()); + + bindingReturnsDynamicProperty = true; + + QCOMPARE(propertySelector.value(), dynamicProperty->value()); + + dynamicProperty.reset(); + + QCOMPARE(propertySelector.value(), 100); + + bindingReturnsDynamicProperty = false; + + QCOMPARE(propertySelector.value(), staticProperty.value()); +} + +void tst_QProperty::recursiveDependency() +{ + QProperty<int> first(1); + + QProperty<int> second; + second = Qt::makePropertyBinding(first); + + QProperty<int> third; + third = Qt::makePropertyBinding(second); + + QCOMPARE(third.value(), int(1)); + + first = 2; + + QCOMPARE(third.value(), int(2)); +} + +void tst_QProperty::bindingAfterUse() +{ + QProperty<int> propWithBindingLater(1); + + QProperty<int> propThatUsesFirstProp; + propThatUsesFirstProp = Qt::makePropertyBinding(propWithBindingLater); + + QCOMPARE(propThatUsesFirstProp.value(), int(1)); + QCOMPARE(QPropertyBasePointer::get(propWithBindingLater).observerCount(), 1); + + QProperty<int> injectedValue(42); + propWithBindingLater = Qt::makePropertyBinding(injectedValue); + + QCOMPARE(propThatUsesFirstProp.value(), int(42)); + QCOMPARE(QPropertyBasePointer::get(propWithBindingLater).observerCount(), 1); +} + +void tst_QProperty::switchBinding() +{ + QProperty<int> first(1); + + QProperty<int> propWithChangingBinding; + propWithChangingBinding = Qt::makePropertyBinding(first); + + QCOMPARE(propWithChangingBinding.value(), 1); + + QProperty<int> output; + output = Qt::makePropertyBinding(propWithChangingBinding); + QCOMPARE(output.value(), 1); + + QProperty<int> second(2); + propWithChangingBinding = Qt::makePropertyBinding(second); + QCOMPARE(output.value(), 2); +} + +void tst_QProperty::avoidDependencyAllocationAfterFirstEval() +{ + QProperty<int> firstDependency(1); + QProperty<int> secondDependency(10); + + QProperty<int> propWithBinding; + propWithBinding = Qt::makePropertyBinding([&]() { return firstDependency + secondDependency; }); + + QCOMPARE(propWithBinding.value(), int(11)); + + QVERIFY(QPropertyBasePointer::get(propWithBinding).bindingPtr()); + QCOMPARE(QPropertyBasePointer::get(propWithBinding).bindingPtr()->dependencyObservers.size(), 2); + QVERIFY(QPropertyBasePointer::get(propWithBinding).bindingPtr()->dependencyObservers.capacity() >= 2); + + firstDependency = 100; + QCOMPARE(propWithBinding.value(), int(110)); + QCOMPARE(QPropertyBasePointer::get(propWithBinding).bindingPtr()->dependencyObservers.size(), 2); + QVERIFY(QPropertyBasePointer::get(propWithBinding).bindingPtr()->dependencyObservers.capacity() >= 2); +} + +void tst_QProperty::propertyArrays() +{ + std::vector<QProperty<int>> properties; + + int expectedSum = 0; + for (int i = 0; i < 10; ++i) { + properties.emplace_back(i); + expectedSum += i; + } + + QProperty<int> sum; + sum = Qt::makePropertyBinding([&]() { + return std::accumulate(properties.begin(), properties.end(), 0); + }); + + QCOMPARE(sum.value(), expectedSum); + + properties[4] = properties[4] + 42; + expectedSum += 42; + QCOMPARE(sum.value(), expectedSum); +} + +void tst_QProperty::boolProperty() +{ + static_assert(sizeof(QProperty<bool>) == sizeof(void*), "Size of QProperty<bool> specialization must not exceed size of pointer"); + + QProperty<bool> first(true); + QProperty<bool> second(false); + QProperty<bool> all; + all = Qt::makePropertyBinding([&]() { return first && second; }); + + QCOMPARE(all.value(), false); + + second = true; + + QCOMPARE(all.value(), true); +} + +void tst_QProperty::takeBinding() +{ + QPropertyBinding<int> existingBinding; + QVERIFY(existingBinding.isNull()); + + QProperty<int> first(100); + QProperty<int> second = Qt::makePropertyBinding(first); + + QCOMPARE(second.value(), int(100)); + + existingBinding = second.takeBinding(); + QVERIFY(!existingBinding.isNull()); + + first = 10; + QCOMPARE(second.value(), int(100)); + + second = 25; + QCOMPARE(second.value(), int(25)); + + second = existingBinding; + QCOMPARE(second.value(), int(10)); + QVERIFY(!existingBinding.isNull()); +} + +void tst_QProperty::replaceBinding() +{ + QProperty<int> first(100); + QProperty<int> second = Qt::makePropertyBinding(first); + + QCOMPARE(second.value(), 100); + + auto constantBinding = Qt::makePropertyBinding([]() { return 42; }); + auto oldBinding = second.setBinding(constantBinding); + QCOMPARE(second.value(), 42); + + second = oldBinding; + QCOMPARE(second.value(), 100); +} + +void tst_QProperty::swap() +{ + QProperty<int> firstDependency(1); + QProperty<int> secondDependency(2); + + QProperty<int> first = Qt::makePropertyBinding(firstDependency); + QProperty<int> second = Qt::makePropertyBinding(secondDependency); + + QCOMPARE(first.value(), 1); + QCOMPARE(second.value(), 2); + + std::swap(first, second); + + QCOMPARE(first.value(), 2); + QCOMPARE(second.value(), 1); + + secondDependency = 20; + QCOMPARE(first.value(), 20); + QCOMPARE(second.value(), 1); + + firstDependency = 100; + QCOMPARE(first.value(), 20); + QCOMPARE(second.value(), 100); +} + +void tst_QProperty::moveNotifies() +{ + QProperty<int> first(1); + QProperty<int> second(2); + + QProperty<int> propertyInTheMiddle = Qt::makePropertyBinding(first); + + QProperty<int> finalProp1 = Qt::makePropertyBinding(propertyInTheMiddle); + QProperty<int> finalProp2 = Qt::makePropertyBinding(propertyInTheMiddle); + + QCOMPARE(finalProp1.value(), 1); + QCOMPARE(finalProp2.value(), 1); + + QCOMPARE(QPropertyBasePointer::get(propertyInTheMiddle).observerCount(), 2); + + QProperty<int> other = Qt::makePropertyBinding(second); + QCOMPARE(other.value(), 2); + + QProperty<int> otherDep = Qt::makePropertyBinding(other); + QCOMPARE(otherDep.value(), 2); + QCOMPARE(QPropertyBasePointer::get(other).observerCount(), 1); + + propertyInTheMiddle = std::move(other); + + QCOMPARE(QPropertyBasePointer::get(other).observerCount(), 0); + + QCOMPARE(finalProp1.value(), 2); + QCOMPARE(finalProp2.value(), 2); +} + +void tst_QProperty::moveCtor() +{ + QProperty<int> first(1); + + QProperty<int> intermediate = Qt::makePropertyBinding(first); + QCOMPARE(intermediate.value(), 1); + QCOMPARE(QPropertyBasePointer::get(first).observerCount(), 1); + + QProperty<int> targetProp(std::move(first)); + + QCOMPARE(QPropertyBasePointer::get(targetProp).observerCount(), 0); +} + +void tst_QProperty::changeHandler() +{ + QProperty<int> testProperty(0); + QVector<int> recordedValues; + + { + auto handler = testProperty.onValueChanged([&]() { + recordedValues << testProperty; + }); + + testProperty = 1; + testProperty = 2; + } + testProperty = 3; + + QCOMPARE(recordedValues.count(), 2); + QCOMPARE(recordedValues.at(0), 1); + QCOMPARE(recordedValues.at(1), 2); +} + +void tst_QProperty::propertyChangeHandlerApi() +{ + int changeHandlerCallCount = 0; + QPropertyChangeHandler handler([&changeHandlerCallCount]() { + ++changeHandlerCallCount; + }); + + QProperty<int> source1; + QProperty<int> source2; + + handler.setSource(source1); + + source1 = 100; + QCOMPARE(changeHandlerCallCount, 1); + + handler.setSource(source2); + source1 = 101; + QCOMPARE(changeHandlerCallCount, 1); + + source2 = 200; + QCOMPARE(changeHandlerCallCount, 2); +} + +void tst_QProperty::subscribe() +{ + QProperty<int> testProperty(42); + QVector<int> recordedValues; + + { + auto handler = testProperty.subscribe([&]() { + recordedValues << testProperty; + }); + + testProperty = 1; + testProperty = 2; + } + testProperty = 3; + + QCOMPARE(recordedValues.count(), 3); + QCOMPARE(recordedValues.at(0), 42); + QCOMPARE(recordedValues.at(1), 1); + QCOMPARE(recordedValues.at(2), 2); +} + +void tst_QProperty::changeHandlerThroughBindings() +{ + QProperty<bool> trigger(false); + QProperty<bool> blockTrigger(false); + QProperty<bool> condition = Qt::makePropertyBinding([&]() { + bool triggerValue = trigger; + bool blockTriggerValue = blockTrigger; + return triggerValue && !blockTriggerValue; + }); + bool changeHandlerCalled = false; + auto handler = condition.onValueChanged([&]() { + changeHandlerCalled = true; + }); + + QVERIFY(!condition); + QVERIFY(!changeHandlerCalled); + + trigger = true; + + QVERIFY(condition); + QVERIFY(changeHandlerCalled); + changeHandlerCalled = false; + + trigger = false; + + QVERIFY(!condition); + QVERIFY(changeHandlerCalled); + changeHandlerCalled = false; + + blockTrigger = true; + + QVERIFY(!condition); + QVERIFY(!changeHandlerCalled); +} + +void tst_QProperty::dontTriggerDependenciesIfUnchangedValue() +{ + QProperty<int> property(42); + + bool triggered = false; + QProperty<int> observer = Qt::makePropertyBinding([&]() { triggered = true; return property.value(); }); + + QCOMPARE(observer.value(), 42); + QVERIFY(triggered); + triggered = false; + property = 42; + QCOMPARE(observer.value(), 42); + QVERIFY(!triggered); +} + +void tst_QProperty::bindingSourceLocation() +{ +#if defined(QT_PROPERTY_COLLECT_BINDING_LOCATION) + auto bindingLine = std::experimental::source_location::current().line() + 1; + auto binding = Qt::makePropertyBinding([]() { return 42; }); + QCOMPARE(QPropertyBindingPrivate::get(binding)->location.line, bindingLine); +#else + QSKIP("Skipping this in the light of missing binding source location support"); +#endif +} + +void tst_QProperty::bindingError() +{ + QProperty<int> prop = Qt::makePropertyBinding([]() -> std::variant<int, QPropertyBindingError> { + QPropertyBindingError error(QPropertyBindingError::UnknownError); + error.setDescription(QLatin1String("my error")); + return error; + }); + QCOMPARE(prop.value(), 0); + QCOMPARE(prop.binding().error().description(), QString("my error")); +} + +void tst_QProperty::bindingLoop() +{ + QScopedPointer<QProperty<int>> firstProp; + + QProperty<int> secondProp = Qt::makePropertyBinding([&]() -> int { + return firstProp ? firstProp->value() : 0; + }); + + QProperty<int> thirdProp = Qt::makePropertyBinding([&]() -> int { + return secondProp.value(); + }); + + firstProp.reset(new QProperty<int>()); + *firstProp = Qt::makePropertyBinding([&]() -> int { + return secondProp.value(); + }); + + QCOMPARE(thirdProp.value(), 0); + QCOMPARE(secondProp.binding().error().type(), QPropertyBindingError::BindingLoop); +} + +void tst_QProperty::changePropertyFromWithinChangeHandler() +{ + QProperty<int> property(100); + bool resetPropertyOnChange = false; + int changeHandlerCallCount = 0; + + auto handler = property.onValueChanged([&]() { + ++changeHandlerCallCount; + if (resetPropertyOnChange) + property = 100; + }); + + QCOMPARE(property.value(), 100); + + resetPropertyOnChange = true; + property = 42; + QCOMPARE(property.value(), 100); + // changing the property value inside the change handler won't result in the change + // handler being called again. + QCOMPARE(changeHandlerCallCount, 1); + changeHandlerCallCount = 0; +} + +void tst_QProperty::changePropertyFromWithinChangeHandlerThroughDependency() +{ + QProperty<int> sourceProperty(100); + QProperty<int> property = Qt::makePropertyBinding(sourceProperty); + bool resetPropertyOnChange = false; + int changeHandlerCallCount = 0; + + auto handler = property.onValueChanged([&]() { + ++changeHandlerCallCount; + if (resetPropertyOnChange) + sourceProperty = 100; + }); + + QCOMPARE(property.value(), 100); + + resetPropertyOnChange = true; + sourceProperty = 42; + QCOMPARE(property.value(), 100); + // changing the property value inside the change handler won't result in the change + // handler being called again. + QCOMPARE(changeHandlerCallCount, 1); + changeHandlerCallCount = 0; +} + +void tst_QProperty::changePropertyFromWithinChangeHandler2() +{ + QProperty<int> property(100); + int changeHandlerCallCount = 0; + + auto handler = property.onValueChanged([&]() { + ++changeHandlerCallCount; + property = property.value() + 1; + }); + + QCOMPARE(property.value(), 100); + + property = 42; + QCOMPARE(property.value(), 43); +} + +void tst_QProperty::settingPropertyValueDoesRemoveBinding() +{ + QProperty<int> source(42); + + QProperty<int> property = Qt::makePropertyBinding(source); + + QCOMPARE(property.value(), 42); + QVERIFY(!property.binding().isNull()); + + property = 100; + QCOMPARE(property.value(), 100); + QVERIFY(property.binding().isNull()); + + source = 1; + QCOMPARE(property.value(), 100); + QVERIFY(property.binding().isNull()); +} + +QTEST_MAIN(tst_QProperty); + +#include "tst_qproperty.moc" diff --git a/tests/auto/corelib/plugin/qpluginloader/CMakeLists.txt b/tests/auto/corelib/plugin/qpluginloader/CMakeLists.txt index ba7d375e3b..a051bb3ea6 100644 --- a/tests/auto/corelib/plugin/qpluginloader/CMakeLists.txt +++ b/tests/auto/corelib/plugin/qpluginloader/CMakeLists.txt @@ -7,6 +7,6 @@ add_subdirectory(tst) if(UNIX AND NOT ANDROID AND NOT APPLE) add_subdirectory(almostplugin) endif() -if(APPLE_OSX AND QT_FEATURE_private_tests AND TARGET Qt::Gui) +if(MACOS AND QT_FEATURE_private_tests AND TARGET Qt::Gui) add_subdirectory(machtest) endif() diff --git a/tests/auto/gui/.prev_CMakeLists.txt b/tests/auto/gui/.prev_CMakeLists.txt index 8cbfa78aad..e7317e932c 100644 --- a/tests/auto/gui/.prev_CMakeLists.txt +++ b/tests/auto/gui/.prev_CMakeLists.txt @@ -1,7 +1,7 @@ # Generated from gui.pro. add_subdirectory(kernel) -if(NOT APPLE_UIKIT) +if(NOT UIKIT) add_subdirectory(image) add_subdirectory(math3d) add_subdirectory(painting) @@ -10,10 +10,10 @@ if(NOT APPLE_UIKIT) add_subdirectory(itemmodels) add_subdirectory(rhi) endif() -if(QT_FEATURE_opengl AND NOT APPLE_UIKIT AND NOT WINRT) +if(QT_FEATURE_opengl AND NOT UIKIT AND NOT WINRT) add_subdirectory(qopenglconfig) add_subdirectory(qopengl) endif() -if(QT_FEATURE_vulkan AND NOT APPLE_UIKIT) +if(QT_FEATURE_vulkan AND NOT UIKIT) add_subdirectory(qvulkan) endif() diff --git a/tests/auto/gui/CMakeLists.txt b/tests/auto/gui/CMakeLists.txt index 9a1312bd48..e9c9ffe9fe 100644 --- a/tests/auto/gui/CMakeLists.txt +++ b/tests/auto/gui/CMakeLists.txt @@ -1,7 +1,7 @@ # Generated from gui.pro. add_subdirectory(kernel) -if(NOT APPLE_UIKIT) +if(NOT UIKIT) add_subdirectory(image) add_subdirectory(math3d) add_subdirectory(painting) @@ -10,10 +10,10 @@ if(NOT APPLE_UIKIT) add_subdirectory(itemmodels) add_subdirectory(rhi) endif() -if(QT_FEATURE_opengl AND NOT APPLE_UIKIT AND NOT WINRT) +if(QT_FEATURE_opengl AND NOT UIKIT AND NOT WINRT) add_subdirectory(qopenglconfig) add_subdirectory(qopengl) endif() -if(QT_FEATURE_vulkan AND NOT APPLE_UIKIT) +if(QT_FEATURE_vulkan AND NOT UIKIT) add_subdirectory(qvulkan) endif() diff --git a/tests/auto/gui/kernel/CMakeLists.txt b/tests/auto/gui/kernel/CMakeLists.txt index b2397bed19..ecac48d1c1 100644 --- a/tests/auto/gui/kernel/CMakeLists.txt +++ b/tests/auto/gui/kernel/CMakeLists.txt @@ -20,7 +20,7 @@ add_subdirectory(qwindow) add_subdirectory(qguiapplication) add_subdirectory(qpixelformat) add_subdirectory(qrasterwindow) -if(NOT ANDROID AND NOT APPLE_UIKIT) +if(NOT ANDROID AND NOT UIKIT) add_subdirectory(qclipboard) endif() if(TARGET Qt::Network) diff --git a/tests/auto/gui/kernel/qclipboard/test/.prev_CMakeLists.txt b/tests/auto/gui/kernel/qclipboard/test/.prev_CMakeLists.txt index 620ef96a5b..36d9f7b00c 100644 --- a/tests/auto/gui/kernel/qclipboard/test/.prev_CMakeLists.txt +++ b/tests/auto/gui/kernel/qclipboard/test/.prev_CMakeLists.txt @@ -15,7 +15,7 @@ add_qt_test(tst_qclipboard ## Scopes: ##################################################################### -extend_target(tst_qclipboard CONDITION APPLE_OSX +extend_target(tst_qclipboard CONDITION MACOS PUBLIC_LIBRARIES ${FWAppKit} ) diff --git a/tests/auto/gui/kernel/qclipboard/test/CMakeLists.txt b/tests/auto/gui/kernel/qclipboard/test/CMakeLists.txt index 620ef96a5b..36d9f7b00c 100644 --- a/tests/auto/gui/kernel/qclipboard/test/CMakeLists.txt +++ b/tests/auto/gui/kernel/qclipboard/test/CMakeLists.txt @@ -15,7 +15,7 @@ add_qt_test(tst_qclipboard ## Scopes: ##################################################################### -extend_target(tst_qclipboard CONDITION APPLE_OSX +extend_target(tst_qclipboard CONDITION MACOS PUBLIC_LIBRARIES ${FWAppKit} ) diff --git a/tests/auto/network/kernel/CMakeLists.txt b/tests/auto/network/kernel/CMakeLists.txt index c1082f60b7..6ce3fcdf32 100644 --- a/tests/auto/network/kernel/CMakeLists.txt +++ b/tests/auto/network/kernel/CMakeLists.txt @@ -13,7 +13,7 @@ endif() if(QT_FEATURE_private_tests) add_subdirectory(qauthenticator) - if(NOT APPLE_OSX) + if(NOT MACOS) add_subdirectory(qhostinfo) endif() endif() diff --git a/tests/auto/other/CMakeLists.txt b/tests/auto/other/CMakeLists.txt index e1d3c0e839..88a29b479b 100644 --- a/tests/auto/other/CMakeLists.txt +++ b/tests/auto/other/CMakeLists.txt @@ -15,7 +15,7 @@ if(TARGET Qt::Network AND TARGET Qt::Widgets AND NOT WINRT) add_subdirectory(lancelot) add_subdirectory(qnetworkaccessmanager_and_qprogressdialog) endif() -if(APPLE_OSX AND TARGET Qt::Gui AND TARGET Qt::Widgets) +if(MACOS AND TARGET Qt::Gui AND TARGET Qt::Widgets) add_subdirectory(macgui) add_subdirectory(macplist) add_subdirectory(qaccessibilitymac) @@ -35,7 +35,7 @@ endif() if(TARGET Qt::Network AND NOT WINRT) add_subdirectory(networkselftest) endif() -if(APPLE_OSX AND TARGET Qt::Gui) +if(MACOS AND TARGET Qt::Gui) add_subdirectory(macnativeevents) endif() if(embedded) diff --git a/tests/auto/other/macgui/.prev_CMakeLists.txt b/tests/auto/other/macgui/.prev_CMakeLists.txt index 4923568a89..1ae468c40e 100644 --- a/tests/auto/other/macgui/.prev_CMakeLists.txt +++ b/tests/auto/other/macgui/.prev_CMakeLists.txt @@ -26,7 +26,7 @@ add_qt_test(tst_macgui ## Scopes: ##################################################################### -extend_target(tst_macgui CONDITION APPLE_OSX +extend_target(tst_macgui CONDITION MACOS PUBLIC_LIBRARIES ${FWApplicationServices} ) diff --git a/tests/auto/other/macgui/CMakeLists.txt b/tests/auto/other/macgui/CMakeLists.txt index de69c43765..4a5aa0aaef 100644 --- a/tests/auto/other/macgui/CMakeLists.txt +++ b/tests/auto/other/macgui/CMakeLists.txt @@ -26,7 +26,7 @@ add_qt_test(tst_macgui ## Scopes: ##################################################################### -extend_target(tst_macgui CONDITION APPLE_OSX +extend_target(tst_macgui CONDITION MACOS PUBLIC_LIBRARIES ${FWApplicationServices} ) diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/CMakeLists.txt b/tests/auto/widgets/dialogs/qfilesystemmodel/CMakeLists.txt index 38c0547390..346e2a7d5a 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/CMakeLists.txt +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/CMakeLists.txt @@ -23,5 +23,5 @@ add_qt_test(tst_qfilesystemmodel #### Keys ignored in scope 2:.:.:qfilesystemmodel.pro:WIN32: # testcase.timeout = "900" -#### Keys ignored in scope 3:.:.:qfilesystemmodel.pro:APPLE_OSX: +#### Keys ignored in scope 3:.:.:qfilesystemmodel.pro:MACOS: # testcase.timeout = "900" diff --git a/tests/auto/widgets/styles/CMakeLists.txt b/tests/auto/widgets/styles/CMakeLists.txt index 4fc260fe39..4ded7b9d80 100644 --- a/tests/auto/widgets/styles/CMakeLists.txt +++ b/tests/auto/widgets/styles/CMakeLists.txt @@ -1,10 +1,10 @@ # Generated from styles.pro. -if (APPLE_OSX) +if (MACOS) add_subdirectory(qmacstyle) endif() add_subdirectory(qstyle) -if (NOT APPLE_UIKIT AND NOT ANDROID AND NOT QNX) +if (NOT UIKIT AND NOT ANDROID AND NOT QNX) add_subdirectory(qstyleoption) endif() if (QT_FEATURE_private_tests) diff --git a/tests/auto/widgets/widgets/qlineedit/CMakeLists.txt b/tests/auto/widgets/widgets/qlineedit/CMakeLists.txt index f95094aa7d..615a5a98cb 100644 --- a/tests/auto/widgets/widgets/qlineedit/CMakeLists.txt +++ b/tests/auto/widgets/widgets/qlineedit/CMakeLists.txt @@ -19,7 +19,7 @@ add_qt_test(tst_qlineedit ## Scopes: ##################################################################### -extend_target(tst_qlineedit CONDITION APPLE_OSX +extend_target(tst_qlineedit CONDITION MACOS PUBLIC_LIBRARIES ${FWAppKit} ) diff --git a/tests/auto/widgets/widgets/qmenu/CMakeLists.txt b/tests/auto/widgets/widgets/qmenu/CMakeLists.txt index a20fe70492..63037b7eaa 100644 --- a/tests/auto/widgets/widgets/qmenu/CMakeLists.txt +++ b/tests/auto/widgets/widgets/qmenu/CMakeLists.txt @@ -17,14 +17,14 @@ add_qt_test(tst_qmenu ## Scopes: ##################################################################### -extend_target(tst_qmenu CONDITION APPLE_OSX +extend_target(tst_qmenu CONDITION MACOS SOURCES tst_qmenu_mac.mm PUBLIC_LIBRARIES objc ) -extend_target(tst_qmenu CONDITION NOT APPLE_OSX +extend_target(tst_qmenu CONDITION NOT MACOS DEFINES QTEST_QPA_MOUSE_HANDLING ) diff --git a/tests/auto/widgets/widgets/qmenubar/CMakeLists.txt b/tests/auto/widgets/widgets/qmenubar/CMakeLists.txt index 43875cd113..415f2aa79f 100644 --- a/tests/auto/widgets/widgets/qmenubar/CMakeLists.txt +++ b/tests/auto/widgets/widgets/qmenubar/CMakeLists.txt @@ -16,7 +16,7 @@ add_qt_test(tst_qmenubar ## Scopes: ##################################################################### -extend_target(tst_qmenubar CONDITION APPLE_OSX +extend_target(tst_qmenubar CONDITION MACOS SOURCES tst_qmenubar_mac.mm PUBLIC_LIBRARIES diff --git a/tests/auto/widgets/widgets/qplaintextedit/CMakeLists.txt b/tests/auto/widgets/widgets/qplaintextedit/CMakeLists.txt index 4106de04de..cb00d5dd93 100644 --- a/tests/auto/widgets/widgets/qplaintextedit/CMakeLists.txt +++ b/tests/auto/widgets/widgets/qplaintextedit/CMakeLists.txt @@ -19,7 +19,7 @@ add_qt_test(tst_qplaintextedit ## Scopes: ##################################################################### -extend_target(tst_qplaintextedit CONDITION APPLE_OSX +extend_target(tst_qplaintextedit CONDITION MACOS PUBLIC_LIBRARIES ${FWAppKit} ) diff --git a/tests/auto/widgets/widgets/qtextedit/CMakeLists.txt b/tests/auto/widgets/widgets/qtextedit/CMakeLists.txt index 61641707b9..719acd8dbc 100644 --- a/tests/auto/widgets/widgets/qtextedit/CMakeLists.txt +++ b/tests/auto/widgets/widgets/qtextedit/CMakeLists.txt @@ -22,7 +22,7 @@ add_qt_test(tst_qtextedit ## Scopes: ##################################################################### -extend_target(tst_qtextedit CONDITION APPLE_OSX +extend_target(tst_qtextedit CONDITION MACOS PUBLIC_LIBRARIES ${FWAppKit} ) diff --git a/tests/manual/CMakeLists.txt b/tests/manual/CMakeLists.txt index d7b45a1d22..20a810a8c1 100644 --- a/tests/manual/CMakeLists.txt +++ b/tests/manual/CMakeLists.txt @@ -2,7 +2,7 @@ # special case begn # Don't build manual tests when targeting iOS. -if(APPLE_UIKIT) +if(UIKIT) return() endif() # special case end diff --git a/util/cmake/condition_simplifier.py b/util/cmake/condition_simplifier.py index d02e70e489..e6588a7cc7 100644 --- a/util/cmake/condition_simplifier.py +++ b/util/cmake/condition_simplifier.py @@ -106,7 +106,7 @@ def _recursive_simplify(expr): # Simplify even further, based on domain knowledge: # windowses = ('WIN32', 'WINRT') - apples = ("APPLE_OSX", "APPLE_UIKIT", "APPLE_IOS", "APPLE_TVOS", "APPLE_WATCHOS") + apples = ("MACOS", "UIKIT", "IOS", "TVOS", "WATCHOS") bsds = ("FREEBSD", "OPENBSD", "NETBSD") androids = ("ANDROID", "ANDROID_EMBEDDED") unixes = ( diff --git a/util/cmake/configurejson2cmake.py b/util/cmake/configurejson2cmake.py index cabf1e41e0..64ab5b749c 100755 --- a/util/cmake/configurejson2cmake.py +++ b/util/cmake/configurejson2cmake.py @@ -807,9 +807,9 @@ def get_feature_mapping(): # special case to disable implicit feature on WIN32, until ANGLE is ported "opengl-dynamic": {"autoDetect": "OFF"}, "opengles2": { # special case to disable implicit feature on WIN32, until ANGLE is ported - "condition": "NOT WIN32 AND ( NOT APPLE_WATCHOS AND NOT QT_FEATURE_opengl_desktop AND GLESv2_FOUND )" + "condition": "NOT WIN32 AND ( NOT WATCHOS AND NOT QT_FEATURE_opengl_desktop AND GLESv2_FOUND )" }, - "simulator_and_device": {"condition": "APPLE_UIKIT AND NOT QT_UIKIT_SDK"}, + "simulator_and_device": {"condition": "UIKIT AND NOT QT_UIKIT_SDK"}, "pkg-config": None, "posix_fallocate": None, # Only needed for sqlite, which we do not want to build "posix-libiconv": { diff --git a/util/cmake/helper.py b/util/cmake/helper.py index 9f88e23f97..00adc940f1 100644 --- a/util/cmake/helper.py +++ b/util/cmake/helper.py @@ -657,9 +657,9 @@ platform_mapping = { "nacl": "NACL", "android": "ANDROID", "android-embedded": "ANDROID_EMBEDDED", - "uikit": "APPLE_UIKIT", - "tvos": "APPLE_TVOS", - "watchos": "APPLE_WATCHOS", + "uikit": "UIKIT", + "tvos": "TVOS", + "watchos": "WATCHOS", "winrt": "WINRT", "wasm": "WASM", "emscripten": "EMSCRIPTEN", @@ -668,17 +668,17 @@ platform_mapping = { "gcc": "GCC", "icc": "ICC", "intel_icc": "ICC", - "osx": "APPLE_OSX", - "ios": "APPLE_IOS", + "osx": "MACOS", + "ios": "IOS", "freebsd": "FREEBSD", "openbsd": "OPENBSD", "netbsd": "NETBSD", "haiku": "HAIKU", "netbsd": "NETBSD", "mac": "APPLE", - "macx": "APPLE_OSX", - "macos": "APPLE_OSX", - "macx-icc": "(APPLE_OSX AND ICC)", + "macx": "MACOS", + "macos": "MACOS", + "macx-icc": "(MACOS AND ICC)", } diff --git a/util/cmake/pro2cmake.py b/util/cmake/pro2cmake.py index 6010120e45..a50c7fe2bd 100755 --- a/util/cmake/pro2cmake.py +++ b/util/cmake/pro2cmake.py @@ -1444,7 +1444,7 @@ def map_condition(condition: str) -> str: condition = re.sub(r"^no-png$", r"NOT QT_FEATURE_png", condition) condition = re.sub(r"contains\(CONFIG, static\)", r"NOT QT_BUILD_SHARED_LIBS", condition) condition = re.sub(r"contains\(QT_CONFIG,\w*shared\)", r"QT_BUILD_SHARED_LIBS", condition) - condition = re.sub(r"CONFIG\(osx\)", r"APPLE_OSX", condition) + condition = re.sub(r"CONFIG\(osx\)", r"MACOS", condition) def gcc_version_handler(match_obj: Match): operator = match_obj.group(1) diff --git a/util/cmake/tests/test_logic_mapping.py b/util/cmake/tests/test_logic_mapping.py index c18c3ddc65..6e4fd20590 100755 --- a/util/cmake/tests/test_logic_mapping.py +++ b/util/cmake/tests/test_logic_mapping.py @@ -116,42 +116,42 @@ def test_simplify_unix_and_win32_or_foobar_or_barfoo(): def test_simplify_watchos_and_win32(): - validate_simplify('APPLE_WATCHOS AND WIN32', 'OFF') + validate_simplify('WATCHOS AND WIN32', 'OFF') def test_simplify_win32_and_watchos(): - validate_simplify('WIN32 AND APPLE_WATCHOS', 'OFF') + validate_simplify('WIN32 AND WATCHOS', 'OFF') def test_simplify_apple_and_appleosx(): - validate_simplify('APPLE AND APPLE_OSX', 'APPLE_OSX') + validate_simplify('APPLE AND MACOS', 'MACOS') def test_simplify_apple_or_appleosx(): - validate_simplify('APPLE OR APPLE_OSX', 'APPLE') + validate_simplify('APPLE OR MACOS', 'APPLE') def test_simplify_apple_or_appleosx_level1(): - validate_simplify('foobar AND (APPLE OR APPLE_OSX )', 'APPLE AND foobar') + validate_simplify('foobar AND (APPLE OR MACOS )', 'APPLE AND foobar') def test_simplify_apple_or_appleosx_level1_double(): - validate_simplify('foobar AND (APPLE OR APPLE_OSX )', 'APPLE AND foobar') + validate_simplify('foobar AND (APPLE OR MACOS )', 'APPLE AND foobar') def test_simplify_apple_or_appleosx_level1_double_with_extra_spaces(): - validate_simplify('foobar AND (APPLE OR APPLE_OSX ) ' - 'AND ( APPLE_OSX OR APPLE )', 'APPLE AND foobar') + validate_simplify('foobar AND (APPLE OR MACOS ) ' + 'AND ( MACOS OR APPLE )', 'APPLE AND foobar') def test_simplify_apple_or_appleosx_level2(): - validate_simplify('foobar AND ( ( APPLE OR APPLE_WATCHOS ) ' - 'OR APPLE_OSX ) AND ( APPLE_OSX OR APPLE ) ' + validate_simplify('foobar AND ( ( APPLE OR WATCHOS ) ' + 'OR MACOS ) AND ( MACOS OR APPLE ) ' 'AND ( (WIN32 OR WINRT) OR UNIX) ', 'APPLE AND foobar') def test_simplify_not_apple_and_appleosx(): - validate_simplify('NOT APPLE AND APPLE_OSX', 'OFF') + validate_simplify('NOT APPLE AND MACOS', 'OFF') def test_simplify_unix_and_bar_or_win32(): @@ -182,5 +182,5 @@ def test_simplify_complex_false(): def test_simplify_android_not_apple(): - validate_simplify('ANDROID AND NOT ANDROID_EMBEDDED AND NOT APPLE_OSX', + validate_simplify('ANDROID AND NOT ANDROID_EMBEDDED AND NOT MACOS', 'ANDROID AND NOT ANDROID_EMBEDDED') diff --git a/util/cmake/tests/test_scope_handling.py b/util/cmake/tests/test_scope_handling.py index 1db8b2a079..51e569fb09 100755 --- a/util/cmake/tests/test_scope_handling.py +++ b/util/cmake/tests/test_scope_handling.py @@ -305,7 +305,7 @@ def test_qstandardpaths_scopes(): scope6 = _new_scope(parent_scope=scope5, condition='UNIX') # mac { # OBJECTIVE_SOURCES += io/qstandardpaths_mac.mm - scope7 = _new_scope(parent_scope=scope6, condition='APPLE_OSX', SOURCES='qsp_mac.mm') + scope7 = _new_scope(parent_scope=scope6, condition='MACOS', SOURCES='qsp_mac.mm') # } else:android:!android-embedded { # SOURCES += io/qstandardpaths_android.cpp scope8 = _new_scope(parent_scope=scope6, condition='else') @@ -330,12 +330,12 @@ def test_qstandardpaths_scopes(): assert scope4.total_condition == 'WINRT' assert scope5.total_condition == 'UNIX' assert scope6.total_condition == 'UNIX' - assert scope7.total_condition == 'APPLE_OSX' - assert scope8.total_condition == 'UNIX AND NOT APPLE_OSX' + assert scope7.total_condition == 'MACOS' + assert scope8.total_condition == 'UNIX AND NOT MACOS' assert scope9.total_condition == 'ANDROID AND NOT ANDROID_EMBEDDED' - assert scope10.total_condition == 'UNIX AND NOT APPLE_OSX AND (ANDROID_EMBEDDED OR NOT ANDROID)' + assert scope10.total_condition == 'UNIX AND NOT MACOS AND (ANDROID_EMBEDDED OR NOT ANDROID)' assert scope11.total_condition == 'HAIKU AND (ANDROID_EMBEDDED OR NOT ANDROID)' - assert scope12.total_condition == 'UNIX AND NOT APPLE_OSX AND NOT HAIKU AND (ANDROID_EMBEDDED OR NOT ANDROID)' + assert scope12.total_condition == 'UNIX AND NOT MACOS AND NOT HAIKU AND (ANDROID_EMBEDDED OR NOT ANDROID)' def test_recursive_expansion(): scope = _new_scope(A='Foo',B='$$A/Bar') |