NVDA アドオン
NVDA Add on Development Guide · nvdaaddons/DevGuide Wiki
nvaccess/AddonTemplate: Template and metadata used by NVDA community add-ons
NVDAと格闘する
1. テンプレートリポジトリをREADMEに従って取ってくる
と思いきや、もっと楽な方法があった。
1. 「高度な設定」で「開発者用スクラッチパッドのフォルダーを開く」にチェックを入れると、サンプルコードを書けるディレクトリを作ってくれる
ディレクトリが作成されたからといって、チェックを入れた後ちゃんと保存しないと、scratchpadディレクトリへの変更が反映されないので注意
2. tonesとかariaとかはNVDAのsourceディレクトリにあるPythonファイルのモジュールで、直接importできるっぽい
例えば以下のようなコードをappModules/chrome.pyに貼る。
Tabキーでボタンにフォーカスを移動すると、ちゃんとaaaとbbbの間にボタンのaccessible nameが読まれることが確認できる。
ブラウズモードでは上手く読み上げられないけど、原因は不明。AIに聞いた感じ、仮想カーソルは別の方法を使わないといけないとかなんとか。
code:python
import appModuleHandler
import ui
import controlTypes
class AppModule(appModuleHandler.AppModule):
def event_gainFocus(self, obj, nextHandler):
if obj.role == controlTypes.Role.BUTTON:
ui.message("aaa")
ui.message(obj.name or "名前なし")
ui.message("bbb")
nextHandler()
objはNVDAObject。
controlTypes.Roleはここらへんで定義されている。
nvda/source/controlTypes/role.py at master · nvaccess/nvda
IA2とかのロールを、NVDA独自のロールにどこかで変換して渡している?ような気がする。
多分ここ↓
https://github.com/nvaccess/nvda/blob/bc45e6fdcf78c9ab3d5cfea36fb01b8bcb224d2d/source/NVDAObjects/IAccessible/__init__.py#L1043
また、str(obj.IA2Attributes)の値を取得すると以下のようになる(GitHubのコードブロックのコピーボタンにフォーカスしたときの値)。
tagはHTML要素名(ここではカスタム要素)、 classはHTML要素についているclassがそのまま。name-fromは、おそらく今回はaria-labelからaccessible nameを取得したのでattirbuteになっている(つまり、仕様書のname fromではauthor)。
これを使っていい感じに読み上げさせることになる。
code:viewer
{'display': 'inline-block', 'tag': 'clipboard-copy', 'xml-roles': 'button', 'name-from': 'attribute', 'explicit-name': 'true', 'class': 'ClipboardButton btn js-clipboard-copy m-2 p-0 focus-visible', 'text-align': 'left'}