Ticket #57 (closed defect: fixed)

Opened 4 years ago

Last modified 4 years ago

NVDA virtual buffer navigation does not synchronize with onscreen focus

Reported by: vtsaran Owned by: jteh
Priority: major Milestone:
Component: Browse mode Version: development
Keywords: virtual buffer navigation onscreen focus Cc:
Operating system: Blocked by:
Blocking:

Description

Currently, NVDA virtual buffer navigation is not synchronized with onscreen navitation such as tabbing from element to elemen or clicking the element with a mouse.
Repro steps:

  1. Load a web page with headings or other HTML elements that you can jump to using NVDA's navigation keys.
  2. Jump to one of the elements, e.g. the first heading on the page.
  3. Now press the TAB key.

Current behavior:
NVDA focuses on the first element on the page.
Expected behavior:
NVDA should focus on the tabbable element which is immediately after the one on which virtual cursor is located.

Change History

comment:1 Changed 4 years ago by pvagner

I was already trying to do something for this but I failed. So here are my thoughts at least:
When navigating to non-focusable objects such as heading NVDA should search for first focusable object in the backwards direction where the user is coming from. E.G. I hit h for next heading. NVDA finds the next available heading, then searches for the prewious focusable object and sets focus to it. Finally it sets navigator object to the heading I was originally about to swith to and reports it. The only think I am not able to figure out my-self is how to search for the focusable object.

comment:2 Changed 4 years ago by vtsaran

You can probably assume that any element that is a link or a form element is a focusable object. Otherwise, you should be able to extract a "focusable" bit from the value of State.
Perhaps this page will help:
 http://www.mozilla.org/access/windows/at-apis

comment:3 Changed 4 years ago by pvagner

yes this is what I am also thinking about. We can simply trust IA2 in this case.
The bit I fail to understand is what to add into the _searchableAttribsForNodeType() method when I don't want to search by role just by state. What should it return? That return value is not clear for me.
I believe Mick or Jamie is able to clear this up.
we already have an example when looking by role e.g. {"IAccessible::role":[IAccessibleHandler.IA2_ROLE_HEADING]}
Also we already have an example when we are interested in both role and state E.G. {"IAccessible::role":[IAccessibleHandler.ROLE_SYSTEM_LINK],"IAccessible::state_%d"%IAccessibleHandler.STATE_SYSTEM_LINKED:[1]}
but when skipping that part with role I am getting exceptions. For sure this is very simple thing I am just stupid enought to not being able to pass through it at this point.
Thanks for your interest anyway. I am sure we will get this sorted soon.

comment:4 follow-ups: ↓ 5 ↓ 8 Changed 4 years ago by jteh

I think there are two separate (but related) issues that actually need to be addressed here:

  • NVDA needs to scroll the screen to include the object under the virtual buffer cursor.
    • Setting focus to the previous/next focusable object is not enough. This is because where there is a large amount of text containing no focusable objects, there is nothing to which to set focus that would bring this into view on screen.
  • Tab and shift+tab should move to the next and previous focusable object, respectively.
    • Peter's solution to this problem might work, but:
      • It is expensive. Every time the cursor moves, the focus would be set. I suspect this would incur a major performance penalty.
      • Setting focus will trigger a focus event, which will cause the virtual cursor to bounce to that object. Flags and logic would have ot be implemented to stop this from happening.
      • Setting focus to the previous focusable object is correct for the tab key, but it would be incorrect for shift+tab. For example, if located on a heading and the focus was set to a link before the heading, pressing shift+tab would take you to the focusable object *before* the link, which is actually two focusable objects before the heading.
      • If there are onFocus events, these will be triggered, which might be undesirable if the user is nowhere near the object in question.
    • Thus, although I am not a fan of overriding application provided keystrokes, I think we need to override tab and shift+tab as is done in several other screen readers.
      • Tab and shift+tab would search for and move to the next and previous objects, respectively.
      • One problem with this approach is that the tab order specified by the page author is overridden. Arguably, this is not a good thing. Thus, I am actually wondering whether we should really be overriding the tab order at all.
      • Note that the tab order already works correctly if the user cursors over a focusable object because this will cause focus to be set to that object. It is only a problem when jumping with quick navigation keys.

comment:5 in reply to: ↑ 4 ; follow-up: ↓ 6 Changed 4 years ago by jteh

Replying to jteh:

One problem with [the approach of overriding tab and shift+tab] is that the tab order specified by the page author is overridden.

The solution to this problem is to only override if the cursor is not within a field. That is, if the cursor is within a field, tab and shift+tab behave normally, thus honouring the page's tab order until the user manually moves the cursor.

comment:6 in reply to: ↑ 5 Changed 4 years ago by jteh

Replying to jteh:

The solution to this problem is to only override if the cursor is not within a field.

Correction: Only override if the cursor is not within the node which currently has the focus.

To make this determination, we get the focus object, grab its offsets in the buffer and determine whether the cursor is within these offsets. If it is, tab/shift+tab should be passed through. Otherwise, tab/shift+tab are overridden as described above.

comment:7 in reply to: ↑ description Changed 4 years ago by jteh

  • Status changed from new to assigned

Replying to vtsaran:

Currently, NVDA virtual buffer navigation is not synchronized with onscreen navitation such as tabbing from element to elemen or clicking the element with a mouse.

Actually, this description does not seem to be quite correct to me. What do you mean by the navigation not being synchronised with clicking elements with a mouse? If the user clicks a focusable element with the mouse, the element will receive focus and the virtual buffer cursor will update accordingly. The same occurs for tab. The issue here is not that NVDA doesn't synchronise with focus. The issue is that the tab key should move to the next focusable element relative to the virtual buffer cursor. Is this a correct summary of the request?

comment:8 in reply to: ↑ 4 ; follow-up: ↓ 9 Changed 4 years ago by jteh

Replying to jteh:

  • NVDA needs to scroll the screen to include the object under the virtual buffer cursor.

IAccessible2's scrollTo method only has constants for scrolling an object to different positions on the screen, but no constant to just scroll the screen as necessary to bring the object on screen. However, Mozilla define their own constant, SCROLL_TYPE_ANYWHERE, for this purpose. This has a value of 0x06. We should be able to use scrollTo with 0x06 to achieve what we want.

comment:9 in reply to: ↑ 8 Changed 4 years ago by jteh

Replying to jteh:

Replying to jteh:

  • NVDA needs to scroll the screen to include the object under the virtual buffer cursor.

We should be able to use scrollTo with 0x06 to achieve what we want.

Implemented by Mick in r2073.

comment:10 Changed 4 years ago by jteh

Tab order override implemented in r2114.

comment:11 Changed 4 years ago by jteh

  • Status changed from assigned to closed
  • Resolution set to fixed
Note: See TracTickets for help on using tickets.