vcl/qt5/QtAccessibleWidget.cxx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
New commits: commit dd58b893f0734916919b14dcfc9941bb9dc3575b Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Tue Oct 1 15:24:25 2024 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Tue Oct 1 19:54:39 2024 +0200 tdf#160837 qt a11y: Don't report window role for non-top-level Quoting from offapi/com/sun/star/accessibility/AccessibleRole.idl, AccessibleRole::Frame is for: > A top level window with a title bar, border, menu bar, etc. > It is often used as the primary window for an application. However, the FRAME role also gets used for frames that are not actually top-levels at least with the Qt-based VCL plugins, where there is an object of role FRAME as a child of the actual top-level for e.g. the Writer main window. (The actual top-level is a QtMainWindow.) That frame contains the window content starting right below the (native) menu bar. Mapping the AccessibleRole::FRAME a11y role to the Qt equivalent QAccessible::Window would result in window-relative positions reported via AT-SPI to be relative to that frame, instead of the actual top-level, s. the implementation in qtbase's AtSpiAdaptor::translateFromScreenCoordinates [1] which calculates the relative position to the first top-level in its a11y hierarchy. This resulted in Accerciser's highlighting of the currently selected object to be too far up, as the "window-relative position" was missing the menu bar height in the y coordinate when window-relative positions are used, which is the case on Wayland, s.a. the commit message of commit a499874d9c0685d79b629b4bb246394b6b15691a Author: Michael Weghorn <m.wegh...@posteo.de> Date: Thu Sep 26 18:22:12 2024 +0200 tdf#160837 qt: Rely on toolkit for frame positions, drop menubar hack for more background. To fix this, prevent reporting an invalid top-level window role for frames that are not actually top-levels: When mapping AccessibleRole::FRAME to a corresponding Qt a11y role, take into account whether the frame still has another (real) top-level window as a parent. This makes the highlighted area in Accerciser become correct when using LO with the qt6 VCL plugin and Accerciser with ACCERCISER_WINDOW_MANAGER=kwin in a KDE Plasma Wayland session. The same would generally make sense for AccessibleRole::DIALOG. However, there that would currently result in the additional semantics of this being a dialog (not another kind of top-level window) getting lost when doing so. As dialogs usually don't have a separate menu bar, at least the incorrect reporting of window-relative positions is less relevant. Leave dialog unchanged for now, maybe reconsider later as needed. Ultimately, using native Qt widgets for dialogs (see tdf#130857) should presumably fix the underlying problem of the extra frame on VCL side being used altogether. [1] https://code.qt.io/cgit/qt/qtbase.git/tree/src/gui/accessible/linux/atspiadaptor.cpp?id=da4a6cf78ff42a4f69c2775997ff174ef647f3f3#n2401 Change-Id: I5ae066bd996f042b370b067a30213d3a1045480e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174350 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> Tested-by: Jenkins diff --git a/vcl/qt5/QtAccessibleWidget.cxx b/vcl/qt5/QtAccessibleWidget.cxx index fc2846fc34f3..819e1d26228c 100644 --- a/vcl/qt5/QtAccessibleWidget.cxx +++ b/vcl/qt5/QtAccessibleWidget.cxx @@ -431,7 +431,16 @@ QAccessible::Role QtAccessibleWidget::role() const return QAccessible::Footer; case AccessibleRole::FOOTNOTE: return QAccessible::Note; - case AccessibleRole::FRAME: // top-level window with title bar + case AccessibleRole::FRAME: + // report Pane instead of Window role for a frame that's not actually + // an accessible frame (top-level window with title bar) itself, + // but a child of the real top-level + if (QAccessibleInterface* pParent = parent()) + { + const QAccessible::Role eParentRole = pParent->role(); + if (eParentRole == QAccessible::Window || eParentRole == QAccessible::Dialog) + return QAccessible::Pane; + } return QAccessible::Window; case AccessibleRole::GLASS_PANE: return QAccessible::UserRole;