vcl/inc/qt5/QtAccessibleEventListener.hxx | 3
vcl/qt5/QtAccessibleEventListener.cxx | 115 +++++++++++++++++++++++++++++-
2 files changed, 116 insertions(+), 2 deletions(-)
New commits:
commit 8c3e8af0e60865ec6d38e2117efdb4ed2f10a20c
Author: Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Fri Jun 17 17:29:19 2022 +0200
Commit: Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Fri Jun 17 19:30:29 2022 +0200
qt a11y: Forward STATE_CHANGED event as such
Handle `AccessibleEventId::STATE_CHANGED` by
sending a corresponding `QAccessibleStateChangeEvent`.
The previous way of sending a `QAccessible::ForegroundChanged`
event looked rather arbitrary and had no effect in practice,
since that type of event is currently ignored in Qt's AT-SPI adapter
anyway.
At this point in time, the Qt library doesn't forward
changes of all states to the AT-SPI layer. Most notably,
it ignores changes to the focused state.
(Qt itself uses events of type `QAccessible::Focus`
instead of `QAccessibleStateChangeEvent` with the `focused`
state set to notify about focus changes, but that's not exactly the
same, and e.g. causes Orca to ignore some focus changes).
I have submitted a change to Qt to implement
forwarding of `QAccessibleStateChangeEvent`s for the
focused state to the AT-SPI layer, currently awaiting
review. [1]
With that Qt change in place, Orca still ignored these
events in LibreOffice message dialogs, since those
use a11y role `ALERT`, which wasn't previously considered
when trying to retrieve a potential dialog that an
a11y object belonged to.
The corresponding Orca merge request [2] has just been merged.
With these two in place, Orca now announces the focused
button when switching focus using the tab key
e.g. in the "Save document?" dialog when using the qt6 VCL plugin.
(Most other things in the LO UI are still usually not announced.)
For some reason, forwarding changes to state `AccessibleStateType::ACTIVE`
resulted in Orca becoming unresponsive (stop talking) quite quickly.
That needs further analysis, so that state change isn't forwarded
to Qt for now.
[1] https://codereview.qt-project.org/c/qt/qtbase/+/416510
[2] https://gitlab.gnome.org/GNOME/orca/-/merge_requests/127
Change-Id: I81c9a0f5ec8c74f95943d3073bba5b304f995d31
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136057
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>
diff --git a/vcl/inc/qt5/QtAccessibleEventListener.hxx
b/vcl/inc/qt5/QtAccessibleEventListener.hxx
index a73f6d31f2f8..1103dc9da598 100644
--- a/vcl/inc/qt5/QtAccessibleEventListener.hxx
+++ b/vcl/inc/qt5/QtAccessibleEventListener.hxx
@@ -33,6 +33,9 @@ public:
private:
css::uno::Reference<css::accessibility::XAccessible> m_xAccessible;
QtAccessibleWidget* m_pAccessibleWidget;
+
+ static void HandleStateChangedEvent(QAccessibleInterface*
pQAccessibleInterface,
+ const
css::accessibility::AccessibleEventObject& rEvent);
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/QtAccessibleEventListener.cxx
b/vcl/qt5/QtAccessibleEventListener.cxx
index 515584351c74..ee9acc651599 100644
--- a/vcl/qt5/QtAccessibleEventListener.cxx
+++ b/vcl/qt5/QtAccessibleEventListener.cxx
@@ -23,6 +23,7 @@
#include <sal/log.hxx>
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
#include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
#include <com/sun/star/accessibility/TextSegment.hpp>
@@ -41,6 +42,117 @@ QtAccessibleEventListener::QtAccessibleEventListener(const
Reference<XAccessible
{
}
+void QtAccessibleEventListener::HandleStateChangedEvent(
+ QAccessibleInterface* pQAccessibleInterface,
+ const css::accessibility::AccessibleEventObject& rEvent)
+{
+ QAccessible::State aState;
+
+ short nState = 0;
+ rEvent.NewValue >>= nState;
+ // States in 'QAccessibleStateChangeEvent' indicate what states have
changed, so if e.g.
+ // an object loses focus (not just if it gains it), 'focus' state needs to
be set to 'true',
+ // so retrieve the old/previous value from the event if necessary.
+ if (nState == AccessibleStateType::INVALID)
+ rEvent.OldValue >>= nState;
+
+ switch (nState)
+ {
+ case AccessibleStateType::ACTIVE:
+ // ignore for now, since it somehow causes Orca to become
unresponsive quite quickly
+ // TODO: analyze further and fix root cause
+ /*
+ aState.active = true;
+ break;
+ */
+ return;
+ case AccessibleStateType::BUSY:
+ aState.busy = true;
+ break;
+ case AccessibleStateType::CHECKED:
+ aState.checked = true;
+ break;
+ case AccessibleStateType::COLLAPSE:
+ aState.collapsed = true;
+ break;
+ case AccessibleStateType::DEFAULT:
+ aState.defaultButton = true;
+ break;
+ case AccessibleStateType::ENABLED:
+ aState.disabled = true;
+ break;
+ case AccessibleStateType::EDITABLE:
+ aState.editable = true;
+ break;
+ case AccessibleStateType::EXPANDABLE:
+ aState.expandable = true;
+ break;
+ case AccessibleStateType::EXPANDED:
+ aState.expanded = true;
+ break;
+ case AccessibleStateType::FOCUSABLE:
+ aState.focusable = true;
+ break;
+ case AccessibleStateType::FOCUSED:
+ aState.focused = true;
+ break;
+ case AccessibleStateType::INVALID:
+ aState.invalid = true;
+ break;
+ case AccessibleStateType::VISIBLE:
+ aState.invisible = true;
+ break;
+ case AccessibleStateType::MODAL:
+ aState.modal = true;
+ break;
+ case AccessibleStateType::MOVEABLE:
+ aState.movable = true;
+ break;
+ case AccessibleStateType::MULTI_LINE:
+ // comment in Qt's qaccessible.h has this:
+ // "// quint64 singleLine : 1; // we have multi line, this is
redundant."
+ case AccessibleStateType::SINGLE_LINE:
+ aState.multiLine = true;
+ break;
+ case AccessibleStateType::MULTI_SELECTABLE:
+ aState.multiSelectable = true;
+ break;
+ case AccessibleStateType::OFFSCREEN:
+ aState.offscreen = true;
+ break;
+ case AccessibleStateType::PRESSED:
+ aState.pressed = true;
+ break;
+ case AccessibleStateType::RESIZABLE:
+ aState.sizeable = true;
+ break;
+ case AccessibleStateType::SELECTABLE:
+ aState.selectable = true;
+ break;
+ case AccessibleStateType::SELECTED:
+ aState.selected = true;
+ break;
+ // These don't seem to have a matching Qt equivalent
+ case AccessibleStateType::ARMED:
+ case AccessibleStateType::DEFUNC:
+ case AccessibleStateType::HORIZONTAL:
+ case AccessibleStateType::ICONIFIED:
+ case AccessibleStateType::INDETERMINATE:
+ case AccessibleStateType::MANAGES_DESCENDANTS:
+ case AccessibleStateType::OPAQUE:
+ case AccessibleStateType::SENSITIVE:
+ case AccessibleStateType::SHOWING:
+ case AccessibleStateType::STALE:
+ case AccessibleStateType::TRANSIENT:
+ case AccessibleStateType::VERTICAL:
+ default:
+ return;
+ }
+
+ QAccessible::updateAccessibility(
+ new QAccessibleStateChangeEvent(pQAccessibleInterface, aState));
+}
+
void QtAccessibleEventListener::notifyEvent(const
css::accessibility::AccessibleEventObject& aEvent)
{
QAccessibleInterface* pQAccessibleInterface = m_pAccessibleWidget;
@@ -211,8 +323,7 @@ void QtAccessibleEventListener::notifyEvent(const
css::accessibility::Accessible
new QAccessibleEvent(pQAccessibleInterface,
QAccessible::LocationChanged));
return;
case AccessibleEventId::STATE_CHANGED:
- QAccessible::updateAccessibility(
- new QAccessibleEvent(pQAccessibleInterface,
QAccessible::ForegroundChanged));
+ HandleStateChangedEvent(pQAccessibleInterface, aEvent);
return;
case AccessibleEventId::VALUE_CHANGED:
{