Skip to content

Commit

Permalink
improve state management in speech.py (#12395)
Browse files Browse the repository at this point in the history
Summary of the issue:
Using shift to resume speech after using shift to pause speech does not resume speech.

This is because when isPaused is imported through speech\__init__.py it is does not reference the global variable used in speech.py

Description of how this pull request fixes the issue:
Removes the use of top level variables in speech.py in favour of a private dataclass to manage state, and an enum for certain modes. Constants (or rather, variables with names in all capitals) remain as is.
  • Loading branch information
seanbudd authored May 12, 2021
1 parent 5d4e64f commit 8938ca4
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 123 deletions.
24 changes: 12 additions & 12 deletions source/NVDAHelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,10 @@ def handleInputCompositionEnd(result):
curInputComposition=None
if isinstance(focus,InputComposition):
curInputComposition=focus
oldSpeechMode=speech.speechMode
speech.speechMode=speech.speechMode_off
oldSpeechMode = speech.getState().speechMode
speech.setSpeechMode(speech.SpeechMode.off)
eventHandler.executeEvent("gainFocus",focus.parent)
speech.speechMode=oldSpeechMode
speech.setSpeechMode(oldSpeechMode)
elif isinstance(focus.parent,InputComposition):
#Candidate list is still up
curInputComposition=focus.parent
Expand All @@ -210,10 +210,10 @@ def handleInputCompositionEnd(result):
# Sometimes InputCompositon object is gone
# Correct to container of CandidateItem
newFocus=focus.container
oldSpeechMode=speech.speechMode
speech.speechMode=speech.speechMode_off
oldSpeechMode = speech.getState().speechMode
speech.setSpeechMode(speech.SpeechMode.off)
eventHandler.executeEvent("gainFocus",newFocus)
speech.speechMode=oldSpeechMode
speech.setSpeechMode(oldSpeechMode)

if curInputComposition and not result:
result=curInputComposition.compositionString.lstrip(u'\u3000 ')
Expand All @@ -240,11 +240,11 @@ def handleInputCompositionStart(compositionString,selectionStart,selectionEnd,is
if parent==focus:
parent=focus
curInputComposition=InputComposition(parent=parent)
oldSpeechMode=speech.speechMode
speech.speechMode=speech.speechMode_off
oldSpeechMode = speech.getState().speechMode
speech.setSpeechMode(speech.SpeechMode.off)
eventHandler.executeEvent("gainFocus",curInputComposition)
focus=curInputComposition
speech.speechMode=oldSpeechMode
speech.setSpeechMode(oldSpeechMode)
focus.compositionUpdate(compositionString,selectionStart,selectionEnd,isReading)

@WINFUNCTYPE(c_long,c_wchar_p,c_int,c_int,c_int)
Expand All @@ -269,10 +269,10 @@ def handleInputCandidateListUpdate(candidatesString,selectionIndex,inputMethod):
focus=api.getFocusObject()
if not (0<=selectionIndex<len(candidateStrings)):
if isinstance(focus,CandidateItem):
oldSpeechMode=speech.speechMode
speech.speechMode=speech.speechMode_off
oldSpeechMode = speech.getState().speechMode
speech.setSpeechMode(speech.SpeechMode.off)
eventHandler.executeEvent("gainFocus",focus.parent)
speech.speechMode=oldSpeechMode
speech.setSpeechMode(oldSpeechMode)
return
oldCandidateItemsText=None
if isinstance(focus,CandidateItem):
Expand Down
2 changes: 1 addition & 1 deletion source/NVDAObjects/behaviors.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ def _reportNewLines(self, lines):
if (
len(lines) == 1
and not self._hasTab
and len(lines[0].strip()) < max(len(speech.curWordChars) + 1, 3)
and len(lines[0].strip()) < max(len(speech.speech._curWordChars) + 1, 3)
):
return
# Clear the typed word buffer for new text lines.
Expand Down
12 changes: 6 additions & 6 deletions source/globalCommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -1549,21 +1549,21 @@ def script_review_currentSymbol(self,gesture):
gesture="kb:NVDA+s"
)
def script_speechMode(self,gesture):
curMode=speech.speechMode
speech.speechMode=speech.speechMode_talk
curMode = speech.getState().speechMode
speech.setSpeechMode(speech.SpeechMode.talk)
newMode=(curMode+1)%3
if newMode==speech.speechMode_off:
if newMode == speech.SpeechMode.off:
# Translators: A speech mode which disables speech output.
name=_("Speech mode off")
elif newMode==speech.speechMode_beeps:
elif newMode == speech.SpeechMode.beeps:
# Translators: A speech mode which will cause NVDA to beep instead of speaking.
name=_("Speech mode beeps")
elif newMode==speech.speechMode_talk:
elif newMode == speech.SpeechMode.talk:
# Translators: The normal speech mode; i.e. NVDA will talk as normal.
name=_("Speech mode talk")
speech.cancelSpeech()
ui.message(name)
speech.speechMode=newMode
speech.setSpeechMode(newMode)

@script(
description=_(
Expand Down
2 changes: 1 addition & 1 deletion source/keyboardHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ def _get_speechEffectWhenExecuted(self):
if self.vkCode==winUser.VK_RETURN and not config.conf['keyboard']['speechInterruptForEnter']:
return None
if self.vkCode in (winUser.VK_SHIFT, winUser.VK_LSHIFT, winUser.VK_RSHIFT):
return self.SPEECHEFFECT_RESUME if speech.isPaused else self.SPEECHEFFECT_PAUSE
return self.SPEECHEFFECT_RESUME if speech.getState().isPaused else self.SPEECHEFFECT_PAUSE
return self.SPEECHEFFECT_CANCEL

def reportExtra(self):
Expand Down
42 changes: 9 additions & 33 deletions source/speech/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# 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) 2006-2020 NV Access Limited, Peter Vágner, Aleksey Sadovoy, Babbage B.V., Bill Dengler,
# Copyright (C) 2006-2021 NV Access Limited, Peter Vágner, Aleksey Sadovoy, Babbage B.V., Bill Dengler,
# Julien Cochuyt

from .speech import (
Expand All @@ -15,14 +15,10 @@
_manager,
_objectSpeech_calculateAllowedProps,
_suppressSpeakTypedCharacters,
_suppressSpeakTypedCharactersNumber,
_suppressSpeakTypedCharactersTime,
beenCanceled,
BLANK_CHUNK_CHARS,
cancelSpeech,
CHUNK_SEPARATOR,
clearTypedWordBuffer,
curWordChars,
FIRST_NONCONTROL_CHAR,
getCharDescListFromText,
getControlFieldSpeech,
Expand All @@ -34,26 +30,21 @@
getPreselectedTextSpeech,
getPropertiesSpeech,
getSpellingSpeech,
getState,
getTableInfoSpeech,
getTextInfoSpeech,
IDT_BASE_FREQUENCY,
IDT_MAX_SPACES,
IDT_TONE_DURATION,
isBlank,
isPaused,
LANGS_WITH_CONJUNCT_CHARS,
oldColumnNumber,
oldColumnSpan,
oldRowNumber,
oldRowSpan,
oldTableID,
oldTreeLevel,
pauseSpeech,
processText,
PROTECTED_CHAR,
RE_CONVERT_WHITESPACE,
RE_INDENTATION_CONVERT,
RE_INDENTATION_SPLIT,
setSpeechMode,
speak,
speakMessage,
speakObject,
Expand All @@ -66,11 +57,7 @@
speakTextInfo,
speakTextSelected,
speakTypedCharacters,
speechMode,
speechMode_beeps,
speechMode_beeps_ms,
speechMode_off,
speechMode_talk,
SpeechMode,
spellTextInfo,
splitTextIndentation,
)
Expand Down Expand Up @@ -105,14 +92,10 @@
"_manager",
"_objectSpeech_calculateAllowedProps",
"_suppressSpeakTypedCharacters",
"_suppressSpeakTypedCharactersNumber",
"_suppressSpeakTypedCharactersTime",
"beenCanceled",
"BLANK_CHUNK_CHARS",
"cancelSpeech",
"CHUNK_SEPARATOR",
"clearTypedWordBuffer",
"curWordChars",
"FIRST_NONCONTROL_CHAR",
"getCharDescListFromText",
"getControlFieldSpeech",
Expand All @@ -124,26 +107,21 @@
"getPreselectedTextSpeech",
"getPropertiesSpeech",
"getSpellingSpeech",
"getState",
"getTableInfoSpeech",
"getTextInfoSpeech",
"IDT_BASE_FREQUENCY",
"IDT_MAX_SPACES",
"IDT_TONE_DURATION",
"isBlank",
"isPaused",
"LANGS_WITH_CONJUNCT_CHARS",
"oldColumnNumber",
"oldColumnSpan",
"oldRowNumber",
"oldRowSpan",
"oldTableID",
"oldTreeLevel",
"pauseSpeech",
"processText",
"PROTECTED_CHAR",
"RE_CONVERT_WHITESPACE",
"RE_INDENTATION_CONVERT",
"RE_INDENTATION_SPLIT",
"setSpeechMode",
"speak",
"speakMessage",
"speakObject",
Expand All @@ -156,23 +134,21 @@
"speakTextInfo",
"speakTextSelected",
"speakTypedCharacters",
"speechMode",
"speechMode_beeps",
"speechMode_beeps_ms",
"speechMode_off",
"speechMode_talk",
"SpeechMode",
"spellTextInfo",
"splitTextIndentation",
]

import synthDriverHandler
import config
from .speech import initialize as speechInitialize


def initialize():
"""Loads and sets the synth driver configured in nvda.ini."""
synthDriverHandler.initialize()
synthDriverHandler.setSynth(config.conf["speech"]["synth"])
speechInitialize()


def terminate():
Expand Down
Loading

0 comments on commit 8938ca4

Please sign in to comment.