Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limit list item quick navigation to current list #8193

Open
LeonarddeR opened this issue Apr 19, 2018 · 18 comments
Open

Limit list item quick navigation to current list #8193

LeonarddeR opened this issue Apr 19, 2018 · 18 comments

Comments

@LeonarddeR
Copy link
Collaborator

LeonarddeR commented Apr 19, 2018

Original idea by @bramd

Description of proposal

The current quick navigation command for list items jumps from list item to list item, thereby ignoring list boundaries. For example:

  • First level, 1

    • Second level, 1
    • Second level, 2
  • First level, 2

  • First level, 3

Piece of text

  1. New list

When using the quick navigation command for list items, every single list item will be navigated. I propose that the list item quicknav command doesn't pass list boundaries (i.e. when First level, 3 has focus in the above example, pressing "i" should report "No next item in current list" rather than jump to New list

Thoughts are welcome. Also, I'd like to invite @bramd to give more information about possible use cases.

@DrSooom
Copy link

DrSooom commented May 14, 2018

See: #5906, #6815, #7804, #8103

I was thinking about this quite a while and found no satisfied solution. We can change the behaviour for I and Shift+I in that case that you have to press it twice to move up/back into a parent list, but in the end this could confuse more than it helps.

So, I'm asking me if it is possible to use tones (and speech) to present the level of the list similar to the line indentation (#5906). If the "lists"-checkbox in the document settings is enabled, "clst*" could be displayed on the braille display as well. "*" represents the level of the child list – to be exactly the distance between the current child list and the highest parent list. And if a list contains one or more child lists, "lst+" instead of "lst" could be shown – and of course spoken by NVDA as well.

  • Parent list, lowest tone, 110 Hz
    • First level child list, tone frequency is equal to the line indentation of 3 spaces
      • Second level child list, tone frequency is equal to the line indentation of 6 spaces
  • Well, and the highest tone frequency is reached with the 10th child list (30 spaces). Child lists above the 10th level will have the same tone frequency like the 10th one's.

Regarding to this tone feedback the user immediately knows on which list level the cursor currently is. So because of that changing the behaviours of I, L and Comma for lists isn't required anymore.

@JulienCochuyt
Copy link
Collaborator

As proposed in #9227 (comment) I'd propose to further extend this limitation to headers.
Eg. pressing 2 would only move to the next H2 within the limits of the same H1.
UX could go something like "no next/previous X in current Y, press again to search outside"

This could even later be extended to radio buttons groups and tab headers lists, effectively turning "i" to "items", not only "list items": Eg. have "r" move to the radio buttons group (ideally to the selected element) and "i" to individual radio buttons within the group.

@lukaszgo1 wrote in #9227 (comment)

JAWS developers used this approach a few years ago. From user perspective this was very confusing. The final argument against this is the fact that Vispero changed this behavior to make it like NVDA. It looks like it had its problems.

What was their UX back then? (I'm apparently specialized in NVDA for too long)
Did they include the proposed easy bypass mechanism of pressing twice and informative announcements?
We included ability to restrict both quick nav and tab nav to a given zone in WebAccess with quite good user feedback so far. (zones there are quite similar to regions but can be set to encompass any node's subtree)

Also, this new behavior could be configurable, preferably IMHO active by default.

@LeonarddeR
Copy link
Collaborator Author

LeonarddeR commented Oct 29, 2019 via email

@JulienCochuyt
Copy link
Collaborator

JulienCochuyt commented Oct 29, 2019

@LeonarddeR wrote:

These are lovely ideas!

Thanks for your enthusiasm!

The logic could be implemented either:

  • centrally in BrowseModeTreeInterceptor._quickNavScript: Easy and smaller impact
  • in each BrowseModeTreeInterceptor._iterNodesByType implementation: Potentially slightly more efficient, but with a much wider impact.

I'd go for the central approach, but what do you think?

@LeonarddeR
Copy link
Collaborator Author

LeonarddeR commented Oct 29, 2019 via email

@JulienCochuyt
Copy link
Collaborator

JulienCochuyt commented Oct 29, 2019

@LeonarddeR wrote:

I Understand that you prefer the global approach, however especcially for UIA, i'm afraid the performance impact will be major if not done in the tree interceptor directly. UIA quicknav is still far from ideal.

Having a look at UIABrowseMode.UIAHeadingQuicknavIterator I think I understand your concerns.

The advantage of the central approach was that the new constraints could easily be expressed in new arguments to the BrowseModeTreeInterceptor.addQuickNav, something like limit=("next", "heading1") for a heading2 or limit=("up", "list") for a listitem.

Maybe a mixture of both approaches could do the trick. In BrowseModeTreeInterceptor._quickNavScript:

  • If self._iterNodesByTypes.implementsLimit, pass the limit parameter and catch a dedicated exception to trigger the specialized message. The function attribute would spare coupling browseMode with VirtualBuffer and the dedicated exception would allow to avoid coupling UIABrowseMode with ui.message
  • otherwise, check the boundaries in a generic way. This would leave all other implementations in the same place.

@DrSooom
Copy link

DrSooom commented Oct 29, 2019

@JulienCochuyt: The hierarchies of headlines are different to lists. Therefore I would separate them from this issue. It could get too complex if we're putting all into one single PR.

I also like your idea for headlines, but I want to have an option how the new "border" is announced by NVDA. I would prefer just a short beep tone and others could prefer speech output. Well, and it should be clear, that this new quick navigation behavior must be able to be enabled or disabled by the end user. Not all websites care about a useful and understandable headline hierarchy.

@lukaszgo1
Copy link
Contributor

@JulienCochuyt wrote:

As proposed in #9227 (comment) I'd propose to further extend this limitation to headers.
Eg. pressing 2 would only move to the next H2 within the limits of the same H1.
UX could go something like "no next/previous X in current Y, press again to search outside"

While I understand doing it for list items I do not see What would it improve for an end user in case of headings.

What was their UX back then? (I'm apparently specialized in NVDA for too long)
Did they include the proposed easy bypass mechanism of pressing twice and informative announcements?

My bad, I've completely missed the part about being able to jump to the next element outside of the region by pressing twice. No they do not, the only way in which it was possible to move to say the next h2 outside of the current h1, was to move first to the next 1 annd the to h2.

Also, this new behavior could be configurable, preferably IMHO active by default.

It has to be, mainly because they would be no other screen reader with such mode of navigation and for people migrating to NVDA it would be really confusing I think.

@JulienCochuyt
Copy link
Collaborator

@DrSooom wrote:

@JulienCochuyt: The hierarchies of headlines are different to lists. Therefore I would separate them from this issue. It could get too complex if we're putting all into one single PR.

This feature is actually quite simple to implement and both lists and headings would share here a great portion of the needed code.
The shared part is actually so important that splitting would lead to either:

  • wait for the first one to be merged before attempting to file the second one
  • or lead to unnecessary work for aligning both when reviewing.

Furthermore, I guess both features will probably meet the same opponents and advocates, thus I guess that for once there is good reasons for grouping.

@JulienCochuyt
Copy link
Collaborator

@lukaszgo1 wrote:

While I understand doing it for list items I do not see What would it improve for an end user in case of headings.

Consider a very long document, with dozens of nested headings, in which you'd want to skip whole parts but could not tell which ones to skip until reading the first few paragraphs.
In this context, if you are reading the first few paragraphs under a level 2 heading and realize you want to skip until the next one, you could currently either:

  • press H and deal with dozens of lower level headings
  • or press 2 and risk to land within the next level 1 heading without noticing, unwillingly skipping its title and introduction altogether
  • or you could of course try using the Elements List dialog, but it is sometimes so poorly responsive with longer documents that it can even be totally unusable.

@LeonarddeR
Copy link
Collaborator Author

* If `self._iterNodesByTypes.implementsLimit`, pass the limit parameter and catch a dedicated exception to trigger the specialized message. The function attribute would spare coupling `browseMode` with `VirtualBuffer` and the dedicated exception would allow to avoid coupling `UIABrowseMode` with `ui.message`

Just to make sure, are you suggesting that some implementations of _iterNodesByType would implement limit and others don't? I think that could be confusing for users.

* otherwise, check the boundaries in a generic way. This would leave all other implementations in the same place.

I agree that there should be a fallback for generic checking, but thinking more and more about this, may be _quickNavScript isn't the best place for this. Could a base implementation of _iterNodesByType in BrowseModeTreeInterceptor be of any help in this, or alternatively, a helper method that has either a generic implementation or for UIA, a specific implementation?

@JulienCochuyt
Copy link
Collaborator

@LeonarddeR wrote:

* If `self._iterNodesByTypes.implementsLimit`, pass the limit parameter and catch a dedicated exception to trigger the specialized message. The function attribute would spare coupling `browseMode` with `VirtualBuffer` and the dedicated exception would allow to avoid coupling `UIABrowseMode` with `ui.message`

Just to make sure, are you suggesting that some implementations of _iterNodesByType would implement limit and others don't? I think that could be confusing for users.

Yes indeed. With a proper explanation in the docstring of _iterNodesByType as well as a comment everywhere the function attribute is set.
My motivation was to limit API impact as much as possible.
(Disclaimer: Yes, this is mostly for ease of maintenance on WebAccess…)

* otherwise, check the boundaries in a generic way. This would leave all other implementations in the same place.

I agree that there should be a fallback for generic checking, but thinking more and more about this, may be _quickNavScript isn't the best place for this. Could a base implementation of _iterNodesByType in BrowseModeTreeInterceptor be of any help in this, or alternatively, a helper method that has either a generic implementation or for UIA, a specific implementation?

The UIA and Edge implementations are quite special in that they require the boundary check to be performed along with the regular search in order not to badly impact performance.
Thus, an external helper would not… help much IMHO.

Though, a base BrowseModeTreeInterceptor.iterNodesByType (without the leading underscore and with the limit kwarg) could implement the generic boundary, and call the existing _iterNodesByType implementations without much API impact. UIA and Edge would then override the outer iterNodesByType and not the inner _iterNodesByType.

Would you prefer this approach?

Maybe would it be clearer with a draft prototype…

@LeonarddeR
Copy link
Collaborator Author

Though, a base BrowseModeTreeInterceptor.iterNodesByType (without the leading underscore and with the limit kwarg) could implement the generic boundary, and call the existing _iterNodesByType implementations without much API impact. UIA and Edge would then override the outer iterNodesByType and not the inner _iterNodesByType.

Would you prefer this approach?

Yes, I really like that idea actually. Probably best to have @michaelDCurran's opinion before creating a draft, though.

@michaelDCurran
Copy link
Member

I agree with the implementation proposal, and I agree that headings and lists could share the same code. I totally agree we should do this by default for list items, but I'm not totally convinced yet for headings. How about for the initial pr, support for list items is implemented, but in an abstract way such that it is very easy and clear to then add headings at a later date.

@DrSooom
Copy link

DrSooom commented Apr 30, 2020

Based on @feerrenrut's comment in issue #11069 and after reading the whole issue comments here I currently have no idea which behavior in which situations is wanted. Therefore here some questions – some suggestions are already mentioned above by different users, but nothing is fixed:

Headlines:

H, Shift+H, 1 to 6 and Shift+1 to Shift+6 jump in NVDA 2019.2.1 between h1 and h6 headlines. The numbers skips headlines on other headline levels.

  1. Should this behavior be changed for H and Shift+H?
  2. Should we add an option to stop jumping when skipping a headline on a different headline level?
  3. If so, which speech, braille and beep feedback is wanted before an additional press of 1 to 6 and Shit+1 to Shift+6 is performed to reach the next respectively the previous headline in the same headline level?

Lists:

L, Shift+L, I and Shift+I are using in NVDA 2019.2.1 to jump between lists and list items. Shift+Comma and Comma are used to jump to the beginning of a container (in this case a list) and outside of the current container in top-bottom-order.
4. Is a list level feedback like I described here wanted?
5. Should the behavior of Comma and Shift+Comma be changed?
6. Should the behavior of L and Shift+L be changed to the one which is currently used for 1 to 6 and Shift+1 to Shift+6 – skipping lists which aren't on the same list level?
7. If so, which speech, braille and beep feedback is wanted before an additional press of l and Shit+L is performed to reach the next respectively the previous list in the same list level?
8. Same question like No. 6 but for I and Shift+I.
9. If so, which speech, braille and beep feedback is wanted before an additional press of l and Shit+I is performed to reach the next respectively the previous list item in the same list level?

General questions:

  1. Which behaviors should be defined as default?
  2. Which behaviors should be make configurable by the end user?
  3. Should the end user have the option to set up speech, braille and beep feedback for which kind of feedback separately?

Notes:

  • A huge new config dialog for setting up speech, braille and beep output for almost all NVDA feedback messages is highly welcome – maybe only for advanced and power users. Thus making these configuration settings available via an additional "NVDA Power Toys" add-on in the near future would be really great. So I'm unsure how many options we should give the "normal" end users in the current NVDA Settings dialog.
  • Keep in mind that webmasters no always take care of the headline levels.
  • This behavior here will also take effect on Electron apps and in the Browse Mode in Microsoft Word 2010/2013/2016/2019.
  • It could also have effects on LibreOffice Writer 6.4, even if NVDA 2019.2.1 hasn't currently implemented the Browse Mode for LibreOffice Writer 6.4, but maybe a later version could have this feature.

@Adriani90
Copy link
Collaborator

@DrSooom I respectfully disagree with this approach. This makes things much too complicated. An enduser will know automatically when pressing 1, 2 or 3 or shift+1, +2or +3 between which heading levels NVDA will jump. We do not need extranious feedback here and it is clear that pressing 2 twice will skip all the other higher or lower heading levels as before.
I would not change the behavior of h and shift+h, this is consistent with all other quick navigation keys and this should be definitely stay as is.

Regarding lists, I would recomment a similar approach like we already have for headings.
For example nvda+shift+l could change numbers navigation from heading levels to list levels, nvda+shift+h would change the behavior of pressing numbers in browse mode from list levels back to heading levels. This is much simpler and would not overwelm anyone.

Another alternative would be to assign ctrl+numbers and ctrl+shift+ numbers to list level navigation but the key strokes are not very confortable for people with motoric disabilities.

To be honnest, I don't see a use case for which it would be useful to limit the navigation to current list. Lists are usually not that huge compared to tables for example.
cc: @feerrenrut

@feerrenrut
Copy link
Contributor

Sorry @DrSooom but this doesn't really help. This only makes this issue more uncertain, when it was basically all but agreed upon

I don't see a use case for which it would be useful to limit the navigation to current list.

@Adriani90 the reason this is important is that (good) lists and headings are often highly contextual and hierarchical. The information in sub-elements relate to the parent. In my opinion this should go further than just limiting to the list, it should limit to siblings at the current level. A good description of why is given by @JulienCochuyt in #8193 (comment)

My preference is to make the UI very simple:

  • PR 1: A single command that takes you to the next sibling list item of the same level.
  • PR 2: Extend to headings: If on a heading, takes you to the next sibling heading item of the same level.
  • PR 3: Optional: find a single free shortcut (or leave unassigned for now)

The goal: navigate hierarchical information structures where context is important.

I would prefer to avoid another conversation about which shortcut to use, let's first agree on the behavior. A PR can introduce the command with no default gesture. If we can get agreement on a default gesture, then a subsequent PR can assign that.

@DrSooom
Copy link

DrSooom commented May 2, 2020

Another suggestion:

  • NVDA+Shift+H: Enable/Disable headline level limitation
  • NVDA+Shift+L: Enable/Disable list level limitation
  • NVDA+Shift+I: Enable/Disable list item level limitation
  • 7 to 9 and Shift+7 to Shift+9: Jump to the next/previous list item located at list level 1 to 3.

Notes:

  • The default behaviors for (Shift+)H, (Shift+)L, (Shift+)I and (Shift+)1 to (Shift+)6 aren't changed. But the end user should get the option to enable these limitations by default in the Browse Mode NVDA Settings via three simple checkboxes.
  • CTRL+1 to CTRL+9 jump to the corresponding tab in Mozilla Firefox and CTRL+0 sets the zoom level back to 100 %. So these keys shouldn't be used in Browse Mode.
  • 0 should be leave unallocated in Browse Mode because on YouTube – and maybe also on other websites with an audio/video player – pressing 0 starts the media playback from the beginning. It would be nice if this "feature" still work in Browse Mode, and not only in Focus Mode. But on the other hand the end user can change this hotkey in the Input Gestures Dialog. Well, and lists with more than three levels are also rare – unless they contain the TOC of course.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants