Follow KWin's layout service when it appears later

getLayout is asked asynchronously, and again whenever org.kde.keyboard
registers, so a late start or a KWin restart no longer leaves the globe
key switching only locally.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-15 10:13:49 +02:00
co-authored by Claude Opus 5.5
parent 536fc12d2f
commit 5f7873995b
2 changed files with 26 additions and 7 deletions
+22 -6
View File
@@ -2,7 +2,9 @@
#include <QDBusConnection>
#include <QDBusMessage>
#include <QDBusReply>
#include <QDBusPendingCallWatcher>
#include <QDBusPendingReply>
#include <QDBusServiceWatcher>
namespace {
const QString Service = QStringLiteral("org.kde.keyboard");
@@ -21,12 +23,26 @@ SystemLayouts::SystemLayouts(QObject *parent)
: QObject(parent)
{
QDBusConnection bus = QDBusConnection::sessionBus();
const QDBusReply<uint> 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<uint> reply = *watcher;
if (reply.isError())
return;
m_system = true;
setCurrent(reply.value());
});
}
void SystemLayouts::next(quint32 count)
+4 -1
View File
@@ -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;
};