1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
content / browser / renderer_host / legacy_render_widget_host_win.h [blame]
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_RENDERER_HOST_LEGACY_RENDER_WIDGET_HOST_WIN_H_
#define CONTENT_BROWSER_RENDERER_HOST_LEGACY_RENDER_WIDGET_HOST_WIN_H_
// clang-format off
// This needs to be included before ATL headers.
#include "base/win/atl.h"
// clang-format on
#include <atlapp.h>
#include <atlcrack.h>
#include <oleacc.h>
#include <wrl/client.h>
#include <memory>
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
#include "ui/accessibility/platform/ax_fragment_root_delegate_win.h"
#include "ui/base/win/internal_constants.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/native_widget_types.h"
namespace ui {
class AXFragmentRootWin;
class AXSystemCaretWin;
class ViewProp;
class WindowEventTarget;
} // namespace ui
namespace content {
class DirectManipulationBrowserTestBase;
class DirectManipulationHelper;
class RenderWidgetHostViewAura;
// Reasons for the existence of this class outlined below:
// 1. Some screen readers expect every tab / every unique web content container
// to be in its own HWND with class name Chrome_RenderWidgetHostHWND.
// With Aura there is one main HWND which comprises the whole browser window
// or the whole desktop. So, we need a fake HWND with the window class as
// Chrome_RenderWidgetHostHWND as the root of the accessibility tree for
// each tab.
// 2. Some legacy trackpad/trackpoint drivers have special code for sending
// mouse wheel and scroll events to the Chrome_RenderWidgetHostHWND window.
// We should attempt to remove this code when the above are fixed.
// This class implements a child HWND with the same size as the content area,
// that delegates its accessibility implementation to the root of the
// BrowserAccessibilityManager tree. This HWND is hooked up as the parent of
// the root object in the BrowserAccessibilityManager tree, so when any
// accessibility client calls ::WindowFromAccessibleObject, they get this
// HWND instead of the DesktopWindowTreeHostWin. It also maintains a ViewProp to
// associate the parent's aura::WindowTreeHost with this HWND for lookup.
class CONTENT_EXPORT LegacyRenderWidgetHostHWND
: public ATL::CWindowImpl<LegacyRenderWidgetHostHWND,
ATL::CWindow,
ATL::CWinTraits<WS_CHILD>>,
public ui::AXFragmentRootDelegateWin {
public:
DECLARE_WND_CLASS_EX(ui::kLegacyRenderWidgetHostHwnd, CS_DBLCLKS, 0)
typedef ATL::CWindowImpl<LegacyRenderWidgetHostHWND,
ATL::CWindow,
ATL::CWinTraits<WS_CHILD>>
Base;
// Creates and returns an instance of the LegacyRenderWidgetHostHWND class on
// successful creation of a child window parented to the parent window passed
// in.
static LegacyRenderWidgetHostHWND* Create(HWND parent,
RenderWidgetHostViewAura* host);
LegacyRenderWidgetHostHWND(const LegacyRenderWidgetHostHWND&) = delete;
LegacyRenderWidgetHostHWND& operator=(const LegacyRenderWidgetHostHWND&) =
delete;
// Destroys the HWND managed by this class.
void Destroy();
BEGIN_MSG_MAP_EX(LegacyRenderWidgetHostHWND)
MESSAGE_HANDLER_EX(WM_GETOBJECT, OnGetObject)
MESSAGE_RANGE_HANDLER(WM_KEYFIRST, WM_KEYLAST, OnKeyboardRange)
MESSAGE_HANDLER_EX(WM_PAINT, OnPaint)
MESSAGE_HANDLER_EX(WM_NCPAINT, OnNCPaint)
MESSAGE_HANDLER_EX(WM_ERASEBKGND, OnEraseBkGnd)
MESSAGE_HANDLER_EX(WM_INPUT, OnInput)
MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseRange)
MESSAGE_HANDLER_EX(WM_MOUSELEAVE, OnMouseLeave)
MESSAGE_HANDLER_EX(WM_MOUSEACTIVATE, OnMouseActivate)
MESSAGE_HANDLER_EX(WM_SETCURSOR, OnSetCursor)
MESSAGE_HANDLER_EX(WM_TOUCH, OnTouch)
MESSAGE_HANDLER_EX(WM_POINTERDOWN, OnPointer)
MESSAGE_HANDLER_EX(WM_POINTERUPDATE, OnPointer)
MESSAGE_HANDLER_EX(WM_POINTERUP, OnPointer)
MESSAGE_HANDLER_EX(WM_POINTERENTER, OnPointer)
MESSAGE_HANDLER_EX(WM_POINTERLEAVE, OnPointer)
MESSAGE_HANDLER_EX(WM_HSCROLL, OnScroll)
MESSAGE_HANDLER_EX(WM_VSCROLL, OnScroll)
MESSAGE_HANDLER_EX(WM_NCHITTEST, OnNCHitTest)
MESSAGE_RANGE_HANDLER(WM_NCMOUSEMOVE, WM_NCXBUTTONDBLCLK, OnMouseRange)
MESSAGE_HANDLER_EX(WM_NCCALCSIZE, OnNCCalcSize)
MESSAGE_HANDLER_EX(WM_SIZE, OnSize)
MESSAGE_HANDLER_EX(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER_EX(DM_POINTERHITTEST, OnPointerHitTest)
END_MSG_MAP()
HWND hwnd() { return m_hWnd; }
// Called when the child window is to be reparented to a new window.
// The |parent| parameter contains the new parent window.
void UpdateParent(HWND parent);
HWND GetParent();
IAccessible* window_accessible() { return window_accessible_.Get(); }
// Functions to show and hide the window.
void Show();
void Hide();
// Resizes the window to the bounds passed in.
void SetBounds(const gfx::Rect& bounds);
// Return the root accessible object for either MSAA or UI Automation.
gfx::NativeViewAccessible GetOrCreateWindowRootAccessible(
bool is_uia_request);
protected:
void OnFinalMessage(HWND hwnd) override;
private:
friend class AccessibilityObjectLifetimeWinBrowserTest;
friend class DirectManipulationBrowserTestBase;
LegacyRenderWidgetHostHWND(RenderWidgetHostViewAura* host);
~LegacyRenderWidgetHostHWND() override;
// If initialization fails, deletes `this` and returns false.
bool InitOrDeleteSelf(HWND parent);
// Returns the target to which the windows input events are forwarded.
static ui::WindowEventTarget* GetWindowEventTarget(HWND parent);
LRESULT OnEraseBkGnd(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnGetObject(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnInput(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnKeyboardRange(UINT message,
WPARAM w_param,
LPARAM l_param,
BOOL& handled);
LRESULT OnMouseLeave(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnMouseRange(UINT message,
WPARAM w_param,
LPARAM l_param,
BOOL& handled);
LRESULT OnMouseActivate(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnPointer(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnTouch(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnScroll(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnNCHitTest(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnNCPaint(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnPaint(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnSetCursor(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnNCCalcSize(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnSize(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnDestroy(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnPointerHitTest(UINT message, WPARAM w_param, LPARAM l_param);
// Overridden from AXFragmentRootDelegateWin.
gfx::NativeViewAccessible GetChildOfAXFragmentRoot() override;
gfx::NativeViewAccessible GetParentOfAXFragmentRoot() override;
bool IsAXFragmentRootAControlElement() override;
gfx::NativeViewAccessible GetOrCreateBrowserAccessibilityRoot();
void CreateDirectManipulationHelper();
Microsoft::WRL::ComPtr<IAccessible> window_accessible_;
// Set to true if we turned on mouse tracking.
bool mouse_tracking_enabled_ = false;
raw_ptr<RenderWidgetHostViewAura> host_;
// Some assistive software need to track the location of the caret.
std::unique_ptr<ui::AXSystemCaretWin> ax_system_caret_;
// Implements IRawElementProviderFragmentRoot when UIA is enabled.
std::unique_ptr<ui::AXFragmentRootWin> ax_fragment_root_;
// Set to true when we return a UIA object. Determines whether we need to
// call UIA to clean up object references on window destruction.
// This is important to avoid triggering a cross-thread COM call which could
// cause re-entrancy during teardown. https://crbug.com/1087553
bool did_return_uia_object_ = false;
// This class provides functionality to register the legacy window as a
// Direct Manipulation consumer. This allows us to support smooth scroll
// in Chrome on Windows 10.
std::unique_ptr<DirectManipulationHelper> direct_manipulation_helper_;
// Instruct aura::WindowTreeHost to use the HWND's parent for lookup.
std::unique_ptr<ui::ViewProp> window_tree_host_prop_;
base::WeakPtrFactory<LegacyRenderWidgetHostHWND> weak_factory_{this};
};
} // namespace content
#endif // CONTENT_BROWSER_RENDERER_HOST_LEGACY_RENDER_WIDGET_HOST_WIN_H_