| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |