New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix nvda find title cancellation #11632
Conversation
Many NVDAObjects derive from Window, including IAccessible. This meant that the fix for focus changes in Gmail was bypassed! Looking at the log, after opening NVDA Find dialog the last queued focus object is set to the following: - NVDAObjects.Dynamic_NvdaDialogDialogIAccessibleWindowNVDAObject - NVDAObjects.Dynamic_IAccessibleEditWindowNVDAObject The first is the dialog, the second the edit field. The full MRO for the dialog is: - class 'NVDAObjects.Dynamic_NvdaDialogDialogIAccessibleWindowNVDAObject' - class 'appModules.nvda.NvdaDialog' - class 'NVDAObjects.behaviors.Dialog' - class 'NVDAObjects.IAccessible.IAccessible' - class 'NVDAObjects.window.Window' - class 'NVDAObjects.NVDAObject' - class 'documentBase.TextContainerObject' - class 'baseObject.ScriptableObject' - class 'baseObject.AutoPropertyObject' - class 'garbageHandler.TrackedObject' - class 'object' Excluding speech cancellation on 'NVDAObjects.behaviors.Dialog' seems to generally make sense, resolves the NVDA Find dialog speech for focus cancellation, and does not appear to interfere with the Gmail fix.
See test results for failed build of commit e7d1ca190c |
While fix proposed here certainly makes dialog titles to be read again I'd like to propose more general approach which would probably also fix #11492. |
This bug is wider than just the Find dialog. For instance NVDA+control+g to bring up the NVDA settings dialog set to the General pannel: The dialog is not announced, only the "General property page". |
@michaelDCurran That's right, there are two focus events received. Actually, I didn't check if there the "dialog" object is actually an ancestor of the new control, theoretically it should be, the timing issue of updating focus ancestors is an interesting angle to investigate. I hoped that all dialogs would get the dialog class added, I guess that is not true for the settings dialog? |
@lukaszgo1 Do you mean not cancel any speech for objects in the foreground window? The main use case for the cancellable speech feature was to fix multiple focus events from "queuing up" speech, such as when navigating through items in Gmail. |
@feerrenrut wrote:
No, that is not what I mend. Currently speech is often cancelled for window titles in case of these dialogs the missing info is the window title and its role. Therefore I've suggested to not cancel speech resulting from foreground events as change of a foreground window should always be announced to the user. |
Yes, we are in the process of working out how to do that. Foreground events are treated as focus events in NVDA, so we can't currently differentiate on that. |
We could just compare the object against api.getForegroundObject() and
never cancel if it is equal.
|
To avoid window change speech from getting cancelled
Encapsulate logic in a class, clarify ownership of obj ref.
I believe this is ready for review. |
or not self.previouslyHadFocus() | ||
or self.isAncestorOfCurrentFocus() | ||
# Ensure titles for dialogs gaining focus are reported, EG NVDA Find dialog | ||
or self.isForegroundObject() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this still necessary after the change from lastQueuedFocusObject to api.getFocusObject()? I wouldn't have thought so, unless the bug is different to what we hypothesized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your are right, checking for self.isForegroundObject()
is not required to fix this particular bug, and I have confirmed that. However, it doesn't harm the core use case of cancellable speech (rapid focus changes in Gmail), and I can't think of a reason why we would want to cancel speech for the foreground object if it wasn't the focus ancestor for some reason.
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is redundant and should be removed, as getforegroundObject always returns a focus ancestor, which is checked already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I follow this. First, I want to confirm you want the self.isForgroundObject()
check removed?
This may not be set by the focus ancestor, usually it is from api.getDesktopObject().objectInForeground()
, see the following code from doPreGainFocus
newForeground=api.getDesktopObject().objectInForeground()
if not newForeground:
log.debugWarning("Can not get real foreground, resorting to focus ancestors")
ancestors=api.getFocusAncestors()
if len(ancestors)>1:
newForeground=ancestors[1]
else:
newForeground=obj
api.setForegroundObject(newForeground)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A part from removing the now redundant foreground check, I'm good with this.
Hmm, I forgot about the first way we set the foreground object. Never
mind. It is best to leave it in then :)
So I'm good with all of this now.
|
Link to issue number:
#11397 (comment)
Summary of the issue:
When Control+Insert+F is used to bring up the Find dialog, NVDA doesn't announce the title of the dialog, "Find dialog", in most instances. This also applies to NVDA settings dialogs.
Description of how this pull request fixes the issue:
I initially tried by not cancelling speech for NVDA Objects that were
Window
objects, while this certainly fixed the issue it also made the cancellable speech feature useless. This is because allIAccessible
NVDA objects areWindow
objects.Specifically this meant that the cancellable speech would no longer fix fast focus changes in Gmail.
Looking at the log, after opening NVDA Find dialog the last
queued focus object is set to the following:
The first is the dialog, the second the edit field.
The full MRO for the dialog is:
Excluding speech cancellation on 'NVDAObjects.behaviors.Dialog' seems to
generally make sense, resolves the NVDA Find dialog speech for focus
cancellation, and does not appear to interfere with the Gmail fix.
However further investigation raised the question: Why is this dialog not part of the focus ancestors?
It turns out that using
api.getForegroundObject()
also resolves the issue, leading to the question: How is this no longer the focused object, but is the foregroundObject?Essentially this came down to a mismatch of the timing for when focus ancestors are set (in
api.setFocusObject()
called indoPreGainFocus
) and when thelastQueuedFocusObject
is set (in_trackFocusObject
called viaqueueEvent
). If the check for "cancelled" happened after a new focus event had been queued, but before that event was executed then the dialog object was no longer the lastQueuedFocusObject, but was not yet added to the focus ancestors.To resolve this mismatch,
api.getFocusObject()
is used to compare the object to NVDA's concept of the current focus, this is updated at the same time as focus ancestors.The state with inline functions was becoming confusing and hard to read, it has been replaced with a class.
Testing performed:
Known issues with pull request:
Change log entry:
Bug: