aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Weghorn <m.weghorn@posteo.de>2025-09-22 12:34:53 +0200
committerMichael Weghorn <m.weghorn@posteo.de>2025-10-30 23:35:22 +0100
commit064790206cae95425d38fbc72d0893f10fd82860 (patch)
treedd64835056714b59fb971831ffa9eca4a7f680f7 /src
parent1227db3adf91a92cf7e5f048dbeca2b9a3663c84 (diff)
a11y: Make QQuickTextInput accessible
So far, accessibility logic was implemented in QQuickTextField, while its base class QQuickTextInput didn't have any implementation. Most of the existing logic only requires QQuickTextInput(Private), however. Move that logic to the QQuickTextInput(Private) base class and only leave the QQuickTextField-specific logic in the subclass. Task-number: QTBUG-139943 Fixes: QTBUG-140441 Change-Id: I757222a7b6c21b575bfe404333cc7ed91af86ed7 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/quick/items/qquicktextinput.cpp60
-rw-r--r--src/quick/items/qquicktextinput_p_p.h22
-rw-r--r--src/quicktemplates/qquicktextfield.cpp39
-rw-r--r--src/quicktemplates/qquicktextfield_p_p.h11
4 files changed, 86 insertions, 46 deletions
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index 95e1b83c20..5adc5ce802 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -91,6 +91,10 @@ void QQuickTextInput::componentComplete()
updateCursorRectangle();
if (d->cursorComponent && isCursorVisible())
QQuickTextUtil::createCursor(d);
+#if QT_CONFIG(accessibility)
+ if (QAccessible::isActive())
+ d->accessibilityActiveChanged(true);
+#endif
}
/*!
@@ -2841,6 +2845,57 @@ void QQuickTextInput::focusOutEvent(QFocusEvent *event)
QQuickImplicitSizeItem::focusOutEvent(event);
}
+void QQuickTextInputPrivate::readOnlyChanged(bool isReadOnly)
+{
+ Q_UNUSED(isReadOnly);
+#if QT_CONFIG(accessibility)
+ if (QQuickAccessibleAttached *accessibleAttached =
+ QQuickAccessibleAttached::attachedProperties(q_func()))
+ accessibleAttached->set_readOnly(isReadOnly);
+#endif
+}
+
+void QQuickTextInputPrivate::echoModeChanged(QQuickTextInput::EchoMode echoMode)
+{
+#if QT_CONFIG(accessibility)
+ if (!QAccessible::isActive())
+ return;
+
+ if (QQuickAccessibleAttached *accessibleAttached =
+ QQuickAccessibleAttached::attachedProperties(q_func()))
+ accessibleAttached->set_passwordEdit((echoMode == QQuickTextInput::Password
+ || echoMode == QQuickTextInput::PasswordEchoOnEdit)
+ ? true
+ : false);
+#else
+ Q_UNUSED(echoMode);
+#endif
+}
+
+#if QT_CONFIG(accessibility)
+void QQuickTextInputPrivate::accessibilityActiveChanged(bool active)
+{
+ if (!active)
+ return;
+
+ Q_Q(QQuickTextInput);
+ QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(
+ qmlAttachedPropertiesObject<QQuickAccessibleAttached>(q, true));
+ Q_ASSERT(accessibleAttached);
+ accessibleAttached->setRole(effectiveAccessibleRole());
+ accessibleAttached->set_readOnly(m_readOnly);
+ accessibleAttached->set_passwordEdit((m_echoMode == QQuickTextInput::Password
+ || m_echoMode == QQuickTextInput::PasswordEchoOnEdit)
+ ? true
+ : false);
+}
+
+QAccessible::Role QQuickTextInputPrivate::accessibleRole() const
+{
+ return QAccessible::EditableText;
+}
+#endif
+
/*!
\qmlproperty bool QtQuick::TextInput::inputMethodComposing
\readonly
@@ -2908,6 +2963,11 @@ void QQuickTextInputPrivate::init()
m_inputControl = new QInputControl(QInputControl::LineEdit, q);
setSizePolicy(QLayoutPolicy::Expanding, QLayoutPolicy::Fixed);
+
+ QObjectPrivate::connect(q, &QQuickTextInput::readOnlyChanged, this,
+ &QQuickTextInputPrivate::readOnlyChanged);
+ QObjectPrivate::connect(q, &QQuickTextInput::echoModeChanged, this,
+ &QQuickTextInputPrivate::echoModeChanged);
}
void QQuickTextInputPrivate::cancelInput()
diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h
index 918a6da0fd..b0c88e5f30 100644
--- a/src/quick/items/qquicktextinput_p_p.h
+++ b/src/quick/items/qquicktextinput_p_p.h
@@ -14,6 +14,9 @@
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qpointer.h>
#include <QtCore/qbasictimer.h>
+#if QT_CONFIG(accessibility)
+#include <QtGui/qaccessible.h>
+#endif
#include <QtGui/qclipboard.h>
#include <QtGui/qguiapplication.h>
#include <QtGui/qpalette.h>
@@ -41,6 +44,9 @@ class QSGInternalTextNode;
class QInputControl;
class Q_QUICK_EXPORT QQuickTextInputPrivate : public QQuickImplicitSizeItemPrivate
+#if QT_CONFIG(accessibility)
+ , public QAccessible::ActivationObserver
+#endif
{
public:
Q_DECLARE_PUBLIC(QQuickTextInput)
@@ -131,6 +137,10 @@ public:
, selectByTouchDrag(false)
#endif
{
+#if QT_CONFIG(accessibility)
+ QAccessible::installActivationObserver(this);
+ setAccessible();
+#endif
}
~QQuickTextInputPrivate()
@@ -140,6 +150,10 @@ public:
// to zero it out
if (m_echoMode != QQuickTextInput::Normal)
m_text.fill(u'\0');
+
+#if QT_CONFIG(accessibility)
+ QAccessible::removeActivationObserver(this);
+#endif
}
void init();
@@ -160,6 +174,14 @@ public:
#endif
void handleFocusEvent(QFocusEvent *event);
+ virtual void readOnlyChanged(bool isReadOnly);
+ void echoModeChanged(QQuickTextInput::EchoMode echoMode);
+
+#if QT_CONFIG(accessibility)
+ void accessibilityActiveChanged(bool active) override;
+ QAccessible::Role accessibleRole() const override;
+#endif
+
struct MaskInputData {
enum Casemode { NoCaseMode, Upper, Lower };
QChar maskChar; // either the separator char or the inputmask
diff --git a/src/quicktemplates/qquicktextfield.cpp b/src/quicktemplates/qquicktextfield.cpp
index ec2088b012..86584ea49e 100644
--- a/src/quicktemplates/qquicktextfield.cpp
+++ b/src/quicktemplates/qquicktextfield.cpp
@@ -86,17 +86,10 @@ using namespace Qt::StringLiterals;
QQuickTextFieldPrivate::QQuickTextFieldPrivate()
{
-#if QT_CONFIG(accessibility)
- QAccessible::installActivationObserver(this);
- setAccessible();
-#endif
}
QQuickTextFieldPrivate::~QQuickTextFieldPrivate()
{
-#if QT_CONFIG(accessibility)
- QAccessible::removeActivationObserver(this);
-#endif
}
void QQuickTextFieldPrivate::setTopInset(qreal value, bool reset)
@@ -261,45 +254,25 @@ void QQuickTextFieldPrivate::implicitHeightChanged()
void QQuickTextFieldPrivate::readOnlyChanged(bool isReadOnly)
{
- Q_UNUSED(isReadOnly);
-#if QT_CONFIG(accessibility)
- if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(q_func()))
- accessibleAttached->set_readOnly(isReadOnly);
-#endif
+ QQuickTextInputPrivate::readOnlyChanged(isReadOnly);
#if QT_CONFIG(cursor)
q_func()->setCursor(isReadOnly && !selectByMouse ? Qt::ArrowCursor : Qt::IBeamCursor);
#endif
}
-void QQuickTextFieldPrivate::echoModeChanged(QQuickTextField::EchoMode echoMode)
-{
-#if QT_CONFIG(accessibility)
- if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(q_func()))
- accessibleAttached->set_passwordEdit((echoMode == QQuickTextField::Password || echoMode == QQuickTextField::PasswordEchoOnEdit) ? true : false);
-#else
- Q_UNUSED(echoMode);
-#endif
-}
-
#if QT_CONFIG(accessibility)
void QQuickTextFieldPrivate::accessibilityActiveChanged(bool active)
{
+ QQuickTextInputPrivate::accessibilityActiveChanged(active);
+
if (!active)
return;
-
Q_Q(QQuickTextField);
QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(q, true));
Q_ASSERT(accessibleAttached);
- accessibleAttached->setRole(effectiveAccessibleRole());
- accessibleAttached->set_readOnly(m_readOnly);
- accessibleAttached->set_passwordEdit((m_echoMode == QQuickTextField::Password || m_echoMode == QQuickTextField::PasswordEchoOnEdit) ? true : false);
accessibleAttached->setDescriptionImplicitly(placeholder);
}
-QAccessible::Role QQuickTextFieldPrivate::accessibleRole() const
-{
- return QAccessible::EditableText;
-}
#endif
void QQuickTextFieldPrivate::cancelBackground()
@@ -387,8 +360,6 @@ QQuickTextField::QQuickTextField(QQuickItem *parent)
#if QT_CONFIG(cursor)
setCursor(Qt::IBeamCursor);
#endif
- QObjectPrivate::connect(this, &QQuickTextInput::readOnlyChanged, d, &QQuickTextFieldPrivate::readOnlyChanged);
- QObjectPrivate::connect(this, &QQuickTextInput::echoModeChanged, d, &QQuickTextFieldPrivate::echoModeChanged);
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
if (qEnvironmentVariable("QT_QUICK_CONTROLS_TEXT_SELECTION_BEHAVIOR") == u"old"_s)
QQuickTextInput::setOldSelectionDefault();
@@ -798,10 +769,6 @@ void QQuickTextField::componentComplete()
if (!d->explicitHoverEnabled)
setAcceptHoverEvents(QQuickControlPrivate::calcHoverEnabled(d->parentItem));
#endif
-#if QT_CONFIG(accessibility)
- if (QAccessible::isActive())
- d->accessibilityActiveChanged(true);
-#endif
}
void QQuickTextField::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
diff --git a/src/quicktemplates/qquicktextfield_p_p.h b/src/quicktemplates/qquicktextfield_p_p.h
index 04e0788ed7..50bf4852c8 100644
--- a/src/quicktemplates/qquicktextfield_p_p.h
+++ b/src/quicktemplates/qquicktextfield_p_p.h
@@ -25,16 +25,9 @@
#include <QtQuickTemplates2/private/qquicktextfield_p.h>
-#if QT_CONFIG(accessibility)
-#include <QtGui/qaccessible.h>
-#endif
-
QT_BEGIN_NAMESPACE
class QQuickTextFieldPrivate : public QQuickTextInputPrivate, public QQuickItemChangeListener
-#if QT_CONFIG(accessibility)
- , public QAccessible::ActivationObserver
-#endif
{
public:
Q_DECLARE_PUBLIC(QQuickTextField)
@@ -77,12 +70,10 @@ public:
void implicitWidthChanged() override;
void implicitHeightChanged() override;
- void readOnlyChanged(bool isReadOnly);
- void echoModeChanged(QQuickTextField::EchoMode echoMode);
+ virtual void readOnlyChanged(bool isReadOnly) override;
#if QT_CONFIG(accessibility)
void accessibilityActiveChanged(bool active) override;
- QAccessible::Role accessibleRole() const override;
#endif
void cancelBackground();