Android A11Y: handle LocationChanged event only for focused element

LocationChanged event unconditionally triggered invalidateVirtualViewId
call. That call results in TYPE_WINDOW_CONTENT_CHANGED Android event,
which causes a lot of background processing.
That is not correct, because LocationChanged event is generated by
every accessible element, not only the one that has A11Y focus.

This patch checks event->uniqueId(), and processes only events that
come from the focused accessible element.

Done-with: Mike Achtelik <mike.achtelik@gmail.com>
Task-number: QTBUG-102594
Pick-to: 6.3 6.2 5.15
Change-Id: I6b941733c9d215fed5ee5a7aeeb5be234add9ebe
Reviewed-by: Mike Achtelik <mike.achtelik@gmail.com>
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
This commit is contained in:
Ivan Solovev 2022-05-10 16:01:48 +02:00
parent 53ee4c8b1f
commit 0613146d21
9 changed files with 17 additions and 15 deletions

View File

@ -949,11 +949,11 @@ public class QtActivityDelegate
m_splashScreen.startAnimation(fadeOut); m_splashScreen.startAnimation(fadeOut);
} }
public void notifyAccessibilityLocationChange() public void notifyAccessibilityLocationChange(int viewId)
{ {
if (m_accessibilityDelegate == null) if (m_accessibilityDelegate == null)
return; return;
m_accessibilityDelegate.notifyLocationChange(); m_accessibilityDelegate.notifyLocationChange(viewId);
} }
public void notifyObjectHide(int viewId, int parentId) public void notifyObjectHide(int viewId, int parentId)

View File

@ -973,13 +973,13 @@ public class QtNative
return m_activityDelegate.isKeyboardVisible() && !m_isKeyboardHiding; return m_activityDelegate.isKeyboardVisible() && !m_isKeyboardHiding;
} }
private static void notifyAccessibilityLocationChange() private static void notifyAccessibilityLocationChange(final int viewId)
{ {
runAction(new Runnable() { runAction(new Runnable() {
@Override @Override
public void run() { public void run() {
if (m_activityDelegate != null) { if (m_activityDelegate != null) {
m_activityDelegate.notifyAccessibilityLocationChange(); m_activityDelegate.notifyAccessibilityLocationChange(viewId);
} }
} }
}); });

View File

@ -193,9 +193,10 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate
return true; return true;
} }
public void notifyLocationChange() public void notifyLocationChange(int viewId)
{ {
invalidateVirtualViewId(m_focusedVirtualViewId); if (m_focusedVirtualViewId == viewId)
invalidateVirtualViewId(m_focusedVirtualViewId);
} }
public void notifyObjectHide(int viewId, int parentId) public void notifyObjectHide(int viewId, int parentId)

View File

@ -1133,9 +1133,9 @@ public class QtActivity extends Activity
QtNative.activityDelegate().updateSelection(selStart, selEnd, candidatesStart, candidatesEnd); QtNative.activityDelegate().updateSelection(selStart, selEnd, candidatesStart, candidatesEnd);
} }
public void notifyAccessibilityLocationChange() public void notifyAccessibilityLocationChange(int viewId)
{ {
QtNative.activityDelegate().notifyAccessibilityLocationChange(); QtNative.activityDelegate().notifyAccessibilityLocationChange(viewId);
} }
public void notifyObjectHide(int viewId, int parentId) public void notifyObjectHide(int viewId, int parentId)

View File

@ -135,9 +135,9 @@ namespace QtAndroidAccessibility
return iface; return iface;
} }
void notifyLocationChange() void notifyLocationChange(uint accessibilityObjectId)
{ {
QtAndroid::notifyAccessibilityLocationChange(); QtAndroid::notifyAccessibilityLocationChange(accessibilityObjectId);
} }
static int parentId_helper(int objectId); // forward declaration static int parentId_helper(int objectId); // forward declaration

View File

@ -51,7 +51,7 @@ namespace QtAndroidAccessibility
void initialize(); void initialize();
bool isActive(); bool isActive();
bool registerNatives(JNIEnv *env); bool registerNatives(JNIEnv *env);
void notifyLocationChange(); void notifyLocationChange(uint accessibilityObjectId);
void notifyObjectHide(uint accessibilityObjectId); void notifyObjectHide(uint accessibilityObjectId);
void notifyObjectFocus(uint accessibilityObjectId); void notifyObjectFocus(uint accessibilityObjectId);
void notifyValueChanged(uint accessibilityObjectId); void notifyValueChanged(uint accessibilityObjectId);

View File

@ -210,9 +210,10 @@ namespace QtAndroid
QJniObject::callStaticMethod<void>(m_applicationClass, "setSystemUiVisibility", "(I)V", jint(uiVisibility)); QJniObject::callStaticMethod<void>(m_applicationClass, "setSystemUiVisibility", "(I)V", jint(uiVisibility));
} }
void notifyAccessibilityLocationChange() void notifyAccessibilityLocationChange(uint accessibilityObjectId)
{ {
QJniObject::callStaticMethod<void>(m_applicationClass, "notifyAccessibilityLocationChange"); QJniObject::callStaticMethod<void>(m_applicationClass, "notifyAccessibilityLocationChange",
"(I)V", accessibilityObjectId);
} }
void notifyObjectHide(uint accessibilityObjectId, uint parentObjectId) void notifyObjectHide(uint accessibilityObjectId, uint parentObjectId)

View File

@ -100,7 +100,7 @@ namespace QtAndroid
jobject createBitmap(int width, int height, QImage::Format format, JNIEnv *env); jobject createBitmap(int width, int height, QImage::Format format, JNIEnv *env);
jobject createBitmapDrawable(jobject bitmap, JNIEnv *env = nullptr); jobject createBitmapDrawable(jobject bitmap, JNIEnv *env = nullptr);
void notifyAccessibilityLocationChange(); void notifyAccessibilityLocationChange(uint accessibilityObjectId);
void notifyObjectHide(uint accessibilityObjectId, uint parentObjectId); void notifyObjectHide(uint accessibilityObjectId, uint parentObjectId);
void notifyObjectFocus(uint accessibilityObjectId); void notifyObjectFocus(uint accessibilityObjectId);
void notifyValueChanged(uint accessibilityObjectId, jstring value); void notifyValueChanged(uint accessibilityObjectId, jstring value);

View File

@ -61,7 +61,7 @@ void QAndroidPlatformAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *
// so that the element can be moved on the screen if it's focused. // so that the element can be moved on the screen if it's focused.
if (event->type() == QAccessible::LocationChanged) { if (event->type() == QAccessible::LocationChanged) {
QtAndroidAccessibility::notifyLocationChange(); QtAndroidAccessibility::notifyLocationChange(event->uniqueId());
} else if (event->type() == QAccessible::ObjectHide) { } else if (event->type() == QAccessible::ObjectHide) {
QtAndroidAccessibility::notifyObjectHide(event->uniqueId()); QtAndroidAccessibility::notifyObjectHide(event->uniqueId());
} else if (event->type() == QAccessible::Focus) { } else if (event->type() == QAccessible::Focus) {