accessibility/inc/standard/accessiblemenubasecomponent.hxx | 1 accessibility/source/standard/accessiblemenubasecomponent.cxx | 18 ++++++++++ include/vcl/vclevent.hxx | 1 offapi/com/sun/star/accessibility/AccessibleEventId.idl | 5 ++ toolkit/source/awt/vclxmenu.cxx | 1 vcl/source/window/menu.cxx | 7 +++ 6 files changed, 33 insertions(+)
New commits: commit 3121642fb1927c9cb1aa35c6b3e6afa818459117 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Thu Jul 27 11:17:42 2023 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Thu Jul 27 16:58:35 2023 +0200 a11y: Clarify AccessibleEventId::ROLE_CHANGED doc Mention that old and new value don't need to be set in this kind of event and how the new role can be retrieved. Change-Id: Iefde16a91b71af87feccb5ec2e6a32e682d60b4c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154987 Reviewed-by: Colomban Wendling <cwendl...@hypra.fr> Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/offapi/com/sun/star/accessibility/AccessibleEventId.idl b/offapi/com/sun/star/accessibility/AccessibleEventId.idl index 375d04085204..2c30cf8a6cd6 100644 --- a/offapi/com/sun/star/accessibility/AccessibleEventId.idl +++ b/offapi/com/sun/star/accessibility/AccessibleEventId.idl @@ -434,6 +434,11 @@ constants AccessibleEventId /** Constant used to indicate that the role of an accessible object has changed. + <p>AccessibleEventObject::OldValue and + AccessibleEventObject::NewValue are empty. + The new role can be retrieved via + XAccessibleContext::getAccessibleRole.</p> + @since LibreOffice 4.3 */ const short ROLE_CHANGED =41; commit ce0a48a1eb16d6309dba175e032a52eb5ede2542 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Wed Jul 26 18:26:48 2023 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Thu Jul 27 16:58:22 2023 +0200 tdf#155625 a11y: Notify about menu item role change Send a `AccessibleEventId::ROLE_CHANGED` event when the accessible role of a menu item changes (s. how `VCLXAccessibleMenuItem::getAccessibleRole` takes into account `MenuItemBits::RADIOCHECK` and `MenuItemBits::CHECKABLE` to determine the accessible role for the underlying menu entry). This fixes the issue of obsolete values for roles being used, which was uncovered by the upcoming Change-Id I1a047864ce8dc1f1bc3056ad00159f7fd5e5b7d3 ("vcl gtk3: Introduce AT-SPI2 tests for the GTK3 accessibility layer"). With this in place, the workaround for tdf#155625 in the upcoming gtk3/AT-SPI tests is no longer necessary and `make CppunitTest_vcl_gtk3_a11y` with https://gerrit.libreoffice.org/c/core/+/153069 patch set 11 still passes after dropping the workaround: diff --git a/vcl/qa/cppunit/a11y/atspi2/atspi2.cxx b/vcl/qa/cppunit/a11y/atspi2/atspi2.cxx index bbcd263fee0c..762401181bf4 100644 --- a/vcl/qa/cppunit/a11y/atspi2/atspi2.cxx +++ b/vcl/qa/cppunit/a11y/atspi2/atspi2.cxx @@ -264,9 +264,6 @@ void Atspi2TestTree::compareObjects(uno::Reference<accessibility::XAccessible> x * be represented with a round trip. */ const auto nLORole = mapToAtspiRole(xLOContext->getAccessibleRole()); auto nAtspiRole = pAtspiAccessible.getRole(); - // FIXME: workaround for https://bugs.documentfoundation.org/show_bug.cgi?id=155625 - if (nLORole == ATSPI_ROLE_CHECK_MENU_ITEM && nAtspiRole == ATSPI_ROLE_MENU_ITEM) - nAtspiRole = nLORole; CPPUNIT_ASSERT_EQUAL(nLORole, nAtspiRole); /* name (no need to worry about debugging suffixes as AccessibilityTools::nameEquals does, as * that will also be part of the name sent to ATSPI) */ Change-Id: I0d88a7eda592f5ee9abf368ce1d5feb6611b9971 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154947 Reviewed-by: Colomban Wendling <cwendl...@hypra.fr> Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/accessibility/inc/standard/accessiblemenubasecomponent.hxx b/accessibility/inc/standard/accessiblemenubasecomponent.hxx index e56120f7fb38..6dd8ab8eb760 100644 --- a/accessibility/inc/standard/accessiblemenubasecomponent.hxx +++ b/accessibility/inc/standard/accessiblemenubasecomponent.hxx @@ -73,6 +73,7 @@ protected: void UpdateSelected( sal_Int32 i, bool bSelected ); void UpdateChecked( sal_Int32 i, bool bChecked ); void UpdateAccessibleName( sal_Int32 i ); + void UpdateItemRole(sal_Int32 i); void UpdateItemText( sal_Int32 i ); sal_Int64 GetChildCount() const; diff --git a/accessibility/source/standard/accessiblemenubasecomponent.cxx b/accessibility/source/standard/accessiblemenubasecomponent.cxx index e1ab9e326ebf..b66b019ca1b1 100644 --- a/accessibility/source/standard/accessiblemenubasecomponent.cxx +++ b/accessibility/source/standard/accessiblemenubasecomponent.cxx @@ -285,6 +285,19 @@ void OAccessibleMenuBaseComponent::UpdateAccessibleName( sal_Int32 i ) } } +void OAccessibleMenuBaseComponent::UpdateItemRole(sal_Int32 i) +{ + if (i < 0 || o3tl::make_unsigned(i) >= m_aAccessibleChildren.size()) + return; + + Reference<XAccessible> xChild(m_aAccessibleChildren[i]); + if (!xChild.is()) + return; + + OAccessibleMenuItemComponent* pComp = static_cast<OAccessibleMenuItemComponent*>(xChild.get()); + assert(pComp); + pComp->NotifyAccessibleEvent(AccessibleEventId::ROLE_CHANGED, Any(), Any()); +} void OAccessibleMenuBaseComponent::UpdateItemText( sal_Int32 i ) { @@ -586,6 +599,11 @@ void OAccessibleMenuBaseComponent::ProcessMenuEvent( const VclMenuEvent& rVclMen UpdateAccessibleName( nItemPos ); } break; + case VclEventId::MenuItemRoleChanged: + { + UpdateItemRole(nItemPos); + } + break; case VclEventId::MenuItemTextChanged: { UpdateAccessibleName( nItemPos ); diff --git a/include/vcl/vclevent.hxx b/include/vcl/vclevent.hxx index a0a11c6a0870..c60e89d8364e 100644 --- a/include/vcl/vclevent.hxx +++ b/include/vcl/vclevent.hxx @@ -77,6 +77,7 @@ enum class VclEventId MenuHighlight, MenuInsertItem, MenuItemChecked, + MenuItemRoleChanged, MenuItemTextChanged, MenuItemUnchecked, MenuRemoveItem, diff --git a/toolkit/source/awt/vclxmenu.cxx b/toolkit/source/awt/vclxmenu.cxx index f8c662ae2480..86c3e87c5b6a 100644 --- a/toolkit/source/awt/vclxmenu.cxx +++ b/toolkit/source/awt/vclxmenu.cxx @@ -152,6 +152,7 @@ IMPL_LINK( VCLXMenu, MenuEventListener, VclMenuEvent&, rMenuEvent, void ) case VclEventId::MenuSubmenuChanged: case VclEventId::MenuDehighlight: case VclEventId::MenuDisable: + case VclEventId::MenuItemRoleChanged: case VclEventId::MenuItemTextChanged: case VclEventId::MenuItemChecked: case VclEventId::MenuItemUnchecked: diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx index 0135a29f4273..284a54a0a3a7 100644 --- a/vcl/source/window/menu.cxx +++ b/vcl/source/window/menu.cxx @@ -675,11 +675,18 @@ void Menu::SetItemBits( sal_uInt16 nItemId, MenuItemBits nBits ) if (pData && (pData->nBits != nBits)) { + // these two menu item bits are relevant for (accessible) role + const MenuItemBits nRoleMask = MenuItemBits::CHECKABLE | MenuItemBits::RADIOCHECK; + const bool bRoleBitsChanged = (pData->nBits & nRoleMask) != (nBits & nRoleMask); + pData->nBits = nBits; // update native menu if (ImplGetSalMenu()) ImplGetSalMenu()->SetItemBits(nPos, nBits); + + if (bRoleBitsChanged) + ImplCallEventListeners(VclEventId::MenuItemRoleChanged, nPos); } }