Skip to content

Commit 794dd23

Browse files
authored
Merge 554e8e2 into 6dae6ab
2 parents 6dae6ab + 554e8e2 commit 794dd23

6 files changed

Lines changed: 110 additions & 13 deletions

File tree

source/gui/nvdaControls.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,23 @@ def onSliderChar(self, evt):
356356
self.SetValue(newValue)
357357

358358

359+
class FocusableReadonlyTextCtrl(wx.TextCtrl):
360+
"""
361+
The standard wx.TextCtrl does not accept focus from keyboard when set to readonly mode
362+
with `wx.TE_READONLY`.
363+
In #7302, an ExpandoTextCtrl was used instead, because even when readonly it accepts focus from keyboard.
364+
When instantiating an ExpandoTextCtrl, by changing panels to Braille or Speech settings,
365+
a WX_EVENT_DESTROY was sent to the parent window (NVDASettingsDialog),
366+
causing #12818. While the parent window remained alive, it was treated as if it was destroyed,
367+
allowing multiple NVDASettingsDialogs.
368+
"""
369+
def __init__(self, *args, **kw):
370+
super().__init__(*args, **kw, style=wx.TE_READONLY)
371+
372+
def AcceptsFocusFromKeyboard(self) -> True:
373+
return True
374+
375+
359376
class TabbableScrolledPanel(scrolledpanel.ScrolledPanel):
360377
"""
361378
This class was created to ensure a ScrolledPanel scrolls to nested children of the panel when navigating

source/gui/settingsDialogs.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import typing
1919
import wx
2020
from vision.providerBase import VisionEnhancementProviderSettings
21-
from wx.lib.expando import ExpandoTextCtrl
2221
import wx.lib.newevent
2322
import winUser
2423
import logHandler
@@ -977,17 +976,11 @@ def makeSettings(self, settingsSizer):
977976
synthGroup = guiHelper.BoxSizerHelper(self, sizer=synthBoxSizer)
978977
settingsSizerHelper.addItem(synthGroup)
979978

980-
# Use a ExpandoTextCtrl because even when readonly it accepts focus from keyboard, which
981-
# standard readonly TextCtrl does not. ExpandoTextCtrl is a TE_MULTILINE control, however
982-
# by default it renders as a single line. Standard TextCtrl with TE_MULTILINE has two lines,
983-
# and a vertical scroll bar. This is not neccessary for the single line of text we wish to
984-
# display here.
985979
synthDesc = getSynth().description
986-
self.synthNameCtrl = ExpandoTextCtrl(
980+
self.synthNameCtrl = nvdaControls.FocusableReadonlyTextCtrl(
987981
synthBox,
988982
size=(self.scaleSize(250), -1),
989983
value=synthDesc,
990-
style=wx.TE_READONLY,
991984
)
992985
self.synthNameCtrl.Bind(wx.EVT_CHAR_HOOK, self._enterTriggersOnChangeSynth)
993986

@@ -3369,10 +3362,9 @@ def makeSettings(self, settingsSizer):
33693362
displayBox = displaySizer.GetStaticBox()
33703363
displayGroup = guiHelper.BoxSizerHelper(self, sizer=displaySizer)
33713364
settingsSizerHelper.addItem(displayGroup)
3372-
self.displayNameCtrl = ExpandoTextCtrl(
3365+
self.displayNameCtrl = nvdaControls.FocusableReadonlyTextCtrl(
33733366
displayBox,
33743367
size=(self.scaleSize(250), -1),
3375-
style=wx.TE_READONLY
33763368
)
33773369
self.bindHelpEvent("BrailleSettingsChange", self.displayNameCtrl)
33783370
self.updateCurrentDisplay()

tests/system/guiDiff.robot

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
--xunit systemTests.xml
44
--pythonpath .\tests\system\libraries
55
--suite NVDASettings
6+
--include readGui
67
--variable whichNVDA:source
78
--variable currentVersion:source
89
--variable cacheFolder:.\tests\system\settingsCache
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[globalCommands.GlobalCommands]
2+
activateBrailleSettingsDialog = kb:control+/

tests/system/robot/NVDASettings.py

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@
1515

1616
# Imported for type information
1717
from robot.libraries.Process import Process as _ProcessLib
18+
from robot.utils.asserts import assert_true, assert_false
1819

1920
from AssertsLib import AssertsLib as _AssertsLib
2021

2122
import os
2223
from typing import Optional
2324
import NvdaLib as _nvdaLib
2425
from NvdaLib import NvdaLib as _nvdaRobotLib
26+
from tests.system.libraries.SystemTestSpy.windows import GetVisibleWindowTitles
2527
_nvdaProcessAlias = _nvdaRobotLib.nvdaProcessAlias
2628

2729
_builtIn: BuiltIn = BuiltIn()
@@ -38,7 +40,7 @@ def navigate_to_settings(settingsName):
3840
spy.emulateKeyPress("leftWindows+upArrow") # maximise
3941
spy.wait_for_speech_to_finish()
4042

41-
# naviagte to setting
43+
# navigate to setting
4244
for letter in settingsName.lower():
4345
spy.emulateKeyPress(letter)
4446

@@ -70,3 +72,58 @@ def read_settings(settingsName, cacheFolder, currentVersion, compareVersion: Opt
7072
compareText = f.read()
7173

7274
_asserts.strings_match(compareText, actualSpeech)
75+
76+
77+
def open_general_to_braille_then_speech():
78+
spy = _nvdaLib.getSpyLib()
79+
# open the general settings dialog
80+
spy.emulateKeyPress("nvda+control+g")
81+
# navigate to the panel selection
82+
spy.emulateKeyPress("shift+tab")
83+
# open the braille settings dialog
84+
spy.emulateKeyPress("b")
85+
86+
# enter the panel
87+
spy.wait_for_speech_to_finish()
88+
spy.emulateKeyPress("tab")
89+
# open the braille driver dialog
90+
spy.emulateKeyPress("alt+h")
91+
92+
# change window focus to desktop
93+
spy.emulateKeyPress("windows+d")
94+
95+
# open the speech settings dialog
96+
spy.emulateKeyPress("nvda+control+v")
97+
spy.wait_for_speech_to_finish()
98+
99+
windowsTitles = GetVisibleWindowTitles()
100+
errMsg = f'open windows titles: {",".join(windowsTitles)}'
101+
assert_true("NVDA Settings: Braille (normal configuration)" in windowsTitles, msg=errMsg)
102+
assert_true("Select Braille Display" in windowsTitles, msg=errMsg)
103+
assert_true("NVDA Settings: Speech (normal configuration)" in windowsTitles, msg=errMsg)
104+
105+
106+
def open_braille_then_speech():
107+
spy = _nvdaLib.getSpyLib()
108+
# open the braille settings dialog directly
109+
# using gesture defined in settings-gestures.ini
110+
spy.emulateKeyPress("control+/")
111+
112+
# enter the panel
113+
spy.wait_for_speech_to_finish()
114+
spy.emulateKeyPress("tab")
115+
# open the braille driver dialog
116+
spy.emulateKeyPress("alt+h")
117+
118+
# change window focus to desktop
119+
spy.emulateKeyPress("windows+d")
120+
121+
# open the speech settings dialog
122+
spy.emulateKeyPress("nvda+control+v")
123+
spy.wait_for_speech_to_finish()
124+
125+
windowsTitles = GetVisibleWindowTitles()
126+
errMsg = f'open windows titles: {",".join(windowsTitles)}'
127+
assert_true("NVDA Settings: Braille (normal configuration)" in windowsTitles, msg=errMsg)
128+
assert_true("Select Braille Display" in windowsTitles, msg=errMsg)
129+
assert_false("NVDA Settings: Speech (normal configuration)" in windowsTitles, msg=errMsg)

tests/system/robot/NVDASettings.robot

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
# This file may be used under the terms of the GNU General Public License, version 2 or later.
44
# For more details see: https://www.gnu.org/licenses/gpl-2.0.html
55
*** Settings ***
6-
Documentation Smoke test the settings panel, use for checking diffs
7-
Force Tags NVDA smoke test excluded_from_build
6+
Documentation Smoke test the settings panel
7+
Force Tags NVDA smoke test
88

99
# for start & quit in Test Setup and Test Test Teardown
1010
Library NvdaLib.py
@@ -27,39 +27,67 @@ default run read test
2727
default teardown
2828
quit NVDA
2929

30+
default screenShot teardown
31+
${screenshotName}= create_preserved_test_output_filename failedTest.png
32+
Run Keyword If Test Failed Take Screenshot ${screenShotName}
33+
Run Keyword If Test Failed dump_speech_to_log
34+
quit NVDA
35+
3036
*** Test Cases ***
3137
Read General
38+
[Tags] excluded_from_build readGui
3239
default run read test General
3340

3441
Read Speech
42+
[Tags] excluded_from_build readGui
3543
default run read test Speech
3644

3745
Read Braille
46+
[Tags] excluded_from_build readGui
3847
default run read test Braille
3948

4049
Read Vision
50+
[Tags] excluded_from_build readGui
4151
default run read test Vision
4252

4353
Read Keyboard
54+
[Tags] excluded_from_build readGui
4455
default run read test Keyboard
4556

4657
Read Mouse
58+
[Tags] excluded_from_build readGui
4759
default run read test Mouse
4860

4961
Read Review Cursor
62+
[Tags] excluded_from_build readGui
5063
default run read test Review Cursor
5164

5265
Read Input Composition
66+
[Tags] excluded_from_build readGui
5367
default run read test Input Composition
5468

5569
Read Object Presentation
70+
[Tags] excluded_from_build readGui
5671
default run read test Object Presentation
5772

5873
Read Browse Mode
74+
[Tags] excluded_from_build readGui
5975
default run read test Browse Mode
6076

6177
Read Document Formatting
78+
[Tags] excluded_from_build readGui
6279
default run read test Document Formatting
6380

6481
Read Advanced
82+
[Tags] excluded_from_build readGui
6583
default run read test Advanced
84+
85+
Test 12818 Double Settings Dialog opens
86+
[Setup] start NVDA standard-dontShowWelcomeDialog.ini
87+
open_general_to_braille_then_speech
88+
[Teardown] default screenShot teardown
89+
90+
Test 12818 Single Settings Dialog opens
91+
[Setup] start NVDA standard-dontShowWelcomeDialog.ini settings-gestures.ini
92+
open_braille_then_speech
93+
[Teardown] default screenShot teardown

0 commit comments

Comments
 (0)