diff --git a/autotests/integration/keyboard_layout_test.cpp b/autotests/integration/keyboard_layout_test.cpp --- a/autotests/integration/keyboard_layout_test.cpp +++ b/autotests/integration/keyboard_layout_test.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -49,6 +50,7 @@ void testReconfigure(); void testChangeLayoutThroughDBus(); void testPerLayoutShortcut(); + void testDBusServiceExport(); private: void reconfigureLayouts(); @@ -242,5 +244,36 @@ kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTCTRL, timestamp++); } +void KeyboardLayoutTest::testDBusServiceExport() +{ + // verifies that the dbus service is only exported if there are at least two layouts + + // first configure layouts, with just one layout + KConfigGroup layoutGroup = kwinApp()->kxkbConfig()->group("Layout"); + layoutGroup.writeEntry("LayoutList", QStringLiteral("us")); + layoutGroup.sync(); + reconfigureLayouts(); + auto xkb = input()->keyboard()->xkb(); + QTRY_COMPARE(xkb->numberOfLayouts(), 1u); + // default layout is English + QTRY_COMPARE(xkb->layoutName(), QStringLiteral("English (US)")); + // with one layout we should not have the dbus interface + QTRY_VERIFY(!QDBusConnection::sessionBus().interface()->isServiceRegistered(QStringLiteral("org.kde.keyboard")).value()); + + // reconfigure to two layouts + layoutGroup.writeEntry("LayoutList", QStringLiteral("us,de")); + layoutGroup.sync(); + reconfigureLayouts(); + QTRY_COMPARE(xkb->numberOfLayouts(), 2u); + QTRY_VERIFY(QDBusConnection::sessionBus().interface()->isServiceRegistered(QStringLiteral("org.kde.keyboard")).value()); + + // and back to one layout + layoutGroup.writeEntry("LayoutList", QStringLiteral("us")); + layoutGroup.sync(); + reconfigureLayouts(); + QTRY_COMPARE(xkb->numberOfLayouts(), 1u); + QTRY_VERIFY(!QDBusConnection::sessionBus().interface()->isServiceRegistered(QStringLiteral("org.kde.keyboard")).value()); +} + WAYLANDTEST_MAIN(KeyboardLayoutTest) #include "keyboard_layout_test.moc" diff --git a/keyboard_layout.h b/keyboard_layout.h --- a/keyboard_layout.h +++ b/keyboard_layout.h @@ -33,6 +33,7 @@ namespace KWin { class Xkb; +class KeyboardLayoutDBusInterface; class KeyboardLayout : public QObject, public InputEventSpy { @@ -74,6 +75,7 @@ KStatusNotifierItem *m_notifierItem; KSharedConfigPtr m_config; QVector m_layoutShortcuts; + KeyboardLayoutDBusInterface *m_dbusInterface = nullptr; }; class KeyboardLayoutDBusInterface : public QObject diff --git a/keyboard_layout.cpp b/keyboard_layout.cpp --- a/keyboard_layout.cpp +++ b/keyboard_layout.cpp @@ -70,20 +70,26 @@ SLOT(reconfigure())); reconfigure(); - - initDBusInterface(); } void KeyboardLayout::initDBusInterface() { - auto dbusInterface = new KeyboardLayoutDBusInterface(m_xkb, this); - connect(this, &KeyboardLayout::layoutChanged, dbusInterface, - [this, dbusInterface] { - emit dbusInterface->currentLayoutChanged(m_xkb->layoutName()); + if (m_xkb->numberOfLayouts() <= 1) { + delete m_dbusInterface; + m_dbusInterface = nullptr; + return; + } + if (m_dbusInterface) { + return; + } + m_dbusInterface = new KeyboardLayoutDBusInterface(m_xkb, this); + connect(this, &KeyboardLayout::layoutChanged, m_dbusInterface, + [this] { + emit m_dbusInterface->currentLayoutChanged(m_xkb->layoutName()); } ); // TODO: the signal might be emitted even if the list didn't change - connect(this, &KeyboardLayout::layoutsReconfigured, dbusInterface, &KeyboardLayoutDBusInterface::layoutListChanged); + connect(this, &KeyboardLayout::layoutsReconfigured, m_dbusInterface, &KeyboardLayoutDBusInterface::layoutListChanged); } void KeyboardLayout::initNotifierItem() @@ -169,6 +175,8 @@ reinitNotifierMenu(); loadShortcuts(); emit layoutsReconfigured(); + + initDBusInterface(); } void KeyboardLayout::loadShortcuts()