Accessibility Linux: Act more like Gtk for key presses
Orca is extremely picky when it comes to key presses and modifiers. Sending ctrl as modifier for itself for example seems to break things. Also use the ATSPI modifier constants, weird as they are. Task-number: QTBUG-39361 Change-Id: Id809e0dd2a7d20a533bd783888ccbdf748becacc Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com>
This commit is contained in:
parent
5f6af9de48
commit
20144165c8
@ -47,6 +47,7 @@
|
|||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
|
|
||||||
#include "deviceeventcontroller_adaptor.h"
|
#include "deviceeventcontroller_adaptor.h"
|
||||||
|
#include "atspi/atspi-constants.h"
|
||||||
|
|
||||||
//#define KEYBOARD_DEBUG
|
//#define KEYBOARD_DEBUG
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
QSpiApplicationAdaptor::QSpiApplicationAdaptor(const QDBusConnection &connection, QObject *parent)
|
QSpiApplicationAdaptor::QSpiApplicationAdaptor(const QDBusConnection &connection, QObject *parent)
|
||||||
: QObject(parent), dbusConnection(connection)
|
: QObject(parent), dbusConnection(connection), inCapsLock(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,13 +108,14 @@ bool QSpiApplicationAdaptor::eventFilter(QObject *target, QEvent *event)
|
|||||||
de.id = keyEvent->nativeVirtualKey();
|
de.id = keyEvent->nativeVirtualKey();
|
||||||
de.hardwareCode = keyEvent->nativeScanCode();
|
de.hardwareCode = keyEvent->nativeScanCode();
|
||||||
|
|
||||||
de.modifiers = keyEvent->nativeModifiers();
|
|
||||||
de.timestamp = QDateTime::currentMSecsSinceEpoch();
|
de.timestamp = QDateTime::currentMSecsSinceEpoch();
|
||||||
|
|
||||||
if (keyEvent->key() == Qt::Key_Tab)
|
if (keyEvent->key() == Qt::Key_Tab)
|
||||||
de.text = QStringLiteral("Tab");
|
de.text = QStringLiteral("Tab");
|
||||||
else if (keyEvent->key() == Qt::Key_Backtab)
|
else if (keyEvent->key() == Qt::Key_Backtab)
|
||||||
de.text = QStringLiteral("Backtab");
|
de.text = QStringLiteral("Backtab");
|
||||||
|
else if (keyEvent->key() == Qt::Key_Control)
|
||||||
|
de.text = QStringLiteral("Control_L");
|
||||||
else if (keyEvent->key() == Qt::Key_Left)
|
else if (keyEvent->key() == Qt::Key_Left)
|
||||||
de.text = (keyEvent->modifiers() & Qt::KeypadModifier) ? QStringLiteral("KP_Left") : QStringLiteral("Left");
|
de.text = (keyEvent->modifiers() & Qt::KeypadModifier) ? QStringLiteral("KP_Left") : QStringLiteral("Left");
|
||||||
else if (keyEvent->key() == Qt::Key_Right)
|
else if (keyEvent->key() == Qt::Key_Right)
|
||||||
@ -142,9 +144,13 @@ bool QSpiApplicationAdaptor::eventFilter(QObject *target, QEvent *event)
|
|||||||
de.text = QStringLiteral("Escape");
|
de.text = QStringLiteral("Escape");
|
||||||
else if (keyEvent->key() == Qt::Key_Space)
|
else if (keyEvent->key() == Qt::Key_Space)
|
||||||
de.text = QStringLiteral("space");
|
de.text = QStringLiteral("space");
|
||||||
else if (keyEvent->key() == Qt::Key_CapsLock)
|
else if (keyEvent->key() == Qt::Key_CapsLock) {
|
||||||
de.text = QStringLiteral("Caps_Lock");
|
de.text = QStringLiteral("Caps_Lock");
|
||||||
else if (keyEvent->key() == Qt::Key_NumLock)
|
if (event->type() == QEvent::KeyPress)
|
||||||
|
inCapsLock = true;
|
||||||
|
else
|
||||||
|
inCapsLock = false;
|
||||||
|
} else if (keyEvent->key() == Qt::Key_NumLock)
|
||||||
de.text = QStringLiteral("Num_Lock");
|
de.text = QStringLiteral("Num_Lock");
|
||||||
else if (keyEvent->key() == Qt::Key_Insert)
|
else if (keyEvent->key() == Qt::Key_Insert)
|
||||||
de.text = QStringLiteral("Insert");
|
de.text = QStringLiteral("Insert");
|
||||||
@ -155,18 +161,28 @@ bool QSpiApplicationAdaptor::eventFilter(QObject *target, QEvent *event)
|
|||||||
// Long term the spec will hopefully change to just use keycodes.
|
// Long term the spec will hopefully change to just use keycodes.
|
||||||
de.isText = !de.text.isEmpty();
|
de.isText = !de.text.isEmpty();
|
||||||
|
|
||||||
|
de.modifiers = 0;
|
||||||
|
if (!inCapsLock && keyEvent->modifiers() & Qt::ShiftModifier)
|
||||||
|
de.modifiers |= 1 << ATSPI_MODIFIER_SHIFT;
|
||||||
|
if (inCapsLock && (keyEvent->key() != Qt::Key_CapsLock))
|
||||||
|
de.modifiers |= 1 << ATSPI_MODIFIER_SHIFTLOCK;
|
||||||
|
if ((keyEvent->modifiers() & Qt::ControlModifier) && (keyEvent->key() != Qt::Key_Control))
|
||||||
|
de.modifiers |= 1 << ATSPI_MODIFIER_CONTROL;
|
||||||
|
if ((keyEvent->modifiers() & Qt::AltModifier) && (keyEvent->key() != Qt::Key_Alt))
|
||||||
|
de.modifiers |= 1 << ATSPI_MODIFIER_ALT;
|
||||||
|
|
||||||
#ifdef KEYBOARD_DEBUG
|
#ifdef KEYBOARD_DEBUG
|
||||||
qDebug() << QStringLiteral("Key event text: ") << event->type() << de.isText << QStringLiteral(" ") << de.text
|
qDebug() << QStringLiteral("Key event text:") << event->type() << de.text
|
||||||
<< QStringLiteral(" hardware code: ") << de.hardwareCode
|
<< QStringLiteral("native virtual key:") << de.id
|
||||||
<< QStringLiteral(" native sc: ") << keyEvent->nativeScanCode()
|
<< QStringLiteral("hardware code/scancode:") << de.hardwareCode
|
||||||
<< QStringLiteral(" native mod: ") << keyEvent->nativeModifiers()
|
<< QStringLiteral("modifiers:") << de.modifiers
|
||||||
<< QStringLiteral("native virt: ") << keyEvent->nativeVirtualKey();
|
<< QStringLiteral("text:") << de.text;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QDBusMessage m = QDBusMessage::createMethodCall(QStringLiteral("org.a11y.atspi.Registry"),
|
QDBusMessage m = QDBusMessage::createMethodCall(QStringLiteral("org.a11y.atspi.Registry"),
|
||||||
QStringLiteral("/org/a11y/atspi/registry/deviceeventcontroller"),
|
QStringLiteral("/org/a11y/atspi/registry/deviceeventcontroller"),
|
||||||
QStringLiteral("org.a11y.atspi.DeviceEventController"), QStringLiteral("NotifyListenersSync"));
|
QStringLiteral("org.a11y.atspi.DeviceEventController"), QStringLiteral("NotifyListenersSync"));
|
||||||
m.setArguments(QVariantList() <<QVariant::fromValue(de));
|
m.setArguments(QVariantList() << QVariant::fromValue(de));
|
||||||
|
|
||||||
// FIXME: this is critical, the timeout should probably be pretty low to allow normal processing
|
// FIXME: this is critical, the timeout should probably be pretty low to allow normal processing
|
||||||
int timeout = 100;
|
int timeout = 100;
|
||||||
@ -175,9 +191,6 @@ bool QSpiApplicationAdaptor::eventFilter(QObject *target, QEvent *event)
|
|||||||
if (sent) {
|
if (sent) {
|
||||||
//queue the event and send it after callback
|
//queue the event and send it after callback
|
||||||
keyEvents.enqueue(QPair<QPointer<QObject>, QKeyEvent*> (QPointer<QObject>(target), copyKeyEvent(keyEvent)));
|
keyEvents.enqueue(QPair<QPointer<QObject>, QKeyEvent*> (QPointer<QObject>(target), copyKeyEvent(keyEvent)));
|
||||||
#ifdef KEYBOARD_DEBUG
|
|
||||||
qDebug() << QStringLiteral("Sent key: ") << de.text;
|
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,7 @@ private:
|
|||||||
|
|
||||||
QQueue<QPair<QPointer<QObject>, QKeyEvent*> > keyEvents;
|
QQueue<QPair<QPointer<QObject>, QKeyEvent*> > keyEvents;
|
||||||
QDBusConnection dbusConnection;
|
QDBusConnection dbusConnection;
|
||||||
|
bool inCapsLock;
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user