From 10701c405615cc557159f039cbe17112cf84a8d7 Mon Sep 17 00:00:00 2001 From: serrebidev Date: Sat, 11 Jul 2026 18:16:01 -0700 Subject: [PATCH] Add settings panel with a toggle for UWP review alert beeps Reviewing a UWP window iterates its element tree, which can take a moment, so the command plays a beep before and after as progress feedback. Some users find the beeps unwanted. Add a Virtual Revision panel to NVDA's settings with a checkbox to turn them off (on by default, preserving the current behaviour). Co-Authored-By: Claude Opus 4.8 --- addon/globalPlugins/virtualRevision.py | 44 ++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/addon/globalPlugins/virtualRevision.py b/addon/globalPlugins/virtualRevision.py index c4ab909..23be8af 100644 --- a/addon/globalPlugins/virtualRevision.py +++ b/addon/globalPlugins/virtualRevision.py @@ -11,6 +11,10 @@ import ui import scriptHandler import addonHandler +import config +import gui +import wx +from gui import guiHelper, settingsDialogs addonHandler.initTranslation() try: @@ -18,6 +22,26 @@ except: SCRCAT_TEXTREVIEW = None +config.conf.spec["virtualRevision"] = { + "playBeep": "boolean(default=True)", +} + + +class VirtualRevisionSettingsPanel(settingsDialogs.SettingsPanel): + # Translators: Title of the Virtual Revision settings panel. + title = _("Virtual Revision") + + def makeSettings(self, settingsSizer): + sHelper = guiHelper.BoxSizerHelper(self, sizer=settingsSizer) + # Translators: Label for the checkbox that toggles the alert beeps for UWP windows. + self.playBeepCheckBox = sHelper.addItem( + wx.CheckBox(self, label=_("Play alert &beeps when reviewing UWP windows")) + ) + self.playBeepCheckBox.SetValue(config.conf["virtualRevision"]["playBeep"]) + + def onSave(self): + config.conf["virtualRevision"]["playBeep"] = self.playBeepCheckBox.GetValue() + def obtainUWPWindowText(): foreground = api.getForegroundObject() desktop = api.getDesktopObject() @@ -60,6 +84,17 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin): scriptCategory = SCRCAT_TEXTREVIEW + def __init__(self): + super().__init__() + if not globalVars.appArgs.secure: + gui.settingsDialogs.NVDASettingsDialog.categoryClasses.append(VirtualRevisionSettingsPanel) + + def terminate(self): + try: + gui.settingsDialogs.NVDASettingsDialog.categoryClasses.remove(VirtualRevisionSettingsPanel) + except ValueError: + pass + @scriptHandler.script( # Translators: Message presented in input help mode. description=_("Opens a window containing the text of the currently focused window for easy review."), @@ -73,10 +108,13 @@ def script_virtualWindowReview(self, gesture): obj = api.getFocusObject() # Because it may take a while to iterate through elements, play abeep to alert users of this fact and the fact it's a UWP screen. if obj.windowClassName.startswith(("Windows.UI.Core", "Windows.UI.Input.InputSite")): - import tones - tones.beep(400, 300) + playBeep = config.conf["virtualRevision"]["playBeep"] + if playBeep: + import tones + tones.beep(400, 300) text = "\n".join(obtainUWPWindowText()) - tones.beep(400, 50) + if playBeep: + tones.beep(400, 50) else: root = None for ancestor in api.getFocusAncestors():