Deliver correct key code on key release on WASM
Changed the behavior in which key events are delivered to targets. Before the change, in case of a EMSCRIPTEN_EVENT_KEYUP event, the key code and text were not filled in correctly as they should. This resulted in wrong behavior when event targets expected these codes being available. Fixes: QTBUG-105213 Change-Id: Ie66b5d6d395d08af655fcb00f1f616ad43d6bea4 Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
This commit is contained in:
parent
998bd0b528
commit
7485213930
@ -1131,63 +1131,28 @@ void QWasmCompositor::WindowManipulation::onPointerUp(const PointerEvent& event)
|
|||||||
m_screen->canvas().call<void>("releasePointerCapture", event.pointerId);
|
m_screen->canvas().call<void>("releasePointerCapture", event.pointerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QWasmCompositor::processKeyboard(int eventType, const EmscriptenKeyboardEvent *keyEvent)
|
bool QWasmCompositor::processKeyboard(int eventType, const EmscriptenKeyboardEvent *emKeyEvent)
|
||||||
{
|
{
|
||||||
Qt::Key qtKey;
|
Q_ASSERT(eventType == EMSCRIPTEN_EVENT_KEYDOWN || eventType == EMSCRIPTEN_EVENT_KEYUP);
|
||||||
QString keyText;
|
|
||||||
QEvent::Type keyType = QEvent::None;
|
|
||||||
switch (eventType) {
|
|
||||||
case EMSCRIPTEN_EVENT_KEYPRESS:
|
|
||||||
case EMSCRIPTEN_EVENT_KEYDOWN: // down
|
|
||||||
keyType = QEvent::KeyPress;
|
|
||||||
qtKey = m_eventTranslator->getKey(keyEvent);
|
|
||||||
keyText = m_eventTranslator->getKeyText(keyEvent, qtKey);
|
|
||||||
break;
|
|
||||||
case EMSCRIPTEN_EVENT_KEYUP: // up
|
|
||||||
keyType = QEvent::KeyRelease;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (keyType == QEvent::None)
|
auto translatedEvent = m_eventTranslator->translateKeyEvent(eventType, emKeyEvent);
|
||||||
return 0;
|
|
||||||
|
|
||||||
QFlags<Qt::KeyboardModifier> modifiers = KeyboardModifier::getForEvent(*keyEvent);
|
const QFlags<Qt::KeyboardModifier> modifiers = KeyboardModifier::getForEvent(*emKeyEvent);
|
||||||
|
|
||||||
// Clipboard fallback path: cut/copy/paste are handled by clipboard event
|
// Clipboard path: cut/copy/paste are handled by clipboard event or direct clipboard access.
|
||||||
// handlers if direct clipboard access is not available.
|
if (translatedEvent.type == QEvent::KeyPress && modifiers.testFlag(Qt::ControlModifier)
|
||||||
if (!QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi && modifiers & Qt::ControlModifier &&
|
&& (translatedEvent.key == Qt::Key_X || translatedEvent.key == Qt::Key_V
|
||||||
(qtKey == Qt::Key_X || qtKey == Qt::Key_C || qtKey == Qt::Key_V)) {
|
|| translatedEvent.key == Qt::Key_C)) {
|
||||||
if (qtKey == Qt::Key_V) {
|
QWasmIntegration::get()->getWasmClipboard()->isPaste = translatedEvent.key == Qt::Key_V;
|
||||||
QWasmIntegration::get()->getWasmClipboard()->isPaste = true;
|
return false; // continue on to event
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool accepted = false;
|
if (translatedEvent.text.isEmpty())
|
||||||
|
translatedEvent.text = QString(emKeyEvent->key);
|
||||||
if (keyType == QEvent::KeyPress &&
|
if (translatedEvent.text.size() > 1)
|
||||||
modifiers.testFlag(Qt::ControlModifier)
|
translatedEvent.text.clear();
|
||||||
&& qtKey == Qt::Key_V) {
|
return QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>(
|
||||||
QWasmIntegration::get()->getWasmClipboard()->isPaste = true;
|
0, translatedEvent.type, translatedEvent.key, modifiers, translatedEvent.text);
|
||||||
accepted = false; // continue on to event
|
|
||||||
} else {
|
|
||||||
if (keyText.isEmpty())
|
|
||||||
keyText = QString(keyEvent->key);
|
|
||||||
if (keyText.size() > 1)
|
|
||||||
keyText.clear();
|
|
||||||
accepted = QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>(
|
|
||||||
0, keyType, qtKey, modifiers, keyText);
|
|
||||||
}
|
|
||||||
if (keyType == QEvent::KeyPress &&
|
|
||||||
modifiers.testFlag(Qt::ControlModifier)
|
|
||||||
&& qtKey == Qt::Key_C) {
|
|
||||||
QWasmIntegration::get()->getWasmClipboard()->isPaste = false;
|
|
||||||
accepted = false; // continue on to event
|
|
||||||
}
|
|
||||||
|
|
||||||
return accepted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QWasmCompositor::processWheel(int eventType, const EmscriptenWheelEvent *wheelEvent)
|
bool QWasmCompositor::processWheel(int eventType, const EmscriptenWheelEvent *wheelEvent)
|
||||||
|
@ -304,34 +304,57 @@ QCursor QWasmEventTranslator::cursorForMode(QWasmCompositor::ResizeMode m)
|
|||||||
return Qt::ArrowCursor;
|
return Qt::ArrowCursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QWasmEventTranslator::getKeyText(const EmscriptenKeyboardEvent *keyEvent, Qt::Key qtKey)
|
QWasmEventTranslator::TranslatedEvent
|
||||||
|
QWasmEventTranslator::translateKeyEvent(int emEventType, const EmscriptenKeyboardEvent *keyEvent)
|
||||||
{
|
{
|
||||||
if (m_emDeadKey != Qt::Key_unknown) {
|
TranslatedEvent ret;
|
||||||
const Qt::Key translatedKey = translateBaseKeyUsingDeadKey(qtKey, m_emDeadKey);
|
switch (emEventType) {
|
||||||
|
case EMSCRIPTEN_EVENT_KEYDOWN:
|
||||||
|
ret.type = QEvent::KeyPress;
|
||||||
|
break;
|
||||||
|
case EMSCRIPTEN_EVENT_KEYUP:
|
||||||
|
ret.type = QEvent::KeyRelease;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Should not be reached - do not call with this event type.
|
||||||
|
Q_ASSERT(false);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
ret.key = translateEmscriptKey(keyEvent);
|
||||||
|
|
||||||
|
if (isDeadKeyEvent(keyEvent) || ret.key == Qt::Key_AltGr) {
|
||||||
|
if (keyEvent->shiftKey && ret.key == Qt::Key_QuoteLeft)
|
||||||
|
ret.key = Qt::Key_AsciiTilde;
|
||||||
|
m_emDeadKey = ret.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_emDeadKey != Qt::Key_unknown
|
||||||
|
&& (m_keyModifiedByDeadKeyOnPress == Qt::Key_unknown
|
||||||
|
|| ret.key == m_keyModifiedByDeadKeyOnPress)) {
|
||||||
|
const Qt::Key baseKey = ret.key;
|
||||||
|
const Qt::Key translatedKey = translateBaseKeyUsingDeadKey(baseKey, m_emDeadKey);
|
||||||
if (translatedKey != Qt::Key_unknown)
|
if (translatedKey != Qt::Key_unknown)
|
||||||
qtKey = translatedKey;
|
ret.key = translatedKey;
|
||||||
|
|
||||||
if (auto text = keyEvent->shiftKey
|
if (auto text = keyEvent->shiftKey
|
||||||
? findKeyTextByKeyId(WebToQtKeyCodeMappingsWithShift, qtKey)
|
? findKeyTextByKeyId(WebToQtKeyCodeMappingsWithShift, ret.key)
|
||||||
: findKeyTextByKeyId(WebToQtKeyCodeMappings, qtKey)) {
|
: findKeyTextByKeyId(WebToQtKeyCodeMappings, ret.key)) {
|
||||||
m_emDeadKey = Qt::Key_unknown;
|
if (ret.type == QEvent::KeyPress) {
|
||||||
return *text;
|
Q_ASSERT(m_keyModifiedByDeadKeyOnPress == Qt::Key_unknown);
|
||||||
|
m_keyModifiedByDeadKeyOnPress = baseKey;
|
||||||
|
} else {
|
||||||
|
Q_ASSERT(ret.type == QEvent::KeyRelease);
|
||||||
|
Q_ASSERT(m_keyModifiedByDeadKeyOnPress == baseKey);
|
||||||
|
m_keyModifiedByDeadKeyOnPress = Qt::Key_unknown;
|
||||||
|
m_emDeadKey = Qt::Key_unknown;
|
||||||
|
}
|
||||||
|
ret.text = *text;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QString::fromUtf8(keyEvent->key);
|
ret.text = QString::fromUtf8(keyEvent->key);
|
||||||
}
|
return ret;
|
||||||
|
|
||||||
Qt::Key QWasmEventTranslator::getKey(const EmscriptenKeyboardEvent *keyEvent)
|
|
||||||
{
|
|
||||||
Qt::Key qtKey = translateEmscriptKey(keyEvent);
|
|
||||||
|
|
||||||
if (isDeadKeyEvent(keyEvent) || qtKey == Qt::Key_AltGr) {
|
|
||||||
if (keyEvent->shiftKey && qtKey == Qt::Key_QuoteLeft)
|
|
||||||
qtKey = Qt::Key_AsciiTilde;
|
|
||||||
m_emDeadKey = qtKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
return qtKey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -24,19 +24,24 @@ class QWasmEventTranslator : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
struct TranslatedEvent
|
||||||
|
{
|
||||||
|
QEvent::Type type;
|
||||||
|
Qt::Key key;
|
||||||
|
QString text;
|
||||||
|
};
|
||||||
explicit QWasmEventTranslator();
|
explicit QWasmEventTranslator();
|
||||||
~QWasmEventTranslator();
|
~QWasmEventTranslator();
|
||||||
|
|
||||||
static QCursor cursorForMode(QWasmCompositor::ResizeMode mode);
|
static QCursor cursorForMode(QWasmCompositor::ResizeMode mode);
|
||||||
|
|
||||||
QString getKeyText(const EmscriptenKeyboardEvent *keyEvent, Qt::Key key);
|
TranslatedEvent translateKeyEvent(int emEventType, const EmscriptenKeyboardEvent *keyEvent);
|
||||||
Qt::Key getKey(const EmscriptenKeyboardEvent *keyEvent);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static quint64 getTimestamp();
|
static quint64 getTimestamp();
|
||||||
|
|
||||||
Qt::Key m_emDeadKey = Qt::Key_unknown;
|
Qt::Key m_emDeadKey = Qt::Key_unknown;
|
||||||
|
Qt::Key m_keyModifiedByDeadKeyOnPress = Qt::Key_unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user