diff options
Diffstat (limited to 'views')
-rw-r--r-- | views/widget/widget.h | 3 | ||||
-rw-r--r-- | views/widget/widget_gtk.cc | 4 | ||||
-rw-r--r-- | views/widget/widget_gtk.h | 1 | ||||
-rw-r--r-- | views/widget/widget_win.cc | 28 | ||||
-rw-r--r-- | views/widget/widget_win.h | 7 | ||||
-rw-r--r-- | views/window/window_win.cc | 17 | ||||
-rw-r--r-- | views/window/window_win.h | 2 |
7 files changed, 54 insertions, 8 deletions
diff --git a/views/widget/widget.h b/views/widget/widget.h index 1ca96a5..3b33c90 100644 --- a/views/widget/widget.h +++ b/views/widget/widget.h @@ -182,6 +182,9 @@ class Widget { // Returns whether the Widget is the currently active window. virtual bool IsActive() const = 0; + // Returns whether the Widget is customized for accessibility. + virtual bool IsAccessibleWidget() const = 0; + // Starts a drag operation for the specified view. |point| is a position in // |view| coordinates that the drag was initiated from. virtual void GenerateMousePressedForView(View* view, diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc index 5eee50f..3dfd8cc 100644 --- a/views/widget/widget_gtk.cc +++ b/views/widget/widget_gtk.cc @@ -777,6 +777,10 @@ bool WidgetGtk::IsActive() const { return is_active_; } +bool WidgetGtk::IsAccessibleWidget() const { + return false; +} + void WidgetGtk::GenerateMousePressedForView(View* view, const gfx::Point& point) { NOTIMPLEMENTED(); diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h index 7a2820e..02d939d 100644 --- a/views/widget/widget_gtk.h +++ b/views/widget/widget_gtk.h @@ -179,6 +179,7 @@ class WidgetGtk virtual Widget* GetRootWidget() const; virtual bool IsVisible() const; virtual bool IsActive() const; + virtual bool IsAccessibleWidget() const; virtual void GenerateMousePressedForView(View* view, const gfx::Point& point); virtual TooltipManager* GetTooltipManager(); diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc index ec0121a..5db4c82 100644 --- a/views/widget/widget_win.cc +++ b/views/widget/widget_win.cc @@ -30,6 +30,12 @@ namespace views { static const wchar_t* const kRootViewWindowProperty = L"__ROOT_VIEW__"; static const wchar_t* kWidgetKey = L"__VIEWS_WIDGET__"; +bool WidgetWin::screen_reader_active_ = false; + +// A custom MSAA object id used to determine if a screen reader is actively +// listening for MSAA events. +#define OBJID_CUSTOM 1 + bool SetRootViewForHWND(HWND hwnd, RootView* root_view) { return SetProp(hwnd, kRootViewWindowProperty, root_view) ? true : false; } @@ -151,6 +157,10 @@ void WidgetWin::Init(gfx::NativeView parent, const gfx::Rect& bounds) { // Create the window. WindowImpl::Init(parent, bounds); + // Attempt to detect screen readers by sending an event with our custom id. + if (!IsAccessibleWidget()) + NotifyWinEvent(EVENT_SYSTEM_ALERT, hwnd(), OBJID_CUSTOM, CHILDID_SELF); + // See if the style has been overridden. opaque_ = !(window_ex_style() & WS_EX_TRANSPARENT); use_layered_buffer_ = (use_layered_buffer_ && @@ -383,6 +393,10 @@ bool WidgetWin::IsActive() const { return win_util::IsWindowActive(hwnd()); } +bool WidgetWin::IsAccessibleWidget() const { + return screen_reader_active_; +} + TooltipManager* WidgetWin::GetTooltipManager() { return tooltip_manager_.get(); } @@ -651,6 +665,16 @@ LRESULT WidgetWin::OnGetObject(UINT uMsg, WPARAM w_param, LPARAM l_param) { reference_result = LresultFromObject(IID_IAccessible, w_param, static_cast<IAccessible*>(accessibility_root_)); } + + if (OBJID_CUSTOM == l_param) { + // An MSAA client requestes our custom id. Assume that we have detected an + // active windows screen reader. + OnScreenReaderDetected(); + + // Return with failure. + return static_cast<LRESULT>(0L); + } + return reference_result; } @@ -1095,6 +1119,10 @@ void WidgetWin::LayoutRootView() { PaintNow(gfx::Rect(0, 0, size.width(), size.height())); } +void WidgetWin::OnScreenReaderDetected() { + screen_reader_active_ = true; +} + bool WidgetWin::ReleaseCaptureOnMouseReleased() { return true; } diff --git a/views/widget/widget_win.h b/views/widget/widget_win.h index b515d17..65047f1 100644 --- a/views/widget/widget_win.h +++ b/views/widget/widget_win.h @@ -220,6 +220,7 @@ class WidgetWin : public gfx::WindowImpl, virtual Widget* GetRootWidget() const; virtual bool IsVisible() const; virtual bool IsActive() const; + virtual bool IsAccessibleWidget() const; virtual TooltipManager* GetTooltipManager(); virtual void GenerateMousePressedForView(View* view, const gfx::Point& point); @@ -437,6 +438,9 @@ class WidgetWin : public gfx::WindowImpl, // Called when the window size or non client metrics change. void LayoutRootView(); + // Called when a MSAA screen reader cleint is detected. + void OnScreenReaderDetected(); + // Returns whether capture should be released on mouse release. The default // is true. virtual bool ReleaseCaptureOnMouseReleased(); @@ -568,6 +572,9 @@ class WidgetWin : public gfx::WindowImpl, // being used. WidgetDelegate* delegate_; + // Value determines whether the Widget is customized for accessibility. + static bool screen_reader_active_; + // The maximum number of view events in our vector below. static const int kMaxAccessibilityViewEvents = 20; diff --git a/views/window/window_win.cc b/views/window/window_win.cc index 5bbc13c..0443478 100644 --- a/views/window/window_win.cc +++ b/views/window/window_win.cc @@ -411,14 +411,18 @@ void WindowWin::UpdateWindowTitle() { // Update the native frame's text. We do this regardless of whether or not // the native frame is being used, since this also updates the taskbar, etc. - std::wstring window_title = window_delegate_->GetWindowTitle(); + std::wstring window_title; + if (IsAccessibleWidget()) + window_title = window_delegate_->GetAccessibleWindowTitle(); + else + window_title = window_delegate_->GetWindowTitle(); std::wstring localized_text; if (base::i18n::AdjustStringForLocaleDirection(window_title, &localized_text)) window_title.assign(localized_text); SetWindowText(GetNativeView(), window_title.c_str()); // Also update the accessibility name. - UpdateAccessibleName(); + UpdateAccessibleName(window_title); } void WindowWin::UpdateWindowIcon() { @@ -1408,17 +1412,16 @@ void WindowWin::ResetWindowRegion(bool force) { DeleteObject(current_rgn); } -void WindowWin::UpdateAccessibleName() { +void WindowWin::UpdateAccessibleName(std::wstring& accessible_name) { ScopedComPtr<IAccPropServices> pAccPropServices; - std::wstring accessible_title = window_delegate_->GetAccessibleWindowTitle(); HRESULT hr = CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, - IID_IAccPropServices, reinterpret_cast<void**>(&pAccPropServices)); + IID_IAccPropServices, reinterpret_cast<void**>(&pAccPropServices)); if (SUCCEEDED(hr)) { VARIANT var; var.vt = VT_BSTR; - var.bstrVal = SysAllocString(accessible_title.c_str()); + var.bstrVal = SysAllocString(accessible_name.c_str()); hr = pAccPropServices->SetHwndProp(GetNativeView(), OBJID_CLIENT, - CHILDID_SELF, PROPID_ACC_NAME, var); + CHILDID_SELF, PROPID_ACC_NAME, var); } } diff --git a/views/window/window_win.h b/views/window/window_win.h index 98ff7070..37d56d1 100644 --- a/views/window/window_win.h +++ b/views/window/window_win.h @@ -194,7 +194,7 @@ class WindowWin : public WidgetWin, void ResetWindowRegion(bool force); // Update accessibility information via our WindowDelegate. - void UpdateAccessibleName(); + void UpdateAccessibleName(std::wstring& accessible_name); void UpdateAccessibleRole(); void UpdateAccessibleState(); |