Page 1 of 1

User made accessibility request

Posted: Sun Sep 29, 2024 1:16 am
by BarryG
Hi all. I received an email from someone today saying that they've test my app with various screen readers (Windows Narrator, JAWS, etc) but none of them work with my app, so he is requesting that I add accessibility support to my app.

What does he mean, and what would that involve? My app is VERY heavy on text (lots of descriptive help for things) and lots of buttons, textgadgets and stringgadgets. If someone made this request to you, what would you do? Thanks.

Re: User made accessibility request

Posted: Sun Sep 29, 2024 1:30 am
by idle
Have a chat with Quin.

Re: User made accessibility request

Posted: Sun Sep 29, 2024 1:59 am
by Quin
Once my demotivation for writing caused by recently introduced college courses goes away I might write up an actually formal guide on this stuff :)

You can start Narrator by using the keyboard shortcut Control+Windows+Enter, and this is an okay way to get a general feel for your app. However, almost no one uses it, as it's not a fully-featured screen reader and Microsoft made it very clear they no longer care when they laid off the entire team and put it in maintanence mode and then broke it...
I would recommend the free NVDA screen reader. This is what I've been using for years, and it's quite popular, beat out only by JAWS in the workplace because of seniority.
The general way screen reader users navigate through your app is with the tab and shift+tab keyboard shortcuts, so try these in all screens and insure you can get to all controls. Luckily, PB is an amazing tool and handles a lot of this logic behind the scenes for you where Windows makes it a pain (e.g. multiline string gadgets).
As far as your particular app goes I'm unsure on what all you can do, you may need to test it yourself and report back exactly what it does (e.g. missing labels on buttonImageGadgets, text fields missing descriptors, etc.). Try closing your eyes and actually using the app all from the keyboard, all with speech.
Maybe I could set up a service where I test apps and give accessibility feedback for a small fee. Wouldn't work for specialized apps but could be nice overall :idea:

Re: User made accessibility request

Posted: Sun Sep 29, 2024 4:14 am
by BarryG
He said he's tested with NVDA as well and it's no good. :( My app has a lot of panelgadgets, too, so using Tab to move around might be confusing, but that can't be changed or helped.

I do already have underline shortcuts for menus ("&General" etc) but NOT for buttons, checkboxes, panel tabs, or anything. I thought doing that might help but pressing those keys (with and without "Alt") doesn't select them; so that idea's out.

I just replied to his email asking what would help, which is probably the best approach. Then see what I can do.

Re: User made accessibility request

Posted: Sun Oct 06, 2024 12:32 pm
by BarryG
So the guy got back to me and said to use the Windows Narrator (Win+Ctrl+Enter hotkey) and then try to navigate my app with the arrow keys. He's right; it doesn't work. :( Even the OptionGadget example from the manual doesn't react to arrow keys to navigate between options:

Code: Select all

If OpenWindow(0, 0, 0, 140, 150, "OptionGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  OptionGadget(0, 30, 20, 65, 20, "Option 1")
  OptionGadget(1, 30, 45, 65, 20, "Option 2")
  OptionGadget(2, 30, 70, 65, 20, "Option 3")
  SetGadgetState(1, 1)
  SetActiveGadget(1)
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
What can I do? Is this a PureBasic limitation? I can't change my code to use left/right/up/down arrows to move between gadgets anyway - am I seriously supposed to keep track of which gadgets are physically left/right/up/down in relation to other gadgets? This is not feasible.

Re: User made accessibility request

Posted: Sun Oct 06, 2024 2:46 pm
by Little John

Re: User made accessibility request

Posted: Sun Oct 06, 2024 6:58 pm
by ChrisR
You can also do it using the tab order and send the tab key for the down arrow et Shift+tab for the up arrow:

Code: Select all

EnableExplicit

Enumeration Window
  #Window
EndEnumeration

Enumeration Gadgets
  #Btn_1
  #Check_1
  #Check_2
  #Opt_1
  #Opt_2
  #String_1
  #Txt_1
EndEnumeration

Enumeration shortcuts
  #Shortcut_Up
  #Shortcut_Down
EndEnumeration

Macro SetTabOrder(Gadget)
  SetWindowPos_(GadgetID(Gadget), #HWND_BOTTOM, 0, 0, 0, 0, #SWP_NOMOVE | #SWP_NOSIZE)
EndMacro

Procedure SendTabKey(Backward=#False)
  Protected Dim InputData.Input(1), i
  
  If Backward
    ReDim InputData(3)
    InputData(i)\type = #INPUT_KEYBOARD
    InputData(i)\ki\wVk = #VK_SHIFT
    i + 1
  EndIf
  
  InputData(i)\type = #INPUT_KEYBOARD
  InputData(i)\ki\wVk = #VK_TAB
  i + 1
  
  InputData(i)\type = #INPUT_KEYBOARD
  InputData(i)\ki\wVk = #VK_TAB
  InputData(i)\ki\dwFlags = #KEYEVENTF_KEYUP
  i + 1
  
  If Backward
    InputData(i)\type = #INPUT_KEYBOARD
    InputData(i)\ki\wVk = #VK_SHIFT
    InputData(i)\ki\dwFlags = #KEYEVENTF_KEYUP
    i + 1
  EndIf      
  
  ProcedureReturn SendInput_(i, @InputData(), SizeOf(Input))
EndProcedure

Procedure Open_Window_0(X = 0, Y = 0, Width = 300, Height = 290)
  If OpenWindow(#Window, X, Y, Width, Height, "Title", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    CheckBoxGadget(#Check_1, 40, 140, 100, 22, "CheckBox_1")
    CheckBoxGadget(#Check_2, 40, 180, 100, 22, "CheckBox_2")
    TextGadget(#Txt_1, 40, 20, 220, 22, "Text_1")
    StringGadget(#String_1, 40, 60, 220, 24, "String_1")
    OptionGadget(#Opt_2, 160, 100, 100, 22, "Option_2")
    OptionGadget(#Opt_1, 40, 100, 100, 22, "Option_1")
    ButtonGadget(#Btn_1, 40, 220, 220, 50, "Button_1")
    
    AddKeyboardShortcut(#Window, #PB_Shortcut_Up, #Shortcut_Up)
    AddKeyboardShortcut(#Window, #PB_Shortcut_Down, #Shortcut_Down)
    
    SetTabOrder(#String_1) : SetTabOrder(#Opt_1) : SetTabOrder(#Opt_2) : SetTabOrder(#Check_1) : SetTabOrder(#Check_2) : SetTabOrder(#Btn_1)
    ProcedureReturn #True
  EndIf
EndProcedure

;- Main Program
If Open_Window_0()
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Break
        
      Case #PB_Event_Menu
        Select EventMenu()
          Case #Shortcut_Up
            SendTabKey(1)
          Case #Shortcut_Down
            SendTabKey()
        EndSelect
        
      Case #PB_Event_Gadget
        Select EventGadget()
          Case #Btn_1   ; Button_1
            MessageRequester("Information", "Button Name : #Btn_1" +#CRLF$+#CRLF$+ "Text : " + GetGadgetText(EventGadget()))
        EndSelect
        
    EndSelect
  ForEver
EndIf

Re: User made accessibility request

Posted: Mon Oct 07, 2024 2:02 am
by BarryG
Thanks guys, but doing arrow movements for OptionGadgets was just one example. This guy literally wants the arrow keys to change the focus to another gadget on the left or right of the current active one (and above or below it). This is not doable at all, yeah?

See the example below: he literally wants to be able to press up/down/left/right on whichever gadget has the focus, and the focus will move to the new gadget according to the key direction. This is not normal behavior for GUIs, right? I've never seen an app that does that.

Or does Windows Narrator do that somehow? I didn't see a way.

Code: Select all

OpenWindow(0,300,200,630,90,"Arrow navigation",#PB_Window_SystemMenu)

ButtonGadget(0,10,10,300,30,"Press DownArrow to select the CheckBoxGadget")
CheckBoxGadget(1,10,50,300,30,"Press RightArrow to select the StringGadget")
StringGadget(2,320,50,300,25,"Press UpArrow to select the OptionGadget")
OptionGadget(3,320,10,300,25,"Press LeftArrow to select the ButtonGadget")

SetActiveGadget(0)

Repeat
  ev=WaitWindowEvent()
Until ev=#PB_Event_CloseWindow

Re: User made accessibility request

Posted: Mon Oct 07, 2024 5:44 am
by Little John
BarryG wrote: Mon Oct 07, 2024 2:02 am See the example below: he literally wants to be able to press up/down/left/right on whichever gadget has the focus, and the focus will move to the new gadget according to the key direction. This is not normal behavior for GUIs, right? I've never seen an app that does that.
Using the arrow keys for moving the focus between options in the same group is standard, otherwise normally [Tab] or [Shift]+[Tab] is used for moving the focus from one gadget to another. You can tell this guy how much time it would take and how much $$ it would cost, if you'd write a special UI only for him, personally. 🙂

Re: User made accessibility request

Posted: Mon Oct 07, 2024 12:35 pm
by Quin
BarryG wrote: Mon Oct 07, 2024 2:02 am Thanks guys, but doing arrow movements for OptionGadgets was just one example. This guy literally wants the arrow keys to change the focus to another gadget on the left or right of the current active one (and above or below it). This is not doable at all, yeah?

See the example below: he literally wants to be able to press up/down/left/right on whichever gadget has the focus, and the focus will move to the new gadget according to the key direction. This is not normal behavior for GUIs, right? I've never seen an app that does that.

Or does Windows Narrator do that somehow? I didn't see a way.

Code: Select all

OpenWindow(0,300,200,630,90,"Arrow navigation",#PB_Window_SystemMenu)

ButtonGadget(0,10,10,300,30,"Press DownArrow to select the CheckBoxGadget")
CheckBoxGadget(1,10,50,300,30,"Press RightArrow to select the StringGadget")
StringGadget(2,320,50,300,25,"Press UpArrow to select the OptionGadget")
OptionGadget(3,320,10,300,25,"Press LeftArrow to select the ButtonGadget")

SetActiveGadget(0)

Repeat
  ev=WaitWindowEvent()
Until ev=#PB_Event_CloseWindow
Can confirm that this is not normal GUI behavior, you're supposed to tab/shift+tab through the controls, not arrow through them :shock: