QDBusAbstractAdaptor: Send signals using correct interface

When forwarding a signal, associate this signal with its
enclosing metaobject instead of its sender's metaobject.
Those two may be different if the signal is declared in
a base class.

Add a regression test into tst_qdbusconnection.

Fixes: QTBUG-33142
Pick-to: 6.5
Change-Id: I532ab3bb6c0671a480568f46d63fceff0c82c097
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Ievgenii Meshcheriakov 2023-05-23 15:03:09 +02:00
parent 69b69a7bcc
commit c968405455
3 changed files with 38 additions and 2 deletions

View File

@ -255,8 +255,8 @@ void QDBusAdaptorConnector::relay(QObject *senderObj, int lastSignalIdx, void **
// QObject signal (destroyed(QObject *)) -- ignore // QObject signal (destroyed(QObject *)) -- ignore
return; return;
const QMetaObject *senderMetaObject = senderObj->metaObject(); QMetaMethod mm = senderObj->metaObject()->method(lastSignalIdx);
QMetaMethod mm = senderMetaObject->method(lastSignalIdx); const QMetaObject *senderMetaObject = mm.enclosingMetaObject();
QObject *realObject = senderObj; QObject *realObject = senderObj;
if (qobject_cast<QDBusAbstractAdaptor *>(senderObj)) if (qobject_cast<QDBusAbstractAdaptor *>(senderObj))

View File

@ -1417,6 +1417,34 @@ void tst_QDBusConnection::emptyServerAddress()
QDBusServer server({}, nullptr); QDBusServer server({}, nullptr);
} }
void tst_QDBusConnection::parentClassSignal()
{
if (!QCoreApplication::instance())
QSKIP("Test requires a QCoreApplication");
const QString path = "/path";
QDBusConnection con = QDBusConnection::sessionBus();
QVERIFY(con.isConnected());
// register one object at root:
MyObject obj;
QVERIFY(con.registerObject(path, &obj, QDBusConnection::ExportAllContents));
QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(&obj));
SignalReceiver recv;
QVERIFY(con.connect(con.baseService(), path, "local.BaseObject", "baseObjectSignal", &recv,
SLOT(oneSlot())));
QVERIFY(con.connect(con.baseService(), path, "local.MyObject", "myObjectSignal", &recv,
SLOT(oneSlot())));
emit obj.baseObjectSignal();
QTRY_COMPARE(recv.signalsReceived, 1);
emit obj.myObjectSignal();
QTRY_COMPARE(recv.signalsReceived, 2);
}
QString MyObject::path; QString MyObject::path;
QString MyObjectWithoutInterface::path; QString MyObjectWithoutInterface::path;
QString MyObjectWithoutInterface::interface; QString MyObjectWithoutInterface::interface;

View File

@ -21,11 +21,14 @@ public:
BaseObject(QObject *parent = nullptr) : QObject(parent) { } BaseObject(QObject *parent = nullptr) : QObject(parent) { }
public slots: public slots:
void anotherMethod() { } void anotherMethod() { }
signals:
void baseObjectSignal();
}; };
class MyObject: public BaseObject class MyObject: public BaseObject
{ {
Q_OBJECT Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "local.MyObject")
public slots: public slots:
void method(const QDBusMessage &msg); void method(const QDBusMessage &msg);
@ -33,6 +36,9 @@ public:
static QString path; static QString path;
int callCount; int callCount;
MyObject(QObject *parent = nullptr) : BaseObject(parent), callCount(0) {} MyObject(QObject *parent = nullptr) : BaseObject(parent), callCount(0) {}
signals:
void myObjectSignal();
}; };
class MyObjectWithoutInterface: public QObject class MyObjectWithoutInterface: public QObject
@ -117,6 +123,8 @@ private slots:
void emptyServerAddress(); void emptyServerAddress();
void parentClassSignal();
public: public:
QString serviceName() const { return "org.qtproject.Qt.Autotests.QDBusConnection"; } QString serviceName() const { return "org.qtproject.Qt.Autotests.QDBusConnection"; }
bool callMethod(const QDBusConnection &conn, const QString &path); bool callMethod(const QDBusConnection &conn, const QString &path);