GNOME Bugzilla – Bug 460735
[blocked] JSpinner not spoken or brailled correctly
Last modified: 2009-03-10 00:04:54 UTC
When a JSpinner value changes, Orca endlessly repeats the value in the JSpinner text field. This occurs about 1 out of 5 times that I change the JSpinner value. The Swing tutorial source code for reproducing the problem is here: http://java.sun.com/docs/books/tutorial/uiswing/examples/zipfiles/components-SpinnerDemoProject.zip
Will, I think it would be a good idea to save the source code for reproducing the bug in a subdirectory under orca/test/java, where the subdirectory name is the bug id.
(In reply to comment #1) > Will, I think it would be a good idea to save the source code for reproducing > the bug in a subdirectory under orca/test/java, where the subdirectory name is > the bug id. > Can you describe more about how this would fit into the regression testing harness?
I wasn't implying that the tests would integrate into the regression test harness (although that might be a good idea). My concern is that the test code might be lost if it is not stored in some well-known location. I've made it a practice to attach test code to bug reports (and that might be sufficient) but I thought it would be better to save the test code in a standard location so it can be reused as some later time, like for regression testing. Right now, we don't have a convenient way to do Java regression testing. Some of the issues that need to be solved are: 1. J2SE needs to be installed on the test system. 2. The Java Access Bridge for GNOME needs to be installed into the J2SE above. 3. The runall.sh and runone.sh scripts need to be modified to launch the Java interpreter and load the test class files. 4. A keystroke file needs to be produced for each test.
> I wasn't implying that the tests would integrate into the regression test > harness (although that might be a good idea). My concern is that the test code > might be lost if it is not stored in some well-known location. I've made it a > practice to attach test code to bug reports (and that might be sufficient) but > I thought it would be better to save the test code in a standard location so it > can be reused as some later time, like for regression testing. Aha.. Good. There's a ./bugs subdirectory that we had been using to hold things like that. We've kind of just taken to adding things to bug reports, though, and have gotten away from keeping the ./bugs up to date. At some point, such as when we are all using the regression testing stuff, I'd like to see a regression test added for each bug we fix. > 3. The runall.sh and runone.sh scripts need to be modified to launch the Java > interpreter and load the test class files. Or, we could make a "java" directory and add the extra stuff in a parallel *.params file (see the keystrokes directories for examples of *.params files -- their contents just get appended to the command line.
Created attachment 93048 [details] [review] proposed patch The text field inside a spin box fires a caret-moved event when the text field gets focus or the contents change. The proposed solution is to check whether a caret-moved event source is inside a spin box. If it is, the displayed label is the spin box name and the displayed text is the spin box value.
(In reply to comment #5) > Created an attachment (id=93048) [edit] > proposed patch > > The text field inside a spin box fires a caret-moved event when the text field > gets focus or the contents change. The proposed solution is to check whether a > caret-moved event source is inside a spin box. If it is, the displayed label is > the spin box name and the displayed text is the spin box value. > This patch definitely improves the situation -- we at least get *something* useful when navigating these beastly objects. The JSpinner object, however, seems to be a very complex component, probably similar to editable comboboxes, and I suspect it will require a lot of work to provide compelling access to them. Areas for consideration include the following: 1) Something seems a little strange with the braille - I see it being updated two or three times when you first tab into a spinbox. In looking a debug output, it looks as though the JSpinner SpinBoxes are indeed text-change happy. It would be nice to do even more filtering (if possible) to prevent the braille flickering that happens as a result of a single keyboard action such as Tab. 2) We like to restrict the speech announcement of label+role to only when you first navigate to a spinbox. When you change it's value thereafter, we should only speak the new value. This is handled via the "already_focused" parameter of a speech generator method. 3) In addition to the multiple updates of the braille display, I'm seeing some strange behavior where the label/role are sometimes displayed and other times they are not. For example. the "Month" label doesn't always appear for the Month spinbox. In looking at the stack traces that appear in the window running the Spinner demo, I'm guessing this is probably due to COMM_FAILURES out of our control. 4) When arrowing left/right and when editing in the text area, the braille display should be updating the cursor position and speech should output the current character information. 5) I notice that speech is very verbose when entering or deleting text. It seems to output the entire label+value+role information for each character change. Instead, it should act like any other text area. For how to do this, I'm not exactly sure. I'm curious if one approach to this problem might be to treat the spinbox as an atomic object rather than a bunch of separate objects like we're getting from Java. For example, I wonder if we should think about setting the locus of focus to the spin box object when we get any focus: event for the spin box or any of its children.
> For how to do this, I'm not exactly sure. I'm curious if one approach to this > problem might be to treat the spinbox as an atomic object rather than a bunch > of separate objects like we're getting from Java. For example, I wonder if we > should think about setting the locus of focus to the spin box object when we > get any focus: event for the spin box or any of its children. Good advice; I'm going work on treating the spin box as a single object.
(In reply to comment #6) > (In reply to comment #5) > > Created an attachment (id=93048) [edit] > > proposed patch > > > > The text field inside a spin box fires a caret-moved event when the text field > > gets focus or the contents change. The proposed solution is to check whether a > > caret-moved event source is inside a spin box. If it is, the displayed label is > > the spin box name and the displayed text is the spin box value. > > > > This patch definitely improves the situation -- we at least get *something* > useful when navigating these beastly objects. The JSpinner object, however, > seems to be a very complex component, probably similar to editable comboboxes, > and I suspect it will require a lot of work to provide compelling access to > them. I'll attach a new patch that address the problems below. > > Areas for consideration include the following: > > 1) Something seems a little strange with the braille - I see it being updated > two or three times when you first tab into a spinbox. In looking a debug > output, it looks as though the JSpinner SpinBoxes are indeed text-change happy. > It would be nice to do even more filtering (if possible) to prevent the > braille flickering that happens as a result of a single keyboard action such as > Tab. The excessive updating is due to events not being filtered out. I've filtered out all events except for: onFocus - to keep track of whether the spin box was already focused. This appears to be necessary since the speechgenerator and braillegenerator methods are always called with already_focused being False. onCaretMoved - a caret-moved event is always fired when a spin box gets focus and when the spin box value changes. > > 2) We like to restrict the speech announcement of label+role to only when you > first navigate to a spinbox. When you change it's value thereafter, we should > only speak the new value. This is handled via the "already_focused" parameter > of a speech generator method. The patch does this by checking the value of _checkBoxAlreadyFocused. > > 3) In addition to the multiple updates of the braille display, I'm seeing some > strange behavior where the label/role are sometimes displayed and other times > they are not. For example. the "Month" label doesn't always appear for the > Month spinbox. In looking at the stack traces that appear in the window > running the Spinner demo, I'm guessing this is probably due to COMM_FAILURES > out of our control. This is an intermittent problem where getDisplayedLabel for the spin box sometimes returns None. This is likely related to Bug 350742 where Java text is not being returned correctly. > > 4) When arrowing left/right and when editing in the text area, the braille > display should be updating the cursor position and speech should output the > current character information. This is fixed by keeping track of the previous caret position and calling default.Script.onCaretMoved, if it has. > > 5) I notice that speech is very verbose when entering or deleting text. It > seems to output the entire label+value+role information for each character > change. Instead, it should act like any other text area. This if fixed. > > For how to do this, I'm not exactly sure. I'm curious if one approach to this > problem might be to treat the spinbox as an atomic object rather than a bunch > of separate objects like we're getting from Java. For example, I wonder if we > should think about setting the locus of focus to the spin box object when we > get any focus: event for the spin box or any of its children. >
Created attachment 94001 [details] [review] updated patch Updated patch.
Thanks for the patch! I have several comments/questions: Spin Button vs. Spin Box: ------------------------- How do spin buttons differ from spin boxes? It looks like a GTK+ spin button is the same thing as a Java spin box. As such, it might provide some consistency to just to this instead of creating new strings: rolenames[ROLE_SPIN_BOX] = rolenames[ROLE_SPIN_BUTTON] Unless, perhaps, GTK+ got it wrong and the spin buttons should be the up/down buttons and the spin box should be the name given to the whole of the text area and up/down buttons. For now, however, just doing the above would eliminate the need for a string change and keep things consistent with GTK+. self._script._spinBoxAlreadyFocused ----------------------------------- Something about using a global script field to manage a spin box seems very unsettling to me. Instead, I wonder if trying to treat the spin box as an atomic object and using locusOfFocus to manage things might be better. This would be more in line with how locusOfFocusChanged and visualAppearanceChanged work. Thus, the logic might be: when the spin box or one of its children get focus, set the locus of focus to the spin box. When something changes inside the spin box, keep the locus of focus on the spin box and call visualAppearanceChanged. There will probably also be some niggling that needs to be done in onCaretMoved and _presentTextAtNewCaret position to handle caret movement events. If trying to work more within the bounds of the architecture doesn't work, then I'd would suggest moving the script globals (_spinBoxAlreadyFocused, _prevSpinBoxLabel, _prevSpinBoxValue, _prevSpinBoxCaretOffset) to the spin box object itself. _getAncestorWithRole -------------------- Gecko.py has a similar method called getContainingRole. I think a refactor is probably called for here -- make a getContainingRole (or getAncestorWithRole) method in default.py. Have the J2SE script use the default.py method and have Gecko.py override it. Thanks!
(In reply to comment #10) > Thanks for the patch! I have several comments/questions: > > Spin Button vs. Spin Box: > ------------------------- > > How do spin buttons differ from spin boxes? It looks like a GTK+ spin button > is the same thing as a Java spin box. As such, it might provide some > consistency to just to this instead of creating new strings: > > rolenames[ROLE_SPIN_BOX] = rolenames[ROLE_SPIN_BUTTON] > > Unless, perhaps, GTK+ got it wrong and the spin buttons should be the up/down > buttons and the spin box should be the name given to the whole of the text area > and up/down buttons. For now, however, just doing the above would eliminate > the need for a string change and keep things consistent with GTK+. I made the change. > > > self._script._spinBoxAlreadyFocused > ----------------------------------- > > Something about using a global script field to manage a spin box seems very > unsettling to me. Instead, I wonder if trying to treat the spin box as an > atomic object and using locusOfFocus to manage things might be better. This > would be more in line with how locusOfFocusChanged and visualAppearanceChanged > work. Thus, the logic might be: when the spin box or one of its children get > focus, set the locus of focus to the spin box. When something changes inside > the spin box, keep the locus of focus on the spin box and call > visualAppearanceChanged. There will probably also be some niggling that needs > to be done in onCaretMoved and _presentTextAtNewCaret position to handle caret > movement events. I tried the above and still have the same problems: 1. already_focus is always false when the getSpeechForSpinBox is called. 2. how can getBrailleRegionsForSpinBox determine whether the spin box already has focus. Any suggestions? > > If trying to work more within the bounds of the architecture doesn't work, then > I'd would suggest moving the script globals (_spinBoxAlreadyFocused, > _prevSpinBoxLabel, _prevSpinBoxValue, _prevSpinBoxCaretOffset) to the spin box > object itself. > > > _getAncestorWithRole > -------------------- > > Gecko.py has a similar method called getContainingRole. I think a refactor is > probably called for here -- make a getContainingRole (or getAncestorWithRole) > method in default.py. Have the J2SE script use the default.py method and have > Gecko.py override it. I also made this change and it works okay. > > Thanks! >
> > and up/down buttons. For now, however, just doing the above would eliminate > > the need for a string change and keep things consistent with GTK+. > > I made the change. Thanks! > I tried the above and still have the same problems: > > 1. already_focus is always false when the getSpeechForSpinBox is called. > > 2. how can getBrailleRegionsForSpinBox determine whether the spin box already > has focus. > > Any suggestions? Bummer. Do you have an updated patch I could take a look at?
Created attachment 94263 [details] [review] debugging patch
Will, I've attached a debugging patch with a lot of trace statements enabled, so you can see how onFocus, onCaretMoved, getSpeechForSpinBox and getBrailleRegionsForSpinBox are called when you tab through a spin box and also use the up and down arrows to change the spin box values. I've tried different combinations of orca.setLocusOfFocus and orca.visualAppearance changed and cannot get the behavior right, without using the global state variables (which I agree we should get rid of). So, I'm kind of stuck here and would appreciate if you would experiment around and see if you can find a fix. Also, it appears that an event is occurring after the caret-moved event that is causing getBrailleRegionsForSpinBox, but not getSpeechForSpinBox, to be called. Setting debug_level to DEBUG_FINEST should show the event, but I haven't tried it yet. Thanks!
> rolenames[ROLE_SPIN_BOX] = rolenames[ROLE_SPIN_BUTTON] Saw you did this. Cool. Thanks! > self._script._spinBoxAlreadyFocused > ----------------------------------- > > Something about using a global script field to manage a spin box seems very > unsettling to me. Instead, I wonder if trying to treat the spin box as an > atomic object and using locusOfFocus to manage things might be better. This > would be more in line with how locusOfFocusChanged and visualAppearanceChanged > work. Thus, the logic might be: when the spin box or one of its children get > focus, set the locus of focus to the spin box. When something changes inside > the spin box, keep the locus of focus on the spin box and call > visualAppearanceChanged. There will probably also be some niggling that needs > to be done in onCaretMoved and _presentTextAtNewCaret position to handle caret > movement events. > > If trying to work more within the bounds of the architecture doesn't work, then > I'd would suggest moving the script globals (_spinBoxAlreadyFocused, > _prevSpinBoxLabel, _prevSpinBoxValue, _prevSpinBoxCaretOffset) to the spin box > object itself. > > > _getAncestorWithRole > -------------------- > > Gecko.py has a similar method called getContainingRole. I think a refactor is > probably called for here -- make a getContainingRole (or getAncestorWithRole) > method in default.py. Have the J2SE script use the default.py method and have > Gecko.py override it. You need to leave the Gecko.py version alone (i.e., do not delete it). The Gecko version adds a check for DOCUMENT_FRAME that's needed. The main refactor was that more than one script was now caring about the containing role, so it seemed to call for a default.py method. For what might be going on with other problem areas, there might be a number of things to consider. This code looks suspect: else: spinbox = self.getContainingRole(event.source, rolenames.ROLE_SPIN_BOX) if spinbox: # For spin boxes, the text field is the object that gets focus, # not the spin box itself. So, set the locusOfFocus to the # spin box itself. # orca.setLocusOfFocus(event, spinbox) default.Script.onFocus(self, event) The call to default.Script.onFocus is going to undo your call to orca.setLocusOfFocus(event, spinbox). So, you might want to avoid the call to default.Script.onFocus: else: spinbox = self.getContainingRole(event.source, rolenames.ROLE_SPIN_BOX) if spinbox: # For spin boxes, the text field is the object that gets focus, # not the spin box itself. So, set the locusOfFocus to the # spin box itself. # orca.setLocusOfFocus(event, spinbox) else: default.Script.onFocus(self, event) With a little more perseverance with debugging, it looks as though onTextDeleted is going to set the locus of focus to the text area if it has focus. So, you may get some intervening focus switching between the text area and the spin button, causing each one to speak when the spin box initially gets focus. Finally, I'm not sure bypassing the onValueChanged handling for the spin box is the right thing to do. Instead, I suspect you really need it in there to handle the case where the user changes the value of the spin button when it has focus. I'm going to play a little bit with the above and will attach a patch in a bit.
Created attachment 94565 [details] [review] Patch to work on some of the thoughts in the previous comment Here's a patch that seems to work OK with the "Year:" spin button. The "Month:" and "Another date:" spin buttons are very strange -- they spew out loads of errors in the window running the JSpinner demo when I change their value using the Up/Down arrows. This might related to why the patch does not work well for them: Aug 29, 2007 2:03:08 PM com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl convertThrowableToSystemException WARNING: "IOP00010202: (UNKNOWN) Unknown user exception thrown by the server" org.omg.CORBA.UNKNOWN: vmcid: SUN minor code: 202 completed: Maybe at com.sun.corba.se.impl.logging.ORBUtilSystemException.runtimeexception(ORBUtilSystemException.java:8365) at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.convertThrowableToSystemException(CorbaMessageMediatorImpl.java:1918) at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleThrowableDuringServerDispatch(CorbaMessageMediatorImpl.java:1868) at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleThrowableDuringServerDispatch(CorbaMessageMediatorImpl.java:1821) at com.sun.corba.se.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:258) at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1680) at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1540) at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:922) at com.sun.corba.se.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:181) at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:694) at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.dispatch(SocketOrChannelConnectionImpl.java:451) at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.doWork(SocketOrChannelConnectionImpl.java:1187) at com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:398) Caused by: java.lang.NullPointerException at org.GNOME.Accessibility.ValueImpl.currentValue(ValueImpl.java:71) at org.GNOME.Accessibility.ValuePOATie.currentValue(ValuePOATie.java:83) at org.GNOME.Accessibility.ValuePOA._invoke(ValuePOA.java:104) at com.sun.corba.se.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:637) at com.sun.corba.se.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:189) ... 8 more I also see COMM_FAILUREs on the Orca side, but I'm not sure if there is a cause/effect between the JSpinner stack traces and the COMM_FAILUREs: Traceback (most recent call last):
+ Trace 158811
s.processObjectEvent(event)
self.listeners[key](event)
event.source.value.currentValue)) COMM_FAILURE
In any case, this might be something to get you further.
BTW, I should note that I'm also not terribly thrilled with the patch I just posted. It gets us closer, but it doesn't make the presentation consistent with what we do with GTK+ spin buttons. For an example of the GTK+ behavior, go to the "Speech" tab of the Orca preferences GUI and enable "Speak progress bar updates". Then, navigate to the "Update interval" spin button and observe what Orca does for speech and braille. We treat the spin button almost like a text area, with special consideration made for when the value changes. In particular pay attention to what happens in speech and braille when you: * First tab to it * Arrow left and right through it * Arrow up and down in it
(In reply to comment #16) All this exceptions are caused by Bug 435585. Just have to live with them until they are fixed in Java 5, update 14. > Created an attachment (id=94565) [edit] > Patch to work on some of the thoughts in the previous comment > > Here's a patch that seems to work OK with the "Year:" spin button. The > "Month:" and "Another date:" spin buttons are very strange -- they spew out > loads of errors in the window running the JSpinner demo when I change their > value using the Up/Down arrows. This might related to why the patch does not > work well for them: > > Aug > 29, 2007 2:03:08 PM com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl > convertThrowableToSystemException > WARNING: "IOP00010202: (UNKNOWN) Unknown user exception > thrown by the server" > > org.omg.CORBA.UNKNOWN: vmcid: SUN minor code: 202 > completed: Maybe > at > com.sun.corba.se.impl.logging.ORBUtilSystemException.runtimeexception(ORBUtilSystemException.java:8365) > > at > com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.convertThrowableToSystemException(CorbaMessageMediatorImpl.java:1918) > > at > com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleThrowableDuringServerDispatch(CorbaMessageMediatorImpl.java:1868) > at > com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleThrowableDuringServerDispatch(CorbaMessageMediatorImpl.java:1821) > at > com.sun.corba.se.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:258) > > at > com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1680) > > at > com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1540) > at > com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:922) > > at > com.sun.corba.se.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:181) > > at > com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:694) > at > com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.dispatch(SocketOrChannelConnectionImpl.java:451) > > > at > com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.doWork(SocketOrChannelConnectionImpl.java:1187) > > at > com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:398) > Caused by: > java.lang.NullPointerException > > at > org.GNOME.Accessibility.ValueImpl.currentValue(ValueImpl.java:71) > > > at org.GNOME.Accessibility.ValuePOATie.currentValue(ValuePOATie.java:83) > at > org.GNOME.Accessibility.ValuePOA._invoke(ValuePOA.java:104) > > at > com.sun.corba.se.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:637) > > at > com.sun.corba.se.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:189) > ... 8 more > > I also see COMM_FAILUREs on the Orca side, but I'm not sure if there is a > cause/effect between the JSpinner stack traces and the COMM_FAILUREs: > > Traceback (most recent call last): > File > "/usr/local/lib/python2.5/site-packages/orca/focus_tracking_presenter.py", line > 627, in _processObjectEvent > s.processObjectEvent(event) > File "/usr/local/lib/python2.5/site-packages/orca/script.py", line 296, in > processObjectEvent > self.listeners[key](event) > File "/usr/local/lib/python2.5/site-packages/orca/J2SE-access-bridge.py", > line 479, in onValueChanged > event.source.value.currentValue)) > COMM_FAILURE > > In any case, this might be something to get you further. >
(In reply to comment #17) > BTW, I should note that I'm also not terribly thrilled with the patch I just > posted. It gets us closer, but it doesn't make the presentation consistent > with what we do with GTK+ spin buttons. For an example of the GTK+ behavior, > go to the "Speech" tab of the Orca preferences GUI and enable "Speak progress > bar updates". Then, navigate to the "Update interval" spin button and observe > what Orca does for speech and braille. > > We treat the spin button almost like a text area, with special consideration > made for when the value changes. In particular pay attention to what happens > in speech and braille when you: > > * First tab to it > * Arrow left and right through it > * Arrow up and down in it > 1. Speech is the same for GTK+ and Swing spinners. I modified _getBrailleRegionsForSpinBox so Swing spinners output the same braille as GTK+ ones. 2. J2SE_access_bridge handles spinner with numeric values correctly, but has problems with non-numeric values (e.g., "January", "February",...). With the patch above, onValueChanged is called for both numeric and non-numeric values. This is okay for numeric values, but not for non-numeric ones, since the obj.value field cannot be used to get non-numeric values. It appears that a better way to get values is by using the onTextInserted method. 3. Bug 350742 continues to cause problems with reliably getting spinner values. I'm marking this bug as blocked on Bug 350742 because frequent failures getting the obj.text cause Orca to be silent about spinner values about a third the time. I recommend that complete fix for this bug be deferred until Bug 350742 is fixed.
Created attachment 94724 [details] [review] debugging patch This is a debugging patch that improves Orca speech and braille for Swing spin boxes. However, Orca still does not speak or braille correctly because of frequent failures getting the spinner text due to Bug 350742.
(In reply to comment #20) > Created an attachment (id=94724) [edit] > debugging patch > > This is a debugging patch that improves Orca speech and braille for Swing spin > boxes. However, Orca still does not speak or braille correctly because of > frequent failures getting the spinner text due to Bug 350742. > See also Bug 435585, which might point to the source of this problem.
Fixed with patch to bug #435623.