Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
androidjniaccessibility.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
6#include "androidjnimain.h"
8#include "qpa/qplatformaccessibility.h"
9#include <QtGui/private/qaccessiblebridgeutils_p.h>
10#include "qguiapplication.h"
11#include "qwindow.h"
12#include "qrect.h"
13#include "QtGui/qaccessible.h"
14#include <QtCore/qmath.h>
15#include <QtCore/private/qjnihelpers_p.h>
16#include <QtCore/QJniObject>
17#include <QtGui/private/qhighdpiscaling_p.h>
18#include <QtCore/QObject>
19#include <QtCore/qvarlengtharray.h>
20
21static const char m_qtTag[] = "Qt A11Y";
22static const char m_classErrorMsg[] = "Can't find class \"%s\"";
23
25
26using namespace Qt::StringLiterals;
27
29{
30 static jmethodID m_addActionMethodID = 0;
31 static jmethodID m_setCheckableMethodID = 0;
32 static jmethodID m_setCheckedMethodID = 0;
33 static jmethodID m_setClickableMethodID = 0;
34 static jmethodID m_setContentDescriptionMethodID = 0;
35 static jmethodID m_setEditableMethodID = 0;
36 static jmethodID m_setEnabledMethodID = 0;
37 static jmethodID m_setFocusableMethodID = 0;
38 static jmethodID m_setFocusedMethodID = 0;
39 static jmethodID m_setHeadingMethodID = 0;
40 static jmethodID m_setScrollableMethodID = 0;
41 static jmethodID m_setTextSelectionMethodID = 0;
42 static jmethodID m_setVisibleToUserMethodID = 0;
43
44 static bool m_accessibilityActivated = false;
45
46 // This object is needed to schedule the execution of the code that
47 // deals with accessibility instances to the Qt main thread.
48 // Because of that almost every method here is split into two parts.
49 // The _helper part is executed in the context of m_accessibilityContext
50 // on the main thread. The other part is executed in Java thread.
52
53 // This method is called from the Qt main thread, and normally a
54 // QGuiApplication instance will be used as a parent.
56 {
60 }
61
62 template <typename Func, typename Ret>
63 void runInObjectContext(QObject *context, Func &&func, Ret *retVal)
64 {
66 if (!protector.acquire()) {
67 __android_log_print(ANDROID_LOG_WARN, m_qtTag,
68 "Could not run accessibility call in object context, accessing "
69 "main thread could lead to deadlock");
70 return;
71 }
72
76 } else {
77 __android_log_print(ANDROID_LOG_WARN, m_qtTag,
78 "Could not run accessibility call in object context, event loop suspended.");
79 }
80 }
81
83 {
84 QJniObject::callStaticMethod<void>(QtAndroid::applicationClass(),
85 "initializeAccessibility");
86 }
87
88 bool isActive()
89 {
91 }
92
93 static void setActive(JNIEnv */*env*/, jobject /*thiz*/, jboolean active)
94 {
98 if (platformIntegration)
99 platformIntegration->accessibility()->setActive(active);
100 else
101 __android_log_print(ANDROID_LOG_WARN, m_qtTag, "Could not (yet) activate platform accessibility.");
102 }
103
104 QAccessibleInterface *interfaceFromId(jint objectId)
105 {
106 QAccessibleInterface *iface = nullptr;
107 if (objectId == -1) {
108 QWindow *win = qApp->focusWindow();
109 if (win)
110 iface = win->accessibleRoot();
111 } else {
112 iface = QAccessible::accessibleInterface(objectId);
113 }
114 return iface;
115 }
116
117 void notifyLocationChange(uint accessibilityObjectId)
118 {
120 }
121
122 static int parentId_helper(int objectId); // forward declaration
123
124 void notifyObjectHide(uint accessibilityObjectId)
125 {
126 const auto parentObjectId = parentId_helper(accessibilityObjectId);
127 QtAndroid::notifyObjectHide(accessibilityObjectId, parentObjectId);
128 }
129
130 void notifyObjectFocus(uint accessibilityObjectId)
131 {
132 QtAndroid::notifyObjectFocus(accessibilityObjectId);
133 }
134
135 static jstring jvalueForAccessibleObject(int objectId); // forward declaration
136
137 void notifyValueChanged(uint accessibilityObjectId)
138 {
139 jstring value = jvalueForAccessibleObject(accessibilityObjectId);
140 QtAndroid::notifyValueChanged(accessibilityObjectId, value);
141 }
142
143 void notifyScrolledEvent(uint accessiblityObjectId)
144 {
145 QtAndroid::notifyScrolledEvent(accessiblityObjectId);
146 }
147
149 {
150 QAccessibleInterface *iface = interfaceFromId(objectId);
151 if (iface && iface->isValid()) {
152 const int childCount = iface->childCount();
153 QVarLengthArray<jint, 8> ifaceIdArray;
154 ifaceIdArray.reserve(childCount);
155 for (int i = 0; i < childCount; ++i) {
156 QAccessibleInterface *child = iface->child(i);
157 if (child && child->isValid())
158 ifaceIdArray.append(QAccessible::uniqueId(child));
159 }
160 return ifaceIdArray;
161 }
162 return {};
163 }
164
165 static jintArray childIdListForAccessibleObject(JNIEnv *env, jobject /*thiz*/, jint objectId)
166 {
168 QVarLengthArray<jint, 8> ifaceIdArray;
171 }, &ifaceIdArray);
172 jintArray jArray = env->NewIntArray(jsize(ifaceIdArray.count()));
173 env->SetIntArrayRegion(jArray, 0, ifaceIdArray.count(), ifaceIdArray.data());
174 return jArray;
175 }
176
177 return env->NewIntArray(jsize(0));
178 }
179
180 static int parentId_helper(int objectId)
181 {
182 QAccessibleInterface *iface = interfaceFromId(objectId);
183 if (iface && iface->isValid()) {
184 QAccessibleInterface *parent = iface->parent();
185 if (parent && parent->isValid()) {
186 if (parent->role() == QAccessible::Application)
187 return -1;
188 return QAccessible::uniqueId(parent);
189 }
190 }
191 return -1;
192 }
193
194 static jint parentId(JNIEnv */*env*/, jobject /*thiz*/, jint objectId)
195 {
196 jint result = -1;
199 return parentId_helper(objectId);
200 }, &result);
201 }
202 return result;
203 }
204
205 static QRect screenRect_helper(int objectId, bool clip = true)
206 {
207 QRect rect;
208 QAccessibleInterface *iface = interfaceFromId(objectId);
209 if (iface && iface->isValid()) {
210 rect = QHighDpi::toNativePixels(iface->rect(), iface->window());
211 }
212 // If the widget is not fully in-bound in its parent then we have to clip the rectangle to draw
213 if (clip && iface && iface->parent() && iface->parent()->isValid()) {
214 const auto parentRect = QHighDpi::toNativePixels(iface->parent()->rect(), iface->parent()->window());
215 rect = rect.intersected(parentRect);
216 }
217 return rect;
218 }
219
220 static jobject screenRect(JNIEnv *env, jobject /*thiz*/, jint objectId)
221 {
222 QRect rect;
225 return screenRect_helper(objectId);
226 }, &rect);
227 }
228 jclass rectClass = env->FindClass("android/graphics/Rect");
229 jmethodID ctor = env->GetMethodID(rectClass, "<init>", "(IIII)V");
230 jobject jrect = env->NewObject(rectClass, ctor, rect.left(), rect.top(), rect.right(), rect.bottom());
231 return jrect;
232 }
233
234 static int hitTest_helper(float x, float y)
235 {
236 QAccessibleInterface *root = interfaceFromId(-1);
237 if (root && root->isValid()) {
238 QPoint pos = QHighDpi::fromNativePixels(QPoint(int(x), int(y)), root->window());
239
240 QAccessibleInterface *child = root->childAt(pos.x(), pos.y());
241 QAccessibleInterface *lastChild = nullptr;
242 while (child && (child != lastChild)) {
243 lastChild = child;
244 child = child->childAt(pos.x(), pos.y());
245 }
246 if (lastChild)
247 return QAccessible::uniqueId(lastChild);
248 }
249 return -1;
250 }
251
252 static jint hitTest(JNIEnv */*env*/, jobject /*thiz*/, jfloat x, jfloat y)
253 {
254 jint result = -1;
257 return hitTest_helper(x, y);
258 }, &result);
259 }
260 return result;
261 }
262
263 static void invokeActionOnInterfaceInMainThread(QAccessibleActionInterface* actionInterface,
264 const QString& action)
265 {
266 // Queue the action and return back to Java thread, so that we do not
267 // block it for too long
268 QMetaObject::invokeMethod(qApp, [actionInterface, action]() {
269 actionInterface->doAction(action);
271 }
272
273 static bool clickAction_helper(int objectId)
274 {
275 QAccessibleInterface *iface = interfaceFromId(objectId);
276 if (!iface || !iface->isValid() || !iface->actionInterface())
277 return false;
278
279 const auto& actionNames = iface->actionInterface()->actionNames();
280
281 if (actionNames.contains(QAccessibleActionInterface::pressAction())) {
282 invokeActionOnInterfaceInMainThread(iface->actionInterface(),
283 QAccessibleActionInterface::pressAction());
284 } else if (actionNames.contains(QAccessibleActionInterface::toggleAction())) {
285 invokeActionOnInterfaceInMainThread(iface->actionInterface(),
286 QAccessibleActionInterface::toggleAction());
287 } else {
288 return false;
289 }
290 return true;
291 }
292
293 static jboolean clickAction(JNIEnv */*env*/, jobject /*thiz*/, jint objectId)
294 {
295 bool result = false;
298 return clickAction_helper(objectId);
299 }, &result);
300 }
301 return result;
302 }
303
304 static bool scroll_helper(int objectId, const QString &actionName)
305 {
306 QAccessibleInterface *iface = interfaceFromId(objectId);
307 if (iface && iface->isValid())
308 return QAccessibleBridgeUtils::performEffectiveAction(iface, actionName);
309 return false;
310 }
311
312 static jboolean scrollForward(JNIEnv */*env*/, jobject /*thiz*/, jint objectId)
313 {
314 bool result = false;
315
316 const auto& ids = childIdListForAccessibleObject_helper(objectId);
317 if (ids.isEmpty())
318 return false;
319
320 const int firstChildId = ids.first();
321 const QRect oldPosition = screenRect_helper(firstChildId, false);
322
325 return scroll_helper(objectId, QAccessibleActionInterface::increaseAction());
326 }, &result);
327 }
328
329 // Don't check for position change if the call was not successful
330 return result && oldPosition != screenRect_helper(firstChildId, false);
331 }
332
333 static jboolean scrollBackward(JNIEnv */*env*/, jobject /*thiz*/, jint objectId)
334 {
335 bool result = false;
336
337 const auto& ids = childIdListForAccessibleObject_helper(objectId);
338 if (ids.isEmpty())
339 return false;
340
341 const int firstChildId = ids.first();
342 const QRect oldPosition = screenRect_helper(firstChildId, false);
343
346 return scroll_helper(objectId, QAccessibleActionInterface::decreaseAction());
347 }, &result);
348 }
349
350 // Don't check for position change if the call was not successful
351 return result && oldPosition != screenRect_helper(firstChildId, false);
352 }
353
354
355#define FIND_AND_CHECK_CLASS(CLASS_NAME) \
356clazz = env->FindClass(CLASS_NAME); \
357if (!clazz) { \
358 __android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_classErrorMsg, CLASS_NAME); \
359 return JNI_FALSE; \
360}
361
362 //__android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE);
363
364 static QString textFromValue(QAccessibleInterface *iface)
365 {
366 QString valueStr;
367 QAccessibleValueInterface *valueIface = iface->valueInterface();
368 if (valueIface) {
369 const QVariant valueVar = valueIface->currentValue();
370 const auto type = valueVar.typeId();
371 if (type == QMetaType::Double || type == QMetaType::Float) {
372 // QVariant's toString() formats floating-point values with
373 // FloatingPointShortest, which is not an accessible
374 // representation; nor, in many cases, is it suitable to the UI
375 // element whose value we're looking at. So roll our own
376 // A11Y-friendly conversion to string.
377 const double val = valueVar.toDouble();
378 // Try to use minimumStepSize() to determine precision
379 bool stepIsValid = false;
380 const double step = qAbs(valueIface->minimumStepSize().toDouble(&stepIsValid));
381 if (!stepIsValid || qFuzzyIsNull(step)) {
382 // Ignore step, use default precision
383 valueStr = qFuzzyIsNull(val) ? u"0"_s : QString::number(val, 'f');
384 } else {
385 const int precision = [](double s) {
386 int count = 0;
387 while (s < 1. && !qFuzzyCompare(s, 1.)) {
388 ++count;
389 s *= 10;
390 }
391 // If s is now 1.25, we want to show some more digits,
392 // but don't want to get silly with a step like 1./7;
393 // so only include a few extra digits.
394 const int stop = count + 3;
395 const auto fractional = [](double v) {
396 double whole = 0.0;
397 std::modf(v + 0.5, &whole);
398 return qAbs(v - whole);
399 };
400 s = fractional(s);
401 while (count < stop && !qFuzzyIsNull(s)) {
402 ++count;
403 s = fractional(s * 10);
404 }
405 return count;
406 }(step);
407 valueStr = qFuzzyIsNull(val / step) ? u"0"_s
409 }
410 } else {
411 valueStr = valueVar.toString();
412 }
413 }
414 return valueStr;
415 }
416
417 static jstring jvalueForAccessibleObject(int objectId)
418 {
419 QAccessibleInterface *iface = interfaceFromId(objectId);
420 const QString value = textFromValue(iface);
421 QJniEnvironment env;
422 jstring jstr = env->NewString((jchar*)value.constData(), (jsize)value.size());
423 if (env.checkAndClearExceptions())
424 __android_log_print(ANDROID_LOG_WARN, m_qtTag, "Failed to create jstring");
425 return jstr;
426 }
427
428 static QString descriptionForInterface(QAccessibleInterface *iface)
429 {
431 if (iface && iface->isValid()) {
432 bool hasValue = false;
433 desc = iface->text(QAccessible::Name);
434 if (desc.isEmpty())
435 desc = iface->text(QAccessible::Description);
436 if (desc.isEmpty()) {
437 desc = iface->text(QAccessible::Value);
438 hasValue = !desc.isEmpty();
439 }
440 if (!hasValue && iface->valueInterface()) {
441 const QString valueStr = textFromValue(iface);
442 if (!valueStr.isEmpty()) {
443 if (!desc.isEmpty())
444 desc.append(QChar(QChar::Space));
445 desc.append(valueStr);
446 }
447 }
448 }
449 return desc;
450 }
451
453 {
454 QAccessibleInterface *iface = interfaceFromId(objectId);
455 return descriptionForInterface(iface);
456 }
457
458 static jstring descriptionForAccessibleObject(JNIEnv *env, jobject /*thiz*/, jint objectId)
459 {
464 }, &desc);
465 }
466 return env->NewString((jchar*) desc.constData(), (jsize) desc.size());
467 }
468
469
470 struct NodeInfo
471 {
472 bool valid = false;
474 QAccessible::Role role;
477 bool hasTextSelection = false;
480 };
481
482 static NodeInfo populateNode_helper(int objectId)
483 {
485 QAccessibleInterface *iface = interfaceFromId(objectId);
486 if (iface && iface->isValid()) {
487 info.valid = true;
488 info.state = iface->state();
489 info.role = iface->role();
491 info.description = descriptionForInterface(iface);
492 QAccessibleTextInterface *textIface = iface->textInterface();
493 if (textIface && (textIface->selectionCount() > 0)) {
494 info.hasTextSelection = true;
495 textIface->selection(0, &info.selectionStart, &info.selectionEnd);
496 }
497 }
498 return info;
499 }
500
501 static jboolean populateNode(JNIEnv *env, jobject /*thiz*/, jint objectId, jobject node)
502 {
506 return populateNode_helper(objectId);
507 }, &info);
508 }
509 if (!info.valid) {
510 __android_log_print(ANDROID_LOG_WARN, m_qtTag, "Accessibility: populateNode for Invalid ID");
511 return false;
512 }
513
514 const bool hasClickableAction =
515 info.actions.contains(QAccessibleActionInterface::pressAction()) ||
516 info.actions.contains(QAccessibleActionInterface::toggleAction());
517 const bool hasIncreaseAction =
518 info.actions.contains(QAccessibleActionInterface::increaseAction());
519 const bool hasDecreaseAction =
520 info.actions.contains(QAccessibleActionInterface::decreaseAction());
521
522 if (info.hasTextSelection && m_setTextSelectionMethodID) {
523 env->CallVoidMethod(node, m_setTextSelectionMethodID, info.selectionStart,
524 info.selectionEnd);
525 }
526
527 env->CallVoidMethod(node, m_setCheckableMethodID, (bool)info.state.checkable);
528 env->CallVoidMethod(node, m_setCheckedMethodID, (bool)info.state.checked);
529 env->CallVoidMethod(node, m_setEditableMethodID, info.state.editable);
530 env->CallVoidMethod(node, m_setEnabledMethodID, !info.state.disabled);
531 env->CallVoidMethod(node, m_setFocusableMethodID, (bool)info.state.focusable);
532 env->CallVoidMethod(node, m_setFocusedMethodID, (bool)info.state.focused);
534 env->CallVoidMethod(node, m_setHeadingMethodID, info.role == QAccessible::Heading);
535 env->CallVoidMethod(node, m_setVisibleToUserMethodID, !info.state.invisible);
536 env->CallVoidMethod(node, m_setScrollableMethodID, hasIncreaseAction || hasDecreaseAction);
537 env->CallVoidMethod(node, m_setClickableMethodID, hasClickableAction || info.role == QAccessible::Link);
538
539 // Add ACTION_CLICK
540 if (hasClickableAction)
541 env->CallVoidMethod(node, m_addActionMethodID, (int)0x00000010); // ACTION_CLICK defined in AccessibilityNodeInfo
542
543 // Add ACTION_SCROLL_FORWARD
544 if (hasIncreaseAction)
545 env->CallVoidMethod(node, m_addActionMethodID, (int)0x00001000); // ACTION_SCROLL_FORWARD defined in AccessibilityNodeInfo
546
547 // Add ACTION_SCROLL_BACKWARD
548 if (hasDecreaseAction)
549 env->CallVoidMethod(node, m_addActionMethodID, (int)0x00002000); // ACTION_SCROLL_BACKWARD defined in AccessibilityNodeInfo
550
551 // try to fill in the text property, this is what the screen reader reads
552 jstring jdesc = env->NewString((jchar*)info.description.constData(),
553 (jsize)info.description.size());
554 //CALL_METHOD(node, "setText", "(Ljava/lang/CharSequence;)V", jdesc)
555 env->CallVoidMethod(node, m_setContentDescriptionMethodID, jdesc);
556
557 return true;
558 }
559
560 static JNINativeMethod methods[] = {
561 {"setActive","(Z)V",(void*)setActive},
562 {"childIdListForAccessibleObject", "(I)[I", (jintArray)childIdListForAccessibleObject},
563 {"parentId", "(I)I", (void*)parentId},
564 {"descriptionForAccessibleObject", "(I)Ljava/lang/String;", (jstring)descriptionForAccessibleObject},
565 {"screenRect", "(I)Landroid/graphics/Rect;", (jobject)screenRect},
566 {"hitTest", "(FF)I", (void*)hitTest},
567 {"populateNode", "(ILandroid/view/accessibility/AccessibilityNodeInfo;)Z", (void*)populateNode},
568 {"clickAction", "(I)Z", (void*)clickAction},
569 {"scrollForward", "(I)Z", (void*)scrollForward},
570 {"scrollBackward", "(I)Z", (void*)scrollBackward},
571 };
572
573#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \
574 VAR = env->GetMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \
575 if (!VAR) { \
576 __android_log_print(ANDROID_LOG_FATAL, QtAndroid::qtTagText(), QtAndroid::methodErrorMsgFmt(), METHOD_NAME, METHOD_SIGNATURE); \
577 return false; \
578 }
579
580 bool registerNatives(JNIEnv *env)
581 {
582 jclass clazz;
583 FIND_AND_CHECK_CLASS("org/qtproject/qt/android/accessibility/QtNativeAccessibility");
584 jclass appClass = static_cast<jclass>(env->NewGlobalRef(clazz));
585
586 if (env->RegisterNatives(appClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
587 __android_log_print(ANDROID_LOG_FATAL,"Qt A11y", "RegisterNatives failed");
588 return false;
589 }
590
591 jclass nodeInfoClass = env->FindClass("android/view/accessibility/AccessibilityNodeInfo");
592 GET_AND_CHECK_STATIC_METHOD(m_addActionMethodID, nodeInfoClass, "addAction", "(I)V");
593 GET_AND_CHECK_STATIC_METHOD(m_setCheckableMethodID, nodeInfoClass, "setCheckable", "(Z)V");
594 GET_AND_CHECK_STATIC_METHOD(m_setCheckedMethodID, nodeInfoClass, "setChecked", "(Z)V");
595 GET_AND_CHECK_STATIC_METHOD(m_setClickableMethodID, nodeInfoClass, "setClickable", "(Z)V");
596 GET_AND_CHECK_STATIC_METHOD(m_setContentDescriptionMethodID, nodeInfoClass, "setContentDescription", "(Ljava/lang/CharSequence;)V");
597 GET_AND_CHECK_STATIC_METHOD(m_setEditableMethodID, nodeInfoClass, "setEditable", "(Z)V");
598 GET_AND_CHECK_STATIC_METHOD(m_setEnabledMethodID, nodeInfoClass, "setEnabled", "(Z)V");
599 GET_AND_CHECK_STATIC_METHOD(m_setFocusableMethodID, nodeInfoClass, "setFocusable", "(Z)V");
600 GET_AND_CHECK_STATIC_METHOD(m_setFocusedMethodID, nodeInfoClass, "setFocused", "(Z)V");
602 GET_AND_CHECK_STATIC_METHOD(m_setHeadingMethodID, nodeInfoClass, "setHeading", "(Z)V");
603 }
604 GET_AND_CHECK_STATIC_METHOD(m_setScrollableMethodID, nodeInfoClass, "setScrollable", "(Z)V");
605 GET_AND_CHECK_STATIC_METHOD(m_setVisibleToUserMethodID, nodeInfoClass, "setVisibleToUser", "(Z)V");
606 GET_AND_CHECK_STATIC_METHOD(m_setTextSelectionMethodID, nodeInfoClass, "setTextSelection", "(II)V");
607
608 return true;
609 }
610}
611
#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE)
#define FIND_AND_CHECK_CLASS(CLASS_NAME)
static const char m_classErrorMsg[]
static const char m_qtTag[]
\inmodule QtGui
\inmodule QtCore
Definition qchar.h:48
@ Space
Definition qchar.h:56
qint64 size() const
Returns the file size in bytes.
static Qt::ApplicationState applicationState()
\inmodule QtCore
\inmodule QtCore
Definition qmutex.h:317
\inmodule QtCore
Definition qobject.h:90
void deleteLater()
\threadsafe
Definition qobject.cpp:2352
\inmodule QtCore\reentrant
Definition qpoint.h:23
\inmodule QtCore
Definition qpointer.h:18
\inmodule QtCore\reentrant
Definition qrect.h:30
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:7822
qsizetype count() const
void append(const T &t)
T * data() noexcept
void reserve(qsizetype sz)
\inmodule QtCore
Definition qvariant.h:64
double toDouble(bool *ok=nullptr) const
Returns the variant as a double if the variant has userType() \l QMetaType::Double,...
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
int typeId() const
Returns the storage type of the value stored in the variant.
Definition qvariant.h:337
\inmodule QtGui
Definition qwindow.h:63
rect
[4]
static bool registerNatives()
QStringList effectiveActionNames(QAccessibleInterface *iface)
bool performEffectiveAction(QAccessibleInterface *iface, const QString &actionName)
T toNativePixels(const T &value, const C *context)
T fromNativePixels(const T &value, const C *context)
Combined button and popup list for selecting options.
static bool clickAction_helper(int objectId)
void notifyLocationChange(uint accessibilityObjectId)
void runInObjectContext(QObject *context, Func &&func, Ret *retVal)
static JNINativeMethod methods[]
static QPointer< QObject > m_accessibilityContext
static jboolean scrollForward(JNIEnv *, jobject, jint objectId)
void notifyObjectFocus(uint accessibilityObjectId)
static jboolean scrollBackward(JNIEnv *, jobject, jint objectId)
static QString descriptionForInterface(QAccessibleInterface *iface)
static int hitTest_helper(float x, float y)
static jmethodID m_setTextSelectionMethodID
static jstring descriptionForAccessibleObject(JNIEnv *env, jobject, jint objectId)
static bool scroll_helper(int objectId, const QString &actionName)
static QString textFromValue(QAccessibleInterface *iface)
void createAccessibilityContextObject(QObject *parent)
static QVarLengthArray< int, 8 > childIdListForAccessibleObject_helper(int objectId)
static NodeInfo populateNode_helper(int objectId)
void notifyObjectHide(uint accessibilityObjectId)
static jint hitTest(JNIEnv *, jobject, jfloat x, jfloat y)
static jboolean clickAction(JNIEnv *, jobject, jint objectId)
static jstring jvalueForAccessibleObject(int objectId)
static void setActive(JNIEnv *, jobject, jboolean active)
static void invokeActionOnInterfaceInMainThread(QAccessibleActionInterface *actionInterface, const QString &action)
QAccessibleInterface * interfaceFromId(jint objectId)
void notifyValueChanged(uint accessibilityObjectId)
static int parentId_helper(int objectId)
static QRect screenRect_helper(int objectId, bool clip=true)
static jmethodID m_setContentDescriptionMethodID
static QString descriptionForAccessibleObject_helper(int objectId)
static jint parentId(JNIEnv *, jobject, jint objectId)
static jobject screenRect(JNIEnv *env, jobject, jint objectId)
static jintArray childIdListForAccessibleObject(JNIEnv *env, jobject, jint objectId)
static jmethodID m_setVisibleToUserMethodID
static jboolean populateNode(JNIEnv *env, jobject, jint objectId, jobject node)
void notifyScrolledEvent(uint accessiblityObjectId)
Q_CORE_EXPORT jint androidSdkVersion()
void notifyAccessibilityLocationChange(uint accessibilityObjectId)
QBasicMutex * platformInterfaceMutex()
void notifyScrolledEvent(uint accessibilityObjectId)
QAndroidPlatformIntegration * androidPlatformIntegration()
void notifyObjectFocus(uint accessibilityObjectId)
void notifyValueChanged(uint accessibilityObjectId, jstring value)
bool blockEventLoopsWhenSuspended()
jclass applicationClass()
void notifyObjectHide(uint accessibilityObjectId, uint parentObjectId)
@ ApplicationSuspended
Definition qnamespace.h:262
@ BlockingQueuedConnection
@ QueuedConnection
static void * context
#define qApp
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:287
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition qfloat16.h:303
constexpr T qAbs(const T &t)
Definition qnumeric.h:328
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLenum GLenum GLsizei const GLuint * ids
GLenum GLenum GLsizei count
GLenum type
GLint y
GLenum func
Definition qopenglext.h:663
GLuint GLfloat * val
GLuint64EXT * result
[6]
GLdouble s
[6]
Definition qopenglext.h:235
GLenum GLint GLint * precision
@ desc
unsigned int uint
Definition qtypes.h:29
QWidget * win
Definition settings.cpp:6
QFileInfo info(fileName)
[8]
QReadWriteLock lock
[0]
QPoint oldPosition
[6]
QLayoutItem * child
[0]
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
\threadsafe This is an overloaded member function, provided for convenience. It differs from the abov...
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent