Commit 3621d745 authored by David Redondo's avatar David Redondo 🏎
Browse files

Keys KCModuleData use async loading

KCMUtils and Systemsettings can now do this async.
parent 839ff9f5
......@@ -27,57 +27,62 @@
#include <kglobalaccel_component_interface.h>
#include <kglobalaccel_interface.h>
// Short timeout, rather fail than block isDefaults for to long which needs to be sync
constexpr int dbusTimeout = 5; // milliseconds
KeysData::KeysData(QObject *parent, const QVariantList &args)
: KCModuleData(parent, args)
{
Q_UNUSED(parent)
Q_UNUSED(args)
}
bool KeysData::isDefaults() const
{
for (int i = KStandardShortcut::AccelNone + 1; i < KStandardShortcut::StandardShortcutCount; ++i) {
const auto id = static_cast<KStandardShortcut::StandardShortcut>(i);
const QList<QKeySequence> activeShortcuts = KStandardShortcut::shortcut(id);
const QList<QKeySequence> defaultShortcuts = KStandardShortcut::hardcodedDefaultShortcut(id);
if (activeShortcuts != defaultShortcuts) {
return false;
m_isDefault = false;
return;
}
}
// need to do this blocking
KGlobalAccelInterface globalAccelInterface(QStringLiteral("org.kde.kglobalaccel"), QStringLiteral("/kglobalaccel"), QDBusConnection::sessionBus());
globalAccelInterface.setTimeout(dbusTimeout);
if (!globalAccelInterface.isValid()) {
return true;
}
auto componentsCall = globalAccelInterface.allComponents();
componentsCall.waitForFinished();
if (componentsCall.isError()) {
return true;
return;
}
const auto components = componentsCall.value();
for (const auto &componentPath : components) {
KGlobalAccelComponentInterface component(globalAccelInterface.service(), componentPath.path(), QDBusConnection::sessionBus());
component.setTimeout(dbusTimeout);
if (!component.isValid()) {
return true;
}
auto allShortcutsCall = component.allShortcutInfos();
allShortcutsCall.waitForFinished();
if (allShortcutsCall.isError()) {
return true;
// Default behavior of KCModuleData is to emit the 'aboutToLoad' after construction which
// triggers the 'loaded' signal. Because we query the data in an async way we emit 'loaded'
// manually when were are done.
disconnect(this, &KCModuleData::aboutToLoad, this, &KCModuleData::loaded);
auto componentsWatcher = new QDBusPendingCallWatcher(globalAccelInterface.allComponents());
connect(componentsWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) {
QDBusPendingReply<QList<QDBusObjectPath>> componentsReply = *watcher;
if (componentsReply.isError() || componentsReply.value().isEmpty()) {
Q_EMIT loaded();
return;
}
const auto allShortcuts = allShortcutsCall.value();
for (const auto &shortcutInfo : allShortcuts) {
if (shortcutInfo.defaultKeys() != shortcutInfo.keys()) {
return false;
}
const auto components = componentsReply.value();
for (const auto &componentPath : components) {
KGlobalAccelComponentInterface component(QStringLiteral("org.kde.kglobalaccel"), componentPath.path(), QDBusConnection::sessionBus());
++m_pendingComponentCalls;
auto shortcutsWatcher = new QDBusPendingCallWatcher(component.allShortcutInfos());
connect(shortcutsWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) {
QDBusPendingReply<QList<KGlobalShortcutInfo>> shortcutsReply = *watcher;
if (shortcutsReply.isValid()) {
const auto allShortcuts = shortcutsReply.value();
bool isNotDefault = std::any_of(allShortcuts.cbegin(), allShortcuts.cend(), [](const KGlobalShortcutInfo &info) {
return info.defaultKeys() != info.keys();
});
m_isDefault &= isNotDefault;
}
if (--m_pendingComponentCalls == 0) {
Q_EMIT loaded();
}
});
}
}
return true;
});
}
bool KeysData::isDefaults() const
{
return m_isDefault;
}
#include "keysdata.moc"
......@@ -29,6 +29,10 @@ class KeysData : public KCModuleData
public:
KeysData(QObject *parent = nullptr, const QVariantList &args = {});
bool isDefaults() const override;
private:
bool m_isDefault = true;
int m_pendingComponentCalls = 0;
};
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment