Skip to content

Tidy advanced gui panel#9239

Merged
feerrenrut merged 33 commits into
masterfrom
tidyAdvancedGuiPanel
Feb 27, 2019
Merged

Tidy advanced gui panel#9239
feerrenrut merged 33 commits into
masterfrom
tidyAdvancedGuiPanel

Conversation

@feerrenrut

@feerrenrut feerrenrut commented Feb 4, 2019

Copy link
Copy Markdown
Contributor

Summary of the issue:

With the introduction of the advanced panel in the settings dialog #9200, there were a couple of UI issues, the text did not wrap properly, and the warning message was only announced when the dialog received focus (not when moving from the category list to the panel itself).
Several times during development, old settings dialog windows were not being destroyed, this meant that the settings dialog could not be opened a second time. The check for multiple instances was trying to serve two purposes:

  • Stop users from opening a second settings dialog while one was already open, changing settings from two places at once could have unintended and confusing outcomes.
  • Warn developers that dialogs are not closing / being disposed of correctly.

Description of how this pull request fixes the issue:

The long text is now wrapped at the width of the panel. The "Warning!" text is larger and bold.

The warning text is announced when the panel receives focus.

A state is appended to the settings dialog instances, this keeps track of whether the dialog has been destroyed and it is removed when the dialog is deleted. We can then give the standard "user friendly" error when the settings dialog is already open, and log an error when the window is destroyed but not deleted.

Testing performed:

The settings dialog should be reported as prior versions.

The panel description should be reported when the dialog gets focus and the focused control is:

  • a control on the document formatting panel
  • a control on the advanced panel
    This description should only be reported once, regardless of whether the change in focus is due to alt+tab (swapping applications), ctrl+tab (swapping settings categories), or moving from the category list to the settings panel

Known issues with pull request:

  • Due to the delays of garbage collection, if the NVDA settings dialog is closed and opened again quickly, an error may be added to the log.

Alternatives:

  • The text could be used as a label for a checkbox which enables / disables the rest of the panel. The checkbox must be checked before modifications can be made. Perhaps it's state is saved in the configuration?

Change log entry:

Section: New features, Changes, Bug fixes

Changes:

 - Descriptive text is now announced for the advanced settings panel and the document formatting panel (#9239).

Attempt to use a known window ID to force a name change event to be spoken.
Otherwise the warning is spoken when the dialog looses and gets focus again.
@michaelDCurran

Copy link
Copy Markdown
Member

I think it should be a warning checkbox at the beginning of the Advanced panel that remembers its state for the lifetime of NVDA, but is not saved in the config. This is similar to Firefox.

@LeonarddeR

Copy link
Copy Markdown
Collaborator

I second this idea, however, I wouldn't put the warning on the checkbox itself if possible.

If I"m correct, you can do the following:

  1. Create another static box (grouping) called warning
  2. Add a static text with the warning to that grouping. I recall that magic will automatically assign that static text to accDescription on the grouping, but that's the weak part in my idea, I'm not entirely sure.
  3. You can then add a check box with a relatively short label.

@DrSooom

DrSooom commented Feb 4, 2019

Copy link
Copy Markdown

• The text could be used as a label for a checkbox which enables / disables the rest of the panel. The checkbox must be checked before modifications can be made. Perhaps it's state is saved in the configuration?

This … no, a checkbox alone, which value is stored in the "nvda.ini" doesn't solve this GUI issue at all, but a button called "Understood" like in Firefox when entering "about:config". All settings in this panel are unaccessible (= write protection) unless this button has pressed.

Well, the checkbox for automatically pressing this button (= disables this button and makes all other settings writable) can be added in this panel too. But we should prevent the normal user for changing something in this panel without showing him the warning first. So a combination of a button and a checkbox should be the best way to solve this GUI issue.

@feerrenrut

Copy link
Copy Markdown
Contributor Author

So after trying lots of options with little success, I think the only viable option is to use the AccPropServer to:

  • override the description for the panel
  • set the panel role to property page

I am then setting the name of the panel using self.SetName, because overriding it with AccPropServer did not result in it being spoken!

One remaining issue is that the alt+tabbing to the dialog results in getDialogText running (in behaviours.py ) which essentially makes the dialog speak twice. For now I have resolved this by removing controlTypes.ROLE_PROPERTYPAGE from the collection of child roles included. We will need a better solution for this.

This result is that we can have these bits of "dialog explaining text" announced.
See the updated description for full test results.

@LeonarddeR

Copy link
Copy Markdown
Collaborator

Is this considered ready for review, or are you still considering changing some things?

@LeonarddeR

Copy link
Copy Markdown
Collaborator

Nevertheless, I have tested the code. Here are some thoughts you might want to consider:

  1. Removing event_gainFocus from the NVDA appModule broke the configuration profile changes.
  2. Have you considered subclassing wx.StaticBox in a way that implements an AccPropServer for accDescription on the StaticBox, instead of setting the description on the panel? This requires setting the "warning" label as a label on the StaticBox, instead of adding a separate static text that contains the label. The advantage of this is that the warning is read again when pressing shift+tab from the UI Automation group. It is not read when entering the property page from the ok button, though.
  3. Using ROLE_PROPERTYPAGE for settings panels is a nice improvement. Make sure that you do not add an accPropServer on the VoiceSettingsPanel and BrailleSettingsSubPanel though. One way to accomplish this is: only add a server on a panel when it has a title.
  4. Rather than giving every settings panel its own AccPropServer instance, you might want to consider registering one accPropServer on MultiCategorySettingsDialog.container, making that a property page and providing the accDescription based on the currently active settings panel. When switching categories, you will have to call SetLabel on the container. Hopefully that will trigger event_namechange on it.

@feerrenrut

feerrenrut commented Feb 7, 2019

Copy link
Copy Markdown
Contributor Author

Is this considered ready for review

To start with I wanted to get some feedback on whether this actually improves things, find out what issues there might be from a UX consideration. If we can agree on what is possible, and that it improves the UX then we can get it ready for an actual review.

broke the configuration profile changes.

Ah, yes. I'll take a look at that.

One way to accomplish this is: only add a server on a panel when it has a title.

Good idea.

you might want to consider registering one accPropServer on MultiCategorySettingsDialog.container

Yes, probably a good idea. Though, do you know of any disadvantages to having multiple accPropServers registered?

Hopefully that will trigger event_namechange on it.

I was hoping to be able to remove stuff from the NVDA app module. It might not be possible yet.

@LeonarddeR

Copy link
Copy Markdown
Collaborator

Though, do you know of any disadvantages to having multiple accPropServers registered?

Not really, except for the fact that systems tend to break when an accPropServer isn't properly unregistered, which could possibly happen if NVDA crashes or when one of the panels refuses to load due to an error within the panel's class. While this is not likely to happen in stable versions, the breakage seems to be pretty major sometimes (#8916).

Hopefully that will trigger event_namechange on it.

I was hoping to be able to remove stuff from the NVDA app module. It might not be possible yet.

I'm pretty sure that gainFocus can be limited to do profile name changes only. I recall that I tested setting the current category's name on the container and then stopped with that because the name wasn't announced automatically when I changed categories, but that probably was because of the panel not having the role of property page.

Simplifies the approach to speaking profile changes in NVDA settings.
Having a non space description overrides the getDialogText behaviour
(in behaviours.py).
@feerrenrut

Copy link
Copy Markdown
Contributor Author

I've pushed a few fixes the concerns raised. I also found how to override the getDialogText behavior. This was causing the dialog to be spoken (up to first focused child). Now the dialog is speaking the current profile as the description. However, this information is also in the title. I am looking for a way to get the accessible name for the dialog to be spoken instead of the title. Another possibility, might be to change the getDialogText behavior so that when encountering a focused property page with a description the recursion stops there.

panel,
propertyAnnotations={
oleacc.PROPID_ACC_ROLE: oleacc.ROLE_SYSTEM_PROPERTYPAGE, # change the role from pane to property page
oleacc.PROPID_ACC_DESCRIPTION: panel.panelDescription, # set a description

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I've just noticed is that the NVDAObjects.behaviors.Dialog overlay is also applied to property pages, so it looks like you can safely remove the accDescription override for panels like this and only override the accRole. I have commented out this line and it did not result in different behavior.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, yeah, you are right. The hard question is what to do about the dialog description. Either we need a way to stop the getDialogText on these functions, or a way to override the dialog title.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What part of the dialog description do you mean in this case?

I really like the setup where the config profile is pronounced as part of the dialog description.

How about doing something like this:

  1. Only have NVDA Settings in the dialog title.
  2. Add a statictext with "editing {profilename}". Then, add the categories list and all other controls. This will make the profile name the first child on the dialog, which will be automatically announced using getDialogText. You no longer have to override accDescription for the dialog
  3. When the current profile name changes, update the particular static text with the new profile name. Do something like this on the dialog:
    winUser.user32.NotifyWinEvent(winUser.EVENT_OBJECT_DESCRIPTIONCHANGE, settingsDialog.Handle,winUser.OBJID_CLIENT,winUser.CHILDID_SELF)
    On the appModule, the only thing you need to do is override event_descriptionChange on the dialog to speak even when the dialog isn't the focus object.

This has the advantage that the visual behavior and non visually perceived behavior match much more than before.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difficult part with what you are proposing is finding a way to make the profile text look right within the dialog. It's not obvious how to achieve that.

What part of the dialog description do you mean in this case?

I meant, after alt tab to the dialog. NVDA walks through to the focused control, speaking all static text until it gets there. I now realise that as long as PROPID_ACC_DESCRIPTION is set to something other than white space this will not happen.

I like the idea of using the accessible description for the dialog to announce the profile name. Next I'm going to look into why NVDA does not seem to be getting the PROPID_ACC_NAME for the dialog. Inspect.exe shows it, but its not in NVDA's dev info.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difficult part with what you are proposing is finding a way to make the profile text look right within the dialog. It's not obvious how to achieve that.

Isn't it possible to position it centered just below the window title?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible, I'll have to play with it to see how it looks. Because it's not editable it might look a little strange. I have been thinking it makes sense to be able to edit profiles that are not actually active, so maybe it should be a control at some stage.

@feerrenrut

Copy link
Copy Markdown
Contributor Author

I haven't worked out why yet, but it seems that inspect.exe will give the name that I set via the acc prop server. However NVDA dev info gives the window title.

The windows title bar includes the profile name. This gets spoken as
"NVDA Settings: (normal configuration) dialog"
Instead we want this spoken as:
"NVDA Settings dialog normal configuration"

The other benefit of the description being set is that when the dialog
receives focus, it uses the description rather than the getDialogText
implemenation in behaviours.py. In the settings dialog, more is spoken
by getDialogText than is necessary, because we have a property page
with a description which also gets spoken. This is required, so that
the explanation of the settings panels is spoken when moving from
the category list to the panel.
The debugging comment is not necessary anymore. The wxInspection tool is going now part of another PR
@lukaszgo1

Copy link
Copy Markdown
Contributor

What do you mean by saying

As much as this is a loss of information when pressing NVDA+tab,

I was talking about NVDA +t. Currently to check which profile we are editing or in which category of the settings we are it is enough to check the title. bar. With the try build from this PR it is nessesary to alt+tab from and alt+tab back to the dialog. Adding to this the fact that when alt+tabbing to any of the settings dialog your position is lost I believe that it isn't an acceptable solution.

@michaelDCurran

michaelDCurran commented Feb 21, 2019 via email

Copy link
Copy Markdown
Member

@lukaszgo1

Copy link
Copy Markdown
Contributor

I don't know if it is an showstopper or not. I am merely pointing out that this change makes retrieving information about currently editing profile and the current category more difficult than it was before.

@feerrenrut

Copy link
Copy Markdown
Contributor Author

Thanks for testing @lukaszgo1, and you raise a good point. Not something that had been considered yet. We would like to get this merged in, since it's holding back the release. For now we will go with the current approach. Please see #9321 which could be an approach to resolving this.

@lukaszgo1

lukaszgo1 commented Feb 25, 2019

Copy link
Copy Markdown
Contributor

I don't believe that #9321 would improve this situation. because there is no way to reread this control on demand like the title bar.
What about merging this as is and for the next release simply make the content of title bar like it was before this pr?

@feerrenrut

Copy link
Copy Markdown
Contributor Author

there is no way to reread this control on demand like the title bar.

I figured if there was an actual control, focus can be moved back to the control to read it. Obviously this is not as quick as just using NVDA+t. It should be noted that when the profile being edited changes, it is still reported. Perhaps a script to report the current profile, those who depend on this set a gesture?

Comment thread source/gui/settingsDialogs.py
@lukaszgo1

Copy link
Copy Markdown
Contributor

I don't think that not having the active config profile and setting category dialog in the title bar is a big regression however it was nice to have and was intuitive. Introducing additional gesture to reread active profile is in my view an overkill. Is it really technically impossible to have the title bar to contain these information? If it is then simply leaving it as is seems to be the best solution.

@feerrenrut

Copy link
Copy Markdown
Contributor Author

Is it really technically impossible to have the title bar to contain these information?

It's not technically impossible, but then there are other problems that would need to be solved. Right now, we are using the description of the dialog to report the configuration profile. If this is empty, then NVDA will try to describe the dialog automatically. On panels like the advanced panel or the document formatting panel, this results in the panel description being read twice. This happens because the panel has a description that matches the static text that describes the dialog, this is so the description is read when the panel gets focus. NVDA's dialog description logic reads all static text starting at the dialog title, descending down until it gets to the first active control.

Adding a command to report the active profile is easy. I have a draft pull request: #9325

@feerrenrut

Copy link
Copy Markdown
Contributor Author

Actually, while testing this again I have noticed that setLabel is also overwriting the visible title.

@LeonarddeR

LeonarddeR commented Feb 25, 2019 via email

Copy link
Copy Markdown
Collaborator

@LeonarddeR

Copy link
Copy Markdown
Collaborator

NVDA's dialog description logic reads all static text starting at the dialog title, descending down until it gets to the first active control.

I'm wondering whether this behaviour of getDialogText is right. If there is a property page in the dialog that has a description retrieved by getDialogText, and that property page has a focusable (not focused) descendant, than the description of the property page shouldn't end up in the description of the dialog at all, since the user can have it read by focusing a decendant of the property page.

Alternatively, there is some logic in this code that stops adding grouping descriptions to the dialog text. Overall, it is pretty complex and error prone.

No longer stop a user from accessing settings when there is a destroyed but
not deleted window. Instead raise an error. Also check for this error on
when terminating the GUI.
Overriding with an empty description so that panel descriptions are not
reported twice (when getDialogText runs). The panel descriptions are still
reported when the panel gets focus.
Include the category name, so that it is easier to know what category one
is in by using NVDA+t
@feerrenrut

Copy link
Copy Markdown
Contributor Author

I think for now we will be best to rely on the NVDA appmodule to override this behaviour. I believe this is ready for review.

@LeonarddeR LeonarddeR left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some cosmetic comments that aren't really important and shuldn't block this.

Comment thread source/appModules/nvda.py Outdated
Comment thread source/gui/nvdaControls.py
Comment thread source/gui/settingsDialogs.py Outdated
Comment thread source/gui/settingsDialogs.py
Comment thread source/gui/settingsDialogs.py Outdated
Comment thread source/appModules/nvda.py Outdated
Comment thread source/gui/settingsDialogs.py
@feerrenrut feerrenrut merged commit ad8e391 into master Feb 27, 2019
@nvaccessAuto nvaccessAuto added this to the 2019.1 milestone Feb 27, 2019
LeonarddeR pushed a commit that referenced this pull request Mar 28, 2019
* Make the warning bigger, and wrap the long text explaining the dialog.
* Add checkbox to enable the advanced controls
  - This helps to ensure that users are aware of what they are changing.
  - api.processPendingEvents is used before calling enable on the panel containing the controls, otherwise NVDA had a mismatch
    with the reported and actual state of the checkbox.
* Add a restore defaults button to the advanced panel.
  - This allows users who have previously changed settings, restore them to recommended settings.
* Change settings panels to use role "property page"
  - Now when they get focus they are announced as "general property page"
* Speak extra info on advanced and document formatting categories.
  - This is essentially a property page description. It is the static text at the start of the panel.
* Created a simplified, reusable acc prop server
  - Takes a mapping of the prop and value to override.
* Fix multi-instance error for settings dialog.
  - No longer stop a user from accessing settings when there is a destroyed but not deleted window. Instead 
 raise an error. Also check for this error on when terminating the GUI.
* Override the description property for the NVDA settings dialog
  - Overriding with an empty description so that panel descriptions are not
reported twice (when getDialogText runs). The panel descriptions are still
reported when the panel gets focus.
LeonarddeR pushed a commit that referenced this pull request Mar 28, 2019
* Make the warning bigger, and wrap the long text explaining the dialog.
* Add checkbox to enable the advanced controls
  - This helps to ensure that users are aware of what they are changing.
  - api.processPendingEvents is used before calling enable on the panel containing the controls, otherwise NVDA had a mismatch
    with the reported and actual state of the checkbox.
* Add a restore defaults button to the advanced panel.
  - This allows users who have previously changed settings, restore them to recommended settings.
* Change settings panels to use role "property page"
  - Now when they get focus they are announced as "general property page"
* Speak extra info on advanced and document formatting categories.
  - This is essentially a property page description. It is the static text at the start of the panel.
* Created a simplified, reusable acc prop server
  - Takes a mapping of the prop and value to override.
* Fix multi-instance error for settings dialog.
  - No longer stop a user from accessing settings when there is a destroyed but not deleted window. Instead 
 raise an error. Also check for this error on when terminating the GUI.
* Override the description property for the NVDA settings dialog
  - Overriding with an empty description so that panel descriptions are not
reported twice (when getDialogText runs). The panel descriptions are still
reported when the panel gets focus.
@feerrenrut feerrenrut deleted the tidyAdvancedGuiPanel branch January 17, 2020 08:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants