summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qmetaobject.h2
-rw-r--r--src/corelib/kernel/qobject.cpp9
-rw-r--r--src/corelib/kernel/qsocketnotifier.cpp89
-rw-r--r--src/corelib/kernel/qsocketnotifier.h61
4 files changed, 150 insertions, 11 deletions
diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h
index bb83080f62..819112dc45 100644
--- a/src/corelib/kernel/qmetaobject.h
+++ b/src/corelib/kernel/qmetaobject.h
@@ -261,7 +261,7 @@ public:
bool isScriptable(const QObject *obj = nullptr) const;
bool isStored(const QObject *obj = nullptr) const;
#if QT_DEPRECATED_SINCE(5, 15)
- QT_DEPRECATED bool isEditable(const QObject *obj = nullptr) const;
+ QT_DEPRECATED_VERSION_5_15 bool isEditable(const QObject *obj = nullptr) const;
#endif
bool isUser(const QObject *obj = nullptr) const;
bool isConstant() const;
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 4cb0133e2f..efa71470d4 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -4376,16 +4376,15 @@ QDebug operator<<(QDebug dbg, const QObject *o)
that values of a given enum can be used as flags and combined using the
bitwise OR operator. For namespaces use \l Q_FLAG_NS() instead.
- The macro must be placed after the enum declaration.
+ The macro must be placed after the enum declaration. The declaration of
+ the flags type is done using the \l Q_DECLARE_FLAGS() macro.
- For example, in QLibrary, the \l{QLibrary::LoadHints}{LoadHints} flag is
+ For example, in QItemSelectionModel, the
+ \l{QItemSelectionModel::SelectionFlags}{SelectionFlags} flag is
declared in the following way:
\snippet code/src_corelib_kernel_qobject.cpp 39
- The declaration of the flags themselves is performed in the public section
- of the QLibrary class itself, using the \l Q_DECLARE_FLAGS() macro.
-
\note The Q_FLAG macro takes care of registering individual flag values
with the meta-object system, so it is unnecessary to use Q_ENUM()
in addition to this macro.
diff --git a/src/corelib/kernel/qsocketnotifier.cpp b/src/corelib/kernel/qsocketnotifier.cpp
index 78269ee605..6e1d2103bd 100644
--- a/src/corelib/kernel/qsocketnotifier.cpp
+++ b/src/corelib/kernel/qsocketnotifier.cpp
@@ -37,23 +37,32 @@
**
****************************************************************************/
+#define BUILDING_QSOCKETNOTIFIER
#include "qsocketnotifier.h"
+#undef BUILDING_QSOCKETNOTIFIER
#include "qplatformdefs.h"
#include "qabstracteventdispatcher.h"
#include "qcoreapplication.h"
+#include "qmetatype.h"
+
#include "qobject_p.h"
#include <private/qthread_p.h>
+#include <QtCore/QLoggingCategory>
+
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcSocketNotifierDeprecation)
+Q_LOGGING_CATEGORY(lcSocketNotifierDeprecation, "qt.core.socketnotifier_deprecation");
+
class QSocketNotifierPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QSocketNotifier)
public:
- qintptr sockfd;
+ QSocketDescriptor sockfd;
QSocketNotifier::Type sntype;
bool snenabled;
};
@@ -143,13 +152,17 @@ QSocketNotifier::QSocketNotifier(qintptr socket, Type type, QObject *parent)
: QObject(*new QSocketNotifierPrivate, parent)
{
Q_D(QSocketNotifier);
+
+ qRegisterMetaType<QSocketDescriptor>();
+ qRegisterMetaType<QSocketNotifier::Type>();
+
d->sockfd = socket;
d->sntype = type;
d->snenabled = true;
auto thisThreadData = d->threadData.loadRelaxed();
- if (socket < 0)
+ if (!d->sockfd.isValid())
qWarning("QSocketNotifier: Invalid socket specified");
else if (!thisThreadData->hasEventDispatcher())
qWarning("QSocketNotifier: Can only be used with threads started with QThread");
@@ -169,6 +182,11 @@ QSocketNotifier::~QSocketNotifier()
/*!
\fn void QSocketNotifier::activated(int socket)
+ \obsolete To avoid unintended truncation of the descriptor, use
+ the QSocketDescriptor overload of this function. If you need
+ compatibility with versions older than 5.15 you need to change
+ the slot to accept qintptr if it currently accepts an int, and
+ then connect using Functor-Based Connection.
This signal is emitted whenever the socket notifier is enabled and
a socket event corresponding to its \l {Type}{type} occurs.
@@ -178,6 +196,18 @@ QSocketNotifier::~QSocketNotifier()
\sa type(), socket()
*/
+/*!
+ \fn void QSocketNotifier::activated(QSocketDescriptor socket, QSocketNotifier::Type type)
+ \since 5.15
+
+ This signal is emitted whenever the socket notifier is enabled and
+ a socket event corresponding to its \a type occurs.
+
+ The socket identifier is passed in the \a socket parameter.
+
+ \sa type(), socket()
+*/
+
/*!
Returns the socket identifier specified to the constructor.
@@ -187,7 +217,7 @@ QSocketNotifier::~QSocketNotifier()
qintptr QSocketNotifier::socket() const
{
Q_D(const QSocketNotifier);
- return d->sockfd;
+ return qintptr(d->sockfd);
}
/*!
@@ -230,7 +260,7 @@ bool QSocketNotifier::isEnabled() const
void QSocketNotifier::setEnabled(bool enable)
{
Q_D(QSocketNotifier);
- if (d->sockfd < 0)
+ if (!d->sockfd.isValid())
return;
if (d->snenabled == enable) // no change
return;
@@ -268,12 +298,61 @@ bool QSocketNotifier::event(QEvent *e)
}
QObject::event(e); // will activate filters
if ((e->type() == QEvent::SockAct) || (e->type() == QEvent::SockClose)) {
- emit activated(d->sockfd, QPrivateSignal());
+ QPointer<QSocketNotifier> alive(this);
+ emit activated(d->sockfd, d->sntype, QPrivateSignal());
+ // ### Qt7: Remove emission if the activated(int) signal is removed
+ if (alive)
+ emit activated(int(qintptr(d->sockfd)), QPrivateSignal());
+
return true;
}
return false;
}
+/*!
+ \class QSocketDescriptor
+ \inmodule QtCore
+ \brief A class which holds a native socket descriptor.
+ \internal
+
+ \ingroup network
+ \ingroup io
+
+ \since 5.15
+
+ QSocketDescriptor makes it easier to handle native socket
+ descriptors in cross-platform code.
+
+ On Windows it holds a \c {Qt::HANDLE} and on Unix it holds an \c int.
+ The class will implicitly convert between the class and the
+ native descriptor type.
+*/
+
+/*!
+ \fn QSocketDescriptor::QSocketDescriptor(DescriptorType descriptor)
+ \internal
+
+ Construct a QSocketDescriptor from a native socket \a descriptor.
+*/
+
+/*!
+ \fn QSocketDescriptor::QSocketDescriptor(qintptr descriptor)
+ \internal
+
+ Construct a QSocketDescriptor from a native socket \a descriptor.
+
+ \note This constructor is only available on Windows.
+*/
+
+/*!
+ \fn Qt::HANDLE QSocketDescriptor::winHandle() const noexcept
+ \internal
+
+ Returns the internal handle.
+
+ \note This function is only available on Windows.
+*/
+
QT_END_NAMESPACE
#include "moc_qsocketnotifier.cpp"
diff --git a/src/corelib/kernel/qsocketnotifier.h b/src/corelib/kernel/qsocketnotifier.h
index 38e5f27247..528f58a1e1 100644
--- a/src/corelib/kernel/qsocketnotifier.h
+++ b/src/corelib/kernel/qsocketnotifier.h
@@ -44,6 +44,7 @@
QT_BEGIN_NAMESPACE
+class QSocketDescriptor;
class QSocketNotifierPrivate;
class Q_CORE_EXPORT QSocketNotifier : public QObject
{
@@ -65,7 +66,23 @@ public Q_SLOTS:
void setEnabled(bool);
Q_SIGNALS:
+#if defined(Q_MOC_RUN)
+ // Add default arguments during Q_MOC_RUN which makes moc generate "signals" which takes less
+ // parameters, but we won't actually allow emitting without all 3. This lets users use the
+ // string-based connect without specifying QSocketNotifier::Type as one of the parameters.
+ void activated(QSocketDescriptor socket, QSocketNotifier::Type activationEvent = Read,
+ QPrivateSignal = {});
+#else
+ void activated(QSocketDescriptor socket, QSocketNotifier::Type activationEvent, QPrivateSignal);
+#endif
+
+ // ### Qt7: consider removing it.
+ // The old signal is compiled internally, but hidden outside of this class.
+ // This means the PMF-based connect(..) will automatically, on recompile, pick up the new
+ // version while the old-style connect(..) can query the metaobject system for this version.
+#if defined(Q_MOC_RUN) || defined(BUILDING_QSOCKETNOTIFIER) || defined(Q_QDOC)
void activated(int socket, QPrivateSignal);
+#endif
protected:
bool event(QEvent *) override;
@@ -74,6 +91,50 @@ private:
Q_DISABLE_COPY(QSocketNotifier)
};
+class QSocketDescriptor
+{
+public:
+#if defined(Q_OS_WIN) || defined(Q_QDOC)
+ using DescriptorType = Qt::HANDLE;
+#define Q_DECL_CONSTEXPR_NOT_WIN
+#else
+ using DescriptorType = int;
+#define Q_DECL_CONSTEXPR_NOT_WIN Q_DECL_CONSTEXPR
+#endif
+
+ /* implicit */ Q_DECL_CONSTEXPR_NOT_WIN
+ QSocketDescriptor(DescriptorType descriptor = DescriptorType(-1)) noexcept : sockfd(descriptor)
+ {
+ }
+
+#if defined(Q_OS_WIN) || defined(Q_QDOC)
+ /* implicit */ QSocketDescriptor(qintptr desc) noexcept : sockfd(DescriptorType(desc)) {}
+ operator qintptr() const noexcept { return qintptr(sockfd); }
+ Q_DECL_CONSTEXPR Qt::HANDLE winHandle() const noexcept { return sockfd; }
+#endif
+ Q_DECL_CONSTEXPR operator DescriptorType() const noexcept { return sockfd; }
+
+ 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
+ {
+ return lhs.sockfd == rhs.sockfd;
+ }
+ friend Q_DECL_CONSTEXPR_NOT_WIN bool operator!=(QSocketDescriptor lhs,
+ QSocketDescriptor rhs) noexcept
+ {
+ return lhs.sockfd != rhs.sockfd;
+ }
+
+#undef Q_DECL_CONSTEXPR_NOT_WIN
+
+private:
+ DescriptorType sockfd;
+};
+
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QSocketNotifier::Type)
+Q_DECLARE_METATYPE(QSocketDescriptor)
#endif // QSOCKETNOTIFIER_H