From 38743adf458264b7c28abae9f61e63aa116a4bdc Mon Sep 17 00:00:00 2001 From: Joseph Lee Date: Tue, 23 Jun 2020 16:12:49 -0700 Subject: [PATCH] Touch interaction: allow users to disable touch support completely (#10557) * ConfSpec: add touch enabled key. Re #9682. Foundation: allow users to disable touch handler overlay by adding 'touch enabled' key to NVDA settings. * Touch handler: copyright header * Touch handler: use platform version tuple to determine if touch support should be used. Re #9682 * Touch handler: enable touch support/overlay if told to do so by users. re #9682. Enable touch support if configured to do so via settings. Also, change log text on touchscreen detection to just announce how many touch points are available before proceeding to enable/disable touch support. * Settings/touch interaction: add touch support toggle. Re #9682. Allow users to enable/disable touch support via Touch Interaction settings panel. * Touch supporte3d: add debugLog flag so excessive log output will not be seen unless requested. Re #9682. * Touch handler: handle configuration profile switches via a dedicated touch mode setter function. Re #9682. Similar to audio ducking support: use a dedicated 'set touch support' function to enable/disable touch handler thread based on whether touch support should be anbeld or not. This function in turn will be called when configuration profile changes to support scenarios such as manually turning off touch support or using profiles for apps where NVDA's own touch support should be turned off. * Touch handler: set touch support mode and register/unregister profile switching support. Re #9682. Touch handler's initialize function will set appropriate touch support mode based on current config value. Also, both initialize and termiante methods support profile switching by calling register/unregister function, respectively. * Touch interaction settings panel: use touchHandler.setTouchSupport function to toggle touch handler thread. Re #9682. * Touch interaction panel: add accelerator. * User guide: add notes on touch interaction support checkbox in settings. Re #9682 * Touch handler: review comments (annotations, docstring). Re #9682. Reviewed by Leonard de Ruijter: add type annotations, along with docstring for touch supported function. * Touch interaction panel: convert to use GUI helper. re #9682. Comment from Leonard de Ruijter: convert touch interaction panel to use GUI helper code just like other panels. * User guide: clarify the behavior of touch support when touch is disabled. Re #9682 * Touch handler: update copyright years --- source/config/configSpec.py | 1 + source/gui/settingsDialogs.py | 13 +++++++-- source/touchHandler.py | 52 ++++++++++++++++++++++++++--------- user_docs/en/userGuide.t2t | 8 +++++- 4 files changed, 57 insertions(+), 17 deletions(-) diff --git a/source/config/configSpec.py b/source/config/configSpec.py index e3651506cc5..dd99b20342a 100644 --- a/source/config/configSpec.py +++ b/source/config/configSpec.py @@ -161,6 +161,7 @@ autoFocusFocusableElements = boolean(default=True) [touch] + enabled = boolean(default=true) touchTyping = boolean(default=False) #Settings for document reading (such as MS Word and wordpad) diff --git a/source/gui/settingsDialogs.py b/source/gui/settingsDialogs.py index f30e41b8049..862fb722cef 100644 --- a/source/gui/settingsDialogs.py +++ b/source/gui/settingsDialogs.py @@ -2223,14 +2223,21 @@ class TouchInteractionPanel(SettingsPanel): title = _("Touch Interaction") def makeSettings(self, settingsSizer): + sHelper = guiHelper.BoxSizerHelper(self, sizer=settingsSizer) + # Translators: This is the label for a checkbox in the + # touch interaction settings panel. + touchSupportEnableLabel = _("Enable touch interaction support") + self.enableTouchSupportCheckBox = sHelper.addItem(wx.CheckBox(self, label=touchSupportEnableLabel)) + self.enableTouchSupportCheckBox.SetValue(config.conf["touch"]["enabled"]) # Translators: This is the label for a checkbox in the # touch interaction settings panel. - self.touchTypingCheckBox=wx.CheckBox(self,label=_("&Touch typing mode")) + self.touchTypingCheckBox = sHelper.addItem(wx.CheckBox(self, label=_("&Touch typing mode"))) self.touchTypingCheckBox.SetValue(config.conf["touch"]["touchTyping"]) - settingsSizer.Add(self.touchTypingCheckBox,border=10,flag=wx.BOTTOM) def onSave(self): - config.conf["touch"]["touchTyping"]=self.touchTypingCheckBox.IsChecked() + config.conf["touch"]["enabled"] = self.enableTouchSupportCheckBox.IsChecked() + config.conf["touch"]["touchTyping"] = self.touchTypingCheckBox.IsChecked() + touchHandler.setTouchSupport(config.conf["touch"]["enabled"]) class UwpOcrPanel(SettingsPanel): # Translators: The title of the Windows 10 OCR panel. diff --git a/source/touchHandler.py b/source/touchHandler.py index 48e2bfd6541..f3bb6eeb5f3 100644 --- a/source/touchHandler.py +++ b/source/touchHandler.py @@ -1,8 +1,7 @@ -#touchHandler.py -#A part of NonVisual Desktop Access (NVDA) -#This file is covered by the GNU General Public License. -#See the file COPYING for more details. -#Copyright (C) 2012-2018 NV Access Limited, Joseph Lee, Babbage B.V. +# A part of NonVisual Desktop Access (NVDA) +# This file is covered by the GNU General Public License. +# See the file COPYING for more details. +# Copyright (C) 2012-2020 NV Access Limited, Joseph Lee, Babbage B.V. """handles touchscreen interaction (Windows 8 and later). Used to provide input gestures for touchscreens, touch modes and other support facilities. @@ -294,30 +293,57 @@ def notifyInteraction(self, obj): handler=None -def touchSupported(): + +def touchSupported(debugLog: bool = False): """Returns if the system and current NVDA session supports touchscreen interaction. + @param debugLog: Whether to log additional details about touch support to the NVDA log. """ if not config.isInstalledCopy() and not config.isAppX: - log.debugWarning("Touch only supported on installed copies") + if debugLog: + log.debugWarning("Touch only supported on installed copies") return False - if (winVersion.winVersion.major*10+winVersion.winVersion.minor)<62: - log.debugWarning("Touch only supported on Windows 8 and higher") + if winVersion.winVersion.platform_version < (6, 2, 9200): + if debugLog: + log.debugWarning("Touch only supported on Windows 8 and higher") return False maxTouches=windll.user32.GetSystemMetrics(SM_MAXIMUMTOUCHES) if maxTouches<=0: - log.debugWarning("No touch devices found") + if debugLog: + log.debugWarning("No touch devices found") return False return True -def initialize(): + +def setTouchSupport(enable: bool): global handler if not touchSupported(): raise NotImplementedError - handler=TouchHandler() - log.debug("Touch support initialized. maximum touch inputs: %d"%windll.user32.GetSystemMetrics(SM_MAXIMUMTOUCHES)) + if not handler and enable: + handler = TouchHandler() + log.debug("Touch support enabled.") + elif handler and not enable: + handler.terminate() + handler = None + log.debug("Touch support disabled.") + + +def handlePostConfigProfileSwitch(): + setTouchSupport(config.conf["touch"]["enabled"]) + + +def initialize(): + global handler + if not touchSupported(debugLog=True): + raise NotImplementedError + log.debug( + "Touchscreen detected, maximum touch inputs: %d" % winUser.user32.GetSystemMetrics(SM_MAXIMUMTOUCHES) + ) + config.post_configProfileSwitch.register(handlePostConfigProfileSwitch) + setTouchSupport(config.conf["touch"]["enabled"]) def terminate(): global handler + config.post_configProfileSwitch.unregister(handlePostConfigProfileSwitch) if handler: handler.terminate() handler=None diff --git a/user_docs/en/userGuide.t2t b/user_docs/en/userGuide.t2t index f52a418660e..6be43e0e0ef 100644 --- a/user_docs/en/userGuide.t2t +++ b/user_docs/en/userGuide.t2t @@ -203,8 +203,9 @@ If your laptop cannot do this or does not allow you to turn Num Lock off, you ma ++ NVDA Touch Gestures ++[NVDATouchGestures] If you are running NVDA on a device with a touchscreen and running Windows 8 or higher, you can also control NVDA directly via touch commands. -While NVDA is running, all touch input will go directly to NVDA. +While NVDA is running, unless touch interaction support is disabled, all touch input will go directly to NVDA. Therefore, actions that can be performed normally without NVDA will not work. +You can change this by enabling or disabling [touch interaction support # TouchSupportEnable] from touch interaction category of the NVDA settings. +++ Exploring the Screen +++[ExploringTheScreen] The most basic action you can perform with the touch screen is to announce the control or text at any point on the screen. @@ -1519,6 +1520,11 @@ If you check this option and you have the "Enable mouse tracking" option enabled This settings category, only available on computers running Windows 8 and later with touch capabilities, allows you to configure how NVDA interacts with touchscreens. This category contains the following options: +==== Enable touch interaction support ====[TouchSupportEnable] +This checkbox enables NVDA's touch interaction support. +If enabled, you can use your fingers to navigate and interact with items on screen using a touchscreen device. +If disabled, touchscreen support will be disabled as though NVDA is not running. + ==== Touch typing mode ====[TouchTypingMode] This checkbox allows you to specify the method you wish to use when entering text using the touch keyboard. If this checkbox is checked, when you locate a key on the touch keyboard, you can lift your finger and the selected key will be pressed.