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

Side by Side Diff: content/browser/tab_contents/tab_contents_view_aura.cc

Issue 10031044: TabContents -> WebContentsImpl, part 5. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase (fixed) Created 8 years, 8 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium 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 "content/browser/tab_contents/tab_contents_view_aura.h"
6
7 #include "base/utf_string_conversions.h"
8 #include "content/browser/renderer_host/render_view_host_factory.h"
9 #include "content/browser/tab_contents/tab_contents.h"
10 #include "content/browser/web_contents/interstitial_page_impl.h"
11 #include "content/public/browser/render_view_host.h"
12 #include "content/public/browser/render_widget_host.h"
13 #include "content/public/browser/render_widget_host_view.h"
14 #include "content/public/browser/web_contents_delegate.h"
15 #include "content/public/browser/web_contents_view_delegate.h"
16 #include "content/public/browser/web_drag_dest_delegate.h"
17 #include "ui/aura/client/drag_drop_client.h"
18 #include "ui/aura/client/drag_drop_delegate.h"
19 #include "ui/aura/event.h"
20 #include "ui/aura/root_window.h"
21 #include "ui/aura/window.h"
22 #include "ui/base/clipboard/custom_data_helper.h"
23 #include "ui/base/dragdrop/drag_drop_types.h"
24 #include "ui/base/dragdrop/os_exchange_data.h"
25 #include "ui/base/dragdrop/os_exchange_data_provider_aura.h"
26 #include "ui/base/hit_test.h"
27 #include "ui/gfx/compositor/layer.h"
28 #include "ui/gfx/screen.h"
29 #include "webkit/glue/webdropdata.h"
30
31 namespace {
32
33 // Listens to all mouse drag events during a drag and drop and sends them to
34 // the renderer.
35 class WebDragSourceAura : public MessageLoopForUI::Observer {
36 public:
37 explicit WebDragSourceAura(TabContents* contents)
38 : contents_(contents) {
39 MessageLoopForUI::current()->AddObserver(this);
40 }
41
42 virtual ~WebDragSourceAura() {
43 MessageLoopForUI::current()->RemoveObserver(this);
44 }
45
46 // MessageLoop::Observer implementation:
47 virtual base::EventStatus WillProcessEvent(
48 const base::NativeEvent& event) OVERRIDE {
49 return base::EVENT_CONTINUE;
50 }
51 virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE {
52 ui::EventType type = ui::EventTypeFromNative(event);
53 content::RenderViewHost* rvh = NULL;
54 switch (type) {
55 case ui::ET_MOUSE_DRAGGED:
56 rvh = contents_->GetRenderViewHost();
57 if (rvh) {
58 gfx::Point screen_loc = ui::EventLocationFromNative(event);
59 gfx::Point client_loc = screen_loc;
60 aura::Window* window = rvh->GetView()->GetNativeView();
61 aura::Window::ConvertPointToWindow(window->GetRootWindow(),
62 window, &client_loc);
63 rvh->DragSourceMovedTo(client_loc.x(), client_loc.y(),
64 screen_loc.x(), screen_loc.y());
65 }
66 break;
67 default:
68 break;
69 }
70 }
71
72
73 private:
74 TabContents* contents_;
75
76 DISALLOW_COPY_AND_ASSIGN(WebDragSourceAura);
77 };
78
79 // Utility to fill a ui::OSExchangeDataProviderAura object from WebDropData.
80 void PrepareDragData(const WebDropData& drop_data,
81 ui::OSExchangeDataProviderAura* provider) {
82 if (!drop_data.plain_text.empty())
83 provider->SetString(drop_data.plain_text);
84 if (drop_data.url.is_valid())
85 provider->SetURL(drop_data.url, drop_data.url_title);
86 if (!drop_data.text_html.empty())
87 provider->SetHtml(drop_data.text_html, drop_data.html_base_url);
88 if (!drop_data.filenames.empty()) {
89 std::vector<FilePath> paths;
90 for (std::vector<string16>::const_iterator it = drop_data.filenames.begin();
91 it != drop_data.filenames.end(); ++it)
92 paths.push_back(FilePath::FromUTF8Unsafe(UTF16ToUTF8(*it)));
93 provider->SetFilenames(paths);
94 }
95 if (!drop_data.custom_data.empty()) {
96 Pickle pickle;
97 ui::WriteCustomDataToPickle(drop_data.custom_data, &pickle);
98 provider->SetPickledData(ui::Clipboard::GetWebCustomDataFormatType(),
99 pickle);
100 }
101 }
102
103 // Utility to fill a WebDropData object from ui::OSExchangeData.
104 void PrepareWebDropData(WebDropData* drop_data,
105 const ui::OSExchangeData& data) {
106 string16 plain_text, url_title;
107 GURL url;
108
109 data.GetString(&plain_text);
110 if (!plain_text.empty())
111 drop_data->plain_text = plain_text;
112
113 data.GetURLAndTitle(&url, &url_title);
114 if (url.is_valid()) {
115 drop_data->url = url;
116 drop_data->url_title = url_title;
117 }
118
119 data.GetHtml(&drop_data->text_html, &drop_data->html_base_url);
120
121 std::vector<FilePath> files;
122 if (data.GetFilenames(&files) && !files.empty()) {
123 for (std::vector<FilePath>::const_iterator it = files.begin();
124 it != files.end(); ++it)
125 drop_data->filenames.push_back(UTF8ToUTF16(it->AsUTF8Unsafe()));
126 }
127
128 Pickle pickle;
129 if (data.GetPickledData(ui::Clipboard::GetWebCustomDataFormatType(),
130 &pickle))
131 ui::ReadCustomDataIntoMap(pickle.data(), pickle.size(),
132 &drop_data->custom_data);
133 }
134
135 // Utilities to convert between WebKit::WebDragOperationsMask and
136 // ui::DragDropTypes.
137 int ConvertFromWeb(WebKit::WebDragOperationsMask ops) {
138 int drag_op = ui::DragDropTypes::DRAG_NONE;
139 if (ops & WebKit::WebDragOperationCopy)
140 drag_op |= ui::DragDropTypes::DRAG_COPY;
141 if (ops & WebKit::WebDragOperationMove)
142 drag_op |= ui::DragDropTypes::DRAG_MOVE;
143 if (ops & WebKit::WebDragOperationLink)
144 drag_op |= ui::DragDropTypes::DRAG_LINK;
145 return drag_op;
146 }
147
148 WebKit::WebDragOperationsMask ConvertToWeb(int drag_op) {
149 int web_drag_op = WebKit::WebDragOperationNone;
150 if (drag_op & ui::DragDropTypes::DRAG_COPY)
151 web_drag_op |= WebKit::WebDragOperationCopy;
152 if (drag_op & ui::DragDropTypes::DRAG_MOVE)
153 web_drag_op |= WebKit::WebDragOperationMove;
154 if (drag_op & ui::DragDropTypes::DRAG_LINK)
155 web_drag_op |= WebKit::WebDragOperationLink;
156 return (WebKit::WebDragOperationsMask) web_drag_op;
157 }
158
159 } // namespace
160
161
162 ////////////////////////////////////////////////////////////////////////////////
163 // TabContentsViewAura, public:
164
165 TabContentsViewAura::TabContentsViewAura(
166 TabContents* tab_contents,
167 content::WebContentsViewDelegate* delegate)
168 : tab_contents_(tab_contents),
169 view_(NULL),
170 delegate_(delegate),
171 current_drag_op_(WebKit::WebDragOperationNone),
172 close_tab_after_drag_ends_(false) {
173 }
174
175 TabContentsViewAura::~TabContentsViewAura() {
176 }
177
178 ////////////////////////////////////////////////////////////////////////////////
179 // TabContentsViewAura, private:
180
181 void TabContentsViewAura::SizeChangedCommon(const gfx::Size& size) {
182 if (tab_contents_->GetInterstitialPage())
183 tab_contents_->GetInterstitialPage()->SetSize(size);
184 content::RenderWidgetHostView* rwhv =
185 tab_contents_->GetRenderWidgetHostView();
186 if (rwhv)
187 rwhv->SetSize(size);
188 }
189
190 void TabContentsViewAura::EndDrag(WebKit::WebDragOperationsMask ops) {
191 aura::RootWindow* root_window = GetNativeView()->GetRootWindow();
192 gfx::Point screen_loc = root_window->last_mouse_location();
193 gfx::Point client_loc = screen_loc;
194 content::RenderViewHost* rvh = tab_contents_->GetRenderViewHost();
195 aura::Window* window = rvh->GetView()->GetNativeView();
196 aura::Window::ConvertPointToWindow(root_window, window, &client_loc);
197 rvh->DragSourceEndedAt(client_loc.x(), client_loc.y(), screen_loc.x(),
198 screen_loc.y(), ops);
199 }
200
201 content::WebDragDestDelegate* TabContentsViewAura::GetDragDestDelegate() {
202 return delegate_.get() ? delegate_->GetDragDestDelegate() : NULL;
203 }
204
205 ////////////////////////////////////////////////////////////////////////////////
206 // TabContentsViewAura, WebContentsView implementation:
207
208 void TabContentsViewAura::CreateView(const gfx::Size& initial_size) {
209 initial_size_ = initial_size;
210
211 window_.reset(new aura::Window(this));
212 window_->set_owned_by_parent(false);
213 window_->SetType(aura::client::WINDOW_TYPE_CONTROL);
214 window_->SetTransparent(false);
215 window_->Init(ui::LAYER_NOT_DRAWN);
216 window_->SetParent(NULL);
217 window_->layer()->SetMasksToBounds(true);
218 window_->SetName("TabContentsViewAura");
219 }
220
221 content::RenderWidgetHostView* TabContentsViewAura::CreateViewForWidget(
222 content::RenderWidgetHost* render_widget_host) {
223 if (render_widget_host->GetView()) {
224 // During testing, the view will already be set up in most cases to the
225 // test view, so we don't want to clobber it with a real one. To verify that
226 // this actually is happening (and somebody isn't accidentally creating the
227 // view twice), we check for the RVH Factory, which will be set when we're
228 // making special ones (which go along with the special views).
229 DCHECK(RenderViewHostFactory::has_factory());
230 return render_widget_host->GetView();
231 }
232
233 view_ = content::RenderWidgetHostView::CreateViewForWidget(
234 render_widget_host);
235 view_->InitAsChild(NULL);
236 GetNativeView()->AddChild(view_->GetNativeView());
237 view_->Show();
238
239 // We listen to drag drop events in the newly created view's window.
240 aura::client::SetDragDropDelegate(view_->GetNativeView(), this);
241 return view_;
242 }
243
244 gfx::NativeView TabContentsViewAura::GetNativeView() const {
245 return window_.get();
246 }
247
248 gfx::NativeView TabContentsViewAura::GetContentNativeView() const {
249 return view_->GetNativeView();
250 }
251
252 gfx::NativeWindow TabContentsViewAura::GetTopLevelNativeWindow() const {
253 return window_->GetToplevelWindow();
254 }
255
256 void TabContentsViewAura::GetContainerBounds(gfx::Rect *out) const {
257 *out = window_->GetScreenBounds();
258 }
259
260 void TabContentsViewAura::SetPageTitle(const string16& title) {
261 window_->set_title(title);
262 }
263
264 void TabContentsViewAura::OnTabCrashed(base::TerminationStatus status,
265 int error_code) {
266 view_ = NULL;
267 }
268
269 void TabContentsViewAura::SizeContents(const gfx::Size& size) {
270 gfx::Rect bounds = window_->bounds();
271 if (bounds.size() != size) {
272 bounds.set_size(size);
273 window_->SetBounds(bounds);
274 } else {
275 // Our size matches what we want but the renderers size may not match.
276 // Pretend we were resized so that the renderers size is updated too.
277 SizeChangedCommon(size);
278
279 }
280 }
281
282 void TabContentsViewAura::RenderViewCreated(content::RenderViewHost* host) {
283 }
284
285 void TabContentsViewAura::Focus() {
286 if (tab_contents_->GetInterstitialPage()) {
287 tab_contents_->GetInterstitialPage()->Focus();
288 return;
289 }
290
291 if (delegate_.get() && delegate_->Focus())
292 return;
293
294 content::RenderWidgetHostView* rwhv =
295 tab_contents_->GetRenderWidgetHostView();
296 if (rwhv)
297 rwhv->Focus();
298 }
299
300 void TabContentsViewAura::SetInitialFocus() {
301 if (tab_contents_->FocusLocationBarByDefault())
302 tab_contents_->SetFocusToLocationBar(false);
303 else
304 Focus();
305 }
306
307 void TabContentsViewAura::StoreFocus() {
308 if (delegate_.get())
309 delegate_->StoreFocus();
310 }
311
312 void TabContentsViewAura::RestoreFocus() {
313 if (delegate_.get())
314 delegate_->RestoreFocus();
315 }
316
317 bool TabContentsViewAura::IsDoingDrag() const {
318 aura::RootWindow* root_window = GetNativeView()->GetRootWindow();
319 if (aura::client::GetDragDropClient(root_window))
320 return aura::client::GetDragDropClient(root_window)->IsDragDropInProgress();
321 return false;
322 }
323
324 void TabContentsViewAura::CancelDragAndCloseTab() {
325 DCHECK(IsDoingDrag());
326 // We can't close the tab while we're in the drag and
327 // |drag_handler_->CancelDrag()| is async. Instead, set a flag to cancel
328 // the drag and when the drag nested message loop ends, close the tab.
329 aura::RootWindow* root_window = GetNativeView()->GetRootWindow();
330 if (aura::client::GetDragDropClient(root_window))
331 aura::client::GetDragDropClient(root_window)->DragCancel();
332
333 close_tab_after_drag_ends_ = true;
334 }
335
336 bool TabContentsViewAura::IsEventTracking() const {
337 return false;
338 }
339
340 void TabContentsViewAura::CloseTabAfterEventTracking() {
341 }
342
343 void TabContentsViewAura::GetViewBounds(gfx::Rect* out) const {
344 *out = window_->GetScreenBounds();
345 }
346
347 ////////////////////////////////////////////////////////////////////////////////
348 // TabContentsViewAura, RenderViewHostDelegate::View implementation:
349
350 void TabContentsViewAura::CreateNewWindow(
351 int route_id,
352 const ViewHostMsg_CreateWindow_Params& params) {
353 tab_contents_view_helper_.CreateNewWindow(tab_contents_, route_id, params);
354 }
355
356 void TabContentsViewAura::CreateNewWidget(int route_id,
357 WebKit::WebPopupType popup_type) {
358 tab_contents_view_helper_.CreateNewWidget(tab_contents_,
359 route_id,
360 false,
361 popup_type);
362 }
363
364 void TabContentsViewAura::CreateNewFullscreenWidget(int route_id) {
365 tab_contents_view_helper_.CreateNewWidget(tab_contents_,
366 route_id,
367 true,
368 WebKit::WebPopupTypeNone);
369 }
370
371 void TabContentsViewAura::ShowCreatedWindow(int route_id,
372 WindowOpenDisposition disposition,
373 const gfx::Rect& initial_pos,
374 bool user_gesture) {
375 tab_contents_view_helper_.ShowCreatedWindow(
376 tab_contents_, route_id, disposition, initial_pos, user_gesture);
377 }
378
379 void TabContentsViewAura::ShowCreatedWidget(int route_id,
380 const gfx::Rect& initial_pos) {
381 tab_contents_view_helper_.ShowCreatedWidget(tab_contents_,
382 route_id,
383 false,
384 initial_pos);
385 }
386
387 void TabContentsViewAura::ShowCreatedFullscreenWidget(int route_id) {
388 tab_contents_view_helper_.ShowCreatedWidget(tab_contents_,
389 route_id,
390 true,
391 gfx::Rect());
392 }
393
394 void TabContentsViewAura::ShowContextMenu(
395 const content::ContextMenuParams& params) {
396 // Allow WebContentsDelegates to handle the context menu operation first.
397 if (tab_contents_->GetDelegate() &&
398 tab_contents_->GetDelegate()->HandleContextMenu(params)) {
399 return;
400 }
401
402 if (delegate_.get())
403 delegate_->ShowContextMenu(params);
404 }
405
406 void TabContentsViewAura::ShowPopupMenu(const gfx::Rect& bounds,
407 int item_height,
408 double item_font_size,
409 int selected_item,
410 const std::vector<WebMenuItem>& items,
411 bool right_aligned) {
412 // External popup menus are only used on Mac.
413 NOTIMPLEMENTED();
414 }
415
416 void TabContentsViewAura::StartDragging(
417 const WebDropData& drop_data,
418 WebKit::WebDragOperationsMask operations,
419 const SkBitmap& image,
420 const gfx::Point& image_offset) {
421 aura::RootWindow* root_window = GetNativeView()->GetRootWindow();
422 if (!aura::client::GetDragDropClient(root_window))
423 return;
424
425 ui::OSExchangeDataProviderAura* provider = new ui::OSExchangeDataProviderAura;
426 PrepareDragData(drop_data, provider);
427 if (!image.isNull()) {
428 provider->set_drag_image(image);
429 provider->set_drag_image_offset(image_offset);
430 }
431 ui::OSExchangeData data(provider); // takes ownership of |provider|.
432
433 scoped_ptr<WebDragSourceAura> drag_source(
434 new WebDragSourceAura(tab_contents_));
435
436 // We need to enable recursive tasks on the message loop so we can get
437 // updates while in the system DoDragDrop loop.
438 int result_op = 0;
439 {
440 // TODO(sad): Avoid using last_mouse_location here, since the drag may not
441 // always start from a mouse-event (e.g. a touch or gesture event could
442 // initiate the drag). The location information should be carried over from
443 // webkit. http://crbug.com/114754
444 gfx::Point location(root_window->last_mouse_location());
445 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
446 result_op = aura::client::GetDragDropClient(root_window)->StartDragAndDrop(
447 data, location, ConvertFromWeb(operations));
448 }
449
450 EndDrag(ConvertToWeb(result_op));
451 tab_contents_->GetRenderViewHost()->DragSourceSystemDragEnded();}
452
453 void TabContentsViewAura::UpdateDragCursor(WebKit::WebDragOperation operation) {
454 current_drag_op_ = operation;
455 }
456
457 void TabContentsViewAura::GotFocus() {
458 if (tab_contents_->GetDelegate())
459 tab_contents_->GetDelegate()->WebContentsFocused(tab_contents_);
460 }
461
462 void TabContentsViewAura::TakeFocus(bool reverse) {
463 if (tab_contents_->GetDelegate() &&
464 !tab_contents_->GetDelegate()->TakeFocus(reverse) &&
465 delegate_.get()) {
466 delegate_->TakeFocus(reverse);
467 }
468 }
469
470 ////////////////////////////////////////////////////////////////////////////////
471 // TabContentsViewAura, aura::WindowDelegate implementation:
472
473 gfx::Size TabContentsViewAura::GetMinimumSize() const {
474 return gfx::Size();
475 }
476
477 void TabContentsViewAura::OnBoundsChanged(const gfx::Rect& old_bounds,
478 const gfx::Rect& new_bounds) {
479 SizeChangedCommon(new_bounds.size());
480 if (delegate_.get())
481 delegate_->SizeChanged(new_bounds.size());
482 }
483
484 void TabContentsViewAura::OnFocus() {
485 }
486
487 void TabContentsViewAura::OnBlur() {
488 }
489
490 bool TabContentsViewAura::OnKeyEvent(aura::KeyEvent* event) {
491 return false;
492 }
493
494 gfx::NativeCursor TabContentsViewAura::GetCursor(const gfx::Point& point) {
495 return gfx::kNullCursor;
496 }
497
498 int TabContentsViewAura::GetNonClientComponent(const gfx::Point& point) const {
499 return HTCLIENT;
500 }
501
502 bool TabContentsViewAura::OnMouseEvent(aura::MouseEvent* event) {
503 if (!tab_contents_->GetDelegate())
504 return false;
505
506 switch (event->type()) {
507 case ui::ET_MOUSE_PRESSED:
508 tab_contents_->GetDelegate()->ActivateContents(tab_contents_);
509 break;
510 case ui::ET_MOUSE_MOVED:
511 tab_contents_->GetDelegate()->ContentsMouseEvent(
512 tab_contents_, gfx::Screen::GetCursorScreenPoint(), true);
513 break;
514 default:
515 break;
516 }
517 return false;
518 }
519
520 ui::TouchStatus TabContentsViewAura::OnTouchEvent(aura::TouchEvent* event) {
521 return ui::TOUCH_STATUS_UNKNOWN;
522 }
523
524 ui::GestureStatus TabContentsViewAura::OnGestureEvent(
525 aura::GestureEvent* event) {
526 return ui::GESTURE_STATUS_UNKNOWN;
527 }
528
529 bool TabContentsViewAura::CanFocus() {
530 return true;
531 }
532
533 void TabContentsViewAura::OnCaptureLost() {
534 }
535
536 void TabContentsViewAura::OnPaint(gfx::Canvas* canvas) {
537 }
538
539 void TabContentsViewAura::OnWindowDestroying() {
540 }
541
542 void TabContentsViewAura::OnWindowDestroyed() {
543 }
544
545 void TabContentsViewAura::OnWindowVisibilityChanged(bool visible) {
546 if (visible)
547 tab_contents_->ShowContents();
548 else
549 tab_contents_->HideContents();
550 }
551 ////////////////////////////////////////////////////////////////////////////////
552 // TabContentsViewAura, aura::client::DragDropDelegate implementation:
553
554 void TabContentsViewAura::OnDragEntered(const aura::DropTargetEvent& event) {
555 if (GetDragDestDelegate())
556 GetDragDestDelegate()->DragInitialize(tab_contents_);
557
558 WebDropData drop_data;
559 PrepareWebDropData(&drop_data, event.data());
560 WebKit::WebDragOperationsMask op = ConvertToWeb(event.source_operations());
561
562 gfx::Point screen_pt =
563 GetNativeView()->GetRootWindow()->last_mouse_location();
564 tab_contents_->GetRenderViewHost()->DragTargetDragEnter(
565 drop_data, event.location(), screen_pt, op);
566
567 if (GetDragDestDelegate()) {
568 GetDragDestDelegate()->OnReceiveDragData(event.data());
569 GetDragDestDelegate()->OnDragEnter();
570 }
571 }
572
573 int TabContentsViewAura::OnDragUpdated(const aura::DropTargetEvent& event) {
574 WebKit::WebDragOperationsMask op = ConvertToWeb(event.source_operations());
575 gfx::Point screen_pt =
576 GetNativeView()->GetRootWindow()->last_mouse_location();
577 tab_contents_->GetRenderViewHost()->DragTargetDragOver(
578 event.location(), screen_pt, op);
579
580 if (GetDragDestDelegate())
581 GetDragDestDelegate()->OnDragOver();
582
583 return ConvertFromWeb(current_drag_op_);
584 }
585
586 void TabContentsViewAura::OnDragExited() {
587 tab_contents_->GetRenderViewHost()->DragTargetDragLeave();
588 if (GetDragDestDelegate())
589 GetDragDestDelegate()->OnDragLeave();
590 }
591
592 int TabContentsViewAura::OnPerformDrop(const aura::DropTargetEvent& event) {
593 tab_contents_->GetRenderViewHost()->DragTargetDrop(
594 event.location(),
595 GetNativeView()->GetRootWindow()->last_mouse_location());
596 if (GetDragDestDelegate())
597 GetDragDestDelegate()->OnDrop();
598 return current_drag_op_;
599 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698