QtBase  v6.3.1
androidjniaccessibility.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2021 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
41 #include "androidjnimain.h"
43 #include "qpa/qplatformaccessibility.h"
44 #include <QtGui/private/qaccessiblebridgeutils_p.h>
45 #include "qguiapplication.h"
46 #include "qwindow.h"
47 #include "qrect.h"
48 #include "QtGui/qaccessible.h"
49 #include <QtCore/qmath.h>
50 #include <QtCore/private/qjnihelpers_p.h>
51 #include <QtCore/QJniObject>
52 #include <QtGui/private/qhighdpiscaling_p.h>
53 #include <QtCore/QObject>
54 
55 static const char m_qtTag[] = "Qt A11Y";
56 static const char m_classErrorMsg[] = "Can't find class \"%s\"";
57 
59 
61 {
62  static jmethodID m_addActionMethodID = 0;
63  static jmethodID m_setCheckableMethodID = 0;
64  static jmethodID m_setCheckedMethodID = 0;
65  static jmethodID m_setClickableMethodID = 0;
66  static jmethodID m_setContentDescriptionMethodID = 0;
67  static jmethodID m_setEditableMethodID = 0;
68  static jmethodID m_setEnabledMethodID = 0;
69  static jmethodID m_setFocusableMethodID = 0;
70  static jmethodID m_setFocusedMethodID = 0;
71  static jmethodID m_setHeadingMethodID = 0;
72  static jmethodID m_setScrollableMethodID = 0;
73  static jmethodID m_setTextSelectionMethodID = 0;
74  static jmethodID m_setVisibleToUserMethodID = 0;
75 
76  static bool m_accessibilityActivated = false;
77 
78  // This object is needed to schedule the execution of the code that
79  // deals with accessibility instances to the Qt main thread.
80  // Because of that almost every method here is split into two parts.
81  // The _helper part is executed in the context of m_accessibilityContext
82  // on the main thread. The other part is executed in Java thread.
83  static QPointer<QObject> m_accessibilityContext = nullptr;
84 
85  // This method is called from the Qt main thread, and normally a
86  // QGuiApplication instance will be used as a parent.
88  {
89  if (m_accessibilityContext)
90  m_accessibilityContext->deleteLater();
91  m_accessibilityContext = new QObject(parent);
92  }
93 
94  template <typename Func, typename Ret>
95  void runInObjectContext(QObject *context, Func &&func, Ret *retVal)
96  {
98  }
99 
100  void initialize()
101  {
102  QJniObject::callStaticMethod<void>(QtAndroid::applicationClass(),
103  "initializeAccessibility");
104  }
105 
106  bool isActive()
107  {
108  return m_accessibilityActivated;
109  }
110 
111  static void setActive(JNIEnv */*env*/, jobject /*thiz*/, jboolean active)
112  {
115  m_accessibilityActivated = active;
116  if (platformIntegration)
117  platformIntegration->accessibility()->setActive(active);
118  else
119  __android_log_print(ANDROID_LOG_WARN, m_qtTag, "Could not (yet) activate platform accessibility.");
120  }
121 
123  {
124  QAccessibleInterface *iface = nullptr;
125  if (objectId == -1) {
126  QWindow *win = qApp->focusWindow();
127  if (win)
128  iface = win->accessibleRoot();
129  } else {
130  iface = QAccessible::accessibleInterface(objectId);
131  }
132  return iface;
133  }
134 
135  void notifyLocationChange(uint accessibilityObjectId)
136  {
137  QtAndroid::notifyAccessibilityLocationChange(accessibilityObjectId);
138  }
139 
140  static int parentId_helper(int objectId); // forward declaration
141 
142  void notifyObjectHide(uint accessibilityObjectId)
143  {
144  const auto parentObjectId = parentId_helper(accessibilityObjectId);
145  QtAndroid::notifyObjectHide(accessibilityObjectId, parentObjectId);
146  }
147 
148  void notifyObjectFocus(uint accessibilityObjectId)
149  {
150  QtAndroid::notifyObjectFocus(accessibilityObjectId);
151  }
152 
153  static jstring jvalueForAccessibleObject(int objectId); // forward declaration
154 
155  void notifyValueChanged(uint accessibilityObjectId)
156  {
157  jstring value = jvalueForAccessibleObject(accessibilityObjectId);
158  QtAndroid::notifyValueChanged(accessibilityObjectId, value);
159  }
160 
161  static QVarLengthArray<int, 8> childIdListForAccessibleObject_helper(int objectId)
162  {
163  QAccessibleInterface *iface = interfaceFromId(objectId);
164  if (iface && iface->isValid()) {
165  const int childCount = iface->childCount();
166  QVarLengthArray<jint, 8> ifaceIdArray;
167  ifaceIdArray.reserve(childCount);
168  for (int i = 0; i < childCount; ++i) {
169  QAccessibleInterface *child = iface->child(i);
170  if (child && child->isValid())
171  ifaceIdArray.append(QAccessible::uniqueId(child));
172  }
173  return ifaceIdArray;
174  }
175  return {};
176  }
177 
178  static jintArray childIdListForAccessibleObject(JNIEnv *env, jobject /*thiz*/, jint objectId)
179  {
180  if (m_accessibilityContext) {
181  QVarLengthArray<jint, 8> ifaceIdArray;
182  runInObjectContext(m_accessibilityContext, [objectId]() {
183  return childIdListForAccessibleObject_helper(objectId);
184  }, &ifaceIdArray);
185  jintArray jArray = env->NewIntArray(jsize(ifaceIdArray.count()));
186  env->SetIntArrayRegion(jArray, 0, ifaceIdArray.count(), ifaceIdArray.data());
187  return jArray;
188  }
189 
190  return env->NewIntArray(jsize(0));
191  }
192 
193  static int parentId_helper(int objectId)
194  {
195  QAccessibleInterface *iface = interfaceFromId(objectId);
196  if (iface && iface->isValid()) {
197  QAccessibleInterface *parent = iface->parent();
198  if (parent && parent->isValid()) {
199  if (parent->role() == QAccessible::Application)
200  return -1;
202  }
203  }
204  return -1;
205  }
206 
207  static jint parentId(JNIEnv */*env*/, jobject /*thiz*/, jint objectId)
208  {
209  jint result = -1;
210  if (m_accessibilityContext) {
211  runInObjectContext(m_accessibilityContext, [objectId]() {
212  return parentId_helper(objectId);
213  }, &result);
214  }
215  return result;
216  }
217 
218  static QRect screenRect_helper(int objectId)
219  {
220  QRect rect;
221  QAccessibleInterface *iface = interfaceFromId(objectId);
222  if (iface && iface->isValid()) {
223  rect = QHighDpi::toNativePixels(iface->rect(), iface->window());
224  }
225  // If the widget is not fully in-bound in its parent then we have to clip the rectangle to draw
226  if (iface && iface->parent() && iface->parent()->isValid()) {
227  const auto parentRect = QHighDpi::toNativePixels(iface->parent()->rect(), iface->parent()->window());
228  rect = rect.intersected(parentRect);
229  }
230  return rect;
231  }
232 
233  static jobject screenRect(JNIEnv *env, jobject /*thiz*/, jint objectId)
234  {
235  QRect rect;
236  if (m_accessibilityContext) {
237  runInObjectContext(m_accessibilityContext, [objectId]() {
238  return screenRect_helper(objectId);
239  }, &rect);
240  }
241  jclass rectClass = env->FindClass("android/graphics/Rect");
242  jmethodID ctor = env->GetMethodID(rectClass, "<init>", "(IIII)V");
243  jobject jrect = env->NewObject(rectClass, ctor, rect.left(), rect.top(), rect.right(), rect.bottom());
244  return jrect;
245  }
246 
247  static int hitTest_helper(float x, float y)
248  {
250  if (root && root->isValid()) {
251  QPoint pos = QHighDpi::fromNativePixels(QPoint(int(x), int(y)), root->window());
252 
253  QAccessibleInterface *child = root->childAt(pos.x(), pos.y());
254  QAccessibleInterface *lastChild = nullptr;
255  while (child && (child != lastChild)) {
256  lastChild = child;
257  child = child->childAt(pos.x(), pos.y());
258  }
259  if (lastChild)
260  return QAccessible::uniqueId(lastChild);
261  }
262  return -1;
263  }
264 
265  static jint hitTest(JNIEnv */*env*/, jobject /*thiz*/, jfloat x, jfloat y)
266  {
267  jint result = -1;
268  if (m_accessibilityContext) {
269  runInObjectContext(m_accessibilityContext, [x, y]() {
270  return hitTest_helper(x, y);
271  }, &result);
272  }
273  return result;
274  }
275 
276  static void invokeActionOnInterfaceInMainThread(QAccessibleActionInterface* actionInterface,
277  const QString& action)
278  {
279  // Queue the action and return back to Java thread, so that we do not
280  // block it for too long
281  QMetaObject::invokeMethod(qApp, [actionInterface, action]() {
282  actionInterface->doAction(action);
284  }
285 
286  static bool clickAction_helper(int objectId)
287  {
288  QAccessibleInterface *iface = interfaceFromId(objectId);
289  if (!iface || !iface->isValid() || !iface->actionInterface())
290  return false;
291 
292  const auto& actionNames = iface->actionInterface()->actionNames();
293 
294  if (actionNames.contains(QAccessibleActionInterface::pressAction())) {
295  invokeActionOnInterfaceInMainThread(iface->actionInterface(),
297  } else if (actionNames.contains(QAccessibleActionInterface::toggleAction())) {
298  invokeActionOnInterfaceInMainThread(iface->actionInterface(),
300  } else {
301  return false;
302  }
303  return true;
304  }
305 
306  static jboolean clickAction(JNIEnv */*env*/, jobject /*thiz*/, jint objectId)
307  {
308  bool result = false;
309  if (m_accessibilityContext) {
310  runInObjectContext(m_accessibilityContext, [objectId]() {
311  return clickAction_helper(objectId);
312  }, &result);
313  }
314  return result;
315  }
316 
317  static bool scroll_helper(int objectId, const QString &actionName)
318  {
319  QAccessibleInterface *iface = interfaceFromId(objectId);
320  if (iface && iface->isValid())
321  return QAccessibleBridgeUtils::performEffectiveAction(iface, actionName);
322  return false;
323  }
324 
325  static jboolean scrollForward(JNIEnv */*env*/, jobject /*thiz*/, jint objectId)
326  {
327  bool result = false;
328  if (m_accessibilityContext) {
329  runInObjectContext(m_accessibilityContext, [objectId]() {
330  return scroll_helper(objectId, QAccessibleActionInterface::increaseAction());
331  }, &result);
332  }
333  return result;
334  }
335 
336  static jboolean scrollBackward(JNIEnv */*env*/, jobject /*thiz*/, jint objectId)
337  {
338  bool result = false;
339  if (m_accessibilityContext) {
340  runInObjectContext(m_accessibilityContext, [objectId]() {
341  return scroll_helper(objectId, QAccessibleActionInterface::decreaseAction());
342  }, &result);
343  }
344  return result;
345  }
346 
347 
348 #define FIND_AND_CHECK_CLASS(CLASS_NAME) \
349 clazz = env->FindClass(CLASS_NAME); \
350 if (!clazz) { \
351  __android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_classErrorMsg, CLASS_NAME); \
352  return JNI_FALSE; \
353 }
354 
355  //__android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE);
356 
357  static QString textFromValue(QAccessibleInterface *iface)
358  {
359  QString valueStr;
360  QAccessibleValueInterface *valueIface = iface->valueInterface();
361  if (valueIface) {
362  const QVariant valueVar = valueIface->currentValue();
363  const auto type = valueVar.typeId();
365  // QVariant's toString() formats floating-point values with
366  // FloatingPointShortest, which is not an accessible
367  // representation; nor, in many cases, is it suitable to the UI
368  // element whose value we're looking at. So roll our own
369  // A11Y-friendly conversion to string.
370  const double val = valueVar.toDouble();
371  // Try to use minimumStepSize() to determine precision
372  bool stepIsValid = false;
373  const double step = qAbs(valueIface->minimumStepSize().toDouble(&stepIsValid));
374  if (!stepIsValid || qFuzzyIsNull(step)) {
375  // Ignore step, use default precision
376  valueStr = qFuzzyIsNull(val) ? u"0"_qs : QString::number(val, 'f');
377  } else {
378  const int precision = [](double s) {
379  int count = 0;
380  while (s < 1. && !qFuzzyCompare(s, 1.)) {
381  ++count;
382  s *= 10;
383  }
384  // If s is now 1.25, we want to show some more digits,
385  // but don't want to get silly with a step like 1./7;
386  // so only include a few extra digits.
387  const int stop = count + 3;
388  const auto fractional = [](double v) {
389  double whole = 0.0;
390  std::modf(v + 0.5, &whole);
391  return qAbs(v - whole);
392  };
393  s = fractional(s);
394  while (count < stop && !qFuzzyIsNull(s)) {
395  ++count;
396  s = fractional(s * 10);
397  }
398  return count;
399  }(step);
400  valueStr = qFuzzyIsNull(val / step) ? u"0"_qs
401  : QString::number(val, 'f', precision);
402  }
403  } else {
404  valueStr = valueVar.toString();
405  }
406  }
407  return valueStr;
408  }
409 
410  static jstring jvalueForAccessibleObject(int objectId)
411  {
412  QAccessibleInterface *iface = interfaceFromId(objectId);
413  const QString value = textFromValue(iface);
414  QJniEnvironment env;
415  jstring jstr = env->NewString((jchar*)value.constData(), (jsize)value.size());
416  if (env.checkAndClearExceptions())
417  __android_log_print(ANDROID_LOG_WARN, m_qtTag, "Failed to create jstring");
418  return jstr;
419  }
420 
421  static QString descriptionForInterface(QAccessibleInterface *iface)
422  {
423  QString desc;
424  if (iface && iface->isValid()) {
425  bool hasValue = false;
426  desc = iface->text(QAccessible::Name);
427  if (desc.isEmpty())
429  if (desc.isEmpty()) {
430  desc = iface->text(QAccessible::Value);
431  hasValue = !desc.isEmpty();
432  }
433  if (!hasValue && iface->valueInterface()) {
434  const QString valueStr = textFromValue(iface);
435  if (!valueStr.isEmpty()) {
436  if (!desc.isEmpty())
437  desc.append(QChar(QChar::Space));
438  desc.append(valueStr);
439  }
440  }
441  }
442  return desc;
443  }
444 
445  static QString descriptionForAccessibleObject_helper(int objectId)
446  {
447  QAccessibleInterface *iface = interfaceFromId(objectId);
448  return descriptionForInterface(iface);
449  }
450 
451  static jstring descriptionForAccessibleObject(JNIEnv *env, jobject /*thiz*/, jint objectId)
452  {
453  QString desc;
454  if (m_accessibilityContext) {
455  runInObjectContext(m_accessibilityContext, [objectId]() {
456  return descriptionForAccessibleObject_helper(objectId);
457  }, &desc);
458  }
459  return env->NewString((jchar*) desc.constData(), (jsize) desc.size());
460  }
461 
462 
463  struct NodeInfo
464  {
465  bool valid = false;
470  bool hasTextSelection = false;
471  int selectionStart = 0;
472  int selectionEnd = 0;
473  };
474 
475  static NodeInfo populateNode_helper(int objectId)
476  {
477  NodeInfo info;
478  QAccessibleInterface *iface = interfaceFromId(objectId);
479  if (iface && iface->isValid()) {
480  info.valid = true;
481  info.state = iface->state();
482  info.role = iface->role();
484  info.description = descriptionForInterface(iface);
485  QAccessibleTextInterface *textIface = iface->textInterface();
486  if (textIface && (textIface->selectionCount() > 0)) {
487  info.hasTextSelection = true;
488  textIface->selection(0, &info.selectionStart, &info.selectionEnd);
489  }
490  }
491  return info;
492  }
493 
494  static jboolean populateNode(JNIEnv *env, jobject /*thiz*/, jint objectId, jobject node)
495  {
496  NodeInfo info;
497  if (m_accessibilityContext) {
498  runInObjectContext(m_accessibilityContext, [objectId]() {
499  return populateNode_helper(objectId);
500  }, &info);
501  }
502  if (!info.valid) {
503  __android_log_print(ANDROID_LOG_WARN, m_qtTag, "Accessibility: populateNode for Invalid ID");
504  return false;
505  }
506 
507  const bool hasClickableAction =
508  info.actions.contains(QAccessibleActionInterface::pressAction()) ||
510  const bool hasIncreaseAction =
512  const bool hasDecreaseAction =
514 
515  if (info.hasTextSelection && m_setTextSelectionMethodID) {
516  env->CallVoidMethod(node, m_setTextSelectionMethodID, info.selectionStart,
517  info.selectionEnd);
518  }
519 
520  env->CallVoidMethod(node, m_setCheckableMethodID, (bool)info.state.checkable);
521  env->CallVoidMethod(node, m_setCheckedMethodID, (bool)info.state.checked);
522  env->CallVoidMethod(node, m_setEditableMethodID, info.state.editable);
523  env->CallVoidMethod(node, m_setEnabledMethodID, !info.state.disabled);
524  env->CallVoidMethod(node, m_setFocusableMethodID, (bool)info.state.focusable);
525  env->CallVoidMethod(node, m_setFocusedMethodID, (bool)info.state.focused);
526  if (m_setHeadingMethodID)
527  env->CallVoidMethod(node, m_setHeadingMethodID, info.role == QAccessible::Heading);
528  env->CallVoidMethod(node, m_setVisibleToUserMethodID, !info.state.invisible);
529  env->CallVoidMethod(node, m_setScrollableMethodID, hasIncreaseAction || hasDecreaseAction);
530  env->CallVoidMethod(node, m_setClickableMethodID, hasClickableAction || info.role == QAccessible::Link);
531 
532  // Add ACTION_CLICK
533  if (hasClickableAction)
534  env->CallVoidMethod(node, m_addActionMethodID, (int)0x00000010); // ACTION_CLICK defined in AccessibilityNodeInfo
535 
536  // Add ACTION_SCROLL_FORWARD
537  if (hasIncreaseAction)
538  env->CallVoidMethod(node, m_addActionMethodID, (int)0x00001000); // ACTION_SCROLL_FORWARD defined in AccessibilityNodeInfo
539 
540  // Add ACTION_SCROLL_BACKWARD
541  if (hasDecreaseAction)
542  env->CallVoidMethod(node, m_addActionMethodID, (int)0x00002000); // ACTION_SCROLL_BACKWARD defined in AccessibilityNodeInfo
543 
544  // try to fill in the text property, this is what the screen reader reads
545  jstring jdesc = env->NewString((jchar*)info.description.constData(),
546  (jsize)info.description.size());
547  //CALL_METHOD(node, "setText", "(Ljava/lang/CharSequence;)V", jdesc)
548  env->CallVoidMethod(node, m_setContentDescriptionMethodID, jdesc);
549 
550  return true;
551  }
552 
553  static JNINativeMethod methods[] = {
554  {"setActive","(Z)V",(void*)setActive},
555  {"childIdListForAccessibleObject", "(I)[I", (jintArray)childIdListForAccessibleObject},
556  {"parentId", "(I)I", (void*)parentId},
557  {"descriptionForAccessibleObject", "(I)Ljava/lang/String;", (jstring)descriptionForAccessibleObject},
558  {"screenRect", "(I)Landroid/graphics/Rect;", (jobject)screenRect},
559  {"hitTest", "(FF)I", (void*)hitTest},
560  {"populateNode", "(ILandroid/view/accessibility/AccessibilityNodeInfo;)Z", (void*)populateNode},
561  {"clickAction", "(I)Z", (void*)clickAction},
562  {"scrollForward", "(I)Z", (void*)scrollForward},
563  {"scrollBackward", "(I)Z", (void*)scrollBackward},
564  };
565 
566 #define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \
567  VAR = env->GetMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \
568  if (!VAR) { \
569  __android_log_print(ANDROID_LOG_FATAL, QtAndroid::qtTagText(), QtAndroid::methodErrorMsgFmt(), METHOD_NAME, METHOD_SIGNATURE); \
570  return false; \
571  }
572 
573  bool registerNatives(JNIEnv *env)
574  {
575  jclass clazz;
576  FIND_AND_CHECK_CLASS("org/qtproject/qt/android/accessibility/QtNativeAccessibility");
577  jclass appClass = static_cast<jclass>(env->NewGlobalRef(clazz));
578 
579  if (env->RegisterNatives(appClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
580  __android_log_print(ANDROID_LOG_FATAL,"Qt A11y", "RegisterNatives failed");
581  return false;
582  }
583 
584  jclass nodeInfoClass = env->FindClass("android/view/accessibility/AccessibilityNodeInfo");
585  GET_AND_CHECK_STATIC_METHOD(m_addActionMethodID, nodeInfoClass, "addAction", "(I)V");
586  GET_AND_CHECK_STATIC_METHOD(m_setCheckableMethodID, nodeInfoClass, "setCheckable", "(Z)V");
587  GET_AND_CHECK_STATIC_METHOD(m_setCheckedMethodID, nodeInfoClass, "setChecked", "(Z)V");
588  GET_AND_CHECK_STATIC_METHOD(m_setClickableMethodID, nodeInfoClass, "setClickable", "(Z)V");
589  GET_AND_CHECK_STATIC_METHOD(m_setContentDescriptionMethodID, nodeInfoClass, "setContentDescription", "(Ljava/lang/CharSequence;)V");
590  GET_AND_CHECK_STATIC_METHOD(m_setEditableMethodID, nodeInfoClass, "setEditable", "(Z)V");
591  GET_AND_CHECK_STATIC_METHOD(m_setEnabledMethodID, nodeInfoClass, "setEnabled", "(Z)V");
592  GET_AND_CHECK_STATIC_METHOD(m_setFocusableMethodID, nodeInfoClass, "setFocusable", "(Z)V");
593  GET_AND_CHECK_STATIC_METHOD(m_setFocusedMethodID, nodeInfoClass, "setFocused", "(Z)V");
595  GET_AND_CHECK_STATIC_METHOD(m_setHeadingMethodID, nodeInfoClass, "setHeading", "(Z)V");
596  }
597  GET_AND_CHECK_STATIC_METHOD(m_setScrollableMethodID, nodeInfoClass, "setScrollable", "(Z)V");
598  GET_AND_CHECK_STATIC_METHOD(m_setVisibleToUserMethodID, nodeInfoClass, "setVisibleToUser", "(Z)V");
599  GET_AND_CHECK_STATIC_METHOD(m_setTextSelectionMethodID, nodeInfoClass, "setTextSelection", "(II)V");
600 
601  return true;
602  }
603 }
604 
small capitals from c petite p scientific f u
Definition: afcover.h:88
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE)
#define FIND_AND_CHECK_CLASS(CLASS_NAME)
@ Float
@ Double
The QAccessibleActionInterface class implements support for invocable actions in the interface.
Definition: qaccessible.h:632
static const QString & decreaseAction()
static const QString & toggleAction()
virtual QStringList actionNames() const =0
virtual void doAction(const QString &actionName)=0
static const QString & increaseAction()
static const QString & pressAction()
static Id uniqueId(QAccessibleInterface *iface)
static QAccessibleInterface * accessibleInterface(Id uniqueId)
The QAccessibleInterface class defines an interface that exposes information about accessible objects...
Definition: qaccessible.h:459
QAccessibleValueInterface * valueInterface()
Definition: qaccessible.h:498
virtual bool isValid() const =0
QAccessibleTextInterface * textInterface()
Definition: qaccessible.h:492
virtual QAccessible::Role role() const =0
virtual QAccessible::State state() const =0
virtual QAccessibleInterface * childAt(int x, int y) const =0
virtual QWindow * window() const
virtual int childCount() const =0
virtual QString text(QAccessible::Text t) const =0
QAccessibleActionInterface * actionInterface()
Definition: qaccessible.h:501
virtual QAccessibleInterface * parent() const =0
virtual QAccessibleInterface * child(int index) const =0
virtual QRect rect() const =0
The QAccessibleTextInterface class implements support for text handling.
Definition: qaccessible.h:526
virtual void selection(int selectionIndex, int *startOffset, int *endOffset) const =0
virtual int selectionCount() const =0
The QAccessibleValueInterface class implements support for objects that manipulate a value.
Definition: qaccessible.h:569
virtual QVariant minimumStepSize() const =0
virtual QVariant currentValue() const =0
virtual QPlatformAccessibility * accessibility() const override
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:84
@ Space
Definition: qchar.h:92
The QJniEnvironment class provides access to the JNI Environment (JNIEnv).
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes.
Definition: qmutex.h:317
The QObject class is the base class of all Qt objects.
Definition: qobject.h:125
void deleteLater()
Definition: qobject.cpp:2319
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:52
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:59
The QString class provides a Unicode character string.
Definition: qstring.h:388
bool isEmpty() const
Definition: qstring.h:1216
static QString number(int, int base=10)
Definition: qstring.cpp:7538
The QStringList class provides a list of strings.
qsizetype count() const
T * data() noexcept
void append(const T &t)
void reserve(qsizetype sz)
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:95
double toDouble(bool *ok=nullptr) const
Definition: qvariant.cpp:1929
QString toString() const
Definition: qvariant.cpp:1416
int typeId() const
Definition: qvariant.h:241
The QWindow class represents a window in the underlying windowing system.
Definition: qwindow.h:99
float step
rect
[4]
backing_store_ptr info
[4]
Definition: jmemsys.h:161
QPainterPath node()
Definition: paths.cpp:574
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)
void notifyLocationChange(uint accessibilityObjectId)
void runInObjectContext(QObject *context, Func &&func, Ret *retVal)
void notifyObjectFocus(uint accessibilityObjectId)
QAccessibleInterface * interfaceFromId(jint objectId)
void createAccessibilityContextObject(QObject *parent)
void notifyObjectHide(uint accessibilityObjectId)
void notifyValueChanged(uint accessibilityObjectId)
void notifyAccessibilityLocationChange(uint accessibilityObjectId)
QBasicMutex * platformInterfaceMutex()
QAndroidPlatformIntegration * androidPlatformIntegration()
void notifyObjectFocus(uint accessibilityObjectId)
void notifyValueChanged(uint accessibilityObjectId, jstring value)
jclass applicationClass()
void notifyObjectHide(uint accessibilityObjectId, uint parentObjectId)
Q_CORE_EXPORT jint androidSdkVersion()
@ BlockingQueuedConnection
Definition: qnamespace.h:1308
@ QueuedConnection
Definition: qnamespace.h:1307
action
Definition: devices.py:78
#define qApp
EGLOutputLayerEXT EGLint EGLAttrib value
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition: qfloat16.h:233
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition: qfloat16.h:249
unsigned int uint
Definition: qglobal.h:334
GLenum type
Definition: qopengl.h:270
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLenum GLenum GLsizei count
GLint y
GLenum func
Definition: qopenglext.h:663
GLuint GLfloat * val
Definition: qopenglext.h:1513
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
GLdouble s
[6]
Definition: qopenglext.h:235
GLenum GLint GLint * precision
Definition: qopenglext.h:1890
QPointF qAbs(const QPointF &p)
Definition: qscroller.cpp:119
@ desc
QWidget * win
Definition: settings.cpp:53
QReadWriteLock lock
[0]
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())
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent