/* SPDX-FileCopyrightText: 2000 Matthias Hölzer-Klüpfel SPDX-FileCopyrightText: 2014 Frederik Gladhorn SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL */ #include "kcmaccess.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kcmaccessibilitybell.h" #include "kcmaccessibilitycolorblindnesscorrection.h" #include "kcmaccessibilitydata.h" #include "kcmaccessibilityinvert.h" #include "kcmaccessibilitykeyboard.h" #include "kcmaccessibilitykeyboardfilters.h" #include "kcmaccessibilitymouse.h" #include "kcmaccessibilityshakecursor.h" #include "kcmaccessibilitydwellclicker.h" #include "kcmaccessibilityzoommagnifier.h" #include "logging.h" using namespace Qt::Literals; K_PLUGIN_FACTORY_WITH_JSON(KCMAccessFactory, "kcm_access.json", registerPlugin(); registerPlugin();) class IntValidatorWithSuffix : public QIntValidator { Q_GADGET public: State validate(QString &text, int &pos) const override { QString strippedText; QRegularExpression re("\\d+"); QRegularExpressionMatchIterator i = re.globalMatch(text); while (i.hasNext()) { QRegularExpressionMatch match = i.next(); strippedText += match.captured(); } return QIntValidator::validate(strippedText, pos); } }; KAccessConfig::KAccessConfig(QObject *parent, const KPluginMetaData &metaData) : KQuickManagedConfigModule(parent, metaData) , m_data(new AccessibilityData(this)) { qmlRegisterAnonymousType("org.kde.plasma.access.kcm", 0); qmlRegisterAnonymousType("org.kde.plasma.access.kcm", 0); qmlRegisterAnonymousType("org.kde.plasma.access.kcm", 0); qmlRegisterAnonymousType("org.kde.plasma.access.kcm", 0); qmlRegisterAnonymousType("org.kde.plasma.access.kcm", 0); qmlRegisterAnonymousType("org.kde.plasma.access.kcm", 0); qmlRegisterAnonymousType("org.kde.plasma.access.kcm", 0); qmlRegisterAnonymousType("org.kde.plasma.access.kcm", 0); qmlRegisterAnonymousType("org.kde.plasma.access.kcm", 0); qmlRegisterType("org.kde.plasma.access.kcm", 0, 0, "IntValidatorWithSuffix"); m_screenReaderInstalled = orcaInstalled(); setButtons(KAbstractConfigModule::Apply | KAbstractConfigModule::Default | KAbstractConfigModule::Help); connect(m_data->bellSettings(), &BellSettings::configChanged, this, &KAccessConfig::bellIsDefaultsChanged); connect(m_data->mouseSettings(), &MouseSettings::configChanged, this, &KAccessConfig::mouseIsDefaultsChanged); connect(m_data->keyboardFiltersSettings(), &KeyboardFiltersSettings::configChanged, this, &KAccessConfig::keyboardFiltersIsDefaultsChanged); connect(m_data->keyboardSettings(), &KeyboardSettings::configChanged, this, &KAccessConfig::keyboardModifiersIsDefaultsChanged); connect(m_data->shakeCursorSettings(), &ShakeCursorSettings::configChanged, this, &KAccessConfig::shakeCursorIsDefaultsChanged); connect(m_data->dwellClickerSettings(), &DwellClickerSettings::configChanged, this, &KAccessConfig::dwellClickerIsDefaultsChanged); connect(m_data->colorblindnessCorrectionSettings(), &ColorblindnessCorrectionSettings::configChanged, this, &KAccessConfig::colorblindnessCorrectionIsDefaultsChanged); connect(m_data->invertSettings(), &InvertSettings::configChanged, this, &KAccessConfig::invertIsDefaultsChanged); connect(m_data->zoomMagnifierSettings(), &ZoomMagnifierSettings::configChanged, this, &KAccessConfig::zoomMagnifierIsDefaultsChanged); } KAccessConfig::~KAccessConfig() { } void KAccessConfig::configureKNotify() { auto *notifyWidget = KNotifyConfigWidget::configure(QApplication::activeWindow(), QStringLiteral("kaccess")); // HACK: Make dialog properly modal, non-ideal but safe QDialog *dialog = qobject_cast(notifyWidget->parent()); if (dialog) { dialog->hide(); dialog->winId(); dialog->windowHandle()->setTransientParent(QApplication::activeWindow()->windowHandle()); dialog->setWindowModality(Qt::WindowModal); dialog->show(); } } void KAccessConfig::configureInvertShortcuts() { KShortcutsDialog *dialog = new KShortcutsDialog(KShortcutsEditor::GlobalAction, KShortcutsEditor::LetterShortcutsDisallowed); KActionCollection *actionCollection = new KActionCollection(dialog, QStringLiteral("kwin")); actionCollection->setComponentDisplayName(i18n("KWin")); QAction *a = actionCollection->addAction(QStringLiteral("Invert")); a->setText(i18n("Toggle Invert Effect")); a->setProperty("isConfigurationAction", true); KGlobalAccel::self()->setDefaultShortcut(a, QList() << (Qt::CTRL | Qt::META | Qt::Key_I)); KGlobalAccel::self()->setShortcut(a, QList() << (Qt::CTRL | Qt::META | Qt::Key_I)); QAction *b = actionCollection->addAction(QStringLiteral("InvertWindow")); b->setText(i18n("Toggle Invert Effect on Window")); b->setProperty("isConfigurationAction", true); KGlobalAccel::self()->setDefaultShortcut(b, QList() << (Qt::CTRL | Qt::META | Qt::Key_U)); KGlobalAccel::self()->setShortcut(b, QList() << (Qt::CTRL | Qt::META | Qt::Key_U)); dialog->addCollection(actionCollection); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->winId(); dialog->windowHandle()->setTransientParent(QApplication::activeWindow()->windowHandle()); dialog->setWindowModality(Qt::WindowModal); dialog->configure(); } void KAccessConfig::configureZoomMagnifyShortcuts() { KShortcutsDialog *dialog = new KShortcutsDialog(KShortcutsEditor::GlobalAction, KShortcutsEditor::LetterShortcutsDisallowed); KActionCollection *actionCollection = new KActionCollection(dialog, QStringLiteral("kwin")); actionCollection->setComponentDisplayName(i18n("KWin")); if (zoomMagnifierSettings()->zoom()) { // Show zoom effect shortcuts QAction *a; a = actionCollection->addAction(KStandardActions::ZoomIn); a->setProperty("isConfigurationAction", true); KGlobalAccel::self()->setDefaultShortcut(a, QList() << (Qt::META | Qt::Key_Plus) << (Qt::META | Qt::Key_Equal)); KGlobalAccel::self()->setShortcut(a, QList() << (Qt::META | Qt::Key_Plus) << (Qt::META | Qt::Key_Equal)); a = actionCollection->addAction(KStandardActions::ZoomOut); a->setProperty("isConfigurationAction", true); KGlobalAccel::self()->setDefaultShortcut(a, QList() << (Qt::META | Qt::Key_Minus)); KGlobalAccel::self()->setShortcut(a, QList() << (Qt::META | Qt::Key_Minus)); a = actionCollection->addAction(KStandardActions::ActualSize); a->setProperty("isConfigurationAction", true); KGlobalAccel::self()->setDefaultShortcut(a, QList() << (Qt::META | Qt::Key_0)); KGlobalAccel::self()->setShortcut(a, QList() << (Qt::META | Qt::Key_0)); a = actionCollection->addAction(QStringLiteral("MoveZoomLeft")); a->setIcon(QIcon::fromTheme(QStringLiteral("go-previous"))); a->setText(i18n("Move Left")); a->setProperty("isConfigurationAction", true); KGlobalAccel::self()->setDefaultShortcut(a, QList() << (Qt::META | Qt::CTRL | Qt::Key_Left)); KGlobalAccel::self()->setShortcut(a, QList() << (Qt::META | Qt::CTRL | Qt::Key_Left)); a = actionCollection->addAction(QStringLiteral("MoveZoomRight")); a->setIcon(QIcon::fromTheme(QStringLiteral("go-next"))); a->setText(i18n("Move Right")); a->setProperty("isConfigurationAction", true); KGlobalAccel::self()->setDefaultShortcut(a, QList() << (Qt::META | Qt::CTRL | Qt::Key_Right)); KGlobalAccel::self()->setShortcut(a, QList() << (Qt::META | Qt::CTRL | Qt::Key_Right)); a = actionCollection->addAction(QStringLiteral("MoveZoomUp")); a->setIcon(QIcon::fromTheme(QStringLiteral("go-up"))); a->setText(i18n("Move Up")); a->setProperty("isConfigurationAction", true); KGlobalAccel::self()->setDefaultShortcut(a, QList() << (Qt::META | Qt::CTRL | Qt::Key_Up)); KGlobalAccel::self()->setShortcut(a, QList() << (Qt::META | Qt::CTRL | Qt::Key_Up)); a = actionCollection->addAction(QStringLiteral("MoveZoomDown")); a->setIcon(QIcon::fromTheme(QStringLiteral("go-down"))); a->setText(i18n("Move Down")); a->setProperty("isConfigurationAction", true); KGlobalAccel::self()->setDefaultShortcut(a, QList() << (Qt::META | Qt::CTRL | Qt::Key_Down)); KGlobalAccel::self()->setShortcut(a, QList() << (Qt::META | Qt::CTRL | Qt::Key_Down)); a = actionCollection->addAction(QStringLiteral("MoveMouseToFocus")); a->setIcon(QIcon::fromTheme(QStringLiteral("view-restore"))); a->setText(i18n("Move Mouse to Focus")); a->setProperty("isConfigurationAction", true); KGlobalAccel::self()->setDefaultShortcut(a, QList() << (Qt::META | Qt::Key_F5)); KGlobalAccel::self()->setShortcut(a, QList() << (Qt::META | Qt::Key_F5)); a = actionCollection->addAction(QStringLiteral("MoveMouseToCenter")); a->setIcon(QIcon::fromTheme(QStringLiteral("view-restore"))); a->setText(i18n("Move Mouse to Center")); a->setProperty("isConfigurationAction", true); KGlobalAccel::self()->setDefaultShortcut(a, QList() << (Qt::META | Qt::Key_F6)); KGlobalAccel::self()->setShortcut(a, QList() << (Qt::META | Qt::Key_F6)); } else if (zoomMagnifierSettings()->magnifier()) { // Show magnifier effect shortcuts QAction *a; a = actionCollection->addAction(KStandardActions::ZoomIn); a->setProperty("isConfigurationAction", true); KGlobalAccel::self()->setDefaultShortcut(a, QList() << (Qt::META | Qt::Key_Plus) << (Qt::META | Qt::Key_Equal)); KGlobalAccel::self()->setShortcut(a, QList() << (Qt::META | Qt::Key_Plus) << (Qt::META | Qt::Key_Equal)); a = actionCollection->addAction(KStandardActions::ZoomOut); a->setProperty("isConfigurationAction", true); KGlobalAccel::self()->setDefaultShortcut(a, QList() << (Qt::META | Qt::Key_Minus)); KGlobalAccel::self()->setShortcut(a, QList() << (Qt::META | Qt::Key_Minus)); a = actionCollection->addAction(KStandardActions::ActualSize); a->setProperty("isConfigurationAction", true); KGlobalAccel::self()->setDefaultShortcut(a, QList() << (Qt::META | Qt::Key_0)); KGlobalAccel::self()->setShortcut(a, QList() << (Qt::META | Qt::Key_0)); } dialog->addCollection(actionCollection); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->winId(); dialog->windowHandle()->setTransientParent(QApplication::activeWindow()->windowHandle()); dialog->setWindowModality(Qt::WindowModal); dialog->configure(); } void KAccessConfig::launchOrcaConfiguration() { const QStringList gsettingArgs = {QStringLiteral("set"), QStringLiteral("org.gnome.desktop.a11y.applications"), QStringLiteral("screen-reader-enabled"), QStringLiteral("true")}; int ret = QProcess::execute(QStringLiteral("gsettings"), gsettingArgs); if (ret) { const QString errorStr = QLatin1String("gsettings ") + gsettingArgs.join(QLatin1Char(' ')); setOrcaLaunchFeedback(i18n("Could not set gsettings for Orca: \"%1\" failed", errorStr)); return; } qint64 pid = 0; bool started = QProcess::startDetached(QStringLiteral("orca"), {QStringLiteral("--setup")}, QString(), &pid); if (!started) { setOrcaLaunchFeedback(i18n("Error: Could not launch \"orca --setup\"")); } } void KAccessConfig::load() { KQuickManagedConfigModule::load(); QDBusMessage screenReaderEnabledMessage = QDBusMessage::createMethodCall(u"org.kde.kded6"_s, u"/modules/screenreader"_s, u"org.kde.screenreader"_s, u"enabled"_s); QDBusReply reply = QDBusConnection::sessionBus().call(screenReaderEnabledMessage); if (reply.isValid()) { m_screenReaderEnabled = reply.value(); Q_EMIT screenReaderEnabledChanged(); } else { qCWarning(KCM_ACCESS) << "Failed to read screenreader enabled" << reply.error().message(); } } void KAccessConfig::save() { const bool shakeCursorSaveNeeded = m_data->shakeCursorSettings()->findItem(QStringLiteral("ShakeCursor"))->isSaveNeeded(); const bool shakeCursorMagnificationSaveNeeded = m_data->shakeCursorSettings()->findItem(QStringLiteral("ShakeCursorMagnification"))->isSaveNeeded(); const bool dwellClickerSaveNeeded = m_data->dwellClickerSettings()->findItem(QStringLiteral("DwellClicker"))->isSaveNeeded(); const bool dwellClickerDelayTimeSaveNeeded = m_data->dwellClickerSettings()->findItem(QStringLiteral("DwellClickerDelayTime"))->isSaveNeeded(); const bool dwellClickerDwellTimeSaveNeeded = m_data->dwellClickerSettings()->findItem(QStringLiteral("DwellClickerDwellTime"))->isSaveNeeded(); const bool dwellClickerDwellColorSaveNeeded = m_data->dwellClickerSettings()->findItem(QStringLiteral("DwellClickerDwellColor"))->isSaveNeeded(); const bool dwellClickerMotionThresholdSaveNeeded = m_data->dwellClickerSettings()->findItem(QStringLiteral("DwellClickerMotionThreshold"))->isSaveNeeded(); const bool colorblindnessCorrectionSaveNeeded = m_data->colorblindnessCorrectionSettings()->findItem(QStringLiteral("ColorblindnessCorrection"))->isSaveNeeded(); const bool colorblindnessCorrectionSettingsSaveNeeded = m_data->colorblindnessCorrectionSettings()->findItem(QStringLiteral("Mode"))->isSaveNeeded() || m_data->colorblindnessCorrectionSettings()->findItem(QStringLiteral("Intensity"))->isSaveNeeded(); const bool invertSaveNeeded = m_data->invertSettings()->findItem(QStringLiteral("Invert"))->isSaveNeeded(); const bool zoomMagnifierSaveNeeded = m_data->zoomMagnifierSettings()->findItem(QStringLiteral("Zoom"))->isSaveNeeded() || m_data->zoomMagnifierSettings()->findItem(QStringLiteral("Magnifier"))->isSaveNeeded(); const bool zoomSettingsSaveNeeded = m_data->zoomMagnifierSettings()->findItem(QStringLiteral("SharedZoomFactor"))->isSaveNeeded() || m_data->zoomMagnifierSettings()->findItem(QStringLiteral("ZoomMouseTracking"))->isSaveNeeded() || m_data->zoomMagnifierSettings()->findItem(QStringLiteral("ZoomEnableTextCaretTracking"))->isSaveNeeded() || m_data->zoomMagnifierSettings()->findItem(QStringLiteral("ZoomUsePatternUpscaler"))->isSaveNeeded() || m_data->zoomMagnifierSettings()->findItem(QStringLiteral("ZoomPixelGridZoom"))->isSaveNeeded() || m_data->zoomMagnifierSettings()->findItem(QStringLiteral("ZoomPointerAxisGestureModifiers"))->isSaveNeeded(); const bool magnifierSettingsSaveNeeded = m_data->zoomMagnifierSettings()->findItem(QStringLiteral("SharedZoomFactor"))->isSaveNeeded() || m_data->zoomMagnifierSettings()->findItem(QStringLiteral("MagnifierWidth"))->isSaveNeeded() || m_data->zoomMagnifierSettings()->findItem(QStringLiteral("MagnifierHeight"))->isSaveNeeded(); KQuickManagedConfigModule::save(); // make kaccess reread the configuration // turning a11y features off needs to be done by kaccess // so run it to clear any enabled features and it will exit if it should QProcess::startDetached(QStringLiteral("kaccess"), {}); if (shakeCursorSaveNeeded) { QDBusMessage reloadMessage = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"), QStringLiteral("/Effects"), QStringLiteral("org.kde.kwin.Effects"), shakeCursorSettings()->shakeCursor() ? QStringLiteral("loadEffect") : QStringLiteral("unloadEffect")); reloadMessage.setArguments({QStringLiteral("shakecursor")}); QDBusConnection::sessionBus().call(reloadMessage); } if (shakeCursorMagnificationSaveNeeded) { QDBusMessage reconfigureMessage = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"), QStringLiteral("/Effects"), QStringLiteral("org.kde.kwin.Effects"), QStringLiteral("reconfigureEffect")); reconfigureMessage.setArguments({QStringLiteral("shakecursor")}); QDBusConnection::sessionBus().call(reconfigureMessage); } if (dwellClickerSaveNeeded) { QDBusMessage reloadMessage = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"), QStringLiteral("/Effects"), QStringLiteral("org.kde.kwin.Effects"), dwellClickerSettings()->dwellClicker() ? QStringLiteral("loadEffect") : QStringLiteral("unloadEffect")); reloadMessage.setArguments({QStringLiteral("dwellclicker")}); QDBusConnection::sessionBus().call(reloadMessage); } if (dwellClickerDelayTimeSaveNeeded || dwellClickerDwellTimeSaveNeeded || dwellClickerDwellColorSaveNeeded || dwellClickerMotionThresholdSaveNeeded) { QDBusMessage reconfigureMessage = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"), QStringLiteral("/Effects"), QStringLiteral("org.kde.kwin.Effects"), QStringLiteral("reconfigureEffect")); reconfigureMessage.setArguments({QStringLiteral("dwellclicker")}); QDBusConnection::sessionBus().call(reconfigureMessage); } if (colorblindnessCorrectionSaveNeeded) { QDBusMessage reloadMessage = QDBusMessage::createMethodCall( QStringLiteral("org.kde.KWin"), QStringLiteral("/Effects"), QStringLiteral("org.kde.kwin.Effects"), colorblindnessCorrectionSettings()->colorblindnessCorrection() ? QStringLiteral("loadEffect") : QStringLiteral("unloadEffect")); reloadMessage.setArguments({QStringLiteral("colorblindnesscorrection")}); QDBusConnection::sessionBus().call(reloadMessage); } if (colorblindnessCorrectionSaveNeeded || colorblindnessCorrectionSettingsSaveNeeded) { QDBusMessage reconfigureMessage = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"), QStringLiteral("/Effects"), QStringLiteral("org.kde.kwin.Effects"), QStringLiteral("reconfigureEffect")); reconfigureMessage.setArguments({QStringLiteral("colorblindnesscorrection")}); QDBusConnection::sessionBus().call(reconfigureMessage); } if (invertSaveNeeded) { QDBusMessage reloadMessage = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"), QStringLiteral("/Effects"), QStringLiteral("org.kde.kwin.Effects"), invertSettings()->invert() ? QStringLiteral("loadEffect") : QStringLiteral("unloadEffect")); reloadMessage.setArguments({QStringLiteral("invert")}); QDBusConnection::sessionBus().call(reloadMessage); } if (zoomMagnifierSaveNeeded) { // Unload both effects QDBusMessage reloadMessage = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"), QStringLiteral("/Effects"), QStringLiteral("org.kde.kwin.Effects"), QStringLiteral("unloadEffect")); reloadMessage.setArguments({QStringLiteral("zoom")}); QDBusConnection::sessionBus().call(reloadMessage); reloadMessage.setArguments({QStringLiteral("magnifier")}); QDBusConnection::sessionBus().call(reloadMessage); if (zoomMagnifierSettings()->zoom() || zoomMagnifierSettings()->magnifier()) { // Load the specified effect QDBusMessage reloadMessage = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"), QStringLiteral("/Effects"), QStringLiteral("org.kde.kwin.Effects"), QStringLiteral("loadEffect")); reloadMessage.setArguments({zoomMagnifierSettings()->zoom() ? QStringLiteral("zoom") : QStringLiteral("magnifier")}); QDBusConnection::sessionBus().call(reloadMessage); } } if (zoomSettingsSaveNeeded) { QDBusMessage reconfigureMessage = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"), QStringLiteral("/Effects"), QStringLiteral("org.kde.kwin.Effects"), QStringLiteral("reconfigureEffect")); reconfigureMessage.setArguments({QStringLiteral("zoom")}); QDBusConnection::sessionBus().call(reconfigureMessage); } if (magnifierSettingsSaveNeeded) { QDBusMessage reconfigureMessage = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"), QStringLiteral("/Effects"), QStringLiteral("org.kde.kwin.Effects"), QStringLiteral("reconfigureEffect")); reconfigureMessage.setArguments({QStringLiteral("magnifier")}); QDBusConnection::sessionBus().call(reconfigureMessage); } QDBusMessage enableScreenReaderMessage = QDBusMessage::createMethodCall(u"org.kde.kded6"_s, u"/modules/screenreader"_s, u"org.kde.screenreader"_s, u"setEnabled"_s); enableScreenReaderMessage.setArguments({m_screenReaderEnabled}); QDBusReply reply = QDBusConnection::sessionBus().call(enableScreenReaderMessage); if (!reply.isValid()) { qCWarning(KCM_ACCESS) << "Failed to send setEnabled" << reply.error().message(); } } void KAccessConfig::defaults() { KQuickManagedConfigModule::defaults(); m_screenReaderEnabled = false; Q_EMIT screenReaderEnabledChanged(); Q_EMIT settingsChanged(); Q_EMIT screenReaderIsDefaultsChanged(); } bool KAccessConfig::isDefaults() const { return screenReaderIsDefaults(); } bool KAccessConfig::isSaveNeeded() const { QDBusMessage msg = QDBusMessage::createMethodCall(u"org.kde.kded6"_s, u"/modules/screenreader"_s, u"org.kde.screenreader"_s, u"enabled"_s); QDBusReply reply = QDBusConnection::sessionBus().call(msg); if (!reply.isValid()) { qCWarning(KCM_ACCESS) << "Failed to read isSaveNeeded" << reply.error().message(); return false; } return m_screenReaderEnabled != reply.value(); } QString KAccessConfig::orcaLaunchFeedback() const { return m_orcaLaunchFeedback; } void KAccessConfig::setOrcaLaunchFeedback(const QString &value) { if (m_orcaLaunchFeedback != value) { m_orcaLaunchFeedback = value; Q_EMIT orcaLaunchFeedbackChanged(); } } bool KAccessConfig::orcaInstalled() { return !QStandardPaths::findExecutable(QStringLiteral("orca")).isEmpty(); } MouseSettings *KAccessConfig::mouseSettings() const { return m_data->mouseSettings(); } BellSettings *KAccessConfig::bellSettings() const { return m_data->bellSettings(); } KeyboardSettings *KAccessConfig::keyboardSettings() const { return m_data->keyboardSettings(); } KeyboardFiltersSettings *KAccessConfig::keyboardFiltersSettings() const { return m_data->keyboardFiltersSettings(); } ShakeCursorSettings *KAccessConfig::shakeCursorSettings() const { return m_data->shakeCursorSettings(); } DwellClickerSettings *KAccessConfig::dwellClickerSettings() const { return m_data->dwellClickerSettings(); } ColorblindnessCorrectionSettings *KAccessConfig::colorblindnessCorrectionSettings() const { return m_data->colorblindnessCorrectionSettings(); } InvertSettings *KAccessConfig::invertSettings() const { return m_data->invertSettings(); } ZoomMagnifierSettings *KAccessConfig::zoomMagnifierSettings() const { return m_data->zoomMagnifierSettings(); } bool KAccessConfig::bellIsDefaults() const { return bellSettings()->isDefaults(); } bool KAccessConfig::mouseIsDefaults() const { return mouseSettings()->isDefaults(); } bool KAccessConfig::keyboardFiltersIsDefaults() const { return keyboardFiltersSettings()->isDefaults(); } bool KAccessConfig::keyboardModifiersIsDefaults() const { return keyboardSettings()->isDefaults(); } bool KAccessConfig::screenReaderIsDefaults() const { QDBusMessage msg = QDBusMessage::createMethodCall(u"org.kde.kded6"_s, u"/modules/screenreader"_s, u"org.kde.screenreader"_s, u"enabledByDefault"_s); QDBusReply reply = QDBusConnection::sessionBus().call(msg); if (!reply.isValid()) { qCWarning(KCM_ACCESS) << "Failed to read enabledByDefault" << reply.error().message(); } return m_screenReaderEnabled == reply.value(); } bool KAccessConfig::shakeCursorIsDefaults() const { return shakeCursorSettings()->isDefaults(); } bool KAccessConfig::dwellClickerIsDefaults() const { return dwellClickerSettings()->isDefaults(); } bool KAccessConfig::colorblindnessCorrectionIsDefaults() const { return colorblindnessCorrectionSettings()->isDefaults(); } bool KAccessConfig::invertIsDefaults() const { return invertSettings()->isDefaults(); } bool KAccessConfig::zoomMagnifierIsDefaults() const { return zoomMagnifierSettings()->isDefaults(); } bool KAccessConfig::screenReaderEnabled() const { return m_screenReaderEnabled; } void KAccessConfig::setScreenReaderEnabled(bool enabled) { m_screenReaderEnabled = enabled; Q_EMIT screenReaderEnabledChanged(); Q_EMIT screenReaderIsDefaultsChanged(); Q_EMIT settingsChanged(); } #include "kcmaccess.moc" #include "moc_kcmaccess.cpp"