summaryrefslogtreecommitdiffstats
path: root/views
diff options
context:
space:
mode:
Diffstat (limited to 'views')
-rw-r--r--views/widget/widget.h3
-rw-r--r--views/widget/widget_gtk.cc4
-rw-r--r--views/widget/widget_gtk.h1
-rw-r--r--views/widget/widget_win.cc28
-rw-r--r--views/widget/widget_win.h7
-rw-r--r--views/window/window_win.cc17
-rw-r--r--views/window/window_win.h2
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();