User made accessibility request

Everything else that doesn't fall into one of the other PB categories.
BarryG
Addict
Addict
Posts: 4173
Joined: Thu Apr 18, 2019 8:17 am

User made accessibility request

Post 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.
User avatar
idle
Always Here
Always Here
Posts: 5896
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: User made accessibility request

Post by idle »

Have a chat with Quin.
Quin
Addict
Addict
Posts: 1133
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

Re: User made accessibility request

Post 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:
BarryG
Addict
Addict
Posts: 4173
Joined: Thu Apr 18, 2019 8:17 am

Re: User made accessibility request

Post 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.
BarryG
Addict
Addict
Posts: 4173
Joined: Thu Apr 18, 2019 8:17 am

Re: User made accessibility request

Post 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.
Little John
Addict
Addict
Posts: 4789
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: User made accessibility request

Post by Little John »

User avatar
ChrisR
Addict
Addict
Posts: 1466
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: User made accessibility request

Post 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
BarryG
Addict
Addict
Posts: 4173
Joined: Thu Apr 18, 2019 8:17 am

Re: User made accessibility request

Post 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
Little John
Addict
Addict
Posts: 4789
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: User made accessibility request

Post 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. 🙂
Quin
Addict
Addict
Posts: 1133
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

Re: User made accessibility request

Post 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:
Post Reply