mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Implement accessibility enhancements (issue #1217)
- Add new CefBrowserHost::SetAccessibilityState method for toggling accessibility state when readers are detected by the client. - Add new CefAccessibilityHandler interface for the delivery of accessibility notifications to windowless (OSR) clients. - Fix delivery of CefFocusHandler callbacks to windowless clients. - cefclient: Add example windowless accessibility implementation on Windows and macOS. - cefclient: Automatically detect screen readers on Windows and macOS.
This commit is contained in:
committed by
Marshall Greenblatt
parent
64fcfa6068
commit
816f700d3e
@@ -13,10 +13,14 @@
|
||||
#include "include/wrapper/cef_closure_task.h"
|
||||
#include "tests/cefclient/browser/bytes_write_handler.h"
|
||||
#include "tests/cefclient/browser/main_context.h"
|
||||
#include "tests/cefclient/browser/osr_accessibility_helper.h"
|
||||
#include "tests/cefclient/browser/osr_accessibility_node.h"
|
||||
#include "tests/cefclient/browser/text_input_client_osr_mac.h"
|
||||
#include "tests/shared/browser/geometry_util.h"
|
||||
#include "tests/shared/browser/main_message_loop.h"
|
||||
|
||||
#import <AppKit/NSAccessibility.h>
|
||||
|
||||
namespace {
|
||||
|
||||
CefTextInputClientOSRMac* GetInputClientFromContext(
|
||||
@@ -29,7 +33,7 @@ CefTextInputClientOSRMac* GetInputClientFromContext(
|
||||
} // namespace
|
||||
|
||||
@interface BrowserOpenGLView
|
||||
: NSOpenGLView <NSDraggingSource, NSDraggingDestination> {
|
||||
: NSOpenGLView <NSDraggingSource, NSDraggingDestination, NSAccessibility> {
|
||||
@private
|
||||
NSTrackingArea* tracking_area_;
|
||||
client::BrowserWindowOsrMac* browser_window_;
|
||||
@@ -52,6 +56,9 @@ CefTextInputClientOSRMac* GetInputClientFromContext(
|
||||
// For intreacting with IME.
|
||||
NSTextInputContext* text_input_context_osr_mac_;
|
||||
|
||||
// Manages Accessibility Tree
|
||||
client::OsrAccessibilityHelper* accessibility_helper_;
|
||||
|
||||
// Event monitor for scroll wheel end event.
|
||||
id endWheelMonitor_;
|
||||
}
|
||||
@@ -99,6 +106,7 @@ CefTextInputClientOSRMac* GetInputClientFromContext(
|
||||
- (NSRect)convertRectToBackingInternal:(NSRect)aRect;
|
||||
- (void)ChangeCompositionRange:(CefRange)range
|
||||
character_bounds:(const CefRenderHandler::RectList&) character_bounds;
|
||||
- (void)UpdateAccessibilityTree:(CefRefPtr<CefValue>)value;
|
||||
@end
|
||||
|
||||
|
||||
@@ -948,6 +956,50 @@ NSPoint ConvertPointFromWindowToScreen(NSWindow* window, NSPoint point) {
|
||||
}
|
||||
}
|
||||
|
||||
// NSAccessibility Protocol implementation.
|
||||
- (BOOL)accessibilityIsIgnored {
|
||||
if(!accessibility_helper_)
|
||||
return YES;
|
||||
else
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString *)attribute {
|
||||
if(!accessibility_helper_)
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) {
|
||||
return NSAccessibilityGroupRole;
|
||||
} else if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) {
|
||||
client::OsrAXNode* node = accessibility_helper_->GetRootNode();
|
||||
std::string desc = node ? node->AxDescription(): "";
|
||||
return [NSString stringWithUTF8String:desc.c_str()];
|
||||
} else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
|
||||
client::OsrAXNode* node = accessibility_helper_->GetRootNode();
|
||||
std::string desc = node ? node->AxValue(): "";
|
||||
return [NSString stringWithUTF8String:desc.c_str()];
|
||||
} else if ([attribute isEqualToString:
|
||||
NSAccessibilityRoleDescriptionAttribute]) {
|
||||
return NSAccessibilityRoleDescriptionForUIElement(self);
|
||||
} else if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
|
||||
client::OsrAXNode* node = accessibility_helper_->GetRootNode();
|
||||
// Add Root as first Kid
|
||||
NSMutableArray* kids = [NSMutableArray arrayWithCapacity:1];
|
||||
NSObject* child = node->GetNativeAccessibleObject(NULL);
|
||||
[kids addObject: child];
|
||||
return NSAccessibilityUnignoredChildren(kids);
|
||||
} else {
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
}
|
||||
|
||||
- (id)accessibilityFocusedUIElement {
|
||||
if (accessibility_helper_) {
|
||||
client::OsrAXNode* node = accessibility_helper_->GetFocusedNode();
|
||||
return node ? node->GetNativeAccessibleObject(NULL) : nil;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Utility methods.
|
||||
- (void)resetDragDrop {
|
||||
current_drag_op_ = NSDragOperationNone;
|
||||
@@ -1142,6 +1194,21 @@ NSPoint ConvertPointFromWindowToScreen(NSWindow* window, NSPoint point) {
|
||||
if (client)
|
||||
[client ChangeCompositionRange: range character_bounds:bounds];
|
||||
}
|
||||
|
||||
- (void)UpdateAccessibilityTree:(CefRefPtr<CefValue>)value {
|
||||
if (!accessibility_helper_) {
|
||||
accessibility_helper_ = new client::OsrAccessibilityHelper(value,
|
||||
[self getBrowser]);
|
||||
} else {
|
||||
accessibility_helper_->UpdateAccessibilityTree(value);
|
||||
}
|
||||
|
||||
if (accessibility_helper_) {
|
||||
NSAccessibilityPostNotification(self,
|
||||
NSAccessibilityValueChangedNotification);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@@ -1493,6 +1560,14 @@ void BrowserWindowOsrMac::OnImeCompositionRangeChanged(
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserWindowOsrMac::UpdateAccessibilityTree(CefRefPtr<CefValue> value) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
if (nsview_) {
|
||||
[GLView(nsview_) UpdateAccessibilityTree:value];
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserWindowOsrMac::Create(ClientWindowHandle parent_handle,
|
||||
const CefRect& rect) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
Reference in New Issue
Block a user