Ensure the layoutChanged DBus signal gets emitted when changing layouts through DBus

Summary:
Unfortunately Xkb does not emit a signal when the keyboard layout
changes. Due to that we need to manually check in KeyboardLayout after
each action which could change the layout whether the layout changed.

This was not yet done for the case when the layout got changed through
the DBus interface. Resulting in the DBus signal not emitted.

This change addresses the issue by invoking the check for change after
changing the keyboard layout.

Test Plan: Added test case

Reviewers: #kwin, #plasma_on_wayland

Subscribers: plasma-devel, kwin

Tags: #plasma_on_wayland, #kwin

Differential Revision: https://phabricator.kde.org/D4387
icc-effect-5.14.5
Martin Gräßlin 2017-02-01 06:49:32 +01:00
parent 8484a2a3a0
commit b16bd4147a
3 changed files with 34 additions and 2 deletions

View File

@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "kwin_wayland_test.h"
#include "keyboard_input.h"
#include "keyboard_layout.h"
#include "platform.h"
#include "wayland_server.h"
@ -78,6 +79,20 @@ void KeyboardLayoutTest::cleanup()
{
}
class LayoutChangedSignalWrapper : public QObject
{
Q_OBJECT
public:
LayoutChangedSignalWrapper()
: QObject()
{
QDBusConnection::sessionBus().connect(QStringLiteral("org.kde.keyboard"), QStringLiteral("/Layouts"), QStringLiteral("org.kde.KeyboardLayouts"), QStringLiteral("currentLayoutChanged"), this, SIGNAL(layoutChanged(QString)));
}
Q_SIGNALS:
void layoutChanged(const QString &name);
};
void KeyboardLayoutTest::testReconfigure()
{
// verifies that we can change the keymap
@ -124,6 +139,10 @@ void KeyboardLayoutTest::testChangeLayoutThroughDBus()
xkb->switchToLayout(0);
QCOMPARE(xkb->layoutName(), QStringLiteral("German"));
LayoutChangedSignalWrapper wrapper;
QSignalSpy layoutChangedSpy(&wrapper, &LayoutChangedSignalWrapper::layoutChanged);
QVERIFY(layoutChangedSpy.isValid());
// now change through DBus to english
auto changeLayout = [] (const QString &layoutName) {
QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.keyboard"), QStringLiteral("/Layouts"), QStringLiteral("org.kde.KeyboardLayouts"), QStringLiteral("setLayout"));
@ -135,24 +154,34 @@ void KeyboardLayoutTest::testChangeLayoutThroughDBus()
QVERIFY(!reply.isError());
QCOMPARE(reply.reply().arguments().first().toBool(), true);
QCOMPARE(xkb->layoutName(), QStringLiteral("English (US)"));
QVERIFY(layoutChangedSpy.wait());
QCOMPARE(layoutChangedSpy.count(), 1);
layoutChangedSpy.clear();
// switch to a layout which does not exist
reply = changeLayout(QStringLiteral("French"));
QVERIFY(!reply.isError());
QCOMPARE(reply.reply().arguments().first().toBool(), false);
QCOMPARE(xkb->layoutName(), QStringLiteral("English (US)"));
QVERIFY(!layoutChangedSpy.wait());
QVERIFY(layoutChangedSpy.isEmpty());
// switch to another layout should work
reply = changeLayout(QStringLiteral("German"));
QVERIFY(!reply.isError());
QCOMPARE(reply.reply().arguments().first().toBool(), true);
QCOMPARE(xkb->layoutName(), QStringLiteral("German"));
QVERIFY(layoutChangedSpy.wait());
QCOMPARE(layoutChangedSpy.count(), 1);
layoutChangedSpy.clear();
// switching to same layout should also work
reply = changeLayout(QStringLiteral("German"));
QVERIFY(!reply.isError());
QCOMPARE(reply.reply().arguments().first().toBool(), true);
QCOMPARE(xkb->layoutName(), QStringLiteral("German"));
QVERIFY(!layoutChangedSpy.wait());
QVERIFY(layoutChangedSpy.isEmpty());
}
WAYLANDTEST_MAIN(KeyboardLayoutTest)

View File

@ -274,9 +274,10 @@ void KeyboardLayout::reinitNotifierMenu()
static const QString s_keyboardService = QStringLiteral("org.kde.keyboard");
static const QString s_keyboardObject = QStringLiteral("/Layouts");
KeyboardLayoutDBusInterface::KeyboardLayoutDBusInterface(Xkb *xkb, QObject *parent)
KeyboardLayoutDBusInterface::KeyboardLayoutDBusInterface(Xkb *xkb, KeyboardLayout *parent)
: QObject(parent)
, m_xkb(xkb)
, m_keyboardLayout(parent)
{
QDBusConnection::sessionBus().registerService(s_keyboardService);
QDBusConnection::sessionBus().registerObject(s_keyboardObject, this, QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals);
@ -300,6 +301,7 @@ bool KeyboardLayoutDBusInterface::setLayout(const QString &layout)
return false;
}
m_xkb->switchToLayout(it.key());
m_keyboardLayout->checkLayoutChange();
return true;
}

View File

@ -82,7 +82,7 @@ class KeyboardLayoutDBusInterface : public QObject
Q_CLASSINFO("D-Bus Interface", "org.kde.KeyboardLayouts")
public:
explicit KeyboardLayoutDBusInterface(Xkb *xkb, QObject *parent);
explicit KeyboardLayoutDBusInterface(Xkb *xkb, KeyboardLayout *parent);
~KeyboardLayoutDBusInterface() override;
public Q_SLOTS:
@ -97,6 +97,7 @@ Q_SIGNALS:
private:
Xkb *m_xkb;
KeyboardLayout *m_keyboardLayout;
};
}