2019-05-28 06:39:18 (edited by daigonite 2019-05-28 06:44:38)

I'm working on building out the XNA engine that implements blind accessibility through automation. It's almost done, just need to add a class for accessible menus, and a few minor bugs, but I came across a problem while testing NVDA.

It works fine for the most part, but one of my functions requires it to be able to read while you're pressing down on a key. I think this conflicts with some functionality in NVDA. I'm using the arrow keys (but it should be able to work with any key that can be bound technically). Basically, as you approach a labeled object it should read off the name. But it doesn't. The string is successfully being reached to NVDA (it appears in the text display) but it doesn't read off, I guess it gets stopped shortly after. Threading doesn't work either.

If I tap the button it will read it which makes me think this is the case.

Is there documentation on how to build a script or something that helps NVDA deal with this problem properly? Thanks. Its mostly just annoying. If I could feed the script which keys to ignore based on a file that contains the keybindings that could do well enough.

Thanks

you like those kinds of gays because they're gays made for straights

2019-05-28 08:17:13

The only way arround is to use the buildin sleep mode. WHy it happens is because NVDA inerrupts its speach each time the button is held. Try for example creating a test program which will display the string "this is a test" for 100 times. During the execution hold down the key, no matter which one and it will interrupt. It's how it is.

If you want to contact me, do not use the forum PM. I respond once a year or two, when I need to write a PM myself. I apologize for the inconvenience.
Telegram: Nuno69a
E-Mail: nuno69a (at) gmail (dot) com

2019-05-28 14:36:58

The only way to achieve this function without NVDA interrupting while holding down keys such as your arrow keys is by using the builtin sleep mode. NVDA shift Z. This doesn't stop NVDA from speaking, however, makes all key response stop within the app. It's a toggle function.

Jonathan Candler, A.K.A, Jonnyboy

2019-05-28 16:08:12 (edited by daigonite 2019-05-28 16:12:49)

Is it possible to trigger this sleep mode programically?

If I could just trigger the sleep mode whenever any button is held down it would be a pretty clean solution.

Thanks.

EDIT: Glancing through the documentation, sleep mode can be toggled for programs through scripts. IDK if this is the best solution. I'll have to dig through the NVDA controller to see if I can control it manually.

If I put the game in sleep mode does NVDA not have any output whatsoever, even if I read the strings?

you like those kinds of gays because they're gays made for straights

2019-05-29 07:02:30

No, you cannot do it programmatically, the think you might try however is installing a low level keyhook through Win32 API to stop nVDA from receiving input, bare in mind, though that using this function will make you unable to stop any speech, until your game has a function which will send a null value to the screenreader

If you want to contact me, do not use the forum PM. I respond once a year or two, when I need to write a PM myself. I apologize for the inconvenience.
Telegram: Nuno69a
E-Mail: nuno69a (at) gmail (dot) com

2019-05-30 00:47:50

Yeah, #5 is correct, this is your best bet if this is what your aiming for. If you have access to the windows API, I would look into the function SetWindowsHookEx. Just make sure to let the control keys through no matter what, and make absolutely sure you remove the hook and/or let all keys pass through it if the game's window isn't active. You'll need to create a callback to handle the hooked keys, I haven't had to do this so not sure if there is a way to detect key repeating events as thinking about it those are the only things you need to block. Basically what's happening here is that when a key is pressed, NVDA automatically stops speech to prepare for whatever is spoken next. But because of the way windows and key repeating works, NVDA thinks your pressing a key every time the windows key repeat triggers. I'm sure you know what I mean, it's the same windows function that lets you hold down the letter z for 10 seconds and print loads and loads of z's. Even if there is no separate event for these key repeats verses key presses, you can still likely block these. Windows only seems to repeat the last key pressed, so it shouldn't be overly difficult to write something to just make sure the same key doesn't get let through twice within a certain timeframe. With a bit of searching it seems you can get the currently set keyboard delay and repeat rate with the API function SystemParametersInfoA. Using this you should be able to both let double tapping a key go through while also blocking key repeats, assuming there is no direct way with the keyboard hook to do so. So I did some more searching as well as looked at some old code I'd written before. Basically, you create a callback that returns 0 to stop normal event handling, and returns 1 to let the handling through to windows. The hook you want to set with SetWindowsHookEx is the constant WH_KEYBOARD_LL, or 13. In the wparam argument of your callback you give it, you either receive the constant WM_KEYDOWN or 256 if a key is pressed, or WM_KEYUP (257) if a key was released. I'm not sure if you keep receiving events for the windows key repeat, I doubt it. Apparently you can send your own keyboard input with the SendInput function. So what you could do to avoid the windows key repeating is to send a key down event with the key if that's received, immediately followed by a key up event. You'll probably have to add a check so you don't end up causing a loop by making your hook get continually called with your sent keys. I haven't tried a lot of this, though I know from some old code more about the SetWindowsHookEx function. I learned of SetInput from: https://stackoverflow.com/questions/195 … s-unwanted Hopefully this helps somewhat. I *may, be able to throw together a DLL that has a couple functions to disable and enable windows keyboard repeating. I'm no C++ master of any sort, I just know enough to hardly get by, that and a lot of helpful stuff from stackoverflow lol. I should be able to get something like that to work though. I'll probably try as I could see something like that being useful for the future, and if when I'm done your still deeling with this issue I can certainly give it to you to use if you wish.

I am a web designer, and a game developer. If you wish see me at http://www.samtupy.com

2019-05-30 09:40:58

Sam is right. It is the repeat keys that are silencing NVDA.
There is no way to fix it through the NVDA controller client, though that would be awesome.
The sleep mode that others suggested, (accessed with NVDA shift Z on the laptop keyboard layout and NVDA shift S on the desktop keyboard layout) seem to solve it nicely, though people have to remember to press those each time they launch your game.
NVDA in sleep mode still speaks any messages you send to it through the NVDA controller.
You can enable sleep mode programmatically for your game through an NVDA app module or addon, but that would require people to install that app module / addon.

Sam's low level keyboard hook will probably solve it too, once it is finished.

In A Hero's Call I solved it by changing the "Windows Filter Keys" settings to disable repeat keys.
I would first save your filter key settings to a file when AHC launched, so I could restore them.
Then whenever the game window was active I disabled repeat keys, and when you alt tabbed away, closed the game, or the game detected itself crashing, I restored the original filter key settings.
I would rather not adjust the filter key settings and then be responsible for setting them back, but I want gamers to have a good experience, and the alternatives are not great.

Aprone mostly avoided the issue in Swamp by making the right mouse button be the only valid move forward key.
Since that was the key you held the most, and mouse buttons don't cancel speech, it solved it most of the time.

Mouse and gamepad buttons don't cause the issue, but they give you a new issue.
Namely NVDA has been cancelling speech for you whenever it detects a key press, so when you enable sleep mode, or use mouse or gamepad buttons, now speech never gets cancelled automatically.
Players actually do want speech cancelled when pressing most keys, such as quickly arrowing through a menu. They want to hear the item they just moved to, not the 5 they quickly moved passed.
This is easier to solve though, since the NVDA controller client provides a method for cancelling speech, so you can just call it whenever your game detects a mouse or gamepad button.
Or even when it detects a key press, assuming sleep mode is on, since sleep mode will stop even normal key presses from cancelling speech.

Then you get the issue that players also like repeat keys in some circumstances, such as holding an arrow key on a grid based map.
Players tend to like to move around the grid map very quickly by holding an arrow key, which acts like it is repeating the key.
You can solve this by just keeping track of which keys are held and triggering your own sort of repeat keys internal to your game.
NVDA will never see those since they are just within your own code, not running through the whole Windows input system.

I have spent a lot of time on input for my next project, especially around the use of gamepads.
Maybe it is just nostalgia, but I think a game just feels better when I'm playing with a gamepad.

Instead of using NVDA controller client directly, you can use Tolk, which will also handle output to other screen readers; JAWS being the other most important one.

I assume you are using C# if you are using XNA.
If you are interested in the C# code for adjusting filter key settings, email me at [email protected] and I'll be happy to pass it along.

Hope some of that is helpful.

~ Ian Reed
Visit BlindGamers.com to rate blind accessible games and see how others have rated them.
Try my free JGT addon, the easy way to play Japanese games in English.
Or try the free games I've created.

2019-05-30 15:40:59

Oh wow I didn't know it was possible to disable repeat keys programatically. One time I had to kill the AHC process for 1 reason or another I don't remember, and my key repeats didn't work until I relaunched and closed the game again, I guess now I know why big_smile

I am a web designer, and a game developer. If you wish see me at http://www.samtupy.com

2019-05-30 20:32:42

Yeah, sorry about that.
Most of the time AHC is able to detect a crash and switch filter keys back to the original settings before closing, but some crashes, or as you say, killing the process, are not detected by it.
When you launch it again it is able to detect that it did not restore the filter key settings previously, and so it fixes them the next time you close it.
It is certainly a downside to that approach, but on the other hand it solves the problem pretty specifically by just disabling repeat keys at the source.
I made a small repeat keys fixer program that restores Windows default filter key settings, because when developing the game there were a lot more cases when I would break my own filter key settings.
Though I think the final game does a pretty good job of not breaking them.

Maybe the low level keyboard hook would be safer, assuming Windows removes it cleanly when a crash occurs.
I wonder if it will work though, because I assume NVDA has to install a low level key hook to detect the key presses that cancel speech in the first place.
So will a new keyboard hook be able to intercept and cancel repeat keys before NVDA's key hook sees them?

This page says the key down message does tell you if it is a repeat key or not:
https://docs.microsoft.com/en-us/window … wm-keydown
quote: The previous key state (bit 30) can be used to determine whether the WM_KEYDOWN message indicates the first down transition or a repeated down transition.

~ Ian Reed
Visit BlindGamers.com to rate blind accessible games and see how others have rated them.
Try my free JGT addon, the easy way to play Japanese games in English.
Or try the free games I've created.

2019-05-30 21:30:40

Yeah I've only had that issue with broken key repeating once. Also yes installing a low level keyboard hook will work, and yes it gets removed, not sure how cleanly, if the process dies. I know because I made a program to lock my keyboard and mouse for my user. As soon as I ran it no keys worked what so ever. NVGA was unable to stop speech or do anything properly once I installed my hook, which just used a callback to always return 0 and thus block every keys. Had to switch to a recovery admin user and kill the process to fix that one lol

I am a web designer, and a game developer. If you wish see me at http://www.samtupy.com