Skip to content

Commit 74f0219

Browse files
Announce alerts through SemanticsService on Windows (flutter#37173)
* Corresponds to changes by reverted PR flutter/engine#36966. * Changes on top of original reverted PR that add IServiceProvider and COM_INTERFACE_ENTRY's to the new node classes. * self_com_ unused
1 parent 224b401 commit 74f0219

19 files changed

+1008
-3
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3073,9 +3073,13 @@ FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_texture_regi
30733073
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_value.h
30743074
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_view.h
30753075
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/flutter_linux.h
3076+
FILE: ../../../flutter/shell/platform/windows/accessibility_alert.cc
3077+
FILE: ../../../flutter/shell/platform/windows/accessibility_alert.h
30763078
FILE: ../../../flutter/shell/platform/windows/accessibility_bridge_delegate_windows.cc
30773079
FILE: ../../../flutter/shell/platform/windows/accessibility_bridge_delegate_windows.h
30783080
FILE: ../../../flutter/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc
3081+
FILE: ../../../flutter/shell/platform/windows/accessibility_root_node.cc
3082+
FILE: ../../../flutter/shell/platform/windows/accessibility_root_node.h
30793083
FILE: ../../../flutter/shell/platform/windows/angle_surface_manager.cc
30803084
FILE: ../../../flutter/shell/platform/windows/angle_surface_manager.h
30813085
FILE: ../../../flutter/shell/platform/windows/client_wrapper/dart_project_unittests.cc

shell/platform/windows/BUILD.gn

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,12 @@ source_set("flutter_windows_headers") {
3838
source_set("flutter_windows_source") {
3939
# Common Windows sources.
4040
sources = [
41+
"accessibility_alert.cc",
42+
"accessibility_alert.h",
4143
"accessibility_bridge_delegate_windows.cc",
4244
"accessibility_bridge_delegate_windows.h",
45+
"accessibility_root_node.cc",
46+
"accessibility_root_node.h",
4347
"angle_surface_manager.cc",
4448
"angle_surface_manager.h",
4549
"cursor_handler.cc",
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "flutter/shell/platform/windows/accessibility_alert.h"
6+
7+
#include "flutter/shell/platform/windows/accessibility_root_node.h"
8+
9+
namespace flutter {
10+
11+
AccessibilityAlert::AccessibilityAlert() : text_(L""), parent_(nullptr) {}
12+
13+
// IAccessible methods.
14+
15+
IFACEMETHODIMP AccessibilityAlert::accHitTest(LONG screen_physical_pixel_x,
16+
LONG screen_physical_pixel_y,
17+
VARIANT* child) {
18+
child->vt = VT_EMPTY;
19+
return S_FALSE;
20+
}
21+
22+
// Performs the object's default action.
23+
IFACEMETHODIMP AccessibilityAlert::accDoDefaultAction(VARIANT var_id) {
24+
return E_FAIL;
25+
}
26+
27+
// Retrieves an IDispatch interface pointer for the specified child.
28+
IFACEMETHODIMP AccessibilityAlert::get_accChild(VARIANT var_child,
29+
IDispatch** disp_child) {
30+
if (V_VT(&var_child) == VT_I4 && V_I4(&var_child) == CHILDID_SELF) {
31+
*disp_child = this;
32+
AddRef();
33+
return S_OK;
34+
}
35+
*disp_child = nullptr;
36+
return E_FAIL;
37+
}
38+
39+
// Retrieves the number of accessible children.
40+
IFACEMETHODIMP AccessibilityAlert::get_accChildCount(LONG* child_count) {
41+
*child_count = 0;
42+
return S_OK;
43+
}
44+
45+
// Retrieves the tooltip description.
46+
IFACEMETHODIMP AccessibilityAlert::get_accDescription(VARIANT var_id,
47+
BSTR* desc) {
48+
*desc = SysAllocString(text_.c_str());
49+
return S_OK;
50+
}
51+
52+
// Retrieves the name of the specified object.
53+
IFACEMETHODIMP AccessibilityAlert::get_accName(VARIANT var_id, BSTR* name) {
54+
*name = SysAllocString(text_.c_str());
55+
return S_OK;
56+
}
57+
58+
// Retrieves the IDispatch interface of the object's parent.
59+
IFACEMETHODIMP AccessibilityAlert::get_accParent(IDispatch** disp_parent) {
60+
*disp_parent = parent_;
61+
if (*disp_parent) {
62+
(*disp_parent)->AddRef();
63+
return S_OK;
64+
}
65+
return S_FALSE;
66+
}
67+
68+
// Retrieves information describing the role of the specified object.
69+
IFACEMETHODIMP AccessibilityAlert::get_accRole(VARIANT var_id, VARIANT* role) {
70+
*role = {.vt = VT_I4, .lVal = ROLE_SYSTEM_ALERT};
71+
return S_OK;
72+
}
73+
74+
// Retrieves the current state of the specified object.
75+
IFACEMETHODIMP AccessibilityAlert::get_accState(VARIANT var_id,
76+
VARIANT* state) {
77+
*state = {.vt = VT_I4, .lVal = STATE_SYSTEM_DEFAULT};
78+
return S_OK;
79+
}
80+
81+
// Gets the help string for the specified object.
82+
IFACEMETHODIMP AccessibilityAlert::get_accHelp(VARIANT var_id, BSTR* help) {
83+
*help = SysAllocString(L"");
84+
return S_OK;
85+
}
86+
87+
// Retrieve or set the string value associated with the specified object.
88+
// Setting the value is not typically used by screen readers, but it's
89+
// used frequently by automation software.
90+
IFACEMETHODIMP AccessibilityAlert::get_accValue(VARIANT var_id, BSTR* value) {
91+
*value = SysAllocString(text_.c_str());
92+
return S_OK;
93+
}
94+
95+
// IAccessible methods not implemented.
96+
IFACEMETHODIMP AccessibilityAlert::get_accSelection(VARIANT* selected) {
97+
selected->vt = VT_EMPTY;
98+
return E_NOTIMPL;
99+
}
100+
101+
IFACEMETHODIMP AccessibilityAlert::accSelect(LONG flags_sel, VARIANT var_id) {
102+
return E_NOTIMPL;
103+
}
104+
105+
IFACEMETHODIMP AccessibilityAlert::put_accValue(VARIANT var_id,
106+
BSTR new_value) {
107+
return E_NOTIMPL;
108+
}
109+
110+
IFACEMETHODIMP AccessibilityAlert::get_accFocus(VARIANT* focus_child) {
111+
focus_child->vt = VT_EMPTY;
112+
return E_NOTIMPL;
113+
}
114+
115+
IFACEMETHODIMP AccessibilityAlert::get_accHelpTopic(BSTR* help_file,
116+
VARIANT var_id,
117+
LONG* topic_id) {
118+
if (help_file) {
119+
*help_file = nullptr;
120+
}
121+
if (topic_id) {
122+
*topic_id = 0;
123+
}
124+
return E_NOTIMPL;
125+
}
126+
127+
IFACEMETHODIMP AccessibilityAlert::put_accName(VARIANT var_id, BSTR put_name) {
128+
return E_NOTIMPL;
129+
}
130+
131+
IFACEMETHODIMP AccessibilityAlert::get_accKeyboardShortcut(VARIANT var_id,
132+
BSTR* access_key) {
133+
*access_key = nullptr;
134+
return E_NOTIMPL;
135+
}
136+
137+
IFACEMETHODIMP AccessibilityAlert::accLocation(LONG* physical_pixel_left,
138+
LONG* physical_pixel_top,
139+
LONG* width,
140+
LONG* height,
141+
VARIANT var_id) {
142+
return E_NOTIMPL;
143+
}
144+
145+
IFACEMETHODIMP AccessibilityAlert::accNavigate(LONG nav_dir,
146+
VARIANT start,
147+
VARIANT* end) {
148+
end->vt = VT_EMPTY;
149+
return E_NOTIMPL;
150+
}
151+
152+
IFACEMETHODIMP AccessibilityAlert::get_accDefaultAction(VARIANT var_id,
153+
BSTR* default_action) {
154+
*default_action = nullptr;
155+
return E_NOTIMPL;
156+
}
157+
158+
// End of IAccessible methods.
159+
160+
//
161+
// IServiceProvider implementation.
162+
//
163+
164+
IFACEMETHODIMP AccessibilityAlert::QueryService(REFGUID guidService,
165+
REFIID riid,
166+
void** object) {
167+
if (!object) {
168+
return E_INVALIDARG;
169+
}
170+
171+
if (guidService == IID_IAccessible) {
172+
return QueryInterface(riid, object);
173+
}
174+
175+
*object = nullptr;
176+
return E_FAIL;
177+
}
178+
179+
void AccessibilityAlert::SetText(const std::wstring& text) {
180+
text_ = text;
181+
}
182+
183+
void AccessibilityAlert::SetParent(AccessibilityRootNode* parent) {
184+
parent_ = parent;
185+
}
186+
187+
} // namespace flutter
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_ACCESSIBILITY_ALERT_H_
6+
#define FLUTTER_SHELL_PLATFORM_WINDOWS_ACCESSIBILITY_ALERT_H_
7+
8+
#include <atlbase.h>
9+
#include <atlcom.h>
10+
#include <oleacc.h>
11+
12+
#include <string>
13+
14+
namespace flutter {
15+
16+
class AccessibilityRootNode;
17+
18+
// An IAccessible node representing an alert read to the screen reader.
19+
// When an announcement is requested by the framework, an instance of
20+
// this class, if none exists already, is created and made a child of
21+
// the root AccessibilityRootNode node, and is therefore also a sibling
22+
// of the window's root node.
23+
// This node is not interactable to the user.
24+
class __declspec(uuid("778c1bd8-383f-4d49-b6be-8937e12b6a32"))
25+
AccessibilityAlert : public CComObjectRootEx<CComMultiThreadModel>,
26+
public IDispatchImpl<IAccessible>,
27+
public IServiceProvider {
28+
public:
29+
BEGIN_COM_MAP(AccessibilityAlert)
30+
COM_INTERFACE_ENTRY(AccessibilityAlert)
31+
COM_INTERFACE_ENTRY(IAccessible)
32+
COM_INTERFACE_ENTRY(IDispatch)
33+
COM_INTERFACE_ENTRY(IServiceProvider)
34+
END_COM_MAP()
35+
//
36+
// IAccessible methods.
37+
//
38+
39+
// Retrieves the child element or child object at a given point on the screen.
40+
IFACEMETHODIMP accHitTest(LONG screen_physical_pixel_x,
41+
LONG screen_physical_pixel_y,
42+
VARIANT* child) override;
43+
44+
// Retrieves an IDispatch interface pointer for the specified child.
45+
IFACEMETHODIMP get_accChild(VARIANT var_child,
46+
IDispatch** disp_child) override;
47+
48+
// Retrieves the number of accessible children.
49+
IFACEMETHODIMP get_accChildCount(LONG* child_count) override;
50+
51+
// Retrieves a string that describes the object's default action.
52+
IFACEMETHODIMP get_accDefaultAction(VARIANT var_id,
53+
BSTR* default_action) override;
54+
55+
// Retrieves the tooltip description.
56+
IFACEMETHODIMP get_accDescription(VARIANT var_id, BSTR* desc) override;
57+
58+
// Retrieves the name of the specified object.
59+
IFACEMETHODIMP get_accName(VARIANT var_id, BSTR* name) override;
60+
61+
// Retrieves the IDispatch interface of the object's parent.
62+
IFACEMETHODIMP get_accParent(IDispatch** disp_parent) override;
63+
64+
// Retrieves information describing the role of the specified object.
65+
IFACEMETHODIMP get_accRole(VARIANT var_id, VARIANT* role) override;
66+
67+
// Retrieves the current state of the specified object.
68+
IFACEMETHODIMP get_accState(VARIANT var_id, VARIANT* state) override;
69+
70+
// Gets the help string for the specified object.
71+
IFACEMETHODIMP get_accHelp(VARIANT var_id, BSTR* help) override;
72+
73+
// Retrieve the string value associated with the specified object.
74+
IFACEMETHODIMP get_accValue(VARIANT var_id, BSTR* value) override;
75+
76+
// IAccessible methods not implemented.
77+
IFACEMETHODIMP accLocation(LONG* physical_pixel_left,
78+
LONG* physical_pixel_top,
79+
LONG* width,
80+
LONG* height,
81+
VARIANT var_id) override;
82+
IFACEMETHODIMP accNavigate(LONG nav_dir,
83+
VARIANT start,
84+
VARIANT* end) override;
85+
IFACEMETHODIMP accDoDefaultAction(VARIANT var_id) override;
86+
IFACEMETHODIMP get_accFocus(VARIANT* focus_child) override;
87+
IFACEMETHODIMP get_accKeyboardShortcut(VARIANT var_id,
88+
BSTR* access_key) override;
89+
IFACEMETHODIMP get_accSelection(VARIANT* selected) override;
90+
IFACEMETHODIMP accSelect(LONG flags_sel, VARIANT var_id) override;
91+
IFACEMETHODIMP get_accHelpTopic(BSTR* help_file,
92+
VARIANT var_id,
93+
LONG* topic_id) override;
94+
IFACEMETHODIMP put_accName(VARIANT var_id, BSTR put_name) override;
95+
IFACEMETHODIMP put_accValue(VARIANT var_id, BSTR new_value) override;
96+
97+
// End of IAccessible methods.
98+
99+
//
100+
// IServiceProvider method.
101+
//
102+
103+
IFACEMETHODIMP QueryService(REFGUID guidService,
104+
REFIID riid,
105+
void** object) override;
106+
107+
AccessibilityAlert();
108+
~AccessibilityAlert() = default;
109+
110+
// Sets the text of this alert to the provided message.
111+
void SetText(const std::wstring& text);
112+
113+
void SetParent(AccessibilityRootNode* parent);
114+
115+
private:
116+
std::wstring text_;
117+
118+
AccessibilityRootNode* parent_;
119+
};
120+
121+
} // namespace flutter
122+
123+
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_ACCESSIBILITY_ALERT_H_

0 commit comments

Comments
 (0)