From 4d27d2c5f9d83112b6db9b6234e2ae617ffced22 Mon Sep 17 00:00:00 2001 From: Michael Weghorn Date: Thu, 17 Aug 2023 11:51:11 +0100 Subject: tdf#141101 tdf#156561 a11y: Handle a11y child events in win parent `VCLXAccessibleComponent::ProcessWindowChildEvent` was only processing `WindowShow` and `WindowHide` events when the `vcl::Window::GetAccessibleParent()` for the window sent in the event would return the window that the `VCLXAccessibleComponent` refers to. This generally seems reasonable, but when the child events are sent for the corresponding window, the window's hierarchy is iterated over using `vcl::Window::GetParent()`, so if the accessible window is not in that hierarchy, no window would take care of the child events. (Note e.g. how `Window::GetParent` uses `mpWindowImpl->mpRealParent` while `Window::getAccessibleParentWindow` uses `mpWindowImpl->mpParent` and has some special handling.) Due to the way that `ImplDockingWindowWrapper::ImplPreparePopupMode` reparents the windows, this is at least the case for the auto filter popup in Calc and the font color popup in Writer's "Character" dialog, so the `VclEventId::WindowShow` event would not be forwarded to the a11y layer as an `AccessibleEventId::CHILD` event, and thus no listener would be registered for the children. As a result, the NVDA screen reader would not announce these objects when they receive focus. Make sure that the child event gets handled by making `VCLXAccessibleComponent::GetChildAccessible` also take into account the `vcl::Window::GetParent()`. This addresses one of the underlying issues why the Calc autofilter was not announced by NVDA before commit dc0706cabfe39ddb6ea23d60ccfb756f2b9e6efb Author: Michael Weghorn Date: Wed Mar 15 17:00:27 2023 +0100 tdf#140762 tdf#152671 Make dock win visible before showing popup It might make sense to reconsider the way of reparenting in `ImplDockingWindowWrapper` and general a11y parent handling at some point, but that will need further analysis and would presumably require more fundamental changes elsewhere, too. Change-Id: I83cf5732bfc9d4886e4f7fa75d4ff462e4d4af6d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155799 Tested-by: Jenkins Reviewed-by: Michael Weghorn --- toolkit/source/awt/vclxaccessiblecomponent.cxx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'toolkit') diff --git a/toolkit/source/awt/vclxaccessiblecomponent.cxx b/toolkit/source/awt/vclxaccessiblecomponent.cxx index 2d290e1ad5e1..2c353fd801eb 100644 --- a/toolkit/source/awt/vclxaccessiblecomponent.cxx +++ b/toolkit/source/awt/vclxaccessiblecomponent.cxx @@ -133,7 +133,13 @@ uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::GetChildAc // MT: Change this later, normally a show/hide event shouldn't have the vcl::Window* in pData. vcl::Window* pChildWindow = static_cast(rVclWindowEvent.GetData()); - if( pChildWindow && GetWindow() == pChildWindow->GetAccessibleParentWindow() ) + // tdf#141101/tdf#156561 Handle the event if this is either the a11y parent or the + // vcl::Window parent, since child events are sent for the vcl::Window hierarchy + // (s. Window::CallEventListeners) and e.g. DockingManager does manual partial reparenting + // that would cause child events to not be forwarded to the a11y level when + // not taking GetParent() into account here + if (pChildWindow && (GetWindow() == pChildWindow->GetAccessibleParentWindow() + || GetWindow() == pChildWindow->GetParent())) return pChildWindow->GetAccessible( rVclWindowEvent.GetId() == VclEventId::WindowShow ); else return uno::Reference< accessibility::XAccessible > (); -- cgit