Commit b12b9193 authored by Jan Grulich's avatar Jan Grulich

FakeInput: add support for keyboard key press and release

Summary: Adds support for keyboard button press and release as defined in linux/input-event-codes.h

Reviewers: davidedmundson, apol, #plasma, romangg

Reviewed By: davidedmundson, #plasma

Subscribers: kde-frameworks-devel

Tags: #frameworks

Differential Revision: https://phabricator.kde.org/D23766
parent 1fb1906a
......@@ -52,6 +52,8 @@ private Q_SLOTS:
void testAxis_data();
void testAxis();
void testTouch();
void testKeyboardKeyLinux_data();
void testKeyboardKeyLinux();
private:
Display *m_display = nullptr;
......@@ -423,6 +425,57 @@ void FakeInputTest::testTouch()
QCOMPARE(touchCancelSpy.count(), 1);
}
void FakeInputTest::testKeyboardKeyLinux_data()
{
QTest::addColumn<quint32>("linuxKey");
QTest::newRow("A") << quint32(KEY_A);
QTest::newRow("S") << quint32(KEY_S);
QTest::newRow("D") << quint32(KEY_D);
QTest::newRow("F") << quint32(KEY_F);
}
void FakeInputTest::testKeyboardKeyLinux()
{
// this test verifies that keyboard key events are properly passed to the server with Qt button codes
QVERIFY(!m_device->isAuthenticated());
QSignalSpy pressedSpy(m_device, &FakeInputDevice::keyboardKeyPressRequested);
QVERIFY(pressedSpy.isValid());
QSignalSpy releasedSpy(m_device, &FakeInputDevice::keyboardKeyReleaseRequested);
QVERIFY(releasedSpy.isValid());
// without an authentication we shouldn't get the signals
QFETCH(quint32, linuxKey);
m_fakeInput->requestKeyboardKeyPress(linuxKey);
m_fakeInput->requestKeyboardKeyRelease(linuxKey);
QVERIFY(!pressedSpy.wait(100));
QVERIFY(pressedSpy.isEmpty());
QVERIFY(releasedSpy.isEmpty());
// now authenticate
m_device->setAuthentication(true);
// now our click should work
m_fakeInput->requestKeyboardKeyPress(linuxKey);
m_fakeInput->requestKeyboardKeyRelease(linuxKey);
QVERIFY(releasedSpy.wait());
QCOMPARE(pressedSpy.count(), 1);
QCOMPARE(releasedSpy.count(), 1);
QTEST(pressedSpy.last().first().value<quint32>(), "linuxKey");
QTEST(releasedSpy.last().first().value<quint32>(), "linuxKey");
// and a press/release "manually"
m_fakeInput->requestKeyboardKeyPress(linuxKey);
QVERIFY(pressedSpy.wait());
QCOMPARE(pressedSpy.count(), 2);
QCOMPARE(releasedSpy.count(), 1);
QTEST(pressedSpy.last().first().value<quint32>(), "linuxKey");
// and release
m_fakeInput->requestKeyboardKeyRelease(linuxKey);
QVERIFY(releasedSpy.wait());
QCOMPARE(pressedSpy.count(), 2);
QCOMPARE(releasedSpy.count(), 2);
QTEST(releasedSpy.last().first().value<quint32>(), "linuxKey");
}
QTEST_GUILESS_MAIN(FakeInputTest)
#include "test_fake_input.moc"
......@@ -216,6 +216,27 @@ void FakeInput::requestTouchFrame()
org_kde_kwin_fake_input_touch_frame(d->manager);
}
void FakeInput::requestKeyboardKeyPress(quint32 linuxKey)
{
Q_ASSERT(d->manager.isValid());
if (wl_proxy_get_version(d->manager) < ORG_KDE_KWIN_FAKE_INPUT_KEYBOARD_KEY_SINCE_VERSION) {
return;
}
org_kde_kwin_fake_input_keyboard_key(d->manager, linuxKey, WL_KEYBOARD_KEY_STATE_PRESSED);
}
void FakeInput::requestKeyboardKeyRelease(quint32 linuxKey)
{
Q_ASSERT(d->manager.isValid());
if (wl_proxy_get_version(d->manager) < ORG_KDE_KWIN_FAKE_INPUT_KEYBOARD_KEY_SINCE_VERSION) {
return;
}
org_kde_kwin_fake_input_keyboard_key(d->manager, linuxKey, WL_KEYBOARD_KEY_STATE_RELEASED);
}
FakeInput::operator org_kde_kwin_fake_input*() const
{
return d->manager;
......
......@@ -210,6 +210,21 @@ public:
**/
void requestTouchFrame();
/**
* Request a keyboard key press.
* @param linuxButton The button code as defined in linux/input-event-codes.h
*
* @since 5.63
**/
void requestKeyboardKeyPress(quint32 linuxKey);
/**
* Request a keyboard button release.
* @param linuxButton The button code as defined in linux/input-event-codes.h
*
* @since 5.63
**/
void requestKeyboardKeyRelease(quint32 linuxKey);
operator org_kde_kwin_fake_input*();
operator org_kde_kwin_fake_input*() const;
......
......@@ -16,7 +16,7 @@
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
]]></copyright>
<interface name="org_kde_kwin_fake_input" version="3">
<interface name="org_kde_kwin_fake_input" version="4">
<description summary="Fake input manager">
This interface allows other processes to provide fake input events.
Purpose is on the one hand side to provide testing facilities like XTest on X11.
......@@ -87,5 +87,9 @@
<arg name="x" type="fixed"/>
<arg name="y" type="fixed"/>
</request>
<request name="keyboard_key" since="4">
<arg name="button" type="uint"/>
<arg name="state" type="uint"/>
</request>
</interface>
</protocol>
......@@ -206,7 +206,7 @@ static const QMap<Registry::Interface, SuppertedInterfaceData> s_interfaces = {
&Registry::remoteAccessManagerRemoved
}},
{Registry::Interface::FakeInput, {
3,
4,
QByteArrayLiteral("org_kde_kwin_fake_input"),
&org_kde_kwin_fake_input_interface,
&Registry::fakeInputAnnounced,
......
......@@ -50,6 +50,7 @@ private:
static void touchUpCallback(wl_client *client, wl_resource *resource, quint32 id);
static void touchCancelCallback(wl_client *client, wl_resource *resource);
static void touchFrameCallback(wl_client *client, wl_resource *resource);
static void keyboardKeyCallback(wl_client *client, wl_resource *resource, uint32_t button, uint32_t state);
static void unbind(wl_resource *resource);
static Private *cast(wl_resource *r) {
......@@ -75,7 +76,7 @@ private:
FakeInputDevice *q;
};
const quint32 FakeInputInterface::Private::s_version = 3;
const quint32 FakeInputInterface::Private::s_version = 4;
QList<quint32> FakeInputInterface::Private::touchIds = QList<quint32>();
#ifndef DOXYGEN_SHOULD_SKIP_THIS
......@@ -89,7 +90,8 @@ const struct org_kde_kwin_fake_input_interface FakeInputInterface::Private::s_in
touchUpCallback,
touchCancelCallback,
touchFrameCallback,
pointerMotionAbsoluteCallback
pointerMotionAbsoluteCallback,
keyboardKeyCallback
};
#endif
......@@ -265,6 +267,26 @@ void FakeInputInterface::Private::touchFrameCallback(wl_client *client, wl_resou
emit d->touchFrameRequested();
}
void FakeInputInterface::Private::keyboardKeyCallback(wl_client *client, wl_resource *resource, uint32_t button, uint32_t state)
{
Q_UNUSED(client)
FakeInputDevice *d = device(resource);
if (!d || !d->isAuthenticated()) {
return;
}
switch (state) {
case WL_KEYBOARD_KEY_STATE_PRESSED:
emit d->keyboardKeyPressRequested(button);
break;
case WL_KEYBOARD_KEY_STATE_RELEASED:
emit d->keyboardKeyReleaseRequested(button);
break;
default:
// nothing
break;
}
}
FakeInputInterface::FakeInputInterface(Display *display, QObject *parent)
: Global(new Private(this, display), parent)
{
......
......@@ -161,6 +161,18 @@ Q_SIGNALS:
* @since 5.23
**/
void touchFrameRequested();
/**
* Requests a keyboard key pressed for @p key.
*
* @since 5.63
**/
void keyboardKeyPressRequested(quint32 key);
/**
* Requests a keyboard key release for @p key.
*
* @since 5.63
**/
void keyboardKeyReleaseRequested(quint32 key);
private:
friend class FakeInputInterface;
......
Markdown is supported
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