File indexing completed on 2024-04-14 03:51:47
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 } 0031 0032 void KDEDModule::setModuleName(const QString &name) 0033 { 0034 d->moduleName = name; 0035 QDBusObjectPath realPath(QLatin1String("/modules/") + d->moduleName); 0036 0037 if (realPath.path().isEmpty()) { 0038 qCWarning(KDBUSADDONS_LOG) << "The kded module name" << name << "is invalid!"; 0039 return; 0040 } 0041 0042 QDBusConnection::RegisterOptions regOptions; 0043 0044 if (this->metaObject()->indexOfClassInfo("D-Bus Interface") != -1) { 0045 // 1. There are kded modules that don't have a D-Bus interface. 0046 // 2. qt 4.4.3 crashes when trying to emit signals on class without 0047 // Q_CLASSINFO("D-Bus Interface", "<your interface>") but 0048 // ExportSignal set. 0049 // We try to solve that for now with just registering Properties and 0050 // Adaptors. But we should investigate where the sense is in registering 0051 // the module at all. Just for autoload? Is there a better solution? 0052 regOptions = QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors; 0053 } else { 0054 // Full functional module. Register everything. 0055 regOptions = QDBusConnection::ExportScriptableSlots // 0056 | QDBusConnection::ExportScriptableProperties // 0057 | QDBusConnection::ExportAdaptors; 0058 qCDebug(KDBUSADDONS_LOG) << "Registration of kded module" << d->moduleName << "without D-Bus interface."; 0059 } 0060 0061 if (!QDBusConnection::sessionBus().registerObject(realPath.path(), this, regOptions)) { 0062 // Happens for khotkeys but the module works. Need some time to investigate. 0063 qCDebug(KDBUSADDONS_LOG) << "registerObject() returned false for" << d->moduleName; 0064 } else { 0065 // qCDebug(KDBUSADDONS_LOG) << "registerObject() successful for" << d->moduleName; 0066 // Fix deadlock with Qt 5.6: this has to be delayed until the dbus thread is unlocked 0067 auto registeredSignal = [this, realPath]() { 0068 moduleRegistered(realPath); 0069 }; 0070 QMetaObject::invokeMethod(this, registeredSignal, Qt::QueuedConnection); 0071 } 0072 } 0073 0074 QString KDEDModule::moduleName() const 0075 { 0076 return d->moduleName; 0077 } 0078 0079 static const char s_modules_path[] = "/modules/"; 0080 0081 QString KDEDModule::moduleForMessage(const QDBusMessage &message) 0082 { 0083 if (message.type() != QDBusMessage::MethodCallMessage) { 0084 return QString(); 0085 } 0086 0087 QString obj = message.path(); 0088 if (!obj.startsWith(QLatin1String(s_modules_path))) { 0089 return QString(); 0090 } 0091 0092 // Remove the <s_modules_path> part 0093 obj = obj.mid(strlen(s_modules_path)); 0094 0095 // Remove the part after the modules name 0096 const int index = obj.indexOf(QLatin1Char('/')); 0097 if (index != -1) { 0098 obj = obj.left(index); 0099 } 0100 0101 return obj; 0102 } 0103 0104 #include "moc_kdedmodule.cpp"