summaryrefslogtreecommitdiff
path: root/src/android
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2022-02-08 14:27:30 +0100
committerIvan Solovev <ivan.solovev@qt.io>2022-02-09 21:46:25 +0100
commit7c00ad4e9a950e4c3493a417895169f1c936ea51 (patch)
treee451fa2a59f357cbe047e1128eb5a1d6ab9d72a4 /src/android
parent0a24e2e984afdbb44c5462038fa6059dc73520d8 (diff)
downloadqtbase-7c00ad4e9a950e4c3493a417895169f1c936ea51.tar.gz
Android: Re-focus focused accessibility node after orientation change
Before this patch the accessibility focus on a selected element could be drawn incorrectly after the screen orientation has changed. The reason for that is that wrong X and Y offsets were used for it. The offsets are used to take the sizes of different panels (like buttons and notifications bar) into account. Normally they are updated only when getNodeForView() is called and the whole accessibility info is reconstructed. However, when the screen orientation changes, we get some getNodeForVirtualViewId(selectedId) calls before the whole accessibility tree is recreated. This is when redrawing happens, and as I understand, this is an internal Android event, so we can't do much about it. The most straightforward fix for the problem would be to query the offsets also in each getNodeForVirtualViewId() call. However, offset calculation seems to be quite heavy operation, and getNodeForVirtualViewId can be called very often (esp. if we have a lot of UI elements). As a result, this fix can't be implemented. In this patch I came up with the second approach - once getNodeForView() is called, and it detects that the offsets have changed, we force re-focus of the currently selected element. This allows us to retain the offsets-caching mechanism. Fixes: QTBUG-93402 Pick-to: 6.3 6.2 5.15 Change-Id: Ic420afe1fe5e80fbdf91b2b2651f2daa71c6e44d Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
Diffstat (limited to 'src/android')
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/accessibility/QtAccessibilityDelegate.java18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/android/jar/src/org/qtproject/qt/android/accessibility/QtAccessibilityDelegate.java b/src/android/jar/src/org/qtproject/qt/android/accessibility/QtAccessibilityDelegate.java
index 72c1e4f023..d31a4fe78f 100644
--- a/src/android/jar/src/org/qtproject/qt/android/accessibility/QtAccessibilityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt/android/accessibility/QtAccessibilityDelegate.java
@@ -89,6 +89,8 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate
// this is because the Android platform window does not take
// the offset of the view on screen into account (eg status bar on top)
private final int[] m_globalOffset = new int[2];
+ private int m_oldOffsetX = 0;
+ private int m_oldOffsetY = 0;
private class HoverEventListener implements View.OnHoverListener
{
@@ -327,6 +329,22 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate
for (int i = 0; i < ids.length; ++i)
result.addChild(m_view, ids[i]);
+ // The offset values have changed, so we need to re-focus the
+ // currently focused item, otherwise it will have an incorrect
+ // focus frame
+ if ((m_oldOffsetX != offsetX) || (m_oldOffsetY != offsetY)) {
+ m_oldOffsetX = offsetX;
+ m_oldOffsetY = offsetY;
+ if (m_focusedVirtualViewId != INVALID_ID) {
+ m_nodeProvider.performAction(m_focusedVirtualViewId,
+ AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS,
+ new Bundle());
+ m_nodeProvider.performAction(m_focusedVirtualViewId,
+ AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS,
+ new Bundle());
+ }
+ }
+
return result;
}