diff --git a/src/app/SystemLayouts.cpp b/src/app/SystemLayouts.cpp index 2e5dbcd..f656671 100644 --- a/src/app/SystemLayouts.cpp +++ b/src/app/SystemLayouts.cpp @@ -2,7 +2,9 @@ #include #include -#include +#include +#include +#include namespace { const QString Service = QStringLiteral("org.kde.keyboard"); @@ -21,12 +23,26 @@ SystemLayouts::SystemLayouts(QObject *parent) : QObject(parent) { QDBusConnection bus = QDBusConnection::sessionBus(); - const QDBusReply reply = bus.call(call(QStringLiteral("getLayout"))); - m_system = reply.isValid(); - if (!m_system) - return; - m_current = reply.value(); + // Follows the service's owner, so it survives KWin restarting. bus.connect(Service, Path, Interface, QStringLiteral("layoutChanged"), this, SLOT(setCurrent(uint))); + auto *watcher = new QDBusServiceWatcher(Service, bus, QDBusServiceWatcher::WatchForOwnerChange, this); + connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &SystemLayouts::fetchCurrent); + connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, [this] { m_system = false; }); + fetchCurrent(); +} + +void SystemLayouts::fetchCurrent() +{ + auto *watcher = new QDBusPendingCallWatcher( + QDBusConnection::sessionBus().asyncCall(call(QStringLiteral("getLayout"))), this); + connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) { + watcher->deleteLater(); + const QDBusPendingReply reply = *watcher; + if (reply.isError()) + return; + m_system = true; + setCurrent(reply.value()); + }); } void SystemLayouts::next(quint32 count) diff --git a/src/app/SystemLayouts.h b/src/app/SystemLayouts.h index 0a76919..857b7e2 100644 --- a/src/app/SystemLayouts.h +++ b/src/app/SystemLayouts.h @@ -4,7 +4,8 @@ // Which of the system's keyboard layouts is active, followed and switched // over KWin's org.kde.keyboard D-Bus interface, so the on-screen and the -// physical keyboard always agree. Without that service it switches locally. +// physical keyboard always agree. Without that service it switches locally, +// until the service appears (KWin starting late or restarting). class SystemLayouts : public QObject { Q_OBJECT @@ -23,6 +24,8 @@ private Q_SLOTS: void setCurrent(uint index); private: + void fetchCurrent(); + bool m_system = false; quint32 m_current = 0; };