diff options
Diffstat (limited to 'src/core/browser_accessibility_qt.cpp')
-rw-r--r-- | src/core/browser_accessibility_qt.cpp | 153 |
1 files changed, 79 insertions, 74 deletions
diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp index 2ac57c44e..de3347df3 100644 --- a/src/core/browser_accessibility_qt.cpp +++ b/src/core/browser_accessibility_qt.cpp @@ -1,57 +1,19 @@ -/**************************************************************************** -** -** Copyright (C) 2022 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE.Chromium file. #include "browser_accessibility_qt.h" +#include "browser_accessibility_manager_qt.h" +#include "qtwebenginecoreglobal_p.h" +#include "type_conversion.h" #if QT_CONFIG(accessibility) - #include "content/browser/accessibility/browser_accessibility.h" #include "ui/accessibility/ax_enums.mojom.h" -#include "browser_accessibility_manager_qt.h" -#include "qtwebenginecoreglobal_p.h" -#include "type_conversion.h" - #include <QtGui/qaccessible.h> namespace QtWebEngineCore { @@ -64,10 +26,9 @@ public: BrowserAccessibilityQt(content::BrowserAccessibilityManager *manager, ui::AXNode *node); ~BrowserAccessibilityQt(); - QtWebEngineCore::BrowserAccessibilityInterface *interface() const { return m_interface; } + bool isReady() const; -private: - QtWebEngineCore::BrowserAccessibilityInterface *m_interface = nullptr; + QtWebEngineCore::BrowserAccessibilityInterface *interface = nullptr; }; class BrowserAccessibilityInterface @@ -80,6 +41,7 @@ class BrowserAccessibilityInterface { public: BrowserAccessibilityInterface(BrowserAccessibilityQt *chromiumInterface); + ~BrowserAccessibilityInterface() override; void destroy(); @@ -165,35 +127,51 @@ public: void modelChange(QAccessibleTableModelChangeEvent *event) override; private: + content::BrowserAccessibility *findTable() const; + QObject *m_object = nullptr; QAccessible::Id m_id = 0; BrowserAccessibilityQt *q; }; -BrowserAccessibilityQt::BrowserAccessibilityQt(content::BrowserAccessibilityManager *manager, ui::AXNode *node) - : content::BrowserAccessibility(manager, node), - m_interface(new BrowserAccessibilityInterface(this)) +BrowserAccessibilityQt::BrowserAccessibilityQt(content::BrowserAccessibilityManager *manager, + ui::AXNode *node) + : content::BrowserAccessibility(manager, node) + , interface(new BrowserAccessibilityInterface(this)) { } BrowserAccessibilityQt::~BrowserAccessibilityQt() { - m_interface->destroy(); + if (interface) + interface->destroy(); +} + +bool BrowserAccessibilityQt::isReady() const +{ + // FIXME: This is just a workaround, remove this when the commented out assert in + // BrowserAccessibilityManager::GetFromID(int32_t id) gets fixed. + return manager()->GetFromID(node()->id()) != nullptr; } BrowserAccessibilityInterface::BrowserAccessibilityInterface(BrowserAccessibilityQt *chromiumInterface) : q(chromiumInterface) { - Q_ASSERT(parent()); - Q_ASSERT(parent()->object()); - m_object = new QObject(parent()->object()); - QString name = toQt(q->GetAuthorUniqueId()); - if (!name.isEmpty()) - m_object->setObjectName(name); + if (parent() && parent()->object()) { + m_object = new QObject(parent()->object()); + QString name = toQt(q->GetAuthorUniqueId()); + if (!name.isEmpty()) + m_object->setObjectName(name); + } m_id = QAccessible::registerAccessibleInterface(this); } +BrowserAccessibilityInterface::~BrowserAccessibilityInterface() +{ + q->interface = nullptr; +} + void BrowserAccessibilityInterface::destroy() { QAccessible::deleteAccessibleInterface(m_id); @@ -201,6 +179,9 @@ void BrowserAccessibilityInterface::destroy() bool BrowserAccessibilityInterface::isValid() const { + if (!q->isReady()) + return false; + auto managerQt = static_cast<content::BrowserAccessibilityManagerQt *>(q->manager()); return managerQt && managerQt->isValid(); } @@ -251,10 +232,10 @@ void *BrowserAccessibilityInterface::interface_cast(QAccessible::InterfaceType t } case QAccessible::TableCellInterface: { QAccessible::Role r = role(); - if (r == QAccessible::Cell || - r == QAccessible::ListItem || - r == QAccessible::TreeItem) - return static_cast<QAccessibleTableCellInterface*>(this); + if (r == QAccessible::Cell || r == QAccessible::ListItem || r == QAccessible::TreeItem) { + if (findTable()) + return static_cast<QAccessibleTableCellInterface *>(this); + } break; } default: @@ -299,11 +280,14 @@ int BrowserAccessibilityInterface::indexOfChild(const QAccessibleInterface *ifac { const BrowserAccessibilityInterface *child = static_cast<const BrowserAccessibilityInterface *>(iface); - return const_cast<BrowserAccessibilityInterface *>(child)->q->GetIndexInParent(); + return const_cast<BrowserAccessibilityInterface *>(child)->q->GetIndexInParent().value(); } QString BrowserAccessibilityInterface::text(QAccessible::Text t) const { + if (!q->isReady()) + return QString(); + switch (t) { case QAccessible::Name: return toQt(q->GetStringAttribute(ax::mojom::StringAttribute::kName)); @@ -325,9 +309,10 @@ void BrowserAccessibilityInterface::setText(QAccessible::Text t, const QString & QRect BrowserAccessibilityInterface::rect() const { - if (!q->manager()) // needed implicitly by GetScreenBoundsRect() + if (!q->manager() || !q->isReady()) // needed implicitly by GetScreenBoundsRect() return QRect(); gfx::Rect bounds = q->GetUnclippedScreenBoundsRect(); + bounds = gfx::ScaleToRoundedRect(bounds, 1.f / q->manager()->device_scale_factor()); // FIXME: check return QRect(bounds.x(), bounds.y(), bounds.width(), bounds.height()); } @@ -392,6 +377,8 @@ QAccessible::Role BrowserAccessibilityInterface::role() const case ax::mojom::Role::kComboBoxMenuButton: case ax::mojom::Role::kTextFieldWithComboBox: return QAccessible::ComboBox; + case ax::mojom::Role::kComboBoxSelect: + return QAccessible::PopupMenu; case ax::mojom::Role::kComplementary: return QAccessible::ComplementaryContent; case ax::mojom::Role::kComment: @@ -724,6 +711,11 @@ QAccessible::Role BrowserAccessibilityInterface::role() const QAccessible::State BrowserAccessibilityInterface::state() const { QAccessible::State state = QAccessible::State(); + if (!q->isReady()) { + state.invalid = true; + return state; + } + if (q->HasState(ax::mojom::State::kCollapsed)) state.collapsed = true; if (q->HasState(ax::mojom::State::kDefault)) @@ -835,7 +827,8 @@ void BrowserAccessibilityInterface::doAction(const QString &actionName) q->manager()->SetFocus(*q); } -QStringList BrowserAccessibilityInterface::keyBindingsForAction(const QString &actionName) const +QStringList +BrowserAccessibilityInterface::keyBindingsForAction(const QString & /*actionName*/) const { QT_NOT_YET_IMPLEMENTED return QStringList(); @@ -1137,14 +1130,20 @@ bool BrowserAccessibilityInterface::isSelected() const return false; } +content::BrowserAccessibility *BrowserAccessibilityInterface::findTable() const +{ + content::BrowserAccessibility *parent = q->PlatformGetParent(); + while (parent && parent->GetRole() != ax::mojom::Role::kTable) + parent = parent->PlatformGetParent(); + + return parent; +} + QAccessibleInterface *BrowserAccessibilityInterface::table() const { - content::BrowserAccessibility *find_table = q->PlatformGetParent(); - while (find_table && find_table->GetRole() != ax::mojom::Role::kTable) - find_table = find_table->PlatformGetParent(); - if (!find_table) - return nullptr; - return content::toQAccessibleInterface(find_table); + content::BrowserAccessibility *table = findTable(); + Q_ASSERT(table); + return content::toQAccessibleInterface(table); } void BrowserAccessibilityInterface::modelChange(QAccessibleTableModelChangeEvent *) @@ -1153,25 +1152,31 @@ void BrowserAccessibilityInterface::modelChange(QAccessibleTableModelChangeEvent } // namespace QtWebEngineCore +#endif // QT_CONFIG(accessibility) namespace content { // static std::unique_ptr<BrowserAccessibility> BrowserAccessibility::Create(BrowserAccessibilityManager *man, ui::AXNode *node) { +#if QT_CONFIG(accessibility) return std::unique_ptr<BrowserAccessibility>(new QtWebEngineCore::BrowserAccessibilityQt(man, node)); +#else + Q_UNUSED(man); + Q_UNUSED(node); + return nullptr; +#endif // #if QT_CONFIG(accessibility) } +#if QT_CONFIG(accessibility) QAccessibleInterface *toQAccessibleInterface(BrowserAccessibility *obj) { - return static_cast<QtWebEngineCore::BrowserAccessibilityQt *>(obj)->interface(); + return static_cast<QtWebEngineCore::BrowserAccessibilityQt *>(obj)->interface; } const QAccessibleInterface *toQAccessibleInterface(const BrowserAccessibility *obj) { - return static_cast<const QtWebEngineCore::BrowserAccessibilityQt *>(obj)->interface(); + return static_cast<const QtWebEngineCore::BrowserAccessibilityQt *>(obj)->interface; } +#endif // #if QT_CONFIG(accessibility) } // namespace content - - -#endif // QT_CONFIG(accessibility) |