diff options
Diffstat (limited to 'src')
41 files changed, 1857 insertions, 111 deletions
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" |