OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/ui/views/tab_contents/tab_contents_view_views.h" | 5 #include "chrome/browser/ui/views/tab_contents/tab_contents_view_views.h" |
6 | 6 |
7 #include <windows.h> | |
8 | |
9 #include <vector> | 7 #include <vector> |
10 | 8 |
11 #include "base/time.h" | 9 #include "base/time.h" |
12 #include "chrome/browser/ui/views/sad_tab_view.h" | 10 #include "chrome/browser/ui/views/sad_tab_view.h" |
13 #include "chrome/browser/ui/views/tab_contents/native_tab_contents_view.h" | 11 #include "chrome/browser/ui/views/tab_contents/native_tab_contents_view.h" |
14 #include "chrome/browser/ui/views/tab_contents/render_view_context_menu_views.h" | 12 #include "chrome/browser/ui/views/tab_contents/render_view_context_menu_views.h" |
15 #include "content/browser/renderer_host/render_process_host.h" | 13 #include "content/browser/renderer_host/render_process_host.h" |
16 #include "content/browser/renderer_host/render_view_host.h" | 14 #include "content/browser/renderer_host/render_view_host.h" |
17 #include "content/browser/renderer_host/render_view_host_factory.h" | 15 #include "content/browser/renderer_host/render_view_host_factory.h" |
18 #include "content/browser/renderer_host/render_widget_host_view.h" | 16 #include "content/browser/renderer_host/render_widget_host_view.h" |
19 #include "content/browser/tab_contents/interstitial_page.h" | 17 #include "content/browser/tab_contents/interstitial_page.h" |
20 #include "content/browser/tab_contents/tab_contents.h" | 18 #include "content/browser/tab_contents/tab_contents.h" |
21 #include "content/browser/tab_contents/tab_contents_delegate.h" | 19 #include "content/browser/tab_contents/tab_contents_delegate.h" |
22 #include "views/focus/focus_manager.h" | 20 #include "views/focus/focus_manager.h" |
23 #include "views/focus/view_storage.h" | 21 #include "views/focus/view_storage.h" |
24 #include "views/screen.h" | 22 #include "views/screen.h" |
25 #include "views/widget/native_widget.h" | 23 #include "views/widget/native_widget.h" |
26 #include "views/widget/root_view.h" | 24 #include "views/widget/root_view.h" |
27 #include "views/widget/widget.h" | 25 #include "views/widget/widget.h" |
28 | 26 |
| 27 #if defined(OS_WIN) |
| 28 #include <windows.h> |
| 29 #endif |
| 30 |
29 using WebKit::WebDragOperation; | 31 using WebKit::WebDragOperation; |
30 using WebKit::WebDragOperationNone; | 32 using WebKit::WebDragOperationNone; |
31 using WebKit::WebDragOperationsMask; | 33 using WebKit::WebDragOperationsMask; |
32 using WebKit::WebInputEvent; | 34 using WebKit::WebInputEvent; |
33 | 35 |
34 // static | 36 // static |
35 TabContentsView* TabContentsView::Create(TabContents* tab_contents) { | 37 TabContentsView* TabContentsView::Create(TabContents* tab_contents) { |
36 return new TabContentsViewViews(tab_contents); | 38 return new TabContentsViewViews(tab_contents); |
37 } | 39 } |
38 | 40 |
39 TabContentsViewViews::TabContentsViewViews(TabContents* tab_contents) | 41 TabContentsViewViews::TabContentsViewViews(TabContents* tab_contents) |
40 : TabContentsView(tab_contents), | 42 : TabContentsView(tab_contents), |
41 ALLOW_THIS_IN_INITIALIZER_LIST(native_tab_contents_view_( | 43 native_tab_contents_view_(NULL), |
42 NativeTabContentsView::CreateNativeTabContentsView(this))), | 44 sad_tab_(NULL), |
43 close_tab_after_drag_ends_(false), | 45 close_tab_after_drag_ends_(false), |
44 sad_tab_(NULL) { | 46 focus_manager_(NULL) { |
45 last_focused_view_storage_id_ = | 47 last_focused_view_storage_id_ = |
46 views::ViewStorage::GetInstance()->CreateStorageID(); | 48 views::ViewStorage::GetInstance()->CreateStorageID(); |
47 } | 49 } |
48 | 50 |
49 TabContentsViewViews::~TabContentsViewViews() { | 51 TabContentsViewViews::~TabContentsViewViews() { |
50 // Makes sure to remove any stored view we may still have in the ViewStorage. | 52 // Makes sure to remove any stored view we may still have in the ViewStorage. |
51 // | 53 // |
52 // It is possible the view went away before us, so we only do this if the | 54 // It is possible the view went away before us, so we only do this if the |
53 // view is registered. | 55 // view is registered. |
54 views::ViewStorage* view_storage = views::ViewStorage::GetInstance(); | 56 views::ViewStorage* view_storage = views::ViewStorage::GetInstance(); |
55 if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL) | 57 if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL) |
56 view_storage->RemoveView(last_focused_view_storage_id_); | 58 view_storage->RemoveView(last_focused_view_storage_id_); |
57 } | 59 } |
58 | 60 |
59 void TabContentsViewViews::Unparent() { | 61 void TabContentsViewViews::Unparent() { |
60 CHECK(native_tab_contents_view_.get()); | 62 // Remember who our FocusManager is, we won't be able to access it once |
| 63 // un-parented. |
| 64 focus_manager_ = GetFocusManager(); |
| 65 CHECK(native_tab_contents_view_); |
61 native_tab_contents_view_->Unparent(); | 66 native_tab_contents_view_->Unparent(); |
62 } | 67 } |
63 | 68 |
64 void TabContentsViewViews::CreateView(const gfx::Size& initial_size) { | 69 void TabContentsViewViews::CreateView(const gfx::Size& initial_size) { |
| 70 native_tab_contents_view_ = |
| 71 NativeTabContentsView::CreateNativeTabContentsView(this); |
65 native_tab_contents_view_->InitNativeTabContentsView(); | 72 native_tab_contents_view_->InitNativeTabContentsView(); |
66 } | 73 } |
67 | 74 |
68 RenderWidgetHostView* TabContentsViewViews::CreateViewForWidget( | 75 RenderWidgetHostView* TabContentsViewViews::CreateViewForWidget( |
69 RenderWidgetHost* render_widget_host) { | 76 RenderWidgetHost* render_widget_host) { |
70 if (render_widget_host->view()) { | 77 if (render_widget_host->view()) { |
71 // During testing, the view will already be set up in most cases to the | 78 // During testing, the view will already be set up in most cases to the |
72 // test view, so we don't want to clobber it with a real one. To verify that | 79 // test view, so we don't want to clobber it with a real one. To verify that |
73 // this actually is happening (and somebody isn't accidentally creating the | 80 // this actually is happening (and somebody isn't accidentally creating the |
74 // view twice), we check for the RVH Factory, which will be set when we're | 81 // view twice), we check for the RVH Factory, which will be set when we're |
75 // making special ones (which go along with the special views). | 82 // making special ones (which go along with the special views). |
76 DCHECK(RenderViewHostFactory::has_factory()); | 83 DCHECK(RenderViewHostFactory::has_factory()); |
77 return render_widget_host->view(); | 84 return render_widget_host->view(); |
78 } | 85 } |
79 | 86 |
80 // If we were showing sad tab, remove it now. | 87 // If we were showing sad tab, remove it now. |
81 if (sad_tab_) { | 88 if (sad_tab_) { |
82 GetWidget()->SetContentsView(new views::View()); | 89 SetContentsView(new views::View()); |
83 sad_tab_ = NULL; | 90 sad_tab_ = NULL; |
84 } | 91 } |
85 | 92 |
86 return native_tab_contents_view_->CreateRenderWidgetHostView( | 93 return native_tab_contents_view_->CreateRenderWidgetHostView( |
87 render_widget_host); | 94 render_widget_host); |
88 } | 95 } |
89 | 96 |
90 gfx::NativeView TabContentsViewViews::GetNativeView() const { | 97 gfx::NativeView TabContentsViewViews::GetNativeView() const { |
91 return GetWidget()->GetNativeView(); | 98 return Widget::GetNativeView(); |
92 } | 99 } |
93 | 100 |
94 gfx::NativeView TabContentsViewViews::GetContentNativeView() const { | 101 gfx::NativeView TabContentsViewViews::GetContentNativeView() const { |
95 RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); | 102 RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); |
96 return rwhv ? rwhv->GetNativeView() : NULL; | 103 return rwhv ? rwhv->GetNativeView() : NULL; |
97 } | 104 } |
98 | 105 |
99 gfx::NativeWindow TabContentsViewViews::GetTopLevelNativeWindow() const { | 106 gfx::NativeWindow TabContentsViewViews::GetTopLevelNativeWindow() const { |
100 return native_tab_contents_view_->GetTopLevelNativeWindow(); | 107 return GetTopLevelWidget()->GetNativeWindow(); |
101 } | 108 } |
102 | 109 |
103 void TabContentsViewViews::GetContainerBounds(gfx::Rect* out) const { | 110 void TabContentsViewViews::GetContainerBounds(gfx::Rect* out) const { |
104 *out = GetWidget()->GetClientAreaScreenBounds(); | 111 *out = GetClientAreaScreenBounds(); |
105 } | 112 } |
106 | 113 |
107 void TabContentsViewViews::StartDragging(const WebDropData& drop_data, | 114 void TabContentsViewViews::StartDragging(const WebDropData& drop_data, |
108 WebDragOperationsMask ops, | 115 WebDragOperationsMask ops, |
109 const SkBitmap& image, | 116 const SkBitmap& image, |
110 const gfx::Point& image_offset) { | 117 const gfx::Point& image_offset) { |
111 native_tab_contents_view_->StartDragging(drop_data, ops, image, image_offset); | 118 native_tab_contents_view_->StartDragging(drop_data, ops, image, image_offset); |
112 } | 119 } |
113 | 120 |
114 void TabContentsViewViews::SetPageTitle(const std::wstring& title) { | 121 void TabContentsViewViews::SetPageTitle(const std::wstring& title) { |
115 native_tab_contents_view_->SetPageTitle(title); | 122 native_tab_contents_view_->SetPageTitle(title); |
116 } | 123 } |
117 | 124 |
118 void TabContentsViewViews::OnTabCrashed(base::TerminationStatus status, | 125 void TabContentsViewViews::OnTabCrashed(base::TerminationStatus status, |
119 int /* error_code */) { | 126 int /* error_code */) { |
120 // Force an invalidation to render sad tab. | 127 // Force an invalidation to render sad tab. |
121 // Note that it's possible to get this message after the window was destroyed. | 128 // Note that it's possible to get this message after the window was destroyed. |
122 if (::IsWindow(GetNativeView())) { | 129 if (GetNativeView()) { |
123 SadTabView::Kind kind = | 130 SadTabView::Kind kind = |
124 status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED ? | 131 status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED ? |
125 SadTabView::KILLED : SadTabView::CRASHED; | 132 SadTabView::KILLED : SadTabView::CRASHED; |
126 sad_tab_ = new SadTabView(tab_contents(), kind); | 133 sad_tab_ = new SadTabView(tab_contents(), kind); |
127 GetWidget()->SetContentsView(sad_tab_); | 134 SetContentsView(sad_tab_); |
128 sad_tab_->SchedulePaint(); | 135 sad_tab_->SchedulePaint(); |
129 } | 136 } |
130 } | 137 } |
131 | 138 |
132 void TabContentsViewViews::SizeContents(const gfx::Size& size) { | 139 void TabContentsViewViews::SizeContents(const gfx::Size& size) { |
133 GetWidget()->SetSize(size); | 140 SetSize(size); |
134 } | 141 } |
135 | 142 |
136 void TabContentsViewViews::Focus() { | 143 void TabContentsViewViews::Focus() { |
137 if (tab_contents()->interstitial_page()) { | 144 if (tab_contents()->interstitial_page()) { |
138 tab_contents()->interstitial_page()->Focus(); | 145 tab_contents()->interstitial_page()->Focus(); |
139 return; | 146 return; |
140 } | 147 } |
141 | 148 |
142 if (tab_contents()->is_crashed() && sad_tab_ != NULL) { | 149 if (tab_contents()->is_crashed() && sad_tab_ != NULL) { |
143 sad_tab_->RequestFocus(); | 150 sad_tab_->RequestFocus(); |
144 return; | 151 return; |
145 } | 152 } |
146 | 153 |
147 if (tab_contents()->constrained_window_count() > 0) { | 154 if (tab_contents()->constrained_window_count() > 0) { |
148 ConstrainedWindow* window = *tab_contents()->constrained_window_begin(); | 155 ConstrainedWindow* window = *tab_contents()->constrained_window_begin(); |
149 DCHECK(window); | 156 DCHECK(window); |
150 window->FocusConstrainedWindow(); | 157 window->FocusConstrainedWindow(); |
151 return; | 158 return; |
152 } | 159 } |
153 | 160 |
154 RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); | 161 RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); |
155 GetWidget()->GetFocusManager()->FocusNativeView(rwhv ? rwhv->GetNativeView() | 162 GetFocusManager()->FocusNativeView(rwhv ? rwhv->GetNativeView() |
156 : GetNativeView()); | 163 : GetNativeView()); |
157 } | 164 } |
158 | 165 |
159 void TabContentsViewViews::SetInitialFocus() { | 166 void TabContentsViewViews::SetInitialFocus() { |
160 if (tab_contents()->FocusLocationBarByDefault()) | 167 if (tab_contents()->FocusLocationBarByDefault()) |
161 tab_contents()->SetFocusToLocationBar(false); | 168 tab_contents()->SetFocusToLocationBar(false); |
162 else | 169 else |
163 Focus(); | 170 Focus(); |
164 } | 171 } |
165 | 172 |
166 void TabContentsViewViews::StoreFocus() { | 173 void TabContentsViewViews::StoreFocus() { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 void TabContentsViewViews::CancelDragAndCloseTab() { | 223 void TabContentsViewViews::CancelDragAndCloseTab() { |
217 DCHECK(IsDoingDrag()); | 224 DCHECK(IsDoingDrag()); |
218 // We can't close the tab while we're in the drag and | 225 // We can't close the tab while we're in the drag and |
219 // |drag_handler_->CancelDrag()| is async. Instead, set a flag to cancel | 226 // |drag_handler_->CancelDrag()| is async. Instead, set a flag to cancel |
220 // the drag and when the drag nested message loop ends, close the tab. | 227 // the drag and when the drag nested message loop ends, close the tab. |
221 native_tab_contents_view_->CancelDrag(); | 228 native_tab_contents_view_->CancelDrag(); |
222 close_tab_after_drag_ends_ = true; | 229 close_tab_after_drag_ends_ = true; |
223 } | 230 } |
224 | 231 |
225 void TabContentsViewViews::GetViewBounds(gfx::Rect* out) const { | 232 void TabContentsViewViews::GetViewBounds(gfx::Rect* out) const { |
226 *out = GetWidget()->GetWindowScreenBounds(); | 233 *out = GetWindowScreenBounds(); |
227 } | 234 } |
228 | 235 |
229 void TabContentsViewViews::UpdateDragCursor(WebDragOperation operation) { | 236 void TabContentsViewViews::UpdateDragCursor(WebDragOperation operation) { |
230 native_tab_contents_view_->SetDragCursor(operation); | 237 native_tab_contents_view_->SetDragCursor(operation); |
231 } | 238 } |
232 | 239 |
233 void TabContentsViewViews::GotFocus() { | 240 void TabContentsViewViews::GotFocus() { |
234 if (tab_contents()->delegate()) | 241 if (tab_contents()->delegate()) |
235 tab_contents()->delegate()->TabContentsFocused(tab_contents()); | 242 tab_contents()->delegate()->TabContentsFocused(tab_contents()); |
236 } | 243 } |
237 | 244 |
238 void TabContentsViewViews::TakeFocus(bool reverse) { | 245 void TabContentsViewViews::TakeFocus(bool reverse) { |
239 if (!tab_contents()->delegate()->TakeFocus(reverse)) { | 246 if (!tab_contents()->delegate()->TakeFocus(reverse)) { |
240 views::FocusManager* focus_manager = | 247 views::FocusManager* focus_manager = |
241 views::FocusManager::GetFocusManagerForNativeView(GetNativeView()); | 248 views::FocusManager::GetFocusManagerForNativeView(GetNativeView()); |
242 | 249 |
243 // We may not have a focus manager if the tab has been switched before this | 250 // We may not have a focus manager if the tab has been switched before this |
244 // message arrived. | 251 // message arrived. |
245 if (focus_manager) | 252 if (focus_manager) |
246 focus_manager->AdvanceFocus(reverse); | 253 focus_manager->AdvanceFocus(reverse); |
247 } | 254 } |
248 } | 255 } |
249 | 256 |
250 views::Widget* TabContentsViewViews::GetWidget() { | |
251 return native_tab_contents_view_->AsNativeWidget()->GetWidget(); | |
252 } | |
253 | |
254 const views::Widget* TabContentsViewViews::GetWidget() const { | |
255 return native_tab_contents_view_->AsNativeWidget()->GetWidget(); | |
256 } | |
257 | |
258 void TabContentsViewViews::CloseTab() { | 257 void TabContentsViewViews::CloseTab() { |
259 tab_contents()->Close(tab_contents()->render_view_host()); | 258 tab_contents()->Close(tab_contents()->render_view_host()); |
260 } | 259 } |
261 | 260 |
262 void TabContentsViewViews::ShowContextMenu(const ContextMenuParams& params) { | 261 void TabContentsViewViews::ShowContextMenu(const ContextMenuParams& params) { |
263 // Allow delegates to handle the context menu operation first. | 262 // Allow delegates to handle the context menu operation first. |
264 if (tab_contents()->delegate()->HandleContextMenu(params)) | 263 if (tab_contents()->delegate()->HandleContextMenu(params)) |
265 return; | 264 return; |
266 | 265 |
267 context_menu_.reset(new RenderViewContextMenuViews(tab_contents(), params)); | 266 context_menu_.reset(new RenderViewContextMenuViews(tab_contents(), params)); |
268 context_menu_->Init(); | 267 context_menu_->Init(); |
269 | 268 |
270 POINT screen_pt = { params.x, params.y }; | 269 gfx::Point screen_point(params.x, params.y); |
271 MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_pt, 1); | 270 views::View::ConvertPointToScreen(GetRootView(), &screen_point); |
272 | 271 |
273 // Enable recursive tasks on the message loop so we can get updates while | 272 // Enable recursive tasks on the message loop so we can get updates while |
274 // the context menu is being displayed. | 273 // the context menu is being displayed. |
275 bool old_state = MessageLoop::current()->NestableTasksAllowed(); | 274 bool old_state = MessageLoop::current()->NestableTasksAllowed(); |
276 MessageLoop::current()->SetNestableTasksAllowed(true); | 275 MessageLoop::current()->SetNestableTasksAllowed(true); |
277 context_menu_->RunMenuAt(screen_pt.x, screen_pt.y); | 276 context_menu_->RunMenuAt(screen_point.x(), screen_point.y()); |
278 MessageLoop::current()->SetNestableTasksAllowed(old_state); | 277 MessageLoop::current()->SetNestableTasksAllowed(old_state); |
279 } | 278 } |
280 | 279 |
281 void TabContentsViewViews::ShowPopupMenu(const gfx::Rect& bounds, | 280 void TabContentsViewViews::ShowPopupMenu(const gfx::Rect& bounds, |
282 int item_height, | 281 int item_height, |
283 double item_font_size, | 282 double item_font_size, |
284 int selected_item, | 283 int selected_item, |
285 const std::vector<WebMenuItem>& items, | 284 const std::vector<WebMenuItem>& items, |
286 bool right_aligned) { | 285 bool right_aligned) { |
287 // External popup menus are only used on Mac. | 286 // External popup menus are only used on Mac. |
(...skipping 20 matching lines...) Expand all Loading... |
308 } | 307 } |
309 | 308 |
310 void TabContentsViewViews::OnNativeTabContentsViewSized(const gfx::Size& size) { | 309 void TabContentsViewViews::OnNativeTabContentsViewSized(const gfx::Size& size) { |
311 if (tab_contents()->interstitial_page()) | 310 if (tab_contents()->interstitial_page()) |
312 tab_contents()->interstitial_page()->SetSize(size); | 311 tab_contents()->interstitial_page()->SetSize(size); |
313 RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); | 312 RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); |
314 if (rwhv) | 313 if (rwhv) |
315 rwhv->SetSize(size); | 314 rwhv->SetSize(size); |
316 } | 315 } |
317 | 316 |
318 void TabContentsViewViews::OnNativeTabContentsViewWheelZoom(int distance) { | 317 void TabContentsViewViews::OnNativeTabContentsViewWheelZoom(bool zoom_in) { |
319 if (tab_contents()->delegate()) { | 318 if (tab_contents()->delegate()) |
320 bool zoom_in = distance > 0; | |
321 tab_contents()->delegate()->ContentsZoomChange(zoom_in); | 319 tab_contents()->delegate()->ContentsZoomChange(zoom_in); |
322 } | |
323 } | 320 } |
324 | 321 |
325 void TabContentsViewViews::OnNativeTabContentsViewMouseDown() { | 322 void TabContentsViewViews::OnNativeTabContentsViewMouseDown() { |
326 // Make sure this TabContents is activated when it is clicked on. | 323 // Make sure this TabContents is activated when it is clicked on. |
327 if (tab_contents()->delegate()) | 324 if (tab_contents()->delegate()) |
328 tab_contents()->delegate()->ActivateContents(tab_contents()); | 325 tab_contents()->delegate()->ActivateContents(tab_contents()); |
329 } | 326 } |
330 | 327 |
331 void TabContentsViewViews::OnNativeTabContentsViewMouseMove() { | 328 void TabContentsViewViews::OnNativeTabContentsViewMouseMove(bool motion) { |
332 // Let our delegate know that the mouse moved (useful for resetting status | 329 // Let our delegate know that the mouse moved (useful for resetting status |
333 // bubble state). | 330 // bubble state). |
334 if (tab_contents()->delegate()) { | 331 if (tab_contents()->delegate()) { |
335 tab_contents()->delegate()->ContentsMouseEvent( | 332 tab_contents()->delegate()->ContentsMouseEvent( |
336 tab_contents(), views::Screen::GetCursorScreenPoint(), true); | 333 tab_contents(), views::Screen::GetCursorScreenPoint(), motion); |
337 } | 334 } |
338 } | 335 } |
339 | 336 |
340 void TabContentsViewViews::OnNativeTabContentsViewDraggingEnded() { | 337 void TabContentsViewViews::OnNativeTabContentsViewDraggingEnded() { |
341 if (close_tab_after_drag_ends_) { | 338 if (close_tab_after_drag_ends_) { |
342 close_tab_timer_.Start(base::TimeDelta::FromMilliseconds(0), this, | 339 close_tab_timer_.Start(base::TimeDelta::FromMilliseconds(0), this, |
343 &TabContentsViewViews::CloseTab); | 340 &TabContentsViewViews::CloseTab); |
344 } | 341 } |
345 tab_contents()->SystemDragEnded(); | 342 tab_contents()->SystemDragEnded(); |
346 } | 343 } |
| 344 |
| 345 views::internal::NativeWidgetDelegate* |
| 346 TabContentsViewViews::AsNativeWidgetDelegate() { |
| 347 return this; |
| 348 } |
| 349 |
| 350 //////////////////////////////////////////////////////////////////////////////// |
| 351 // TabContentsViewViews, views::Widget overrides: |
| 352 |
| 353 views::FocusManager* TabContentsViewViews::GetFocusManager() { |
| 354 views::FocusManager* focus_manager = Widget::GetFocusManager(); |
| 355 if (focus_manager) { |
| 356 // If focus_manager_ is non NULL, it means we have been reparented, in which |
| 357 // case its value may not be valid anymore. |
| 358 focus_manager_ = NULL; |
| 359 return focus_manager; |
| 360 } |
| 361 // TODO(jcampan): we should DCHECK on focus_manager_, as it should not be |
| 362 // NULL. We are not doing it as it breaks some unit-tests. We should |
| 363 // probably have an empty TabContentView implementation for the unit-tests, |
| 364 // that would prevent that code being executed in the unit-test case. |
| 365 // DCHECK(focus_manager_); |
| 366 return focus_manager_; |
| 367 } |
| 368 |
OLD | NEW |