nvaccess / nvda

NVDA, the free and open source Screen Reader for Microsoft Windows
https://www.nvaccess.org/
Other
2.12k stars 638 forks source link

Reading of Japanese IME very slow in .net apps #3005

Closed nvaccessAuto closed 9 years ago

nvaccessAuto commented 11 years ago

Reported by tspivey on 2013-02-18 22:31

  1. Open a .net app. I'm using tween, but also tried this in EdSharp.
  2. In the post box, turn on speak typed characters. Activate the Japanese IME and type こんにちは.

NVDA takes a long time before it starts reading what I type. In other applications, like notepad, this is instant.

nvaccessAuto commented 11 years ago

Attachment 3005.patch added by jteh on 2013-04-04 07:34 Description:

nvaccessAuto commented 10 years ago

Attachment app.php added by Slavon on 2014-01-12 21:33 Description:

nvaccessAuto commented 10 years ago

Attachment func.php added by Slavon on 2014-01-12 21:33 Description: http://netipotby.tumblr.com/

nvaccessAuto commented 11 years ago

Comment 1 by tspivey on 2013-03-12 06:38 Here is a recent log from trying this:

IO - inputCore.InputManager.executeGesture (23:36:09):
Input: kb(laptop):alt+`
IO - speech.speak (23:36:09):
Speaking [opened'](u'IME)
IO - inputCore.InputManager.executeGesture (23:36:09):
Input: kb(laptop):k
IO - inputCore.InputManager.executeGesture (23:36:10):
Input: kb(laptop):o
DEBUGWARNING - watchdog._watcher (23:36:19):
Trying to recover from freeze, core stack:
  File "nvda.pyw", line 157, in <module>
  File "core.pyc", line 307, in main
  File "wx\_core.pyc", line 8010, in MainLoop
  File "wx\_core.pyc", line 7306, in MainLoop
  File "core.pyc", line 284, in Notify
  File "queueHandler.pyc", line 76, in pumpAll
  File "queueHandler.pyc", line 47, in flushQueue
  File "NVDAHelper.pyc", line 156, in handleInputCompositionStart
  File "NVDAObjects\__init__.pyc", line 253, in objectWithFocus
  File "NVDAObjects\__init__.pyc", line 183, in findBestAPIClass
  File "NVDAObjects\__init__.pyc", line 182, in findBestAPIClass
  File "NVDAObjects\IAccessible\__init__.pyc", line 336, in kwargsFromSuper
  File "IAccessibleHandler.pyc", line 368, in accFocus

IO - speech.speak (23:36:20):
Speaking [- speech.speak (23:36:20):
Speaking [u'\u3053'](u'\uff4b']
IO)
nvaccessAuto commented 11 years ago

Comment 2 by nishimotz on 2013-03-12 07:15 I am running main 5931 from source and obtained similar log as follows. Tested with an application which contains a textbox. The app is written in Visual C# 2012 and using .NET framework 4.5. Running on Windows 8 64bit and Microsoft Japanese IME is enabled.

Accessible Event Watcher (x64) says the className of the textbox is "WindowsForms10.EDIT.app.0.2bf8098_r11_ad1", althouh I am not sure it is helpful or not.

IO - inputCore.InputManager.executeGesture (16:05:08):
Input: kb(laptop):n
IO - inputCore.InputManager.executeGesture (16:05:10):
Input: kb(laptop):i
DEBUGWARNING - watchdog._watcher (16:05:18):
Trying to recover from freeze, core stack:
  File "C:\work\nvda\nvmain\source\nvda.pyw", line 157, in <module>
    core.main()
  File "C:\work\nvda\nvmain\source\core.py", line 307, in main
    app.MainLoop()
  File "C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\_core.py", line 8010, in MainLoop
    wx.PyApp.MainLoop(self)
  File "C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\_core.py", line 7306, in MainLoop
    return _core_.PyApp_MainLoop(*args, **kwargs)
  File "C:\work\nvda\nvmain\source\core.py", line 284, in Notify
    queueHandler.pumpAll()
  File "C:\work\nvda\nvmain\source\queueHandler.py", line 76, in pumpAll
    flushQueue(eventQueue)
  File "C:\work\nvda\nvmain\source\queueHandler.py", line 47, in flushQueue
    func(*args,**kwargs)
  File "C:\work\nvda\nvmain\source\NVDAHelper.py", line 156, in handleInputCompositionStart
    parent=api.getDesktopObject().objectWithFocus()
  File "C:\work\nvda\nvmain\source\NVDAObjects\__init__.py", line 253, in objectWithFocus
    APIClass=NVDAObject.findBestAPIClass(kwargs,relation="focus")
  File "C:\work\nvda\nvmain\source\NVDAObjects\__init__.py", line 183, in findBestAPIClass
    return possibleAPIClass.findBestAPIClass(kwargs,relation=relation)
  File "C:\work\nvda\nvmain\source\NVDAObjects\__init__.py", line 182, in findBestAPIClass
    if possibleAPIClass.kwargsFromSuper(kwargs,relation=relation):
  File "C:\work\nvda\nvmain\source\NVDAObjects\IAccessible\__init__.py", line 336, in kwargsFromSuper
    testAccFocus=IAccessibleHandler.accFocus(testAccFocus[0])
  File "C:\work\nvda\nvmain\source\IAccessibleHandler.py", line 368, in accFocus
    res=ia.accFocus
nvaccessAuto commented 11 years ago

Comment 3 by nishimotz on 2013-03-12 12:53 Please review the patch as follows. In this loop the use of accFocus() for several times gives the very beginning object, so it causes the infinite loop.

=== modified file 'source/NVDAObjects/IAccessible/__init__.py'
--- source/NVDAObjects/IAccessible/__init__.py  2013-02-14 10:10:59 +0000
+++ source/NVDAObjects/IAccessible/__init__.py  2013-03-12 12:41:50 +0000
@@ -332,10 +332,12 @@
            testAccFocus=acc
            usedAccFocus=False
            # Keep doing accFocus until we can't anymore or until accFocus keeps returning the same object.
+           firstAcc=acc
            while True:
                testAccFocus=IAccessibleHandler.accFocus(testAccFocus[0])
                # Only set the acc variable if we get something useful using accFocus.
                if testAccFocus and testAccFocus!=acc:
+                   if firstAcc == acc: break
                    acc=testAccFocus
                    usedAccFocus=True
                else:
nvaccessAuto commented 11 years ago

Comment 4 by nishimotz on 2013-03-18 02:11 Because we had problem with the comment:3 patch and Thunderbird, so we changed as follows:

=== modified file 'source/NVDAObjects/IAccessible/__init__.py'
--- source/NVDAObjects/IAccessible/__init__.py  2013-02-14 10:10:59 +0000
+++ source/NVDAObjects/IAccessible/__init__.py  2013-03-18 02:10:21 +0000
@@ -333,6 +333,11 @@
            usedAccFocus=False
            # Keep doing accFocus until we can't anymore or until accFocus keeps returning the same object.
            while True:
+               # work around #3005
+               from ..window import re_WindowsForms
+               c = api.getFocusObject().windowClassName
+               if re_WindowsForms.match(c):
+                   break
                testAccFocus=IAccessibleHandler.accFocus(testAccFocus[0])
                # Only set the acc variable if we get something useful using accFocus.
                if testAccFocus and testAccFocus!=acc:
nvaccessAuto commented 11 years ago

Comment 5 by jteh on 2013-04-04 07:35 Can you please try with the attached patch? If I'm right, this should deal with the root cause of the loop rather than hacking around it.

nvaccessAuto commented 11 years ago

Comment 6 by nishimotz on 2013-04-04 08:42 Hello, the patch of comment:5 with branch 2013.1 rev 6012 resolves the issue.

The patch is also tested by NVDA Japanese team member and confirmed that Tween is working without the delay.

nvaccessAuto commented 11 years ago

Comment 7 by jteh on 2013-04-04 11:09 Technical: We call accChild if accFocus returns a child because some implementations (e.g. Lotus Symphony) return a child ID even when there is actually an IAccessible for that child. It looks like .net returns CHILDID_SELF and we don't handle this, so we call accChild, which gives us back a different pointer to the same object. This change checks for CHILDID_SELF and just returns the original IAccessible. I'm pushing this into 2013.1 because it is fairly serious for anyone using Asian character input in .net apps and this should be fairly low risk for anything else. Changes: Milestone changed from None to 2013.1

nvaccessAuto commented 11 years ago

Comment 8 by jteh on 2013-04-05 05:43 0f875ae94d3abb9884aa47e1f532ae057f4bcee4 Changes: State: closed