Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(202)

Side by Side Diff: content/browser/renderer_host/legacy_render_widget_host_win.cc

Issue 1987903002: Create only a single LegacyRenderWidgetHostHWND per WebContentsViewAura. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix last merge issue Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/legacy_render_widget_host_win.h" 5 #include "content/browser/renderer_host/legacy_render_widget_host_win.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/win/win_util.h" 10 #include "base/win/win_util.h"
11 #include "base/win/windows_version.h" 11 #include "base/win/windows_version.h"
12 #include "content/browser/accessibility/browser_accessibility_manager_win.h" 12 #include "content/browser/renderer_host/legacy_render_widget_host_win_delegate.h "
13 #include "content/browser/accessibility/browser_accessibility_win.h"
14 #include "content/browser/renderer_host/render_widget_host_impl.h" 13 #include "content/browser/renderer_host/render_widget_host_impl.h"
15 #include "content/browser/renderer_host/render_widget_host_view_aura.h" 14 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
16 #include "content/public/browser/browser_accessibility_state.h" 15 #include "content/public/browser/browser_accessibility_state.h"
17 #include "content/public/common/content_switches.h" 16 #include "content/public/common/content_switches.h"
18 #include "ui/base/touch/touch_enabled.h" 17 #include "ui/base/touch/touch_enabled.h"
19 #include "ui/base/view_prop.h" 18 #include "ui/base/view_prop.h"
20 #include "ui/base/win/internal_constants.h" 19 #include "ui/base/win/internal_constants.h"
21 #include "ui/base/win/window_event_target.h" 20 #include "ui/base/win/window_event_target.h"
22 #include "ui/display/win/screen_win.h" 21 #include "ui/display/win/screen_win.h"
23 #include "ui/gfx/geometry/rect.h" 22 #include "ui/gfx/geometry/rect.h"
24 #include "ui/gfx/win/direct_manipulation.h" 23 #include "ui/gfx/win/direct_manipulation.h"
25 24
26 namespace content { 25 namespace content {
27 26
27 namespace {
28
28 // A custom MSAA object id used to determine if a screen reader or some 29 // A custom MSAA object id used to determine if a screen reader or some
29 // other client is listening on MSAA events - if so, we enable full web 30 // other client is listening on MSAA events - if so, we enable full web
30 // accessibility support. 31 // accessibility support.
31 const int kIdScreenReaderHoneyPot = 1; 32 const int kIdScreenReaderHoneyPot = 1;
32 33
34 } // namespace
35
36 LegacyRenderWidgetHostHWND::~LegacyRenderWidgetHostHWND() {
37 // Re-enable flicks for just a moment
38 base::win::EnableFlicks(hwnd());
39
40 if (::IsWindow(hwnd()))
41 ::DestroyWindow(hwnd());
42 }
43
33 // static 44 // static
34 LegacyRenderWidgetHostHWND* LegacyRenderWidgetHostHWND::Create( 45 LegacyRenderWidgetHostHWND* LegacyRenderWidgetHostHWND::Create(
35 HWND parent) { 46 HWND parent,
47 LegacyRenderWidgetHostHWNDDelegate* delegate) {
36 // content_unittests passes in the desktop window as the parent. We allow 48 // content_unittests passes in the desktop window as the parent. We allow
37 // the LegacyRenderWidgetHostHWND instance to be created in this case for 49 // the LegacyRenderWidgetHostHWND instance to be created in this case for
38 // these tests to pass. 50 // these tests to pass.
39 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 51 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
40 switches::kDisableLegacyIntermediateWindow) || 52 switches::kDisableLegacyIntermediateWindow) ||
41 (!GetWindowEventTarget(parent) && parent != ::GetDesktopWindow())) 53 (!GetWindowEventTarget(parent) && parent != ::GetDesktopWindow()))
42 return nullptr; 54 return nullptr;
43 55
44 LegacyRenderWidgetHostHWND* legacy_window_instance = 56 LegacyRenderWidgetHostHWND* legacy_window_instance =
45 new LegacyRenderWidgetHostHWND(parent); 57 new LegacyRenderWidgetHostHWND(parent, delegate);
46 // If we failed to create the child, or if the switch to disable the legacy 58
47 // window is passed in, then return NULL. 59 // If we failed to create the child, return nullptr.
48 if (!::IsWindow(legacy_window_instance->hwnd())) { 60 if (!::IsWindow(legacy_window_instance->hwnd())) {
49 delete legacy_window_instance; 61 delete legacy_window_instance;
50 return NULL; 62 return nullptr;
51 } 63 }
52 legacy_window_instance->Init(); 64 legacy_window_instance->Init();
53 return legacy_window_instance; 65 return legacy_window_instance;
54 } 66 }
55 67
56 void LegacyRenderWidgetHostHWND::Destroy() {
57 if (::IsWindow(hwnd()))
58 ::DestroyWindow(hwnd());
59 }
60
61 void LegacyRenderWidgetHostHWND::UpdateParent(HWND parent) { 68 void LegacyRenderWidgetHostHWND::UpdateParent(HWND parent) {
62 if (GetWindowEventTarget(GetParent())) 69 if (GetWindowEventTarget(GetParent()))
63 GetWindowEventTarget(GetParent())->HandleParentChanged(); 70 GetWindowEventTarget(GetParent())->HandleParentChanged();
71
72 if (!::IsWindow(hwnd()))
73 return;
74
64 ::SetParent(hwnd(), parent); 75 ::SetParent(hwnd(), parent);
65 // If the new parent is the desktop Window, then we disable the child window 76 // If the new parent is the desktop Window, then we disable the child window
66 // to ensure that it does not receive any input events. It should not because 77 // to ensure that it does not receive any input events. It should not because
67 // of WS_EX_TRANSPARENT. This is only for safety. 78 // of WS_EX_TRANSPARENT. This is only for safety.
68 if (parent == ::GetDesktopWindow()) { 79 if (parent == ::GetDesktopWindow()) {
69 ::EnableWindow(hwnd(), FALSE); 80 ::EnableWindow(hwnd(), FALSE);
70 } else { 81 } else {
71 ::EnableWindow(hwnd(), TRUE); 82 ::EnableWindow(hwnd(), TRUE);
72 } 83 }
73 } 84 }
74 85
75 HWND LegacyRenderWidgetHostHWND::GetParent() { 86 HWND LegacyRenderWidgetHostHWND::GetParent() {
87 if (!::IsWindow(hwnd()))
88 return NULL;
89
76 return ::GetParent(hwnd()); 90 return ::GetParent(hwnd());
77 } 91 }
78 92
79 void LegacyRenderWidgetHostHWND::Show() { 93 void LegacyRenderWidgetHostHWND::Show() {
80 ::ShowWindow(hwnd(), SW_SHOW); 94 if (::IsWindow(hwnd()))
95 ::ShowWindow(hwnd(), SW_SHOW);
81 } 96 }
82 97
83 void LegacyRenderWidgetHostHWND::Hide() { 98 void LegacyRenderWidgetHostHWND::Hide() {
84 ::ShowWindow(hwnd(), SW_HIDE); 99 if (::IsWindow(hwnd()))
100 ::ShowWindow(hwnd(), SW_HIDE);
85 } 101 }
86 102
87 void LegacyRenderWidgetHostHWND::SetBounds(const gfx::Rect& bounds) { 103 void LegacyRenderWidgetHostHWND::SetBounds(const gfx::Rect& bounds) {
104 if (!::IsWindow(hwnd()))
105 return;
106
88 gfx::Rect bounds_in_pixel = display::win::ScreenWin::DIPToClientRect(hwnd(), 107 gfx::Rect bounds_in_pixel = display::win::ScreenWin::DIPToClientRect(hwnd(),
89 bounds); 108 bounds);
90 ::SetWindowPos(hwnd(), NULL, bounds_in_pixel.x(), bounds_in_pixel.y(), 109 ::SetWindowPos(hwnd(), NULL, bounds_in_pixel.x(), bounds_in_pixel.y(),
91 bounds_in_pixel.width(), bounds_in_pixel.height(), 110 bounds_in_pixel.width(), bounds_in_pixel.height(),
92 SWP_NOREDRAW); 111 SWP_NOREDRAW);
93 if (direct_manipulation_helper_) 112 if (direct_manipulation_helper_)
94 direct_manipulation_helper_->SetBounds(bounds_in_pixel); 113 direct_manipulation_helper_->SetBounds(bounds_in_pixel);
95 } 114 }
96 115
97 void LegacyRenderWidgetHostHWND::OnFinalMessage(HWND hwnd) { 116 LegacyRenderWidgetHostHWND::LegacyRenderWidgetHostHWND(
98 if (host_) { 117 HWND parent,
99 host_->OnLegacyWindowDestroyed(); 118 LegacyRenderWidgetHostHWNDDelegate* delegate)
100 host_ = NULL;
101 }
102
103 // Re-enable flicks for just a moment
104 base::win::EnableFlicks(hwnd);
105
106 delete this;
107 }
108
109 LegacyRenderWidgetHostHWND::LegacyRenderWidgetHostHWND(HWND parent)
110 : mouse_tracking_enabled_(false), 119 : mouse_tracking_enabled_(false),
111 host_(NULL) { 120 delegate_(delegate) {
121 DCHECK(delegate_);
112 RECT rect = {0}; 122 RECT rect = {0};
113 Base::Create(parent, rect, L"Chrome Legacy Window", 123 Base::Create(parent, rect, L"Chrome Legacy Window",
114 WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 124 WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
115 WS_EX_TRANSPARENT); 125 WS_EX_TRANSPARENT);
116 } 126 }
117 127
118 LegacyRenderWidgetHostHWND::~LegacyRenderWidgetHostHWND() {
119 DCHECK(!::IsWindow(hwnd()));
120 }
121
122 bool LegacyRenderWidgetHostHWND::Init() { 128 bool LegacyRenderWidgetHostHWND::Init() {
123 if (base::win::GetVersion() >= base::win::VERSION_WIN7 && 129 if (base::win::GetVersion() >= base::win::VERSION_WIN7 &&
124 ui::AreTouchEventsEnabled()) 130 ui::AreTouchEventsEnabled())
125 RegisterTouchWindow(hwnd(), TWF_WANTPALM); 131 RegisterTouchWindow(hwnd(), TWF_WANTPALM);
126 132
127 HRESULT hr = ::CreateStdAccessibleObject( 133 HRESULT hr = ::CreateStdAccessibleObject(
128 hwnd(), OBJID_WINDOW, IID_IAccessible, 134 hwnd(), OBJID_WINDOW, IID_IAccessible,
129 reinterpret_cast<void **>(window_accessible_.Receive())); 135 reinterpret_cast<void **>(window_accessible_.Receive()));
130 DCHECK(SUCCEEDED(hr)); 136 DCHECK(SUCCEEDED(hr));
131 137
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 // because it sometimes gets sign-extended incorrectly (but not always). 175 // because it sometimes gets sign-extended incorrectly (but not always).
170 DWORD obj_id = static_cast<DWORD>(static_cast<DWORD_PTR>(l_param)); 176 DWORD obj_id = static_cast<DWORD>(static_cast<DWORD_PTR>(l_param));
171 177
172 if (kIdScreenReaderHoneyPot == obj_id) { 178 if (kIdScreenReaderHoneyPot == obj_id) {
173 // When an MSAA client has responded to our fake event on this id, 179 // When an MSAA client has responded to our fake event on this id,
174 // enable screen reader support. 180 // enable screen reader support.
175 BrowserAccessibilityState::GetInstance()->OnScreenReaderDetected(); 181 BrowserAccessibilityState::GetInstance()->OnScreenReaderDetected();
176 return static_cast<LRESULT>(0L); 182 return static_cast<LRESULT>(0L);
177 } 183 }
178 184
179 if (static_cast<DWORD>(OBJID_CLIENT) != obj_id || !host_) 185 if (static_cast<DWORD>(OBJID_CLIENT) != obj_id)
180 return static_cast<LRESULT>(0L); 186 return static_cast<LRESULT>(0L);
181 187
182 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From( 188 base::win::ScopedComPtr<IAccessible> native_accessible(
183 host_->GetRenderWidgetHost()); 189 delegate_->GetNativeViewAccessible());
184 if (!rwhi) 190 if (!native_accessible)
185 return static_cast<LRESULT>(0L); 191 return static_cast<LRESULT>(0L);
186 192
187 BrowserAccessibilityManagerWin* manager =
188 static_cast<BrowserAccessibilityManagerWin*>(
189 rwhi->GetRootBrowserAccessibilityManager());
190 if (!manager)
191 return static_cast<LRESULT>(0L);
192
193 base::win::ScopedComPtr<IAccessible> root(
194 ToBrowserAccessibilityWin(manager->GetRoot()));
195 return LresultFromObject(IID_IAccessible, w_param, 193 return LresultFromObject(IID_IAccessible, w_param,
196 static_cast<IAccessible*>(root.Detach())); 194 static_cast<IAccessible*>(native_accessible.Detach()));
197 } 195 }
198 196
199 // We send keyboard/mouse/touch messages to the parent window via SendMessage. 197 // We send keyboard/mouse/touch messages to the parent window via SendMessage.
200 // While this works, this has the side effect of converting input messages into 198 // While this works, this has the side effect of converting input messages into
201 // sent messages which changes their priority and could technically result 199 // sent messages which changes their priority and could technically result
202 // in these messages starving other messages in the queue. Additionally 200 // in these messages starving other messages in the queue. Additionally
203 // keyboard/mouse hooks would not see these messages. The alternative approach 201 // keyboard/mouse hooks would not see these messages. The alternative approach
204 // is to set and release capture as needed on the parent to ensure that it 202 // is to set and release capture as needed on the parent to ensure that it
205 // receives all mouse events. However that was shelved due to possible issues 203 // receives all mouse events. However that was shelved due to possible issues
206 // with capture changes. 204 // with capture changes.
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 direct_manipulation_helper_->Activate(hwnd()); 412 direct_manipulation_helper_->Activate(hwnd());
415 } else if (window_pos->flags & SWP_HIDEWINDOW) { 413 } else if (window_pos->flags & SWP_HIDEWINDOW) {
416 direct_manipulation_helper_->Deactivate(hwnd()); 414 direct_manipulation_helper_->Deactivate(hwnd());
417 } 415 }
418 } 416 }
419 SetMsgHandled(FALSE); 417 SetMsgHandled(FALSE);
420 return 0; 418 return 0;
421 } 419 }
422 420
423 } // namespace content 421 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698