Skip to content
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

Special attribute for macOS accessibility #10305

Merged
merged 5 commits into from Sep 11, 2017
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions atom/browser/api/atom_api_app.cc
Expand Up @@ -869,6 +869,18 @@ bool App::IsAccessibilitySupportEnabled() {
return ax_state->IsAccessibleBrowser();
}

void App::SetAccessibilitySupportEnabled(bool enabled) {
auto ax_state = content::BrowserAccessibilityState::GetInstance();

if (enabled) {
ax_state->OnScreenReaderDetected();
} else {
ax_state->DisableAccessibility();
}

Browser::Get()->OnAccessibilitySupportChanged();
}

Browser::LoginItemSettings App::GetLoginItemSettings(mate::Arguments* args) {
Browser::LoginItemSettings options;
args->GetNext(&options);
Expand Down Expand Up @@ -1141,6 +1153,8 @@ void App::BuildPrototype(
.SetMethod("relaunch", &App::Relaunch)
.SetMethod("isAccessibilitySupportEnabled",
&App::IsAccessibilitySupportEnabled)
.SetMethod("setAccessibilitySupportEnabled",
&App::SetAccessibilitySupportEnabled)
.SetMethod("disableHardwareAcceleration",
&App::DisableHardwareAcceleration)
.SetMethod("disableDomainBlockingFor3DAPIs",
Expand Down
1 change: 1 addition & 0 deletions atom/browser/api/atom_api_app.h
Expand Up @@ -171,6 +171,7 @@ class App : public AtomBrowserClient::Delegate,
void DisableHardwareAcceleration(mate::Arguments* args);
void DisableDomainBlockingFor3DAPIs(mate::Arguments* args);
bool IsAccessibilitySupportEnabled();
void SetAccessibilitySupportEnabled(bool enabled);
Browser::LoginItemSettings GetLoginItemSettings(mate::Arguments* args);
#if defined(USE_NSS_CERTS)
void ImportCertificate(const base::DictionaryValue& options,
Expand Down
3 changes: 3 additions & 0 deletions atom/browser/mac/atom_application.mm
Expand Up @@ -72,6 +72,9 @@ - (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute {
bool enableAccessibility = ([self voiceOverEnabled] && [value boolValue]);
[self updateAccessibilityEnabled:enableAccessibility];
}
else if ([attribute isEqualToString:@"AXManualAccessibility"]) {
[self updateAccessibilityEnabled:[value boolValue]];
}
return [super accessibilitySetValue:value forAttribute:attribute];
}

Expand Down
9 changes: 9 additions & 0 deletions docs/api/app.md
Expand Up @@ -890,6 +890,15 @@ technologies, such as screen readers, has been detected. See
https://www.chromium.org/developers/design-documents/accessibility for more
details.

### `app.setAccessibilitySupportEnabled(enabled)` _macOS_ _Windows_

* `enabled` Boolean - Enable or disable accessibility tree rendering
Copy link
Contributor

Choose a reason for hiding this comment

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

Is accessibility support disabled by default? If so, these docs should probably mention that.

For folks who don't know what the "accessibility tree rendering" is, a link would be helpful. Is this the right URL? https://developers.google.com/web/fundamentals/accessibility/semantics-builtin/the-accessibility-tree

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it's disabled by default both in Chrome and Electron. The link is super helpful, adding it.


Manually enables Chrome's accessibility support, allowing to expose accessibility switch to users in application settings. https://www.chromium.org/developers/design-documents/accessibility for more
details.

**Note:** Rendering accessibility tree can significantly affect the performance of your app. It should not be enabled by default.

### `app.setAboutPanelOptions(options)` _macOS_

* `options` Object
Expand Down
33 changes: 31 additions & 2 deletions docs/tutorial/accessibility.md
Expand Up @@ -8,7 +8,7 @@ Accessibility concerns in Electron applications are similar to those of websites

These new features bring those auditing tools to your Electron app. You can choose to add audits to your tests with Spectron or use them within DevTools with Devtron. Read on for a summary of the tools or checkout our [accessibility documentation](https://electron.atom.io/docs/tutorial/accessibility) for more information.

### Spectron
## Spectron

In the testing framework Spectron, you can now audit each window and `<webview>` tag in your application. For example:

Expand All @@ -22,7 +22,7 @@ app.client.auditAccessibility().then(function (audit) {

You can read more about this feature in [Spectron's documentation](https://github.com/electron/spectron#accessibility-testing).

### Devtron
## Devtron

In Devtron, there is a new accessibility tab which will allow you to audit a page in your app, sort and filter the results.

Expand All @@ -31,3 +31,32 @@ In Devtron, there is a new accessibility tab which will allow you to audit a pag
Both of these tools are using the [Accessibility Developer Tools](https://github.com/GoogleChrome/accessibility-developer-tools) library built by Google for Chrome. You can learn more about the accessibility audit rules this library uses on that [repository's wiki](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules).

If you know of other great accessibility tools for Electron, add them to the [accessibility documentation](https://electron.atom.io/docs/tutorial/accessibility) with a pull request.

## Enabling Accessibility

Electron applications keep accessibility disabled by default for performance reasons but there are multiple ways to enable it.

### Inside Application

By using [`app.setAccessibilitySupportEnabled(enabled)`](https://electron.atom.io/docs/api/app.md#appsetaccessibilitysupportenabledenabled-macos-windows), you can expose accessibility switch to users in the application preferences.

### Assistive Technology

Electron application will enable accessibility automatically when it detects assistive technology (Windows) or VoiceOver (macOS). See Chrome's [accessibility documentation](https://www.chromium.org/developers/design-documents/accessibility#TOC-How-Chrome-detects-the-presence-of-Assistive-Technology) for more details.
Copy link
Contributor

Choose a reason for hiding this comment

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

"Electron application will enable accessibility automatically" -- just so I understand correctly: does this mean the presence of these assistive features will automatically cause accessibility to be enabled, regardless of the current setting?

Or does it only mean that these features will be used if setAccessibilitySupportEnabled(true) was explicitly called in the app?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The first one – system assistive utilities have a priority and will enable accessibility regardless of the setAccessibilitySupportEnabled(). So an Electron app's developer can be unaware of this method and accessibility will still work for many users who have VoiceOver on.

For users who need accessibility without VoiceOver there are 3 options:

  • ask an Electron app's developer to expose accessibility switch in settings using setAccessibilitySupportEnabled(true)
  • ask their assistive software developer to start applying the AXManualAccessibility attribute on Electron apps
  • use some custom utility to apply AXManualAccessibility on Electron apps (I'm going to create an open-source one later)


On macOS 3rd party assistive technology can switch accessibility inside Electron applications by setting the attribute `AXManualAccessibility` programmatically:
Copy link
Contributor

Choose a reason for hiding this comment

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

On macOS, third-party


```objc
CFStringRef kAXManualAccessibility = CFSTR("AXManualAccessibility");

+ (void)enableAccessibility:(BOOL)enable inElectronApplication:(NSRunningApplication *)app
{
AXUIElementRef appRef = AXUIElementCreateApplication(app.processIdentifier);
if (appRef == nil)
return;

CFBooleanRef value = enable ? kCFBooleanTrue : kCFBooleanFalse;
AXUIElementSetAttributeValue(appRef, kAXManualAccessibility, value);
CFRelease(appRef);
}
```