summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qapplicationstatic.h4
-rw-r--r--src/corelib/kernel/qapplicationstatic.qdoc7
-rw-r--r--src/corelib/kernel/qcore_foundation.mm11
-rw-r--r--src/corelib/kernel/qcore_mac.mm2
-rw-r--r--src/corelib/kernel/qcore_mac_p.h5
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp4
-rw-r--r--src/corelib/kernel/qelapsedtimer.cpp5
-rw-r--r--src/corelib/kernel/qelapsedtimer.h39
-rw-r--r--src/corelib/kernel/qeventdispatcher_cf_p.h4
-rw-r--r--src/corelib/kernel/qjniarray.h52
-rw-r--r--src/corelib/kernel/qjnienvironment.cpp24
-rw-r--r--src/corelib/kernel/qjnihelpers.cpp75
-rw-r--r--src/corelib/kernel/qjnihelpers_p.h20
-rw-r--r--src/corelib/kernel/qjniobject.cpp52
-rw-r--r--src/corelib/kernel/qjniobject.h14
-rw-r--r--src/corelib/kernel/qjnitypes.h14
-rw-r--r--src/corelib/kernel/qmetaobject.cpp4
-rw-r--r--src/corelib/kernel/qmetaobject_p.h20
-rw-r--r--src/corelib/kernel/qmetatype.cpp63
-rw-r--r--src/corelib/kernel/qmetatype.h41
-rw-r--r--src/corelib/kernel/qobject.cpp41
-rw-r--r--src/corelib/kernel/qpermissions.cpp7
-rw-r--r--src/corelib/kernel/qpermissions_p.h2
-rw-r--r--src/corelib/kernel/qpermissions_wasm.cpp8
-rw-r--r--src/corelib/kernel/qpointer.h37
-rw-r--r--src/corelib/kernel/qpointer.qdoc48
-rw-r--r--src/corelib/kernel/qproperty.h1
-rw-r--r--src/corelib/kernel/qproperty_p.h5
-rw-r--r--src/corelib/kernel/qpropertyprivate.h35
-rw-r--r--src/corelib/kernel/qsocketnotifier.h16
-rw-r--r--src/corelib/kernel/qtimer.cpp2
-rw-r--r--src/corelib/kernel/qvariant.h1
32 files changed, 453 insertions, 210 deletions
diff --git a/src/corelib/kernel/qapplicationstatic.h b/src/corelib/kernel/qapplicationstatic.h
index bf5e79b8bf..345a880748 100644
--- a/src/corelib/kernel/qapplicationstatic.h
+++ b/src/corelib/kernel/qapplicationstatic.h
@@ -11,6 +11,10 @@
#include <new>
+#if 0
+#pragma qt_class(QApplicationStatic)
+#endif
+
QT_BEGIN_NAMESPACE
namespace QtGlobalStatic {
diff --git a/src/corelib/kernel/qapplicationstatic.qdoc b/src/corelib/kernel/qapplicationstatic.qdoc
index 5cbac65df9..1d13fbd84a 100644
--- a/src/corelib/kernel/qapplicationstatic.qdoc
+++ b/src/corelib/kernel/qapplicationstatic.qdoc
@@ -2,9 +2,14 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
+ \headerfile <QApplicationStatic>
+ \inmodule QtCore
+*/
+
+/*!
\macro Q_APPLICATION_STATIC(Type, VariableName, ...)
\since 6.3
- \relates QGlobalStatic
+ \relates <QApplicationStatic>
This macro extends Q_GLOBAL_STATIC and creates a global and static object
of type \l QGlobalStatic, of name \a VariableName, initialized by the
diff --git a/src/corelib/kernel/qcore_foundation.mm b/src/corelib/kernel/qcore_foundation.mm
index a31040944f..6d2451e078 100644
--- a/src/corelib/kernel/qcore_foundation.mm
+++ b/src/corelib/kernel/qcore_foundation.mm
@@ -300,8 +300,8 @@ QUuid QUuid::fromCFUUID(CFUUIDRef uuid)
*/
CFUUIDRef QUuid::toCFUUID() const
{
- const QByteArray bytes = toRfc4122();
- return CFUUIDCreateFromUUIDBytes(0, *reinterpret_cast<const CFUUIDBytes *>(bytes.constData()));
+ const auto bytes = toBytes();
+ return CFUUIDCreateFromUUIDBytes(0, *reinterpret_cast<const CFUUIDBytes *>(&bytes));
}
/*!
@@ -333,8 +333,11 @@ QUuid QUuid::fromNSUUID(const NSUUID *uuid)
*/
NSUUID *QUuid::toNSUUID() const
{
- const QByteArray bytes = toRfc4122();
- return [[[NSUUID alloc] initWithUUIDBytes:*reinterpret_cast<const uuid_t *>(bytes.constData())] autorelease];
+ const auto bytes = toBytes();
+ static_assert(sizeof bytes == sizeof(uuid_t));
+ uuid_t u;
+ memcpy(&u, &bytes, sizeof(uuid_t));
+ return [[[NSUUID alloc] initWithUUIDBytes:u] autorelease];
}
// ----------------------------------------------------------------------------
diff --git a/src/corelib/kernel/qcore_mac.mm b/src/corelib/kernel/qcore_mac.mm
index 54c4373aed..00b0d078d7 100644
--- a/src/corelib/kernel/qcore_mac.mm
+++ b/src/corelib/kernel/qcore_mac.mm
@@ -541,7 +541,7 @@ QMacRootLevelAutoReleasePool::QMacRootLevelAutoReleasePool()
if (qEnvironmentVariableIsSet(ROOT_LEVEL_POOL_DISABLE_SWITCH))
return;
- pool.reset(new QMacAutoReleasePool);
+ pool.emplace();
[[[ROOT_LEVEL_POOL_MARKER alloc] init] autorelease];
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index e63c320805..5ecf8072f4 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -19,6 +19,8 @@
#include <QtCore/qoperatingsystemversion.h>
+#include <optional>
+
#ifdef Q_OS_MACOS
#include <mach/port.h>
struct mach_header;
@@ -48,7 +50,6 @@ kern_return_t IOObjectRelease(io_object_t object);
#endif
#include "qstring.h"
-#include "qscopedpointer.h"
#include "qpair.h"
#if defined( __OBJC__) && defined(QT_NAMESPACE)
@@ -129,7 +130,7 @@ public:
Q_NODISCARD_CTOR QMacRootLevelAutoReleasePool();
~QMacRootLevelAutoReleasePool();
private:
- QScopedPointer<QMacAutoReleasePool> pool;
+ std::optional<QMacAutoReleasePool> pool = std::nullopt;
};
#endif
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index bd00f69c1c..4262c14405 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -1825,6 +1825,8 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type
// Exception-safe cleaning up without the need for a try/catch block
struct CleanUp {
+ Q_DISABLE_COPY_MOVE(CleanUp)
+
QObject *receiver;
int event_type;
QThreadData *data;
@@ -3251,7 +3253,7 @@ void QCoreApplication::installNativeEventFilter(QAbstractNativeEventFilter *filt
*/
void QCoreApplication::removeNativeEventFilter(QAbstractNativeEventFilter *filterObject)
{
- QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
+ QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(QCoreApplicationPrivate::theMainThread.loadAcquire());
if (!filterObject || !eventDispatcher)
return;
eventDispatcher->removeNativeEventFilter(filterObject);
diff --git a/src/corelib/kernel/qelapsedtimer.cpp b/src/corelib/kernel/qelapsedtimer.cpp
index 511b81a04e..c4308a0b8f 100644
--- a/src/corelib/kernel/qelapsedtimer.cpp
+++ b/src/corelib/kernel/qelapsedtimer.cpp
@@ -14,6 +14,8 @@ QT_BEGIN_NAMESPACE
\reentrant
\ingroup tools
+ \compares strong
+
The QElapsedTimer class is usually used to quickly calculate how much
time has elapsed between two events. Its API is similar to that of QTime,
so code that was using that can be ported quickly to the new class.
@@ -155,8 +157,7 @@ QT_BEGIN_NAMESPACE
Returns \c true if \a lhs and \a rhs contain different times, false otherwise.
*/
/*!
- \fn bool operator<(const QElapsedTimer &lhs, const QElapsedTimer &rhs) noexcept
- \relates QElapsedTimer
+ \fn bool QElapsedTimer::operator<(const QElapsedTimer &lhs, const QElapsedTimer &rhs) noexcept
Returns \c true if \a lhs was started before \a rhs, false otherwise.
diff --git a/src/corelib/kernel/qelapsedtimer.h b/src/corelib/kernel/qelapsedtimer.h
index 7d8b889f61..e71573456d 100644
--- a/src/corelib/kernel/qelapsedtimer.h
+++ b/src/corelib/kernel/qelapsedtimer.h
@@ -4,6 +4,7 @@
#ifndef QELAPSEDTIMER_H
#define QELAPSEDTIMER_H
+#include <QtCore/qcompare.h>
#include <QtCore/qglobal.h>
#include <chrono>
@@ -45,15 +46,41 @@ public:
Duration durationTo(const QElapsedTimer &other) const noexcept;
qint64 msecsTo(const QElapsedTimer &other) const noexcept;
qint64 secsTo(const QElapsedTimer &other) const noexcept;
-
- friend bool operator==(const QElapsedTimer &lhs, const QElapsedTimer &rhs) noexcept
- { return lhs.t1 == rhs.t1 && lhs.t2 == rhs.t2; }
- friend bool operator!=(const QElapsedTimer &lhs, const QElapsedTimer &rhs) noexcept
- { return !(lhs == rhs); }
-
friend bool Q_CORE_EXPORT operator<(const QElapsedTimer &lhs, const QElapsedTimer &rhs) noexcept;
private:
+ friend bool comparesEqual(const QElapsedTimer &lhs, const QElapsedTimer &rhs) noexcept
+ {
+ return lhs.t1 == rhs.t1 && lhs.t2 == rhs.t2;
+ }
+ Q_DECLARE_EQUALITY_COMPARABLE(QElapsedTimer)
+
+ friend Qt::strong_ordering compareThreeWay(const QElapsedTimer &lhs,
+ const QElapsedTimer &rhs) noexcept
+ {
+ return Qt::compareThreeWay(lhs.t1, rhs.t1);
+ }
+
+#if defined(__cpp_lib_three_way_comparison)
+ friend std::strong_ordering
+ operator<=>(const QElapsedTimer &lhs, const QElapsedTimer &rhs) noexcept
+ {
+ return compareThreeWay(lhs, rhs);
+ }
+#else
+ friend bool operator>(const QElapsedTimer &lhs, const QElapsedTimer &rhs) noexcept
+ {
+ return is_gt(compareThreeWay(lhs, rhs));
+ }
+ friend bool operator<=(const QElapsedTimer &lhs, const QElapsedTimer &rhs) noexcept
+ {
+ return is_lteq(compareThreeWay(lhs, rhs));
+ }
+ friend bool operator>=(const QElapsedTimer &lhs, const QElapsedTimer &rhs) noexcept
+ {
+ return is_gteq(compareThreeWay(lhs, rhs));
+ }
+#endif // defined(__cpp_lib_three_way_comparison)
qint64 t1 = Q_INT64_C(0x8000000000000000);
qint64 t2 = Q_INT64_C(0x8000000000000000);
};
diff --git a/src/corelib/kernel/qeventdispatcher_cf_p.h b/src/corelib/kernel/qeventdispatcher_cf_p.h
index 3575a6fb39..95bd328c5e 100644
--- a/src/corelib/kernel/qeventdispatcher_cf_p.h
+++ b/src/corelib/kernel/qeventdispatcher_cf_p.h
@@ -63,8 +63,8 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(RunLoopModeTracker));
QT_BEGIN_NAMESPACE
namespace QtPrivate {
-Q_DECLARE_EXPORTED_LOGGING_CATEGORY(lcEventDispatcher, Q_CORE_EXPORT)
-Q_DECLARE_EXPORTED_LOGGING_CATEGORY(lcEventDispatcherTimers, Q_CORE_EXPORT)
+QT_DECLARE_EXPORTED_QT_LOGGING_CATEGORY(lcEventDispatcher, Q_CORE_EXPORT)
+QT_DECLARE_EXPORTED_QT_LOGGING_CATEGORY(lcEventDispatcherTimers, Q_CORE_EXPORT)
}
class QEventDispatcherCoreFoundation;
diff --git a/src/corelib/kernel/qjniarray.h b/src/corelib/kernel/qjniarray.h
index 976b4e92e3..e3e9d0c4dc 100644
--- a/src/corelib/kernel/qjniarray.h
+++ b/src/corelib/kernel/qjniarray.h
@@ -18,7 +18,7 @@ QT_BEGIN_NAMESPACE
template <typename T> class QJniArray;
template <typename T>
-struct QJniArrayIterator
+struct QT_TECH_PREVIEW_API QJniArrayIterator
{
QJniArrayIterator() = default;
@@ -86,16 +86,16 @@ private:
{}
};
-class QJniArrayBase
+class QT_TECH_PREVIEW_API QJniArrayBase
{
// for SFINAE'ing out the fromContainer named constructor
- template <typename Container, typename = void> struct CanConvertHelper : std::false_type {};
- template <typename Container>
- struct CanConvertHelper<Container, std::void_t<decltype(std::data(std::declval<Container>())),
- decltype(std::size(std::declval<Container>())),
- typename Container::value_type
- >
- > : std::true_type {};
+ template <typename C, typename = void> struct IsContiguousContainerHelper : std::false_type {};
+ template <typename C>
+ struct IsContiguousContainerHelper<C, std::void_t<decltype(std::data(std::declval<C>())),
+ decltype(std::size(std::declval<C>())),
+ typename C::value_type
+ >
+ > : std::true_type {};
public:
using size_type = jsize;
@@ -114,13 +114,12 @@ public:
return 0;
}
- template <typename Container>
- static constexpr bool canConvert = CanConvertHelper<q20::remove_cvref_t<Container>>::value;
- template <typename Container>
- using IfCanConvert = std::enable_if_t<canConvert<Container>, bool>;
- template <typename Container
- , IfCanConvert<Container> = true
- >
+ template <typename C>
+ static constexpr bool isContiguousContainer = IsContiguousContainerHelper<q20::remove_cvref_t<C>>::value;
+ template <typename C>
+ using if_contiguous_container = std::enable_if_t<isContiguousContainer<C>, bool>;
+
+ template <typename Container, if_contiguous_container<Container> = true>
static auto fromContainer(Container &&container)
{
Q_ASSERT_X(size_t(std::size(container)) <= size_t((std::numeric_limits<size_type>::max)()),
@@ -193,7 +192,7 @@ private:
};
template <typename T>
-class QJniArray : public QJniArrayBase
+class QT_TECH_PREVIEW_API QJniArray : public QJniArrayBase
{
friend struct QJniArrayIterator<T>;
public:
@@ -218,23 +217,21 @@ public:
QJniArray &operator=(const QJniArray &other) = default;
QJniArray &operator=(QJniArray &&other) noexcept = default;
- template <typename Container
- , IfCanConvert<Container> = true
- >
+ template <typename Container, if_contiguous_container<Container> = true>
explicit QJniArray(Container &&container)
: QJniArrayBase(QJniArrayBase::fromContainer(std::forward<Container>(container)))
{
}
- template <typename E = T
- , IfCanConvert<std::initializer_list<E>> = true
- >
Q_IMPLICIT inline QJniArray(std::initializer_list<T> list)
: QJniArrayBase(QJniArrayBase::fromContainer(list))
{
}
- template <typename Other, std::enable_if_t<std::is_convertible_v<Other, Type>, bool> = true>
+ template <typename Other>
+ using if_convertible = std::enable_if_t<std::is_convertible_v<Other, T>, bool>;
+
+ template <typename Other, if_convertible<Other> = true>
QJniArray(QJniArray<Other> &&other)
: QJniArrayBase(std::forward<QJniArray<Other>>(other))
{
@@ -366,6 +363,13 @@ public:
}
};
+// Deduction guide so that we can construct as 'QJniArray list(Container<T>)'. Since
+// fromContainer() maps several C++ types to the same JNI type (e.g. both jboolean and
+// bool become QJniArray<jboolean>), we have to deduce to what fromContainer() would
+// give us.
+template <typename Container, QJniArrayBase::if_contiguous_container<Container> = true>
+QJniArray(Container) -> QJniArray<typename decltype(QJniArrayBase::fromContainer(std::declval<Container>()))::value_type>;
+
template <typename ElementType, typename List, typename NewFn, typename SetFn>
auto QJniArrayBase::makeArray(List &&list, NewFn &&newArray, SetFn &&setRegion)
{
diff --git a/src/corelib/kernel/qjnienvironment.cpp b/src/corelib/kernel/qjnienvironment.cpp
index 1e2826e76b..b4f8497ddd 100644
--- a/src/corelib/kernel/qjnienvironment.cpp
+++ b/src/corelib/kernel/qjnienvironment.cpp
@@ -320,6 +320,30 @@ JavaVM *QJniEnvironment::javaVM()
}
/*!
+ \fn template <typename Class> bool QJniEnvironment::registerNativeMethods(std::initializer_list<JNINativeMethod> methods)
+ \overload
+
+ Registers the Java methods in \a methods with the Java class represented by
+ \c Class, and returns whether the registration was successful.
+
+ The \c Class type has to be declared within the QtJniTypes namespace using
+ the Q_DECLARE_JNI_CLASS macro. Functions that are implemented as free C or
+ C++ functions have to be declared using one of the
+ Q_DECLARE_JNI_NATIVE_METHOD macros, and passed into the registration using
+ the Q_JNI_NATIVE_METHOD macro.
+
+ \include jni.qdoc register-free-function
+
+ For functions that are implemented as static class member functions, use
+ the \l{Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE}{macros for scoped
+ functions} instead.
+
+ \include jni.qdoc register-scoped-function
+*/
+
+/*!
+ \overload
+
Registers the Java methods in the array \a methods of size \a size, each of
which can call native C++ functions from class \a className. These methods
must be registered before any attempt to call them.
diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp
index d900b74d37..4d5ccd7d9b 100644
--- a/src/corelib/kernel/qjnihelpers.cpp
+++ b/src/corelib/kernel/qjnihelpers.cpp
@@ -18,6 +18,10 @@
QT_BEGIN_NAMESPACE
+Q_DECLARE_JNI_CLASS(QtInputDelegate, "org/qtproject/qt/android/QtInputDelegate");
+Q_DECLARE_JNI_CLASS(MotionEvent, "android/view/MotionEvent");
+Q_DECLARE_JNI_CLASS(KeyEvent, "android/view/KeyEvent");
+
namespace QtAndroidPrivate {
// *Listener virtual function implementations.
// Defined out-of-line to pin the vtable/type_info.
@@ -141,6 +145,68 @@ void QtAndroidPrivate::handleNewIntent(JNIEnv *env, jobject intent)
}
}
+QtAndroidPrivate::GenericMotionEventListener::~GenericMotionEventListener() {}
+namespace {
+struct GenericMotionEventListeners {
+ QMutex mutex;
+ QList<QtAndroidPrivate::GenericMotionEventListener *> listeners;
+};
+}
+Q_GLOBAL_STATIC(GenericMotionEventListeners, g_genericMotionEventListeners)
+
+static jboolean dispatchGenericMotionEvent(JNIEnv *, jclass, QtJniTypes::MotionEvent event)
+{
+ jboolean ret = JNI_FALSE;
+ QMutexLocker locker(&g_genericMotionEventListeners()->mutex);
+ for (auto *listener : std::as_const(g_genericMotionEventListeners()->listeners))
+ ret |= listener->handleGenericMotionEvent(event.object());
+ return ret;
+}
+Q_DECLARE_JNI_NATIVE_METHOD(dispatchGenericMotionEvent);
+
+QtAndroidPrivate::KeyEventListener::~KeyEventListener() {}
+namespace {
+struct KeyEventListeners {
+ QMutex mutex;
+ QList<QtAndroidPrivate::KeyEventListener *> listeners;
+};
+}
+Q_GLOBAL_STATIC(KeyEventListeners, g_keyEventListeners)
+
+static jboolean dispatchKeyEvent(JNIEnv *, jclass, QtJniTypes::KeyEvent event)
+{
+ jboolean ret = JNI_FALSE;
+ QMutexLocker locker(&g_keyEventListeners()->mutex);
+ for (auto *listener : std::as_const(g_keyEventListeners()->listeners))
+ ret |= listener->handleKeyEvent(event.object());
+ return ret;
+}
+Q_DECLARE_JNI_NATIVE_METHOD(dispatchKeyEvent);
+
+void QtAndroidPrivate::registerGenericMotionEventListener(QtAndroidPrivate::GenericMotionEventListener *listener)
+{
+ QMutexLocker locker(&g_genericMotionEventListeners()->mutex);
+ g_genericMotionEventListeners()->listeners.push_back(listener);
+}
+
+void QtAndroidPrivate::unregisterGenericMotionEventListener(QtAndroidPrivate::GenericMotionEventListener *listener)
+{
+ QMutexLocker locker(&g_genericMotionEventListeners()->mutex);
+ g_genericMotionEventListeners()->listeners.removeOne(listener);
+}
+
+void QtAndroidPrivate::registerKeyEventListener(QtAndroidPrivate::KeyEventListener *listener)
+{
+ QMutexLocker locker(&g_keyEventListeners()->mutex);
+ g_keyEventListeners()->listeners.push_back(listener);
+}
+
+void QtAndroidPrivate::unregisterKeyEventListener(QtAndroidPrivate::KeyEventListener *listener)
+{
+ QMutexLocker locker(&g_keyEventListeners()->mutex);
+ g_keyEventListeners()->listeners.removeOne(listener);
+}
+
namespace {
class ResumePauseListeners
{
@@ -245,6 +311,15 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env)
return JNI_ERR;
QJniEnvironment qJniEnv;
+ using namespace QtJniTypes;
+ if (!QtInputDelegate::registerNativeMethods(
+ { Q_JNI_NATIVE_METHOD(dispatchGenericMotionEvent),
+ Q_JNI_NATIVE_METHOD(dispatchKeyEvent) })) {
+ qCritical() << "Failed to register natives methods for"
+ << Traits<QtInputDelegate>::className();
+ return JNI_ERR;
+ }
+
if (!registerPermissionNatives(qJniEnv))
return JNI_ERR;
diff --git a/src/corelib/kernel/qjnihelpers_p.h b/src/corelib/kernel/qjnihelpers_p.h
index b5e05fcaf1..a7b879d9e1 100644
--- a/src/corelib/kernel/qjnihelpers_p.h
+++ b/src/corelib/kernel/qjnihelpers_p.h
@@ -56,6 +56,20 @@ namespace QtAndroidPrivate
virtual jobject onBind(jobject intent) = 0;
};
+ class Q_CORE_EXPORT GenericMotionEventListener
+ {
+ public:
+ virtual ~GenericMotionEventListener();
+ virtual bool handleGenericMotionEvent(jobject event) = 0;
+ };
+
+ class Q_CORE_EXPORT KeyEventListener
+ {
+ public:
+ virtual ~KeyEventListener();
+ virtual bool handleKeyEvent(jobject event) = 0;
+ };
+
Q_CORE_EXPORT QtJniTypes::Activity activity();
Q_CORE_EXPORT QtJniTypes::Service service();
Q_CORE_EXPORT QtJniTypes::Context context();
@@ -77,6 +91,12 @@ namespace QtAndroidPrivate
Q_CORE_EXPORT void registerNewIntentListener(NewIntentListener *listener);
Q_CORE_EXPORT void unregisterNewIntentListener(NewIntentListener *listener);
+ Q_CORE_EXPORT void registerGenericMotionEventListener(GenericMotionEventListener *listener);
+ Q_CORE_EXPORT void unregisterGenericMotionEventListener(GenericMotionEventListener *listener);
+
+ Q_CORE_EXPORT void registerKeyEventListener(KeyEventListener *listener);
+ Q_CORE_EXPORT void unregisterKeyEventListener(KeyEventListener *listener);
+
Q_CORE_EXPORT void handlePause();
Q_CORE_EXPORT void handleResume();
Q_CORE_EXPORT void registerResumePauseListener(ResumePauseListener *listener);
diff --git a/src/corelib/kernel/qjniobject.cpp b/src/corelib/kernel/qjniobject.cpp
index 8244a4390f..d5b0cd5663 100644
--- a/src/corelib/kernel/qjniobject.cpp
+++ b/src/corelib/kernel/qjniobject.cpp
@@ -34,19 +34,10 @@ using namespace Qt::StringLiterals;
\sa QJniEnvironment
- \section1 General Notes
-
- \list
- \li Class names need to be fully-qualified, for example: \c "java/lang/String".
- \li Method signatures are written as \c "(ArgumentsTypes)ReturnType", see \l {JNI Types}.
- \li All object types are returned as a QJniObject.
- \endlist
-
\section1 Method Signatures
QJniObject provides convenience functions that will use the correct signature based on the
- provided template types. For functions that only return and take \l {JNI types}, the
- signature can be generate at compile time:
+ provided or deduced template arguments.
\code
jint x = QJniObject::callMethod<jint>("getSize");
@@ -54,13 +45,11 @@ using namespace Qt::StringLiterals;
jint ret = jString1.callMethod<jint>("compareToIgnoreCase", jString2.object<jstring>());
\endcode
- These functions are variadic templates, and the compiler will deduce the template arguments
- from the actual argument types. In many situations, only the return type needs to be provided
- explicitly.
-
- For functions that take other argument types, you need to supply the signature yourself. It is
- important that the signature matches the function you want to call. The example below
- demonstrates how to call different static functions:
+ These functions are variadic templates, and the compiler will deduce the
+ signature from the actual argument types. Only the return type needs to be
+ provided explicitly. QJniObject can deduce the signature string for
+ functions that take \l {JNI types}, and for types that have been declared
+ with the QtJniTypes type mapping.
\code
// Java class
@@ -73,6 +62,31 @@ using namespace Qt::StringLiterals;
}
\endcode
+ \code
+ // C++ code
+ Q_DECLARE_JNI_CLASS(TestClass, "org/qtproject/qt/TestClass")
+
+ // ...
+ using namespace QtJniTypes;
+ TestClass testClass = TestClass::callStaticMethod<TestClass>("create");
+ \endcode
+
+ This allows working with arbitrary Java and Android types in C++ code, without having to
+ create JNI signature strings explicitly.
+
+ \section2 Explicit JNI Signatures
+
+ It is possible to supply the signature yourself. In that case, it is important
+ that the signature matches the function you want to call.
+
+ \list
+ \li Class names need to be fully-qualified, for example: \c "java/lang/String".
+ \li Method signatures are written as \c "(ArgumentsTypes)ReturnType", see \l {JNI Types}.
+ \li All object types are returned as a QJniObject.
+ \endlist
+
+ The example below demonstrates how to call different static functions:
+
The signature structure is \c "(ArgumentsTypes)ReturnType". Array types in the signature
must have the \c {[} prefix, and the fully-qualified \c Object type names must have the
\c L prefix and the \c ; suffix. The signature for the \c create function is
@@ -105,9 +119,9 @@ using namespace Qt::StringLiterals;
// C++ code
QJniObject string1 = QJniObject::fromString("String1");
QJniObject string2 = QJniObject::fromString("String2");
- QJniObject stringArray = QJniObject::callStaticObjectMethod<jstringArray>(
+ QJniObject stringArray = QJniObject::callStaticObjectMethod<jobjectArray>(
"org/qtproject/qt/TestClass",
- "stringArray"
+ "stringArray",
string1.object<jstring>(),
string2.object<jstring>());
\endcode
diff --git a/src/corelib/kernel/qjniobject.h b/src/corelib/kernel/qjniobject.h
index 589f6489f7..af6c54e5aa 100644
--- a/src/corelib/kernel/qjniobject.h
+++ b/src/corelib/kernel/qjniobject.h
@@ -670,7 +670,7 @@ inline bool operator!=(const QJniObject &obj1, const QJniObject &obj2)
}
namespace QtJniTypes {
-struct JObjectBase
+struct QT_TECH_PREVIEW_API JObjectBase
{
operator QJniObject() const { return m_object; }
@@ -685,6 +685,10 @@ struct JObjectBase
protected:
JObjectBase() = default;
+ JObjectBase(const JObjectBase &) = default;
+ JObjectBase(JObjectBase &&) = default;
+ JObjectBase &operator=(const JObjectBase &) = default;
+ JObjectBase &operator=(JObjectBase &&) = default;
~JObjectBase() = default;
Q_IMPLICIT JObjectBase(jobject object) : m_object(object) {}
@@ -695,7 +699,7 @@ protected:
};
template<typename Type>
-class JObject : public JObjectBase
+class QT_TECH_PREVIEW_API JObject : public JObjectBase
{
public:
using Class = Type;
@@ -707,7 +711,7 @@ public:
Q_IMPLICIT JObject(const QJniObject &object) : JObjectBase(object) {}
Q_IMPLICIT JObject(QJniObject &&object) noexcept : JObjectBase(std::move(object)) {}
- // base class destructor is protected, so need to provide all SMFs
+ // base class SMFs are protected, make them public:
JObject(const JObject &other) = default;
JObject(JObject &&other) noexcept = default;
JObject &operator=(const JObject &other) = default;
@@ -822,7 +826,7 @@ auto QJniObject::LocalFrame<Args...>::convertToJni(T &&value)
return newLocalRef<jstring>(QJniObject::fromString(value));
} else if constexpr (QtJniTypes::IsJniArray<Type>::value) {
return value.arrayObject();
- } else if constexpr (QJniArrayBase::canConvert<T>) {
+ } else if constexpr (QJniArrayBase::isContiguousContainer<T>) {
using QJniArrayType = decltype(QJniArrayBase::fromContainer(std::forward<T>(value)));
using ArrayType = decltype(std::declval<QJniArrayType>().arrayObject());
return newLocalRef<ArrayType>(QJniArrayBase::fromContainer(std::forward<T>(value)).template object<jobject>());
@@ -843,7 +847,7 @@ auto QJniObject::LocalFrame<Args...>::convertFromJni(QJniObject &&object)
return object.toString();
} else if constexpr (QtJniTypes::IsJniArray<Type>::value) {
return T(std::move(object));
- } else if constexpr (QJniArrayBase::canConvert<Type>) {
+ } else if constexpr (QJniArrayBase::isContiguousContainer<Type>) {
// if we were to create a QJniArray from Type...
using QJniArrayType = decltype(QJniArrayBase::fromContainer(std::declval<Type>()));
// then that QJniArray would have elements of type
diff --git a/src/corelib/kernel/qjnitypes.h b/src/corelib/kernel/qjnitypes.h
index 1eaae6312b..033445be6a 100644
--- a/src/corelib/kernel/qjnitypes.h
+++ b/src/corelib/kernel/qjnitypes.h
@@ -11,6 +11,7 @@
QT_BEGIN_NAMESPACE
+// QT_TECH_PREVIEW_API
#define Q_DECLARE_JNI_TYPE_HELPER(Type) \
namespace QtJniTypes { \
struct Type : JObject<Type> \
@@ -19,19 +20,19 @@ struct Type : JObject<Type> \
}; \
} \
-
+// QT_TECH_PREVIEW_API
#define Q_DECLARE_JNI_TYPE(Type, Signature) \
Q_DECLARE_JNI_TYPE_HELPER(Type) \
template<> \
struct QtJniTypes::Traits<QtJniTypes::Type> { \
static constexpr auto signature() \
{ \
- static_assert((Signature[0] == 'L' \
- || Signature[0] == '[') \
- && Signature[sizeof(Signature) - 2] == ';', \
+ constexpr QtJniTypes::CTString sig(Signature); \
+ static_assert((sig.startsWith('L') || sig.startsWith("[L")) \
+ && sig.endsWith(';'), \
"Type signature needs to start with 'L' or" \
- " '[' and end with ';'"); \
- return QtJniTypes::CTString(Signature); \
+ " '[L', and end with ';'"); \
+ return sig; \
} \
}; \
@@ -176,7 +177,6 @@ va_##Method(JNIEnv *env, jclass thiz, ...)
}, argTuple); \
} \
-
#define Q_DECLARE_JNI_NATIVE_METHOD(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_JNI_NATIVE_METHOD, __VA_ARGS__) \
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 148983f126..05662b385a 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -3656,8 +3656,8 @@ QMetaProperty::QMetaProperty(const QMetaObject *mobj, int index)
data(getMetaPropertyData(mobj, index))
{
Q_ASSERT(index >= 0 && index < priv(mobj->d.data)->propertyCount);
-
- if (!(data.flags() & EnumOrFlag))
+ // The code below here just resolves menum if the property is an enum type:
+ if (!(data.flags() & EnumOrFlag) || !metaType().flags().testFlag(QMetaType::IsEnumeration))
return;
QByteArrayView enum_name = typeNameFromTypeInfo(mobj, data.type());
menum = mobj->enumerator(QMetaObjectPrivate::indexOfEnumerator(mobj, enum_name));
diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h
index d2c36fceb4..d5dc9a356a 100644
--- a/src/corelib/kernel/qmetaobject_p.h
+++ b/src/corelib/kernel/qmetaobject_p.h
@@ -111,22 +111,18 @@ public:
const_cast<QArgumentType *>(this)->_name = QMetaType(_type).name();
return _name;
}
- bool operator==(const QArgumentType &other) const
- {
- if (_type && other._type)
- return _type == other._type;
- else
- return name() == other.name();
- }
- bool operator!=(const QArgumentType &other) const
+
+private:
+ friend bool comparesEqual(const QArgumentType &lhs,
+ const QArgumentType &rhs) noexcept
{
- if (_type && other._type)
- return _type != other._type;
+ if (lhs._type && rhs._type)
+ return lhs._type == rhs._type;
else
- return name() != other.name();
+ return lhs.name() == rhs.name();
}
+ Q_DECLARE_EQUALITY_COMPARABLE(QArgumentType)
-private:
int _type;
QByteArray _name;
};
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 387c0f49ab..1c2665e53c 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -474,6 +474,7 @@ const char *QtMetaTypePrivate::typedefNameForType(const QtPrivate::QMetaTypeInte
\ingroup objectmodel
\threadsafe
+ \compares equality
The class is used as a helper to marshall types in QVariant and
in queued signals and slots connections. It associates a type
@@ -925,20 +926,20 @@ void QMetaType::unregisterMetaType(QMetaType type)
Returns the QMetaType corresponding to the type in the template parameter.
*/
-/*! \fn bool QMetaType::operator==(QMetaType a, QMetaType b)
+/*! \fn bool QMetaType::operator==(const QMetaType &lhs, const QMetaType &rhs)
\since 5.15
\overload
- Returns \c true if the QMetaType \a a represents the same type
- as the QMetaType \a b, otherwise returns \c false.
+ Returns \c true if the QMetaType \a lhs represents the same type
+ as the QMetaType \a rhs, otherwise returns \c false.
*/
-/*! \fn bool QMetaType::operator!=(QMetaType a, QMetaType b)
+/*! \fn bool QMetaType::operator!=(const QMetaType &lhs, const QMetaType &rhs)
\since 5.15
\overload
- Returns \c true if the QMetaType \a a represents a different type
- than the QMetaType \a b, otherwise returns \c false.
+ Returns \c true if the QMetaType \a lhs represents a different type
+ than the QMetaType \a rhs, otherwise returns \c false.
*/
/*! \internal */
@@ -2659,6 +2660,36 @@ bool QMetaType::hasRegisteredConverterFunction(QMetaType fromType, QMetaType toT
}
/*!
+ \internal
+ Non-template helper ("SCARY") for IsMetaTypePair::registerConverter().
+*/
+bool QtPrivate::hasRegisteredConverterFunctionToPairVariantInterface(QMetaType m)
+{
+ const QMetaType to = QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
+ return QMetaType::hasRegisteredConverterFunction(m, to);
+}
+
+/*!
+ \internal
+ Non-template helper ("SCARY") for SequentialValueTypeIsMetaType::registerConverter().
+*/
+bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType m)
+{
+ const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
+ return QMetaType::hasRegisteredConverterFunction(m, to);
+}
+
+/*!
+ \internal
+ Non-template helper ("SCARY") for AssociativeKeyTypeIsMetaType::registerConverter().
+*/
+bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType m)
+{
+ const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
+ return QMetaType::hasRegisteredConverterFunction(m, to);
+}
+
+/*!
\fn template<typename From, typename To> bool QMetaType::hasRegisteredMutableViewFunction()
Returns \c true, if the meta type system has a registered mutable view on type From of type To.
\since 6.0
@@ -2676,6 +2707,26 @@ bool QMetaType::hasRegisteredMutableViewFunction(QMetaType fromType, QMetaType t
}
/*!
+ \internal
+ Non-template helper ("SCARY") for SequentialValueTypeIsMetaType::registerMutableView().
+*/
+bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType m)
+{
+ const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
+ return QMetaType::hasRegisteredMutableViewFunction(m, to);
+}
+
+/*!
+ \internal
+ Non-template helper ("SCARY") for AssociativeKeyTypeIsMetaType::registerMutableView().
+*/
+bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType m)
+{
+ const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
+ return QMetaType::hasRegisteredMutableViewFunction(m, to);
+}
+
+/*!
\fn const char *QMetaType::typeName(int typeId)
\deprecated
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index e3ef1474da..1e944660c6 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -18,6 +18,7 @@
#include <QtCore/qobjectdefs.h>
#endif
#include <QtCore/qscopeguard.h>
+#include <QtCore/qttypetraits.h>
#include <array>
#include <new>
@@ -518,20 +519,20 @@ public:
template<typename T>
constexpr static QMetaType fromType();
static QMetaType fromName(QByteArrayView name);
-
- friend bool operator==(QMetaType a, QMetaType b)
+private:
+ friend bool comparesEqual(const QMetaType &lhs,
+ const QMetaType &rhs) noexcept
{
- if (a.d_ptr == b.d_ptr)
+ if (lhs.d_ptr == rhs.d_ptr)
return true;
- if (!a.d_ptr || !b.d_ptr)
+ if (!lhs.d_ptr || !rhs.d_ptr)
return false; // one type is undefined, the other is defined
// avoid id call if we already have the id
- const int aId = a.id();
- const int bId = b.id();
+ const int aId = lhs.id();
+ const int bId = rhs.id();
return aId == bId;
}
- friend bool operator!=(QMetaType a, QMetaType b) { return !(a == b); }
-
+ Q_DECLARE_EQUALITY_COMPARABLE(QMetaType)
#ifndef QT_NO_DEBUG_STREAM
private:
friend Q_CORE_EXPORT QDebug operator<<(QDebug d, QMetaType m);
@@ -1750,11 +1751,19 @@ QT_FOR_EACH_STATIC_TYPE(Q_DECLARE_BUILTIN_METATYPE)
QT_BEGIN_NAMESPACE
+namespace QtPrivate {
+// out-of-line helpers to reduce template code bloat ("SCARY") and improve compile times:
+Q_CORE_EXPORT bool hasRegisteredConverterFunctionToPairVariantInterface(QMetaType m);
+Q_CORE_EXPORT bool hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType m);
+Q_CORE_EXPORT bool hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType m);
+Q_CORE_EXPORT bool hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType m);
+Q_CORE_EXPORT bool hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType m);
+}
+
template <typename T>
inline bool QtPrivate::IsMetaTypePair<T, true>::registerConverter()
{
- const QMetaType to = QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
- if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<T>(), to)) {
+ if (!QtPrivate::hasRegisteredConverterFunctionToPairVariantInterface(QMetaType::fromType<T>())) {
QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> o;
return QMetaType::registerConverter<T, QtMetaTypePrivate::QPairVariantInterfaceImpl>(o);
}
@@ -1786,8 +1795,7 @@ struct SequentialValueTypeIsMetaType<T, true>
{
static bool registerConverter()
{
- const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
- if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<T>(), to)) {
+ if (!QtPrivate::hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType::fromType<T>())) {
QSequentialIterableConvertFunctor<T> o;
return QMetaType::registerConverter<T, QIterable<QMetaSequence>>(o);
}
@@ -1796,8 +1804,7 @@ struct SequentialValueTypeIsMetaType<T, true>
static bool registerMutableView()
{
- const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
- if (!QMetaType::hasRegisteredMutableViewFunction(QMetaType::fromType<T>(), to)) {
+ if (!QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType::fromType<T>())) {
QSequentialIterableMutableViewFunctor<T> o;
return QMetaType::registerMutableView<T, QIterable<QMetaSequence>>(o);
}
@@ -1830,8 +1837,7 @@ struct AssociativeKeyTypeIsMetaType<T, true> : AssociativeMappedTypeIsMetaType<T
{
static bool registerConverter()
{
- const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
- if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<T>(), to)) {
+ if (!QtPrivate::hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType::fromType<T>())) {
QAssociativeIterableConvertFunctor<T> o;
return QMetaType::registerConverter<T, QIterable<QMetaAssociation>>(o);
}
@@ -1840,8 +1846,7 @@ struct AssociativeKeyTypeIsMetaType<T, true> : AssociativeMappedTypeIsMetaType<T
static bool registerMutableView()
{
- const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
- if (!QMetaType::hasRegisteredMutableViewFunction(QMetaType::fromType<T>(), to)) {
+ if (!QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType::fromType<T>())) {
QAssociativeIterableMutableViewFunctor<T> o;
return QMetaType::registerMutableView<T, QIterable<QMetaAssociation>>(o);
}
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index e1129c5d25..31b779dc9b 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -4698,16 +4698,25 @@ QDebug operator<<(QDebug dbg, const QObject *o)
\sa {Qt's Property System}
*/
-
/*!
\macro Q_OBJECT
\relates QObject
- The Q_OBJECT macro must appear in the private section of a class
- definition that declares its own signals and slots or that uses
- other services provided by Qt's meta-object system.
+ The Q_OBJECT macro is used to enable meta-object features, such as dynamic
+ properties, signals, and slots.
- For example:
+ You can add the Q_OBJECT macro to any section of a class definition that
+ declares its own signals and slots or that uses other services provided by
+ Qt's meta-object system.
+
+//! [qobject-macros-private-access-specifier]
+ \note This macro expansion ends with a \c private: access specifier. If you
+ declare members immediately after this macro, those members will also be
+ private. To add public (or protected) members right after the macro, use a
+ \c {public:} (or \c {protected:}) access specifier.
+//! [qobject-macros-private-access-specifier]
+
+ Example:
\snippet signalsandslots/signalsandslots.h 1
\codeline
@@ -4715,15 +4724,8 @@ QDebug operator<<(QDebug dbg, const QObject *o)
\snippet signalsandslots/signalsandslots.h 3
\note This macro requires the class to be a subclass of QObject. Use
- Q_GADGET or Q_GADGET_EXPORT instead of Q_OBJECT to enable the meta object system's support
- for enums in a class that is not a QObject subclass.
-
-//! [qobject-macros-private-access-specifier]
- \note This macro expansion ends with a \c private: access specifier, which makes member
- declarations immediately after the macro private, too. If you want add public (or protected)
- members immediately after the macro, you need to use a \c public: (or \c protected:)
- access specifier.
-//! [qobject-macros-private-access-specifier]
+ Q_GADGET or Q_GADGET_EXPORT instead of Q_OBJECT to enable the meta object
+ system's support for enums in a class that is not a QObject subclass.
\sa {Meta-Object System}, {Signals and Slots}, {Qt's Property System}
*/
@@ -4734,8 +4736,9 @@ QDebug operator<<(QDebug dbg, const QObject *o)
The Q_GADGET macro is a lighter version of the Q_OBJECT macro for classes
that do not inherit from QObject but still want to use some of the
- reflection capabilities offered by QMetaObject. Just like the Q_OBJECT
- macro, it must appear in the private section of a class definition.
+ reflection capabilities offered by QMetaObject.
+
+ \include qobject.cpp qobject-macros-private-access-specifier
Q_GADGETs can have Q_ENUM, Q_PROPERTY and Q_INVOKABLE, but they cannot have
signals or slots.
@@ -4744,8 +4747,6 @@ QDebug operator<<(QDebug dbg, const QObject *o)
\c{staticMetaObject} is of type QMetaObject and provides access to the
enums declared with Q_ENUM.
- \include qobject.cpp qobject-macros-private-access-specifier
-
\sa Q_GADGET_EXPORT
*/
@@ -4761,6 +4762,8 @@ QDebug operator<<(QDebug dbg, const QObject *o)
enclosing class as a whole should not be (e.g. because it consists of mostly
inline functions).
+ \include qobject.cpp qobject-macros-private-access-specifier
+
For example:
\code
@@ -4771,8 +4774,6 @@ QDebug operator<<(QDebug dbg, const QObject *o)
~~~
\endcode
- \include qobject.cpp qobject-macros-private-access-specifier
-
\sa Q_GADGET, {Creating Shared Libraries}
*/
diff --git a/src/corelib/kernel/qpermissions.cpp b/src/corelib/kernel/qpermissions.cpp
index d0d2d9eb10..ae9cc6161d 100644
--- a/src/corelib/kernel/qpermissions.cpp
+++ b/src/corelib/kernel/qpermissions.cpp
@@ -85,7 +85,8 @@ Q_LOGGING_CATEGORY(lcPermissions, "qt.permissions", QtWarningMsg);
\target apple-usage-description
Each permission you request must be accompanied by a so called
- \e {usage description} string in the application's \c Info.plist
+ \e {usage description} string in the application's
+ \l{Information Property List Files}{\c Info.plist}
file, describing why the application needs to access the given
permission. For example:
@@ -97,6 +98,10 @@ Q_LOGGING_CATEGORY(lcPermissions, "qt.permissions", QtWarningMsg);
The relevant usage description keys are described in the documentation
for each permission type.
+ To ensure the relevant permission backend is included with your
+ application, please \l{Information Property List Files}
+ {point the build system to your custom \c Info.plist}.
+
\sa {Information Property List Files}.
\section3 Android
diff --git a/src/corelib/kernel/qpermissions_p.h b/src/corelib/kernel/qpermissions_p.h
index 36f497f198..8838b36d9a 100644
--- a/src/corelib/kernel/qpermissions_p.h
+++ b/src/corelib/kernel/qpermissions_p.h
@@ -28,7 +28,7 @@ QT_REQUIRE_CONFIG(permissions);
QT_BEGIN_NAMESPACE
-Q_DECLARE_EXPORTED_LOGGING_CATEGORY(lcPermissions, Q_CORE_EXPORT)
+QT_DECLARE_EXPORTED_QT_LOGGING_CATEGORY(lcPermissions, Q_CORE_EXPORT)
namespace QPermissions::Private
{
diff --git a/src/corelib/kernel/qpermissions_wasm.cpp b/src/corelib/kernel/qpermissions_wasm.cpp
index 846e62ccf7..11bd4e864f 100644
--- a/src/corelib/kernel/qpermissions_wasm.cpp
+++ b/src/corelib/kernel/qpermissions_wasm.cpp
@@ -51,9 +51,13 @@ namespace
{
updatePermission(permissionName, permissionState["state"].as<std::string>(), {});
};
- callbacks.catchFunc = [permissionName](val)
+ callbacks.catchFunc = [permissionName](val err)
{
- updatePermission(permissionName, wapiDenied, {});
+ if (err["name"].as<std::string>() == "NotAllowedError")
+ return updatePermission(permissionName, wapiDenied, {});
+
+ qCInfo(lcPermissions, "'%s' '%s'", err["name"].as<std::string>().c_str(),
+ err["message"].as<std::string>().c_str());
};
val query = val::object();
diff --git a/src/corelib/kernel/qpointer.h b/src/corelib/kernel/qpointer.h
index 39e4ba3e0f..8875eef5c3 100644
--- a/src/corelib/kernel/qpointer.h
+++ b/src/corelib/kernel/qpointer.h
@@ -4,6 +4,7 @@
#ifndef QPOINTER_H
#define QPOINTER_H
+#include <QtCore/qcompare.h>
#include <QtCore/qsharedpointer.h>
#include <QtCore/qtypeinfo.h>
@@ -90,27 +91,21 @@ public:
friend void swap(QPointer &lhs, QPointer &rhs) noexcept
{ lhs.swap(rhs); }
-#define DECLARE_COMPARE_SET(T1, A1, T2, A2) \
- friend bool operator==(T1, T2) noexcept \
- { return A1 == A2; } \
- friend bool operator!=(T1, T2) noexcept \
- { return A1 != A2; }
-
-#define DECLARE_TEMPLATE_COMPARE_SET(T1, A1, T2, A2) \
- template <typename X> \
- friend bool operator==(T1, T2) noexcept \
- { return A1 == A2; } \
- template <typename X> \
- friend bool operator!=(T1, T2) noexcept \
- { return A1 != A2; }
-
- DECLARE_TEMPLATE_COMPARE_SET(const QPointer &p1, p1.data(), const QPointer<X> &p2, p2.data())
- DECLARE_TEMPLATE_COMPARE_SET(const QPointer &p1, p1.data(), X *ptr, ptr)
- DECLARE_TEMPLATE_COMPARE_SET(X *ptr, ptr, const QPointer &p2, p2.data())
- DECLARE_COMPARE_SET(const QPointer &p1, p1.data(), std::nullptr_t, nullptr)
- DECLARE_COMPARE_SET(std::nullptr_t, nullptr, const QPointer &p2, p2.data())
-#undef DECLARE_COMPARE_SET
-#undef DECLARE_TEMPLATE_COMPARE_SET
+private:
+ template <typename X>
+ friend bool comparesEqual(const QPointer &lhs, const QPointer<X> &rhs) noexcept
+ { return lhs.data() == rhs.data(); }
+ QT_DECLARE_EQUALITY_OPERATORS_HELPER(QPointer, QPointer<X>, /* non-constexpr */,
+ template <typename X>)
+
+ template <typename X>
+ friend bool comparesEqual(const QPointer &lhs, X *rhs) noexcept
+ { return lhs.data() == rhs; }
+ Q_DECLARE_EQUALITY_COMPARABLE(QPointer, X*, template <typename X>)
+
+ friend bool comparesEqual(const QPointer &lhs, std::nullptr_t) noexcept
+ { return lhs.data() == nullptr; }
+ Q_DECLARE_EQUALITY_COMPARABLE(QPointer, std::nullptr_t)
};
template <class T> Q_DECLARE_TYPEINFO_BODY(QPointer<T>, Q_RELOCATABLE_TYPE);
diff --git a/src/corelib/kernel/qpointer.qdoc b/src/corelib/kernel/qpointer.qdoc
index 9e4c9b2658..63a2a72e6f 100644
--- a/src/corelib/kernel/qpointer.qdoc
+++ b/src/corelib/kernel/qpointer.qdoc
@@ -8,6 +8,12 @@
\ingroup objectmodel
+ \compares equality
+ \compareswith equality QPointer<X> X* std::nullptr_t
+ Where X and T are compatible types, which means that they are either the same (except
+ for their cv-qualifiers), or one is a base type of the other.
+ \endcompareswith
+
A guarded pointer, QPointer<T>, behaves like a normal C++
pointer \c{T *}, except that it is automatically cleared when the
referenced object is destroyed (unlike normal C++ pointers, which
@@ -202,38 +208,38 @@
*/
/*!
- \fn template <typename T> template<typename X> bool QPointer<T>::operator==(X *o, const QPointer<T> &p)
+ \fn template <typename T> template<typename X> bool QPointer<T>::operator==(X* const &lhs, const QPointer<T> &rhs)
- Equality operator. Returns \c true if \a o and the guarded
- pointer \a p are pointing to the same object, otherwise
+ Equality operator. Returns \c true if \a lhs and the guarded
+ pointer \a rhs are pointing to the same object, otherwise
returns \c false.
*/
/*!
- \fn template <typename T> template<typename X> bool QPointer<T>::operator==(const QPointer<T> &p, X *o)
+ \fn template <typename T> template<typename X> bool QPointer<T>::operator==(const QPointer<T> &lhs, X* const &rhs)
- Equality operator. Returns \c true if \a o and the guarded
- pointer \a p are pointing to the same object, otherwise
+ Equality operator. Returns \c true if \a rhs and the guarded
+ pointer \a lhs are pointing to the same object, otherwise
returns \c false.
*/
/*!
- \fn template <typename T> template<typename X> bool QPointer<T>::operator==(const QPointer<T> &p1, const QPointer<X> &p2)
+ \fn template <typename T> template<typename X> bool QPointer<T>::operator==(const QPointer<T> &lhs, const QPointer<X> &rhs)
- Equality operator. Returns \c true if the guarded pointers \a p1 and \a p2
+ Equality operator. Returns \c true if the guarded pointers \a lhs and \a rhs
are pointing to the same object, otherwise
returns \c false.
*/
/*!
- \fn template <typename T> bool QPointer<T>::operator==(std::nullptr_t, const QPointer<T> &rhs)
+ \fn template <typename T> bool QPointer<T>::operator==(std::nullptr_t const &lhs, const QPointer<T> &rhs)
Equality operator. Returns \c true if the pointer guarded by \a rhs
is \nullptr, otherwise
returns \c false.
*/
/*!
- \fn template <typename T> bool QPointer<T>::operator==(const QPointer<T> &lhs, std::nullptr_t)
+ \fn template <typename T> bool QPointer<T>::operator==(const QPointer<T> &lhs, std::nullptr_t const &rhs)
Equality operator. Returns \c true if the pointer guarded by \a lhs
is \nullptr, otherwise
@@ -241,35 +247,35 @@
*/
/*!
- \fn template <typename T> template<typename X> bool QPointer<T>::operator!=(const QPointer<T> &p, X *o)
+ \fn template <typename T> template<typename X> bool QPointer<T>::operator!=(const QPointer<T> &lhs, X* const &rhs)
- Inequality operator. Returns \c true if \a o and the guarded
- pointer \a p are not pointing to the same object, otherwise
+ Inequality operator. Returns \c true if \a rhs and the guarded
+ pointer \a lhs are not pointing to the same object, otherwise
returns \c false.
*/
/*!
- \fn template <typename T> template<typename X> bool QPointer<T>::operator!=(X *o, const QPointer<T> &p)
+ \fn template <typename T> template<typename X> bool QPointer<T>::operator!=(X* const &lhs, const QPointer<T> &rhs)
- Inequality operator. Returns \c true if \a o and the guarded
- pointer \a p are not pointing to the same object, otherwise
+ Inequality operator. Returns \c true if \a lhs and the guarded
+ pointer \a rhs are not pointing to the same object, otherwise
returns \c false.
*/
/*!
- \fn template <typename T> template<typename X> bool QPointer<T>::operator!=(const QPointer<T> &p1, const QPointer<X> &p2)
+ \fn template <typename T> template<typename X> bool QPointer<T>::operator!=(const QPointer<T> &lhs, const QPointer<X> &rhs)
- Inequality operator. Returns \c true if the guarded pointers \a p1 and
- \a p2 are not pointing to the same object, otherwise
+ Inequality operator. Returns \c true if the guarded pointers \a lhs and
+ \a rhs are not pointing to the same object, otherwise
returns \c false.
*/
/*!
- \fn template <typename T> bool QPointer<T>::operator!=(std::nullptr_t, const QPointer<T> &rhs)
+ \fn template <typename T> bool QPointer<T>::operator!=(std::nullptr_t const &lhs, const QPointer<T> &rhs)
Inequality operator. Returns \c true if the pointer guarded by \a rhs is
a valid (ie not \nullptr) pointer, otherwise
returns \c false.
*/
/*!
- \fn template <typename T> bool QPointer<T>::operator!=(const QPointer<T> &lhs, std::nullptr_t)
+ \fn template <typename T> bool QPointer<T>::operator!=(const QPointer<T> &lhs, std::nullptr_t const &rhs)
Inequality operator. Returns \c true if the pointer guarded by \a lhs is
a valid (ie not \nullptr) pointer, otherwise
diff --git a/src/corelib/kernel/qproperty.h b/src/corelib/kernel/qproperty.h
index 0373867a66..8c4b13cf5e 100644
--- a/src/corelib/kernel/qproperty.h
+++ b/src/corelib/kernel/qproperty.h
@@ -7,6 +7,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/qshareddata.h>
#include <QtCore/qstring.h>
+#include <QtCore/qttypetraits.h>
#include <QtCore/qbindingstorage.h>
#include <type_traits>
diff --git a/src/corelib/kernel/qproperty_p.h b/src/corelib/kernel/qproperty_p.h
index 8ae6664a2b..376482a6af 100644
--- a/src/corelib/kernel/qproperty_p.h
+++ b/src/corelib/kernel/qproperty_p.h
@@ -19,12 +19,13 @@
#include <qproperty.h>
#include <qmetaobject.h>
-#include <qscopedpointer.h>
#include <qscopedvaluerollback.h>
#include <qvariant.h>
#include <vector>
#include <QtCore/QVarLengthArray>
+#include <memory>
+
QT_BEGIN_NAMESPACE
namespace QtPrivate {
@@ -292,7 +293,7 @@ private:
ObserverArray inlineDependencyObservers; // for things we are observing
QPropertyObserverPointer firstObserver; // list of observers observing us
- QScopedPointer<std::vector<QPropertyObserver>> heapObservers; // for things we are observing
+ std::unique_ptr<std::vector<QPropertyObserver>> heapObservers; // for things we are observing
protected:
QUntypedPropertyData *propertyDataPtr = nullptr;
diff --git a/src/corelib/kernel/qpropertyprivate.h b/src/corelib/kernel/qpropertyprivate.h
index 86dc08a6bc..c4a73f2c91 100644
--- a/src/corelib/kernel/qpropertyprivate.h
+++ b/src/corelib/kernel/qpropertyprivate.h
@@ -19,6 +19,7 @@
#include <QtCore/qtaggedpointer.h>
#include <QtCore/qmetatype.h>
#include <QtCore/qcontainerfwd.h>
+#include <QtCore/qttypetraits.h>
#include <functional>
@@ -95,28 +96,20 @@ public:
void swap(QPropertyBindingPrivatePtr &other) noexcept
{ qt_ptr_swap(d, other.d); }
- friend bool operator==(const QPropertyBindingPrivatePtr &p1, const QPropertyBindingPrivatePtr &p2) noexcept
- { return p1.d == p2.d; }
- friend bool operator!=(const QPropertyBindingPrivatePtr &p1, const QPropertyBindingPrivatePtr &p2) noexcept
- { return p1.d != p2.d; }
- friend bool operator==(const QPropertyBindingPrivatePtr &p1, const T *ptr) noexcept
- { return p1.d == ptr; }
- friend bool operator!=(const QPropertyBindingPrivatePtr &p1, const T *ptr) noexcept
- { return p1.d != ptr; }
- friend bool operator==(const T *ptr, const QPropertyBindingPrivatePtr &p2) noexcept
- { return ptr == p2.d; }
- friend bool operator!=(const T *ptr, const QPropertyBindingPrivatePtr &p2) noexcept
- { return ptr != p2.d; }
- friend bool operator==(const QPropertyBindingPrivatePtr &p1, std::nullptr_t) noexcept
- { return !p1; }
- friend bool operator!=(const QPropertyBindingPrivatePtr &p1, std::nullptr_t) noexcept
- { return p1; }
- friend bool operator==(std::nullptr_t, const QPropertyBindingPrivatePtr &p2) noexcept
- { return !p2; }
- friend bool operator!=(std::nullptr_t, const QPropertyBindingPrivatePtr &p2) noexcept
- { return p2; }
-
private:
+ friend bool comparesEqual(const QPropertyBindingPrivatePtr &lhs,
+ const QPropertyBindingPrivatePtr &rhs) noexcept
+ { return lhs.d == rhs.d; }
+ Q_DECLARE_EQUALITY_COMPARABLE(QPropertyBindingPrivatePtr)
+ friend bool comparesEqual(const QPropertyBindingPrivatePtr &lhs,
+ const T *rhs) noexcept
+ { return lhs.d == rhs; }
+ Q_DECLARE_EQUALITY_COMPARABLE(QPropertyBindingPrivatePtr, T*)
+ friend bool comparesEqual(const QPropertyBindingPrivatePtr &lhs,
+ std::nullptr_t) noexcept
+ { return !lhs; }
+ Q_DECLARE_EQUALITY_COMPARABLE(QPropertyBindingPrivatePtr, std::nullptr_t)
+
QtPrivate::RefCounted *d;
};
diff --git a/src/corelib/kernel/qsocketnotifier.h b/src/corelib/kernel/qsocketnotifier.h
index 8288a6b2b5..ac9e577ebc 100644
--- a/src/corelib/kernel/qsocketnotifier.h
+++ b/src/corelib/kernel/qsocketnotifier.h
@@ -83,20 +83,20 @@ public:
Q_DECL_CONSTEXPR_NOT_WIN bool isValid() const noexcept { return *this != QSocketDescriptor(); }
- friend Q_DECL_CONSTEXPR_NOT_WIN bool operator==(QSocketDescriptor lhs,
- QSocketDescriptor rhs) noexcept
+private:
+ friend Q_DECL_CONSTEXPR_NOT_WIN bool comparesEqual(const QSocketDescriptor &lhs,
+ const QSocketDescriptor &rhs) noexcept
{
return lhs.sockfd == rhs.sockfd;
}
- friend Q_DECL_CONSTEXPR_NOT_WIN bool operator!=(QSocketDescriptor lhs,
- QSocketDescriptor rhs) noexcept
- {
- return lhs.sockfd != rhs.sockfd;
- }
+#if defined(Q_OS_WIN) || defined(Q_QDOC)
+ Q_DECLARE_EQUALITY_COMPARABLE(QSocketDescriptor)
+#else
+ Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(QSocketDescriptor)
+#endif
#undef Q_DECL_CONSTEXPR_NOT_WIN
-private:
DescriptorType sockfd;
};
diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp
index 294369c1b3..8d3ea7865d 100644
--- a/src/corelib/kernel/qtimer.cpp
+++ b/src/corelib/kernel/qtimer.cpp
@@ -74,7 +74,7 @@ QT_BEGIN_NAMESPACE
more and more platforms, we expect that zero-millisecond
QTimer objects will gradually be replaced by \l{QThread}s.
- \note Since Qt 6.7 this class is superseded by \l{QChronoTimer}.
+ \note Since Qt 6.8 this class is superseded by \l{QChronoTimer}.
The maximum interval QTimer supports is limited by the number of
milliseconds that would fit in an \c int (which is around 24 days);
whereas QChronoTimer stores its interval as \c std::chrono::nanoseconds
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index d567bcbb7c..306e5b3a38 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -497,6 +497,7 @@ public:
// If possible we reuse the current QVariant private.
if (isDetached() && d.type() == metaType) {
*reinterpret_cast<VT *>(const_cast<void *>(constData())) = std::forward<T>(avalue);
+ d.is_null = false;
} else {
*this = QVariant::fromValue<VT>(std::forward<T>(avalue));
}