Skip to content

Commit

Permalink
TEMPORARY - Screen reader mode for testing
Browse files Browse the repository at this point in the history
  • Loading branch information
ZeroInternalReflection committed Mar 11, 2024
1 parent d2faac4 commit 12226bf
Show file tree
Hide file tree
Showing 3 changed files with 364 additions and 77 deletions.
165 changes: 155 additions & 10 deletions doc/USER_INTERFACE_AND_ACCESSIBILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,42 @@ text to show correctly.

## Compatibility with screen readers

There are people who use screen readers to play Cataclysm DDA. In order for screen
readers to announce the most important information in a UI, the terminal cursor has
to be placed at the correct location. This information may be text such as selected
item names in a list, etc, and the cursor has to be placed exactly at the beginning
of the text for screen readers to announce it. (Note: from my test with an Ubuntu
VM, if the cursor is placed after the end of the text, the cursor might be wrapped
to the next line and cause the screen reader to announce the text incorrectly. It
also seems to be easier for people to control the screen reader to read from the
beginning of the text where the cursor is placed.)
There are people who use screen readers to play Cataclysm DDA. There are several
things to keep in mind when checking the user interface for compatibility with
screen readers. These include:

1. Screen reader mode:
An option ("SCREEN_READER_MODE") has been added where the user can indicate that
they are using a screen reader. If a change to the UI to optimize for screen
readers would be undesirable for other users, consider checking against
"SCREEN_READER_MODE", and including the change when true.

2. Text color:
Text color is not announced by screen readers. If key information is only
communicated to the player through text color, that information will not be
available to players using screen readers. For example, a simple
uilist where some options have been disabled:

----------------------------------------------------------------------------
|Execute which action? |
|--------------------------------------------------------------------------|
|<color_c_green>1</color> <color_c_light_gray>Cut up an item</color> |
|<color_c_green>f</color> <color_c_light_gray>Start a fire quickly</color> |
|<color_c_dark_gray>h Use holster</color> |
----------------------------------------------------------------------------

A screen reader user will only know that "Use holster" is unavailable when they
attempt to use it. When presenting information, consider hiding inaccessible
options and adding text to confirm information conveyed by text color. As an
example, the display of food spoilage status:

<color_c_light_blue>Acorns (fresh)</color>
<color_c_yellow>Acorns (old)</color>

3. Cursor placement
In general, screen readers will start reading where the program has set the terminal
cursor. Thus, the cursor should be set to the beginning of the most important
section of the UI.

The recommended way to place the cursor is to use `ui_adaptor`. This ensures the
desired cursor position is preserved when subsequent output code changes the
Expand All @@ -62,4 +89,122 @@ For debugging purposes, you can set the `DEBUG_CURSES_CURSOR` compile flag to
always show the cursor in the terminal (currently only works with the curses
build).

For more information and examples, please see the documentation in `ui_manager.h`.
4. Window layout
While setting the terminal cursor position is sufficient to set things up for
screen readers in many cases, there are caveats to this. Screen readers will also
attempt to detect text changes. If that text change is after the terminal cursor,
the screen reader may skip over text. As an example (terminal position noted
by X):

XEye color: amber

changing into

XEye color: blue

The screen reader will only read the word "blue", even though the cursor is
set to start reading at "Eye".

Another complication is if the screen reader detects text changes above the
terminal cursor. As an example:

Lifestyle: underpowered
XStrength: 8

changing into

Lifestyle: weak
XStrength: 9

The screen reader will start reading at "weak".

Behaviour like this means that screen readers struggle with certain common UI
layouts. Examples of how to implement SCREEN_READER_MODE in various UI layouts
can be found in src/newcharacter.cpp.

Note: In all following examples, the terminal cursor is marked "X".

4a. List with additional information at the top or bottom:

-----------------------------------------------------
|Choose type of butchery: |
|---------------------------------------------------|
XB Quick butchery 6 minutes |
|b Full butchery 39 minutes |
|---------------------------------------------------|
|This technique is used when you are in a hurry, but|
|still want to harvest something from the corpse. |
-----------------------------------------------------
Figure 4ai - List with details at the bottom, current configuration

If the cursor is set at "Quick butchery", then the screen reader will read all of the
other options before getting to the description of what "Quick butchery" entails. The
preferred layout in SCREEN_READER_MODE is the following:

-----------------------------------------------------
|Choose type of butchery: |
|---------------------------------------------------|
| |
| |
|---------------------------------------------------|
XB Quick butchery 6 minutes |
|This technique is used when you are in a hurry, but|
-----------------------------------------------------
Figure 4aii - List with details at the bottom, recommended "SCREEN_READER_MODE"

That is:
1. Add the currently-selected list entry to the detail pane at the bottom, and
2. Disable display of the list of options.
The screen reader user can then scroll through the list of available options, only
hearing about the details of the currently-selected option.

Hiding the list of options is necessary even when the cursor is set to point X.
In addition to following the terminal cursor, screen readers will try to detect when
text changes, and can be misled by scrolling text. As an example:

-----------------------------------------------------
|Choose type of butchery: |
|---------------------------------------------------|
Yb Full butchery 39 minutes |
|f Field dress corpse 5 minutes |
|---------------------------------------------------|
XThis technique is used to properly butcher a corpse|
|and requires a rope & a tree or a butchering rack, |
-----------------------------------------------------
Figure 4aiii - List with details at the bottom with scrolling issues

When the list scrolls, the text at the top changes, and the screen reader will
'helpfully' start reading at point Y rather than the current cursor position X.

4b. List with additional information at the side:

_______________________________
|List | Details relating to|
XItem 1 | item 1. Lorem |
|Item 2 | ipsum |
|Item 3 | |
|Item 4 | |
|Item 5 | |
-------------------------------
Figure 4bi - List with details at the side, current configuration

In this common layout, the screen reader is unable to differentiate between the two
panes, and ends up reading the list interwoven with the details of the currently-selected
item. This is true whether the terminal cursor is set to the current item or to the top
left of the details pane.

The recommended layout in SCREEN_READER_MODE is the following:

_______________________________
| | XItem 1 |
| | Details relating to|
| | item 1. Lorem |
| | ipsum |
| | |
| | |
-------------------------------
Figure 4bii - List with details at the side, recommended "SCREEN_READER_MODE"

That is:
1. Add the currently-selected list entry to the detail pane at the side, and
2. Disable display of the list of options.
Loading

0 comments on commit 12226bf

Please sign in to comment.