diff options
author | Johan Klokkhammer Helsing <johan.helsing@qt.io> | 2018-03-27 15:30:26 +0200 |
---|---|---|
committer | Johan Helsing <johan.helsing@qt.io> | 2018-04-27 10:17:10 +0000 |
commit | bd5917025fe7491c9f24e99c20484c7ffce9f172 (patch) | |
tree | 006435d90eb25738b04a2c86aa45c0b3e8babdf1 /src/compositor/compositor_api/qwaylandseat.cpp | |
parent | 531a767040782007181bb13583fe69b4ba4b1ba3 (diff) |
Add QWaylandSeat::sendKeyEvent(int qtKey, bool pressed)
Makes it possible to send keyboard events using the QML API:
Button {
onPressedChanged: seat.sendKeyEvent(Qt.Key_Left, pressed)
}
The wl_keyboard.key event requires a keyboard scan code, so in order to get
this we iterate over all the keys in the current keymap checking which QtKey
they map to, storing the results in a QMap which is reused by later calls to
QWaylandKeymap::toScanCode.
This also fixes a bug when sending QKeyEvents without a native scan code using
QWaylandSeat::sendFullKeyEvent. (generated key events have no nativeScanCode).
Now we try QWaylandKeyboard::toScanCode, and if unsuccessful we return with a
warning instead of letting the assertion in QWaylandKeyboard fail.
This also adds more thorough testing for the keyboard, including keymaps and
checking that the events, including enter and leave, are actually received on
the client side.
Change-Id: I601b0c7d909071863abb146bd65a990215dcaff7
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src/compositor/compositor_api/qwaylandseat.cpp')
-rw-r--r-- | src/compositor/compositor_api/qwaylandseat.cpp | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/src/compositor/compositor_api/qwaylandseat.cpp b/src/compositor/compositor_api/qwaylandseat.cpp index c67e6020d..957f5ea83 100644 --- a/src/compositor/compositor_api/qwaylandseat.cpp +++ b/src/compositor/compositor_api/qwaylandseat.cpp @@ -440,10 +440,50 @@ void QWaylandSeat::sendFullKeyEvent(QKeyEvent *event) return; if (!d->keyboard.isNull() && !event->isAutoRepeat()) { + + uint scanCode = event->nativeScanCode(); + if (scanCode == 0) + scanCode = d->keyboard->toScanCode(event->key()); + + if (scanCode == 0) { + qWarning() << "Can't send Wayland key event: Unable to get a valid scan code"; + return; + } + if (event->type() == QEvent::KeyPress) - d->keyboard->sendKeyPressEvent(event->nativeScanCode()); + d->keyboard->sendKeyPressEvent(scanCode); else if (event->type() == QEvent::KeyRelease) - d->keyboard->sendKeyReleaseEvent(event->nativeScanCode()); + d->keyboard->sendKeyReleaseEvent(scanCode); + } +} + +/*! + * \qmlmethod void QtWaylandCompositor::WaylandSeat::sendKeyEvent(int qtKey, bool pressed) + * \since 5.12 + * + * Sends a key press or release to the keyboard device. + */ + +/*! + * Sends a key press or release to the keyboard device. + * + * \since 5.12 + */ +void QWaylandSeat::sendKeyEvent(int qtKey, bool pressed) +{ + Q_D(QWaylandSeat); + if (!keyboardFocus()) { + qWarning("Cannot send Wayland key event, no keyboard focus, fix the compositor"); + return; + } + + if (auto scanCode = d->keyboard->toScanCode(qtKey)) { + if (pressed) + d->keyboard->sendKeyPressEvent(scanCode); + else + d->keyboard->sendKeyReleaseEvent(scanCode); + } else { + qWarning() << "Can't send Wayland key event: Unable to get scan code for" << Qt::Key(qtKey); } } |