LCOV - code coverage report
Current view: top level - muse/framework/accessibility/internal - accessibleapprootobject.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 27.9 % 61 17
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-Studio-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2026 MuseScore Limited
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program is distributed in the hope that it will be useful,
      15              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      17              :  * GNU General Public License for more details.
      18              :  *
      19              :  * You should have received a copy of the GNU General Public License
      20              :  * along with this program. If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : #include "accessibleapprootobject.h"
      23              : 
      24              : #include <QAccessible>
      25              : #include <QGuiApplication>
      26              : 
      27              : #include "accessibleapprootinterface.h"
      28              : 
      29              : #include "log.h"
      30              : 
      31              : using namespace muse::accessibility;
      32              : 
      33              : class AccessibilityActivationObserver : public QAccessible::ActivationObserver
      34              : {
      35              : public:
      36            1 :     AccessibilityActivationObserver()
      37            1 :         : m_active(QAccessible::isActive()) {}
      38              : 
      39            0 :     bool isActive() const { return m_active; }
      40              : 
      41            0 :     void accessibilityActiveChanged(bool active) override { m_active = active; }
      42              : 
      43              : private:
      44              :     bool m_active = false;
      45              : };
      46              : 
      47              : static AccessibilityActivationObserver* s_activationObserver = nullptr;
      48              : 
      49            1 : AccessibleAppRootObject::AccessibleAppRootObject()
      50            1 :     : QObject(nullptr)
      51              : {
      52            1 :     s_activationObserver = new AccessibilityActivationObserver();
      53            1 :     QAccessible::installActivationObserver(s_activationObserver);
      54            1 : }
      55              : 
      56            1 : void AccessibleAppRootObject::init()
      57              : {
      58            1 :     if (m_inited) {
      59            0 :         return;
      60              :     }
      61            1 :     m_inited = true;
      62              : 
      63            1 :     QAccessible::installRootObjectHandler(nullptr);
      64            1 :     QAccessible::setRootObject(this);
      65              : }
      66              : 
      67            2 : AccessibleAppRootObject::~AccessibleAppRootObject()
      68              : {
      69            1 :     QAccessible::installActivationObserver(nullptr);
      70            1 :     delete s_activationObserver;
      71            1 :     s_activationObserver = nullptr;
      72            2 : }
      73              : 
      74            0 : QObject* AccessibleAppRootObject::asQObject()
      75              : {
      76            0 :     return this;
      77              : }
      78              : 
      79            0 : QAccessibleInterface* AccessibleAppRootObject::accessibleInterface(QObject* object)
      80              : {
      81            0 :     AccessibleAppRootObject* root = qobject_cast<AccessibleAppRootObject*>(object);
      82            0 :     if (!root) {
      83            0 :         return nullptr;
      84              :     }
      85            0 :     return new AccessibleAppRootInterface(root);
      86              : }
      87              : 
      88            0 : void AccessibleAppRootObject::registerWindow(QWindow* window, AccessibleObject* windowRoot)
      89              : {
      90            0 :     if (!window || !windowRoot) {
      91            0 :         return;
      92              :     }
      93              : 
      94            0 :     for (const WindowEntry& entry : m_windows) {
      95            0 :         if (entry.window == window) {
      96            0 :             LOGW() << "Window already registered";
      97            0 :             return;
      98              :         }
      99              :     }
     100              : 
     101            0 :     m_windows.append({ window, windowRoot });
     102              : }
     103              : 
     104            0 : void AccessibleAppRootObject::unregisterWindow(QWindow* window)
     105              : {
     106            0 :     for (int i = 0; i < m_windows.size(); ++i) {
     107            0 :         if (m_windows[i].window == window) {
     108            0 :             QAccessibleInterface* iface = QAccessible::queryAccessibleInterface(window);
     109            0 :             if (iface) {
     110            0 :                 QAccessible::deleteAccessibleInterface(QAccessible::uniqueId(iface));
     111              :             }
     112            0 :             m_windows.removeAt(i);
     113            0 :             return;
     114              :         }
     115              :     }
     116              : }
     117              : 
     118            0 : int AccessibleAppRootObject::windowCount() const
     119              : {
     120            0 :     return m_windows.size();
     121              : }
     122              : 
     123            0 : QWindow* AccessibleAppRootObject::windowAt(int index) const
     124              : {
     125            0 :     if (index < 0 || index >= m_windows.size()) {
     126            0 :         return nullptr;
     127              :     }
     128            0 :     return m_windows[index].window;
     129              : }
     130              : 
     131            0 : AccessibleObject* AccessibleAppRootObject::windowRoot(QWindow* window) const
     132              : {
     133            0 :     for (const WindowEntry& entry : m_windows) {
     134            0 :         if (entry.window == window) {
     135            0 :             return entry.windowRoot;
     136              :         }
     137              :     }
     138            0 :     return nullptr;
     139              : }
     140              : 
     141            0 : QAccessibleInterface* AccessibleAppRootObject::windowIface(int index) const
     142              : {
     143            0 :     QWindow* w = windowAt(index);
     144            0 :     if (!w) {
     145            0 :         return nullptr;
     146              :     }
     147            0 :     return QAccessible::queryAccessibleInterface(w);
     148              : }
     149              : 
     150            0 : bool AccessibleAppRootObject::isAccessibilityActive() const
     151              : {
     152            0 :     return s_activationObserver && s_activationObserver->isActive();
     153              : }
        

Generated by: LCOV version 2.0-1