File indexing completed on 2024-04-28 11:35:28
0001 /* 0002 This file is part of the KDE libraries 0003 0004 SPDX-FileCopyrightText: 2001 Waldo Bastian <bastian@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "kdedmodule.h" 0010 #include "kdbusaddons_debug.h" 0011 0012 #include <QDBusConnection> 0013 #include <QDBusMessage> 0014 #include <QDBusObjectPath> 0015 0016 class KDEDModulePrivate 0017 { 0018 public: 0019 QString moduleName; 0020 }; 0021 0022 KDEDModule::KDEDModule(QObject *parent) 0023 : QObject(parent) 0024 , d(new KDEDModulePrivate) 0025 { 0026 } 0027 0028 KDEDModule::~KDEDModule() 0029 { 0030 Q_EMIT moduleDeleted(this); 0031 } 0032 0033 void KDEDModule::setModuleName(const QString &name) 0034 { 0035 d->moduleName = name; 0036 QDBusObjectPath realPath(QLatin1String("/modules/") + d->moduleName); 0037 0038 if (realPath.path().isEmpty()) { 0039 qCWarning(KDBUSADDONS_LOG) << "The kded module name" << name << "is invalid!"; 0040 return; 0041 } 0042 0043 QDBusConnection::RegisterOptions regOptions; 0044 0045 if (this->metaObject()->indexOfClassInfo("D-Bus Interface") != -1) { 0046 // 1. There are kded modules that don't have a D-Bus interface. 0047 // 2. qt 4.4.3 crashes when trying to emit signals on class without 0048 // Q_CLASSINFO("D-Bus Interface", "<your interface>") but 0049 // ExportSignal set. 0050 // We try to solve that for now with just registering Properties and 0051 // Adaptors. But we should investigate where the sense is in registering 0052 // the module at all. Just for autoload? Is there a better solution? 0053 regOptions = QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors; 0054 } else { 0055 // Full functional module. Register everything. 0056 regOptions = QDBusConnection::ExportScriptableSlots // 0057 | QDBusConnection::ExportScriptableProperties // 0058 | QDBusConnection::ExportAdaptors; 0059 qCDebug(KDBUSADDONS_LOG) << "Registration of kded module" << d->moduleName << "without D-Bus interface."; 0060 } 0061 0062 if (!QDBusConnection::sessionBus().registerObject(realPath.path(), this, regOptions)) { 0063 // Happens for khotkeys but the module works. Need some time to investigate. 0064 qCDebug(KDBUSADDONS_LOG) << "registerObject() returned false for" << d->moduleName; 0065 } else { 0066 // qCDebug(KDBUSADDONS_LOG) << "registerObject() successful for" << d->moduleName; 0067 // Fix deadlock with Qt 5.6: this has to be delayed until the dbus thread is unlocked 0068 auto registeredSignal = [this, realPath]() { 0069 moduleRegistered(realPath); 0070 }; 0071 QMetaObject::invokeMethod(this, registeredSignal, Qt::QueuedConnection); 0072 } 0073 } 0074 0075 QString KDEDModule::moduleName() const 0076 { 0077 return d->moduleName; 0078 } 0079 0080 static const char s_modules_path[] = "/modules/"; 0081 0082 QString KDEDModule::moduleForMessage(const QDBusMessage &message) 0083 { 0084 if (message.type() != QDBusMessage::MethodCallMessage) { 0085 return QString(); 0086 } 0087 0088 QString obj = message.path(); 0089 if (!obj.startsWith(QLatin1String(s_modules_path))) { 0090 return QString(); 0091 } 0092 0093 // Remove the <s_modules_path> part 0094 obj = obj.mid(strlen(s_modules_path)); 0095 0096 // Remove the part after the modules name 0097 const int index = obj.indexOf(QLatin1Char('/')); 0098 if (index != -1) { 0099 obj = obj.left(index); 0100 } 0101 0102 return obj; 0103 } 0104 0105 #include "moc_kdedmodule.cpp"