Use gpu::Mailbox in IPCs instead of std::string
[chromium-blink-merge.git] / content / browser / renderer_host / render_widget_host_view_aura.cc
blob643ef00ef31a390518c4abf9a872eb8bf3e43a26
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.
5 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/command_line.h"
10 #include "base/debug/trace_event.h"
11 #include "base/logging.h"
12 #include "base/message_loop.h"
13 #include "base/string_number_conversions.h"
14 #include "cc/compositor_frame.h"
15 #include "cc/compositor_frame_ack.h"
16 #include "content/browser/renderer_host/backing_store_aura.h"
17 #include "content/browser/renderer_host/dip_util.h"
18 #include "content/browser/renderer_host/overscroll_controller.h"
19 #include "content/browser/renderer_host/render_view_host_delegate.h"
20 #include "content/browser/renderer_host/render_widget_host_impl.h"
21 #include "content/browser/renderer_host/ui_events_helper.h"
22 #include "content/browser/renderer_host/web_input_event_aura.h"
23 #include "content/common/gpu/client/gl_helper.h"
24 #include "content/common/gpu/gpu_messages.h"
25 #include "content/common/view_messages.h"
26 #include "content/port/browser/render_widget_host_view_port.h"
27 #include "content/public/browser/browser_context.h"
28 #include "content/public/browser/browser_thread.h"
29 #include "content/public/browser/render_process_host.h"
30 #include "content/public/browser/render_view_host.h"
31 #include "content/public/browser/user_metrics.h"
32 #include "content/public/common/content_switches.h"
33 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositionUnderline.h"
34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
35 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
36 #include "ui/aura/client/activation_client.h"
37 #include "ui/aura/client/aura_constants.h"
38 #include "ui/aura/client/cursor_client.h"
39 #include "ui/aura/client/focus_client.h"
40 #include "ui/aura/client/screen_position_client.h"
41 #include "ui/aura/client/stacking_client.h"
42 #include "ui/aura/client/tooltip_client.h"
43 #include "ui/aura/client/window_types.h"
44 #include "ui/aura/env.h"
45 #include "ui/aura/root_window.h"
46 #include "ui/aura/window.h"
47 #include "ui/aura/window_observer.h"
48 #include "ui/aura/window_tracker.h"
49 #include "ui/base/clipboard/scoped_clipboard_writer.h"
50 #include "ui/base/events/event.h"
51 #include "ui/base/events/event_utils.h"
52 #include "ui/base/gestures/gesture_recognizer.h"
53 #include "ui/base/hit_test.h"
54 #include "ui/base/ime/input_method.h"
55 #include "ui/base/ui_base_types.h"
56 #include "ui/compositor/layer.h"
57 #include "ui/gfx/canvas.h"
58 #include "ui/gfx/display.h"
59 #include "ui/gfx/rect_conversions.h"
60 #include "ui/gfx/screen.h"
61 #include "ui/gfx/size_conversions.h"
62 #include "ui/gfx/skia_util.h"
64 #if defined(OS_WIN)
65 #include "ui/base/win/hidden_window.h"
66 #include "ui/gfx/gdi_util.h"
67 #endif
69 using gfx::RectToSkIRect;
70 using gfx::SkIRectToRect;
72 using WebKit::WebScreenInfo;
73 using WebKit::WebTouchEvent;
75 namespace content {
76 namespace {
78 // In mouse lock mode, we need to prevent the (invisible) cursor from hitting
79 // the border of the view, in order to get valid movement information. However,
80 // forcing the cursor back to the center of the view after each mouse move
81 // doesn't work well. It reduces the frequency of useful mouse move messages
82 // significantly. Therefore, we move the cursor to the center of the view only
83 // if it approaches the border. |kMouseLockBorderPercentage| specifies the width
84 // of the border area, in percentage of the corresponding dimension.
85 const int kMouseLockBorderPercentage = 15;
87 // When accelerated compositing is enabled and a widget resize is pending,
88 // we delay further resizes of the UI. The following constant is the maximum
89 // length of time that we should delay further UI resizes while waiting for a
90 // resized frame from a renderer.
91 const int kResizeLockTimeoutMs = 67;
93 #if defined(OS_WIN)
94 // Used to associate a plugin HWND with its RenderWidgetHostViewAura instance.
95 const wchar_t kWidgetOwnerProperty[] = L"RenderWidgetHostViewAuraOwner";
97 BOOL CALLBACK WindowDestroyingCallback(HWND window, LPARAM param) {
98 RenderWidgetHostViewAura* widget =
99 reinterpret_cast<RenderWidgetHostViewAura*>(param);
100 if (GetProp(window, kWidgetOwnerProperty) == widget) {
101 // Properties set on HWNDs must be removed to avoid leaks.
102 RemoveProp(window, kWidgetOwnerProperty);
103 RenderWidgetHostViewBase::DetachPluginWindowsCallback(window);
105 return TRUE;
108 BOOL CALLBACK HideWindowsCallback(HWND window, LPARAM param) {
109 RenderWidgetHostViewAura* widget =
110 reinterpret_cast<RenderWidgetHostViewAura*>(param);
111 if (GetProp(window, kWidgetOwnerProperty) == widget)
112 SetParent(window, ui::GetHiddenWindow());
113 return TRUE;
116 BOOL CALLBACK ShowWindowsCallback(HWND window, LPARAM param) {
117 RenderWidgetHostViewAura* widget =
118 reinterpret_cast<RenderWidgetHostViewAura*>(param);
120 if (GetProp(window, kWidgetOwnerProperty) == widget) {
121 HWND parent =
122 widget->GetNativeView()->GetRootWindow()->GetAcceleratedWidget();
123 SetParent(window, parent);
125 return TRUE;
128 struct CutoutRectsParams {
129 RenderWidgetHostViewAura* widget;
130 std::vector<gfx::Rect> cutout_rects;
131 std::map<HWND, webkit::npapi::WebPluginGeometry>* geometry;
134 // Used to update the region for the windowed plugin to draw in. We start with
135 // the clip rect from the renderer, then remove the cutout rects from the
136 // renderer, and then remove the transient windows from the root window and the
137 // constrained windows from the parent window.
138 BOOL CALLBACK SetCutoutRectsCallback(HWND window, LPARAM param) {
139 CutoutRectsParams* params = reinterpret_cast<CutoutRectsParams*>(param);
141 if (GetProp(window, kWidgetOwnerProperty) == params->widget) {
142 // First calculate the offset of this plugin from the root window, since
143 // the cutouts are relative to the root window.
144 HWND parent = params->widget->GetNativeView()->GetRootWindow()->
145 GetAcceleratedWidget();
146 POINT offset;
147 offset.x = offset.y = 0;
148 MapWindowPoints(window, parent, &offset, 1);
150 // Now get the cached clip rect and cutouts for this plugin window that came
151 // from the renderer.
152 std::map<HWND, webkit::npapi::WebPluginGeometry>::iterator i =
153 params->geometry->begin();
154 while (i != params->geometry->end() &&
155 i->second.window != window &&
156 GetParent(i->second.window) != window) {
157 ++i;
160 if (i == params->geometry->end()) {
161 NOTREACHED();
162 return TRUE;
165 HRGN hrgn = CreateRectRgn(i->second.clip_rect.x(),
166 i->second.clip_rect.y(),
167 i->second.clip_rect.right(),
168 i->second.clip_rect.bottom());
169 // We start with the cutout rects that came from the renderer, then add the
170 // ones that came from transient and constrained windows.
171 std::vector<gfx::Rect> cutout_rects = i->second.cutout_rects;
172 for (size_t i = 0; i < params->cutout_rects.size(); ++i) {
173 gfx::Rect offset_cutout = params->cutout_rects[i];
174 offset_cutout.Offset(-offset.x, -offset.y);
175 cutout_rects.push_back(offset_cutout);
177 gfx::SubtractRectanglesFromRegion(hrgn, cutout_rects);
178 SetWindowRgn(window, hrgn, TRUE);
180 return TRUE;
183 // A callback function for EnumThreadWindows to enumerate and dismiss
184 // any owned popup windows.
185 BOOL CALLBACK DismissOwnedPopups(HWND window, LPARAM arg) {
186 const HWND toplevel_hwnd = reinterpret_cast<HWND>(arg);
188 if (::IsWindowVisible(window)) {
189 const HWND owner = ::GetWindow(window, GW_OWNER);
190 if (toplevel_hwnd == owner) {
191 ::PostMessage(window, WM_CANCELMODE, 0, 0);
195 return TRUE;
197 #endif
199 void UpdateWebTouchEventAfterDispatch(WebKit::WebTouchEvent* event,
200 WebKit::WebTouchPoint* point) {
201 if (point->state != WebKit::WebTouchPoint::StateReleased &&
202 point->state != WebKit::WebTouchPoint::StateCancelled)
203 return;
204 --event->touchesLength;
205 for (unsigned i = point - event->touches;
206 i < event->touchesLength;
207 ++i) {
208 event->touches[i] = event->touches[i + 1];
212 bool CanRendererHandleEvent(const ui::MouseEvent* event) {
213 if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED)
214 return false;
216 #if defined(OS_WIN)
217 // Renderer cannot handle WM_XBUTTON or NC events.
218 switch (event->native_event().message) {
219 case WM_XBUTTONDOWN:
220 case WM_XBUTTONUP:
221 case WM_XBUTTONDBLCLK:
222 case WM_NCMOUSELEAVE:
223 case WM_NCMOUSEMOVE:
224 case WM_NCXBUTTONDOWN:
225 case WM_NCXBUTTONUP:
226 case WM_NCXBUTTONDBLCLK:
227 return false;
228 default:
229 break;
231 #endif
232 return true;
235 // We don't mark these as handled so that they're sent back to the
236 // DefWindowProc so it can generate WM_APPCOMMAND as necessary.
237 bool IsXButtonUpEvent(const ui::MouseEvent* event) {
238 #if defined(OS_WIN)
239 switch (event->native_event().message) {
240 case WM_XBUTTONUP:
241 case WM_NCXBUTTONUP:
242 return true;
244 #endif
245 return false;
248 void GetScreenInfoForWindow(WebScreenInfo* results, aura::Window* window) {
249 const gfx::Display display = window ?
250 gfx::Screen::GetScreenFor(window)->GetDisplayNearestWindow(window) :
251 gfx::Screen::GetScreenFor(window)->GetPrimaryDisplay();
252 results->rect = display.bounds();
253 results->availableRect = display.work_area();
254 // TODO(derat|oshima): Don't hardcode this. Get this from display object.
255 results->depth = 24;
256 results->depthPerComponent = 8;
257 results->deviceScaleFactor = display.device_scale_factor();
260 bool ShouldSendPinchGesture() {
261 static bool pinch_allowed =
262 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableViewport) ||
263 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePinch);
264 return pinch_allowed;
267 bool PointerEventActivates(const ui::Event& event) {
268 if (event.type() == ui::ET_MOUSE_PRESSED)
269 return true;
271 if (event.type() == ui::ET_GESTURE_BEGIN) {
272 const ui::GestureEvent& gesture =
273 static_cast<const ui::GestureEvent&>(event);
274 return gesture.details().touch_points() == 1;
277 return false;
280 // Swap ack for the renderer when kCompositeToMailbox is enabled.
281 void SendCompositorFrameAck(
282 int32 route_id,
283 int renderer_host_id,
284 const gpu::Mailbox& received_mailbox,
285 const gfx::Size& received_size,
286 bool skip_frame,
287 const scoped_refptr<ui::Texture>& texture_to_produce) {
288 cc::CompositorFrameAck ack;
289 ack.gl_frame_data.reset(new cc::GLFrameData());
290 DCHECK(!texture_to_produce || !skip_frame);
291 if (texture_to_produce) {
292 ack.gl_frame_data->mailbox = texture_to_produce->Produce();
293 ack.gl_frame_data->size = texture_to_produce->size();
294 ack.gl_frame_data->sync_point =
295 content::ImageTransportFactory::GetInstance()->InsertSyncPoint();
296 } else if (skip_frame) {
297 // Skip the frame, i.e. tell the producer to reuse the same buffer that
298 // we just received.
299 ack.gl_frame_data->size = received_size;
300 ack.gl_frame_data->mailbox = received_mailbox;
303 RenderWidgetHostImpl::SendSwapCompositorFrameAck(
304 route_id, renderer_host_id, ack);
307 void AcknowledgeBufferForGpu(
308 int32 route_id,
309 int gpu_host_id,
310 const gpu::Mailbox& received_mailbox,
311 bool skip_frame,
312 const scoped_refptr<ui::Texture>& texture_to_produce) {
313 AcceleratedSurfaceMsg_BufferPresented_Params ack;
314 uint32 sync_point = 0;
315 DCHECK(!texture_to_produce || !skip_frame);
316 if (texture_to_produce) {
317 ack.mailbox_name = texture_to_produce->Produce();
318 sync_point =
319 content::ImageTransportFactory::GetInstance()->InsertSyncPoint();
320 } else if (skip_frame) {
321 ack.mailbox_name = received_mailbox;
322 ack.sync_point = 0;
325 ack.sync_point = sync_point;
326 RenderWidgetHostImpl::AcknowledgeBufferPresent(
327 route_id, gpu_host_id, ack);
330 } // namespace
332 // We need to watch for mouse events outside a Web Popup or its parent
333 // and dismiss the popup for certain events.
334 class RenderWidgetHostViewAura::EventFilterForPopupExit :
335 public ui::EventHandler {
336 public:
337 explicit EventFilterForPopupExit(RenderWidgetHostViewAura* rwhva)
338 : rwhva_(rwhva) {
339 DCHECK(rwhva_);
340 aura::RootWindow* root_window = rwhva_->window_->GetRootWindow();
341 DCHECK(root_window);
342 root_window->AddPreTargetHandler(this);
345 virtual ~EventFilterForPopupExit() {
346 aura::RootWindow* root_window = rwhva_->window_->GetRootWindow();
347 DCHECK(root_window);
348 root_window->RemovePreTargetHandler(this);
351 // Overridden from ui::EventHandler
352 virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
353 rwhva_->ApplyEventFilterForPopupExit(event);
356 private:
357 RenderWidgetHostViewAura* rwhva_;
359 DISALLOW_COPY_AND_ASSIGN(EventFilterForPopupExit);
362 void RenderWidgetHostViewAura::ApplyEventFilterForPopupExit(
363 ui::MouseEvent* event) {
364 if (in_shutdown_) {
365 event_filter_for_popup_exit_.reset();
366 return;
368 if (is_fullscreen_ || event->type() != ui::ET_MOUSE_PRESSED ||
369 !event->target())
370 return;
372 DCHECK(popup_parent_host_view_);
373 aura::Window* target = static_cast<aura::Window*>(event->target());
374 if (target != window_ && target != popup_parent_host_view_->window_) {
375 event_filter_for_popup_exit_.reset();
376 in_shutdown_ = true;
377 host_->Shutdown();
381 // We have to implement the WindowObserver interface on a separate object
382 // because clang doesn't like implementing multiple interfaces that have
383 // methods with the same name. This object is owned by the
384 // RenderWidgetHostViewAura.
385 class RenderWidgetHostViewAura::WindowObserver : public aura::WindowObserver {
386 public:
387 explicit WindowObserver(RenderWidgetHostViewAura* view)
388 : view_(view) {
389 view_->window_->AddObserver(this);
392 virtual ~WindowObserver() {
393 view_->window_->RemoveObserver(this);
396 // Overridden from aura::WindowObserver:
397 virtual void OnWindowAddedToRootWindow(aura::Window* window) OVERRIDE {
398 if (window == view_->window_)
399 view_->AddedToRootWindow();
402 virtual void OnWindowRemovingFromRootWindow(aura::Window* window) OVERRIDE {
403 if (window == view_->window_)
404 view_->RemovingFromRootWindow();
407 private:
408 RenderWidgetHostViewAura* view_;
410 DISALLOW_COPY_AND_ASSIGN(WindowObserver);
413 #if defined(OS_WIN)
414 // On Windows, we need to watch the top level window for changes to transient
415 // windows because they can cover the view and we need to ensure that they're
416 // rendered on top of windowed NPAPI plugins.
417 class RenderWidgetHostViewAura::TransientWindowObserver
418 : public aura::WindowObserver {
419 public:
420 explicit TransientWindowObserver(RenderWidgetHostViewAura* view)
421 : view_(view), top_level_(NULL) {
422 view_->window_->AddObserver(this);
425 virtual ~TransientWindowObserver() {
426 view_->window_->RemoveObserver(this);
427 StopObserving();
430 // Overridden from aura::WindowObserver:
431 virtual void OnWindowHierarchyChanged(
432 const aura::WindowObserver::HierarchyChangeParams& params) OVERRIDE {
433 aura::Window* top_level = GetToplevelWindow();
434 if (top_level == top_level_)
435 return;
437 StopObserving();
438 top_level_ = top_level;
439 if (top_level_ && top_level_ != view_->window_)
440 top_level_->AddObserver(this);
443 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
444 if (window == top_level_)
445 StopObserving();
448 virtual void OnWindowBoundsChanged(aura::Window* window,
449 const gfx::Rect& old_bounds,
450 const gfx::Rect& new_bounds) OVERRIDE {
451 if (window->transient_parent())
452 SendPluginCutoutRects();
455 virtual void OnWindowVisibilityChanged(aura::Window* window,
456 bool visible) OVERRIDE {
457 if (window->transient_parent())
458 SendPluginCutoutRects();
461 virtual void OnAddTransientChild(aura::Window* window,
462 aura::Window* transient) OVERRIDE {
463 transient->AddObserver(this);
464 // Just wait for the OnWindowBoundsChanged of the transient, since the size
465 // is not known now.
468 virtual void OnRemoveTransientChild(aura::Window* window,
469 aura::Window* transient) OVERRIDE {
470 transient->RemoveObserver(this);
471 SendPluginCutoutRects();
474 aura::Window* GetToplevelWindow() {
475 aura::RootWindow* root = view_->window_->GetRootWindow();
476 if (!root)
477 return NULL;
478 aura::client::ActivationClient* activation_client =
479 aura::client::GetActivationClient(root);
480 if (!activation_client)
481 return NULL;
482 return activation_client->GetToplevelWindow(view_->window_);
485 void StopObserving() {
486 if (!top_level_)
487 return;
489 const aura::Window::Windows& transients = top_level_->transient_children();
490 for (size_t i = 0; i < transients.size(); ++i)
491 transients[i]->RemoveObserver(this);
493 if (top_level_ != view_->window_)
494 top_level_->RemoveObserver(this);
495 top_level_ = NULL;
498 void SendPluginCutoutRects() {
499 std::vector<gfx::Rect> cutouts;
500 const aura::Window::Windows& transients = top_level_->transient_children();
501 for (size_t i = 0; i < transients.size(); ++i) {
502 if (transients[i]->IsVisible())
503 cutouts.push_back(transients[i]->GetBoundsInRootWindow());
506 view_->UpdateTransientRects(cutouts);
508 private:
509 RenderWidgetHostViewAura* view_;
510 aura::Window* top_level_;
512 DISALLOW_COPY_AND_ASSIGN(TransientWindowObserver);
515 #endif
517 class RenderWidgetHostViewAura::ResizeLock {
518 public:
519 ResizeLock(aura::RootWindow* root_window,
520 const gfx::Size new_size,
521 bool defer_compositor_lock)
522 : root_window_(root_window),
523 new_size_(new_size),
524 compositor_lock_(defer_compositor_lock ?
525 NULL :
526 root_window_->compositor()->GetCompositorLock()),
527 weak_ptr_factory_(this),
528 defer_compositor_lock_(defer_compositor_lock) {
529 root_window_->HoldMouseMoves();
531 BrowserThread::PostDelayedTask(
532 BrowserThread::UI, FROM_HERE,
533 base::Bind(&RenderWidgetHostViewAura::ResizeLock::CancelLock,
534 weak_ptr_factory_.GetWeakPtr()),
535 base::TimeDelta::FromMilliseconds(kResizeLockTimeoutMs));
538 ~ResizeLock() {
539 CancelLock();
542 void UnlockCompositor() {
543 defer_compositor_lock_ = false;
544 compositor_lock_ = NULL;
547 void CancelLock() {
548 if (!root_window_)
549 return;
550 UnlockCompositor();
551 root_window_->ReleaseMouseMoves();
552 root_window_ = NULL;
555 const gfx::Size& expected_size() const {
556 return new_size_;
559 bool GrabDeferredLock() {
560 if (root_window_ && defer_compositor_lock_) {
561 compositor_lock_ = root_window_->compositor()->GetCompositorLock();
562 defer_compositor_lock_ = false;
563 return true;
565 return false;
568 private:
569 aura::RootWindow* root_window_;
570 gfx::Size new_size_;
571 scoped_refptr<ui::CompositorLock> compositor_lock_;
572 base::WeakPtrFactory<ResizeLock> weak_ptr_factory_;
573 bool defer_compositor_lock_;
575 DISALLOW_COPY_AND_ASSIGN(ResizeLock);
578 ////////////////////////////////////////////////////////////////////////////////
579 // RenderWidgetHostViewAura, public:
581 RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host)
582 : host_(RenderWidgetHostImpl::From(host)),
583 ALLOW_THIS_IN_INITIALIZER_LIST(window_(new aura::Window(this))),
584 in_shutdown_(false),
585 is_fullscreen_(false),
586 popup_parent_host_view_(NULL),
587 popup_child_host_view_(NULL),
588 is_loading_(false),
589 text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
590 can_compose_inline_(true),
591 has_composition_text_(false),
592 device_scale_factor_(1.0f),
593 paint_canvas_(NULL),
594 synthetic_move_sent_(false),
595 accelerated_compositing_state_changed_(false),
596 can_lock_compositor_(YES),
597 paint_observer_(NULL) {
598 host_->SetView(this);
599 window_observer_.reset(new WindowObserver(this));
600 aura::client::SetTooltipText(window_, &tooltip_);
601 aura::client::SetActivationDelegate(window_, this);
602 aura::client::SetActivationChangeObserver(window_, this);
603 aura::client::SetFocusChangeObserver(window_, this);
604 gfx::Screen::GetScreenFor(window_)->AddObserver(this);
605 #if defined(OS_WIN)
606 transient_observer_.reset(new TransientWindowObserver(this));
607 #endif
610 ////////////////////////////////////////////////////////////////////////////////
611 // RenderWidgetHostViewAura, RenderWidgetHostView implementation:
613 void RenderWidgetHostViewAura::InitAsChild(
614 gfx::NativeView parent_view) {
615 window_->Init(ui::LAYER_TEXTURED);
616 window_->SetName("RenderWidgetHostViewAura");
619 void RenderWidgetHostViewAura::InitAsPopup(
620 RenderWidgetHostView* parent_host_view,
621 const gfx::Rect& bounds_in_screen) {
622 popup_parent_host_view_ =
623 static_cast<RenderWidgetHostViewAura*>(parent_host_view);
625 RenderWidgetHostViewAura* old_child =
626 popup_parent_host_view_->popup_child_host_view_;
627 if (old_child) {
628 // TODO(jhorwich): Allow multiple popup_child_host_view_ per view, or
629 // similar mechanism to ensure a second popup doesn't cause the first one
630 // to never get a chance to filter events. See crbug.com/160589.
631 DCHECK(old_child->popup_parent_host_view_ == popup_parent_host_view_);
632 old_child->popup_parent_host_view_ = NULL;
634 popup_parent_host_view_->popup_child_host_view_ = this;
635 window_->SetType(aura::client::WINDOW_TYPE_MENU);
636 window_->Init(ui::LAYER_TEXTURED);
637 window_->SetName("RenderWidgetHostViewAura");
639 aura::RootWindow* root = popup_parent_host_view_->window_->GetRootWindow();
640 window_->SetDefaultParentByRootWindow(root, bounds_in_screen);
642 // TODO(erg): While I could make sure details of the StackingClient are
643 // hidden behind aura, hiding the details of the ScreenPositionClient will
644 // take another effort.
645 aura::client::ScreenPositionClient* screen_position_client =
646 aura::client::GetScreenPositionClient(root);
647 gfx::Point origin_in_parent(bounds_in_screen.origin());
648 if (screen_position_client) {
649 screen_position_client->ConvertPointFromScreen(
650 window_->parent(), &origin_in_parent);
652 SetBounds(gfx::Rect(origin_in_parent, bounds_in_screen.size()));
653 Show();
656 void RenderWidgetHostViewAura::InitAsFullscreen(
657 RenderWidgetHostView* reference_host_view) {
658 is_fullscreen_ = true;
659 window_->SetType(aura::client::WINDOW_TYPE_NORMAL);
660 window_->Init(ui::LAYER_TEXTURED);
661 window_->SetName("RenderWidgetHostViewAura");
662 window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
664 aura::RootWindow* parent = NULL;
665 gfx::Rect bounds;
666 if (reference_host_view) {
667 aura::Window* reference_window =
668 static_cast<RenderWidgetHostViewAura*>(reference_host_view)->window_;
669 if (reference_window) {
670 host_tracker_.reset(new aura::WindowTracker);
671 host_tracker_->Add(reference_window);
673 gfx::Display display = gfx::Screen::GetScreenFor(window_)->
674 GetDisplayNearestWindow(reference_window);
675 parent = reference_window->GetRootWindow();
676 bounds = display.bounds();
678 window_->SetDefaultParentByRootWindow(parent, bounds);
679 Show();
680 Focus();
683 RenderWidgetHost* RenderWidgetHostViewAura::GetRenderWidgetHost() const {
684 return host_;
687 void RenderWidgetHostViewAura::WasShown() {
688 if (!host_->is_hidden())
689 return;
690 host_->WasShown();
692 if (!current_surface_ && host_->is_accelerated_compositing_active() &&
693 !released_front_lock_.get()) {
694 released_front_lock_ = GetCompositor()->GetCompositorLock();
697 #if defined(OS_WIN)
698 LPARAM lparam = reinterpret_cast<LPARAM>(this);
699 EnumChildWindows(ui::GetHiddenWindow(), ShowWindowsCallback, lparam);
700 transient_observer_->SendPluginCutoutRects();
701 #endif
704 void RenderWidgetHostViewAura::WasHidden() {
705 if (host_->is_hidden())
706 return;
707 host_->WasHidden();
709 released_front_lock_ = NULL;
711 #if defined(OS_WIN)
712 aura::RootWindow* root_window = window_->GetRootWindow();
713 if (root_window) {
714 HWND parent = root_window->GetAcceleratedWidget();
715 LPARAM lparam = reinterpret_cast<LPARAM>(this);
717 EnumChildWindows(parent, HideWindowsCallback, lparam);
719 #endif
722 void RenderWidgetHostViewAura::SetSize(const gfx::Size& size) {
723 SetBounds(gfx::Rect(window_->bounds().origin(), size));
726 void RenderWidgetHostViewAura::SetBounds(const gfx::Rect& rect) {
727 if (window_->bounds().size() != rect.size() &&
728 host_->is_accelerated_compositing_active()) {
729 aura::RootWindow* root_window = window_->GetRootWindow();
730 ui::Compositor* compositor = root_window ?
731 root_window->compositor() : NULL;
732 if (root_window && compositor) {
733 // Listen to changes in the compositor lock state.
734 if (!compositor->HasObserver(this))
735 compositor->AddObserver(this);
737 bool defer_compositor_lock =
738 can_lock_compositor_ == NO_PENDING_RENDERER_FRAME ||
739 can_lock_compositor_ == NO_PENDING_COMMIT;
741 if (can_lock_compositor_ == YES)
742 can_lock_compositor_ = YES_DID_LOCK;
744 resize_locks_.push_back(make_linked_ptr(
745 new ResizeLock(root_window, rect.size(), defer_compositor_lock)));
748 window_->SetBounds(rect);
749 host_->WasResized();
752 gfx::NativeView RenderWidgetHostViewAura::GetNativeView() const {
753 return window_;
756 gfx::NativeViewId RenderWidgetHostViewAura::GetNativeViewId() const {
757 #if defined(OS_WIN)
758 aura::RootWindow* root_window = window_->GetRootWindow();
759 if (root_window) {
760 HWND window = root_window->GetAcceleratedWidget();
761 return reinterpret_cast<gfx::NativeViewId>(window);
763 #endif
764 return static_cast<gfx::NativeViewId>(NULL);
767 gfx::NativeViewAccessible RenderWidgetHostViewAura::GetNativeViewAccessible() {
768 NOTIMPLEMENTED();
769 return static_cast<gfx::NativeViewAccessible>(NULL);
772 void RenderWidgetHostViewAura::MovePluginWindows(
773 const gfx::Vector2d& scroll_offset,
774 const std::vector<webkit::npapi::WebPluginGeometry>& plugin_window_moves) {
775 #if defined(OS_WIN)
776 // We need to clip the rectangle to the tab's viewport, otherwise we will draw
777 // over the browser UI.
778 if (!window_->GetRootWindow()) {
779 DCHECK(plugin_window_moves.empty());
780 return;
782 HWND parent = window_->GetRootWindow()->GetAcceleratedWidget();
783 gfx::Rect view_bounds = window_->GetBoundsInRootWindow();
784 std::vector<webkit::npapi::WebPluginGeometry> moves = plugin_window_moves;
786 gfx::Rect view_port(scroll_offset.x(), scroll_offset.y(), view_bounds.width(),
787 view_bounds.height());
789 for (size_t i = 0; i < moves.size(); ++i) {
790 gfx::Rect clip(moves[i].clip_rect);
791 gfx::Vector2d view_port_offset(
792 moves[i].window_rect.OffsetFromOrigin() + scroll_offset);
793 clip.Offset(view_port_offset);
794 clip.Intersect(view_port);
795 clip.Offset(-view_port_offset);
796 moves[i].clip_rect = clip;
798 moves[i].window_rect.Offset(view_bounds.OffsetFromOrigin());
800 plugin_window_moves_[moves[i].window] = moves[i];
802 // transient_rects_ and constrained_rects_ are relative to the root window.
803 // We want to convert them to be relative to the plugin window.
804 std::vector<gfx::Rect> cutout_rects;
805 cutout_rects.assign(transient_rects_.begin(), transient_rects_.end());
806 cutout_rects.insert(cutout_rects.end(), constrained_rects_.begin(),
807 constrained_rects_.end());
808 for (size_t j = 0; j < cutout_rects.size(); ++j) {
809 gfx::Rect offset_cutout = cutout_rects[j];
810 offset_cutout -= moves[i].window_rect.OffsetFromOrigin();
811 moves[i].cutout_rects.push_back(offset_cutout);
815 MovePluginWindowsHelper(parent, moves);
817 // Make sure each plugin window (or its wrapper if it exists) has a pointer to
818 // |this|.
819 for (size_t i = 0; i < moves.size(); ++i) {
820 HWND window = moves[i].window;
821 if (GetParent(window) != parent) {
822 window = GetParent(window);
823 DCHECK(GetParent(window) == parent);
825 if (!GetProp(window, kWidgetOwnerProperty))
826 CHECK(SetProp(window, kWidgetOwnerProperty, this));
828 #endif // defined(OS_WIN)
831 void RenderWidgetHostViewAura::Focus() {
832 // Make sure we have a FocusClient before attempting to Focus(). In some
833 // situations we may not yet be in a valid Window hierarchy (such as reloading
834 // after out of memory discarded the tab).
835 aura::client::FocusClient* client = aura::client::GetFocusClient(window_);
836 if (client)
837 window_->Focus();
840 void RenderWidgetHostViewAura::Blur() {
841 window_->Blur();
844 bool RenderWidgetHostViewAura::HasFocus() const {
845 return window_->HasFocus();
848 bool RenderWidgetHostViewAura::IsSurfaceAvailableForCopy() const {
849 return current_surface_ || !!host_->GetBackingStore(false);
852 void RenderWidgetHostViewAura::Show() {
853 window_->Show();
856 void RenderWidgetHostViewAura::Hide() {
857 window_->Hide();
860 bool RenderWidgetHostViewAura::IsShowing() {
861 return window_->IsVisible();
864 gfx::Rect RenderWidgetHostViewAura::GetViewBounds() const {
865 return window_->GetBoundsInScreen();
868 void RenderWidgetHostViewAura::UpdateCursor(const WebCursor& cursor) {
869 current_cursor_ = cursor;
870 const gfx::Display display = gfx::Screen::GetScreenFor(window_)->
871 GetDisplayNearestWindow(window_);
872 current_cursor_.SetDeviceScaleFactor(display.device_scale_factor());
873 UpdateCursorIfOverSelf();
876 void RenderWidgetHostViewAura::SetIsLoading(bool is_loading) {
877 if (is_loading_ && !is_loading && paint_observer_)
878 paint_observer_->OnPageLoadComplete();
879 is_loading_ = is_loading;
880 UpdateCursorIfOverSelf();
883 void RenderWidgetHostViewAura::TextInputStateChanged(
884 const ViewHostMsg_TextInputState_Params& params) {
885 if (text_input_type_ != params.type ||
886 can_compose_inline_ != params.can_compose_inline) {
887 text_input_type_ = params.type;
888 can_compose_inline_ = params.can_compose_inline;
889 if (GetInputMethod())
890 GetInputMethod()->OnTextInputTypeChanged(this);
894 void RenderWidgetHostViewAura::ImeCancelComposition() {
895 if (GetInputMethod())
896 GetInputMethod()->CancelComposition(this);
897 has_composition_text_ = false;
900 void RenderWidgetHostViewAura::ImeCompositionRangeChanged(
901 const ui::Range& range,
902 const std::vector<gfx::Rect>& character_bounds) {
903 composition_character_bounds_ = character_bounds;
906 void RenderWidgetHostViewAura::DidUpdateBackingStore(
907 const gfx::Rect& scroll_rect,
908 const gfx::Vector2d& scroll_delta,
909 const std::vector<gfx::Rect>& copy_rects) {
910 if (accelerated_compositing_state_changed_)
911 UpdateExternalTexture();
913 // Use the state of the RenderWidgetHost and not the window as the two may
914 // differ. In particular if the window is hidden but the renderer isn't and we
915 // ignore the update and the window is made visible again the layer isn't
916 // marked as dirty and we show the wrong thing.
917 // We do this after UpdateExternalTexture() so that when we become visible
918 // we're not drawing a stale texture.
919 if (host_->is_hidden())
920 return;
922 gfx::Rect clip_rect;
923 if (paint_canvas_) {
924 SkRect sk_clip_rect;
925 if (paint_canvas_->sk_canvas()->getClipBounds(&sk_clip_rect))
926 clip_rect = gfx::ToEnclosingRect(gfx::SkRectToRectF(sk_clip_rect));
929 if (!scroll_rect.IsEmpty())
930 SchedulePaintIfNotInClip(scroll_rect, clip_rect);
932 #if defined(OS_WIN)
933 aura::RootWindow* root_window = window_->GetRootWindow();
934 #endif
935 for (size_t i = 0; i < copy_rects.size(); ++i) {
936 gfx::Rect rect = gfx::SubtractRects(copy_rects[i], scroll_rect);
937 if (rect.IsEmpty())
938 continue;
940 SchedulePaintIfNotInClip(rect, clip_rect);
942 #if defined(OS_WIN)
943 if (root_window) {
944 // Send the invalid rect in screen coordinates.
945 gfx::Rect screen_rect = GetViewBounds();
946 gfx::Rect invalid_screen_rect(rect);
947 invalid_screen_rect.Offset(screen_rect.x(), screen_rect.y());
948 HWND hwnd = root_window->GetAcceleratedWidget();
949 PaintPluginWindowsHelper(hwnd, invalid_screen_rect);
951 #endif // defined(OS_WIN)
955 void RenderWidgetHostViewAura::RenderViewGone(base::TerminationStatus status,
956 int error_code) {
957 UpdateCursorIfOverSelf();
958 Destroy();
961 void RenderWidgetHostViewAura::Destroy() {
962 // Beware, this function is not called on all destruction paths. It will
963 // implicitly end up calling ~RenderWidgetHostViewAura though, so all
964 // destruction/cleanup code should happen there, not here.
965 in_shutdown_ = true;
966 delete window_;
969 void RenderWidgetHostViewAura::SetTooltipText(const string16& tooltip_text) {
970 tooltip_ = tooltip_text;
971 aura::RootWindow* root_window = window_->GetRootWindow();
972 if (aura::client::GetTooltipClient(root_window))
973 aura::client::GetTooltipClient(root_window)->UpdateTooltip(window_);
976 void RenderWidgetHostViewAura::SelectionChanged(const string16& text,
977 size_t offset,
978 const ui::Range& range) {
979 RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
981 #if defined(USE_X11) && !defined(OS_CHROMEOS)
982 if (text.empty() || range.is_empty())
983 return;
985 BrowserContext* browser_context = host_->GetProcess()->GetBrowserContext();
986 // Set the BUFFER_SELECTION to the ui::Clipboard.
987 ui::ScopedClipboardWriter clipboard_writer(
988 ui::Clipboard::GetForCurrentThread(),
989 ui::Clipboard::BUFFER_SELECTION,
990 BrowserContext::GetMarkerForOffTheRecordContext(browser_context));
991 clipboard_writer.WriteText(text);
992 #endif // defined(USE_X11) && !defined(OS_CHROMEOS)
995 void RenderWidgetHostViewAura::SelectionBoundsChanged(
996 const ViewHostMsg_SelectionBounds_Params& params) {
997 if (selection_anchor_rect_ == params.anchor_rect &&
998 selection_focus_rect_ == params.focus_rect)
999 return;
1001 selection_anchor_rect_ = params.anchor_rect;
1002 selection_focus_rect_ = params.focus_rect;
1004 if (GetInputMethod())
1005 GetInputMethod()->OnCaretBoundsChanged(this);
1008 void RenderWidgetHostViewAura::ScrollOffsetChanged() {
1009 aura::RootWindow* root = window_->GetRootWindow();
1010 if (!root)
1011 return;
1012 aura::client::CursorClient* cursor_client =
1013 aura::client::GetCursorClient(root);
1014 if (cursor_client && !cursor_client->IsCursorVisible())
1015 cursor_client->DisableMouseEvents();
1018 BackingStore* RenderWidgetHostViewAura::AllocBackingStore(
1019 const gfx::Size& size) {
1020 return new BackingStoreAura(host_, size);
1023 void RenderWidgetHostViewAura::CopyFromCompositingSurface(
1024 const gfx::Rect& src_subrect,
1025 const gfx::Size& dst_size,
1026 const base::Callback<void(bool, const SkBitmap&)>& callback) {
1027 base::ScopedClosureRunner scoped_callback_runner(
1028 base::Bind(callback, false, SkBitmap()));
1030 if (!current_surface_)
1031 return;
1033 gfx::Size dst_size_in_pixel = ConvertSizeToPixel(this, dst_size);
1035 SkBitmap output;
1036 output.setConfig(SkBitmap::kARGB_8888_Config,
1037 dst_size_in_pixel.width(), dst_size_in_pixel.height());
1038 if (!output.allocPixels())
1039 return;
1040 output.setIsOpaque(true);
1042 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
1043 GLHelper* gl_helper = factory->GetGLHelper();
1044 if (!gl_helper)
1045 return;
1047 unsigned char* addr = static_cast<unsigned char*>(output.getPixels());
1048 scoped_callback_runner.Release();
1049 // Wrap the callback with an internal handler so that we can inject our
1050 // own completion handlers (where we can try to free the frontbuffer).
1051 base::Callback<void(bool)> wrapper_callback = base::Bind(
1052 &RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinished,
1053 AsWeakPtr(),
1054 output,
1055 callback);
1056 ++pending_thumbnail_tasks_;
1058 // Convert |src_subrect| from the views coordinate (upper-left origin) into
1059 // the OpenGL coordinate (lower-left origin).
1060 gfx::Rect src_subrect_in_gl = src_subrect;
1061 src_subrect_in_gl.set_y(GetViewBounds().height() - src_subrect.bottom());
1063 gfx::Rect src_subrect_in_pixel = ConvertRectToPixel(this, src_subrect_in_gl);
1064 gl_helper->CropScaleReadbackAndCleanTexture(
1065 current_surface_->PrepareTexture(),
1066 current_surface_->size(),
1067 src_subrect_in_pixel,
1068 dst_size_in_pixel,
1069 addr,
1070 wrapper_callback);
1073 void RenderWidgetHostViewAura::CopyFromCompositingSurfaceToVideoFrame(
1074 const gfx::Rect& src_subrect,
1075 const scoped_refptr<media::VideoFrame>& target,
1076 const base::Callback<void(bool)>& callback) {
1077 NOTIMPLEMENTED();
1078 callback.Run(false);
1081 bool RenderWidgetHostViewAura::CanCopyToVideoFrame() const {
1082 return false;
1085 void RenderWidgetHostViewAura::OnAcceleratedCompositingStateChange() {
1086 // Delay processing the state change until we either get a software frame if
1087 // switching to software mode or receive a buffers swapped notification
1088 // if switching to accelerated mode.
1089 // Sometimes (e.g. on a page load) the renderer will spuriously disable then
1090 // re-enable accelerated compositing, causing us to flash.
1091 // TODO(piman): factor the enable/disable accelerated compositing message into
1092 // the UpdateRect/AcceleratedSurfaceBuffersSwapped messages so that we have
1093 // fewer inconsistent temporary states.
1094 accelerated_compositing_state_changed_ = true;
1097 bool RenderWidgetHostViewAura::ShouldSkipFrame(gfx::Size size_in_dip) {
1098 if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME ||
1099 can_lock_compositor_ == NO_PENDING_COMMIT ||
1100 resize_locks_.empty())
1101 return false;
1103 ResizeLockList::iterator it = resize_locks_.begin();
1104 while (it != resize_locks_.end()) {
1105 if ((*it)->expected_size() == size_in_dip)
1106 break;
1107 ++it;
1110 // We could be getting an unexpected frame due to an animation
1111 // (i.e. we start resizing but we get an old size frame first).
1112 return it == resize_locks_.end() || ++it != resize_locks_.end();
1115 void RenderWidgetHostViewAura::CheckResizeLocks(gfx::Size size_in_dip) {
1116 ResizeLockList::iterator it = resize_locks_.begin();
1117 while (it != resize_locks_.end()) {
1118 if ((*it)->expected_size() == size_in_dip)
1119 break;
1120 ++it;
1122 if (it != resize_locks_.end()) {
1123 ++it;
1124 ui::Compositor* compositor = GetCompositor();
1125 if (compositor) {
1126 // Delay the release of the lock until we've kicked a frame with the
1127 // new texture, to avoid resizing the UI before we have a chance to
1128 // draw a "good" frame.
1129 locks_pending_commit_.insert(
1130 locks_pending_commit_.begin(), resize_locks_.begin(), it);
1131 // However since we got the size we were looking for, unlock the
1132 // compositor.
1133 for (ResizeLockList::iterator it2 = resize_locks_.begin();
1134 it2 !=it; ++it2) {
1135 it2->get()->UnlockCompositor();
1137 if (!compositor->HasObserver(this))
1138 compositor->AddObserver(this);
1140 resize_locks_.erase(resize_locks_.begin(), it);
1144 void RenderWidgetHostViewAura::UpdateExternalTexture() {
1145 // Delay processing accelerated compositing state change till here where we
1146 // act upon the state change. (Clear the external texture if switching to
1147 // software mode or set the external texture if going to accelerated mode).
1148 if (accelerated_compositing_state_changed_)
1149 accelerated_compositing_state_changed_ = false;
1151 if (current_surface_ && host_->is_accelerated_compositing_active()) {
1152 window_->SetExternalTexture(current_surface_.get());
1153 gfx::Size container_size = ConvertSizeToDIP(this, current_surface_->size());
1154 CheckResizeLocks(container_size);
1155 } else {
1156 window_->SetExternalTexture(NULL);
1157 resize_locks_.clear();
1161 bool RenderWidgetHostViewAura::SwapBuffersPrepare(
1162 const gfx::Rect& surface_rect,
1163 const gfx::Rect& damage_rect,
1164 const gpu::Mailbox& mailbox_name,
1165 const BufferPresentedCallback& ack_callback) {
1166 if (last_swapped_surface_size_ != surface_rect.size()) {
1167 // The surface could have shrunk since we skipped an update, in which
1168 // case we can expect a full update.
1169 DLOG_IF(ERROR, damage_rect != surface_rect) << "Expected full damage rect";
1170 skipped_damage_.setEmpty();
1171 last_swapped_surface_size_ = surface_rect.size();
1174 if (ShouldSkipFrame(ConvertSizeToDIP(this, surface_rect.size())) ||
1175 mailbox_name.IsZero()) {
1176 skipped_damage_.op(RectToSkIRect(damage_rect), SkRegion::kUnion_Op);
1177 ack_callback.Run(true, scoped_refptr<ui::Texture>());
1178 return false;
1181 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
1182 current_surface_ = factory->CreateTransportClient(device_scale_factor_);
1183 if (!current_surface_) {
1184 LOG(ERROR) << "Failed to create ImageTransport texture";
1185 ack_callback.Run(true, scoped_refptr<ui::Texture>());
1186 return false;
1189 current_surface_->Consume(mailbox_name, surface_rect.size());
1190 released_front_lock_ = NULL;
1191 UpdateExternalTexture();
1193 return true;
1196 void RenderWidgetHostViewAura::SwapBuffersCompleted(
1197 const BufferPresentedCallback& ack_callback,
1198 const scoped_refptr<ui::Texture>& texture_to_return) {
1199 ui::Compositor* compositor = GetCompositor();
1200 if (!compositor) {
1201 ack_callback.Run(false, texture_to_return);
1202 } else {
1203 // Add sending an ACK to the list of things to do OnCompositingDidCommit
1204 can_lock_compositor_ = NO_PENDING_COMMIT;
1205 on_compositing_did_commit_callbacks_.push_back(
1206 base::Bind(ack_callback, false, texture_to_return));
1207 if (!compositor->HasObserver(this))
1208 compositor->AddObserver(this);
1212 #if defined(OS_WIN)
1213 void RenderWidgetHostViewAura::UpdateTransientRects(
1214 const std::vector<gfx::Rect>& rects) {
1215 transient_rects_ = rects;
1216 UpdateCutoutRects();
1219 void RenderWidgetHostViewAura::UpdateConstrainedWindowRects(
1220 const std::vector<gfx::Rect>& rects) {
1221 constrained_rects_ = rects;
1222 UpdateCutoutRects();
1225 void RenderWidgetHostViewAura::UpdateCutoutRects() {
1226 if (!window_->GetRootWindow())
1227 return;
1228 HWND parent = window_->GetRootWindow()->GetAcceleratedWidget();
1229 CutoutRectsParams params;
1230 params.widget = this;
1231 params.cutout_rects.assign(transient_rects_.begin(), transient_rects_.end());
1232 params.cutout_rects.insert(params.cutout_rects.end(),
1233 constrained_rects_.begin(),
1234 constrained_rects_.end());
1235 params.geometry = &plugin_window_moves_;
1236 LPARAM lparam = reinterpret_cast<LPARAM>(&params);
1237 EnumChildWindows(parent, SetCutoutRectsCallback, lparam);
1239 #endif
1241 void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped(
1242 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params_in_pixel,
1243 int gpu_host_id) {
1244 BufferPresentedCallback ack_callback = base::Bind(
1245 &AcknowledgeBufferForGpu,
1246 params_in_pixel.route_id,
1247 gpu_host_id,
1248 params_in_pixel.mailbox_name);
1249 BuffersSwapped(
1250 params_in_pixel.size, params_in_pixel.mailbox_name, ack_callback);
1253 void RenderWidgetHostViewAura::SwapDelegatedFrame(
1254 scoped_ptr<cc::DelegatedFrameData> frame_data,
1255 float frame_device_scale_factor) {
1256 gfx::Size frame_size_in_dip;
1257 if (!frame_data->render_pass_list.empty()) {
1258 frame_size_in_dip = gfx::ToFlooredSize(gfx::ScaleSize(
1259 frame_data->render_pass_list.back()->output_rect.size(),
1260 1.f/frame_device_scale_factor));
1262 if (ShouldSkipFrame(frame_size_in_dip)) {
1263 SendDelegatedFrameAck();
1264 return;
1266 window_->layer()->SetDelegatedFrame(frame_data.Pass(), frame_size_in_dip);
1267 released_front_lock_ = NULL;
1268 CheckResizeLocks(frame_size_in_dip);
1270 if (paint_observer_)
1271 paint_observer_->OnUpdateCompositorContent();
1273 ui::Compositor* compositor = GetCompositor();
1274 if (!compositor) {
1275 SendDelegatedFrameAck();
1276 } else {
1277 can_lock_compositor_ = NO_PENDING_COMMIT;
1278 on_compositing_did_commit_callbacks_.push_back(
1279 base::Bind(&RenderWidgetHostViewAura::SendDelegatedFrameAck,
1280 base::Unretained(this)));
1281 if (!compositor->HasObserver(this))
1282 compositor->AddObserver(this);
1286 void RenderWidgetHostViewAura::SendDelegatedFrameAck() {
1287 cc::CompositorFrameAck ack;
1288 window_->layer()->TakeUnusedResourcesForChildCompositor(&ack.resources);
1289 RenderWidgetHostImpl::SendSwapCompositorFrameAck(
1290 host_->GetRoutingID(), host_->GetProcess()->GetID(), ack);
1293 void RenderWidgetHostViewAura::OnSwapCompositorFrame(
1294 scoped_ptr<cc::CompositorFrame> frame) {
1295 if (frame->delegated_frame_data) {
1296 SwapDelegatedFrame(frame->delegated_frame_data.Pass(),
1297 frame->metadata.device_scale_factor);
1298 return;
1300 if (!frame->gl_frame_data || frame->gl_frame_data->mailbox.IsZero())
1301 return;
1303 BufferPresentedCallback ack_callback = base::Bind(
1304 &SendCompositorFrameAck,
1305 host_->GetRoutingID(), host_->GetProcess()->GetID(),
1306 frame->gl_frame_data->mailbox, frame->gl_frame_data->size);
1308 if (!frame->gl_frame_data->sync_point) {
1309 LOG(ERROR) << "CompositorFrame without sync point. Skipping frame...";
1310 ack_callback.Run(true, scoped_refptr<ui::Texture>());
1311 return;
1314 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
1315 factory->WaitSyncPoint(frame->gl_frame_data->sync_point);
1317 BuffersSwapped(
1318 frame->gl_frame_data->size, frame->gl_frame_data->mailbox, ack_callback);
1321 void RenderWidgetHostViewAura::BuffersSwapped(
1322 const gfx::Size& size,
1323 const gpu::Mailbox& mailbox_name,
1324 const BufferPresentedCallback& ack_callback) {
1325 scoped_refptr<ui::Texture> texture_to_return(current_surface_);
1326 const gfx::Rect surface_rect = gfx::Rect(gfx::Point(), size);
1327 if (!SwapBuffersPrepare(
1328 surface_rect, surface_rect, mailbox_name, ack_callback)) {
1329 return;
1332 previous_damage_.setRect(RectToSkIRect(surface_rect));
1333 skipped_damage_.setEmpty();
1335 ui::Compositor* compositor = GetCompositor();
1336 if (compositor) {
1337 gfx::Size surface_size = ConvertSizeToDIP(this, size);
1338 window_->SchedulePaintInRect(gfx::Rect(surface_size));
1341 if (paint_observer_)
1342 paint_observer_->OnUpdateCompositorContent();
1344 SwapBuffersCompleted(ack_callback, texture_to_return);
1347 void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer(
1348 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params_in_pixel,
1349 int gpu_host_id) {
1350 scoped_refptr<ui::Texture> previous_texture(current_surface_);
1351 const gfx::Rect surface_rect =
1352 gfx::Rect(gfx::Point(), params_in_pixel.surface_size);
1353 gfx::Rect damage_rect(params_in_pixel.x,
1354 params_in_pixel.y,
1355 params_in_pixel.width,
1356 params_in_pixel.height);
1357 BufferPresentedCallback ack_callback = base::Bind(
1358 &AcknowledgeBufferForGpu, params_in_pixel.route_id, gpu_host_id,
1359 params_in_pixel.mailbox_name);
1361 if (!SwapBuffersPrepare(
1362 surface_rect, damage_rect, params_in_pixel.mailbox_name, ack_callback)) {
1363 return;
1366 SkRegion damage(RectToSkIRect(damage_rect));
1367 if (!skipped_damage_.isEmpty()) {
1368 damage.op(skipped_damage_, SkRegion::kUnion_Op);
1369 skipped_damage_.setEmpty();
1372 DCHECK(surface_rect.Contains(SkIRectToRect(damage.getBounds())));
1373 ui::Texture* current_texture = current_surface_.get();
1375 const gfx::Size surface_size_in_pixel = params_in_pixel.surface_size;
1376 DLOG_IF(ERROR, previous_texture &&
1377 previous_texture->size() != current_texture->size() &&
1378 SkIRectToRect(damage.getBounds()) != surface_rect) <<
1379 "Expected full damage rect after size change";
1380 if (previous_texture && !previous_damage_.isEmpty() &&
1381 previous_texture->size() == current_texture->size()) {
1382 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
1383 GLHelper* gl_helper = factory->GetGLHelper();
1384 gl_helper->CopySubBufferDamage(
1385 current_texture->PrepareTexture(),
1386 previous_texture->PrepareTexture(),
1387 damage,
1388 previous_damage_);
1390 previous_damage_ = damage;
1392 ui::Compositor* compositor = GetCompositor();
1393 if (compositor) {
1394 // Co-ordinates come in OpenGL co-ordinate space.
1395 // We need to convert to layer space.
1396 gfx::Rect rect_to_paint = ConvertRectToDIP(this, gfx::Rect(
1397 params_in_pixel.x,
1398 surface_size_in_pixel.height() - params_in_pixel.y -
1399 params_in_pixel.height,
1400 params_in_pixel.width,
1401 params_in_pixel.height));
1403 // Damage may not have been DIP aligned, so inflate damage to compensate
1404 // for any round-off error.
1405 rect_to_paint.Inset(-1, -1);
1406 rect_to_paint.Intersect(window_->bounds());
1408 if (paint_observer_)
1409 paint_observer_->OnUpdateCompositorContent();
1410 window_->SchedulePaintInRect(rect_to_paint);
1413 SwapBuffersCompleted(ack_callback, previous_texture);
1416 void RenderWidgetHostViewAura::AcceleratedSurfaceSuspend() {
1419 void RenderWidgetHostViewAura::AcceleratedSurfaceRelease() {
1420 // This really tells us to release the frontbuffer.
1421 if (current_surface_) {
1422 ui::Compositor* compositor = GetCompositor();
1423 if (compositor) {
1424 // We need to wait for a commit to clear to guarantee that all we
1425 // will not issue any more GL referencing the previous surface.
1426 can_lock_compositor_ = NO_PENDING_COMMIT;
1427 on_compositing_did_commit_callbacks_.push_back(
1428 base::Bind(&RenderWidgetHostViewAura::
1429 SetSurfaceNotInUseByCompositor,
1430 AsWeakPtr(),
1431 current_surface_)); // Hold a ref so the texture will not
1432 // get deleted until after commit.
1433 if (!compositor->HasObserver(this))
1434 compositor->AddObserver(this);
1436 current_surface_ = NULL;
1437 UpdateExternalTexture();
1441 bool RenderWidgetHostViewAura::HasAcceleratedSurface(
1442 const gfx::Size& desired_size) {
1443 // Aura doesn't use GetBackingStore for accelerated pages, so it doesn't
1444 // matter what is returned here as GetBackingStore is the only caller of this
1445 // method. TODO(jbates) implement this if other Aura code needs it.
1446 return false;
1449 void RenderWidgetHostViewAura::SetSurfaceNotInUseByCompositor(
1450 scoped_refptr<ui::Texture>) {
1453 void RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinished(
1454 base::WeakPtr<RenderWidgetHostViewAura> render_widget_host_view,
1455 const SkBitmap& bitmap,
1456 const base::Callback<void(bool, const SkBitmap&)>& callback,
1457 bool result) {
1458 callback.Run(result, bitmap);
1460 if (!render_widget_host_view.get())
1461 return;
1462 --render_widget_host_view->pending_thumbnail_tasks_;
1465 void RenderWidgetHostViewAura::SetBackground(const SkBitmap& background) {
1466 RenderWidgetHostViewBase::SetBackground(background);
1467 host_->SetBackground(background);
1468 window_->layer()->SetFillsBoundsOpaquely(background.isOpaque());
1471 void RenderWidgetHostViewAura::GetScreenInfo(WebScreenInfo* results) {
1472 GetScreenInfoForWindow(results, window_->GetRootWindow() ? window_ : NULL);
1475 gfx::Rect RenderWidgetHostViewAura::GetBoundsInRootWindow() {
1476 return window_->GetToplevelWindow()->GetBoundsInScreen();
1479 void RenderWidgetHostViewAura::ProcessAckedTouchEvent(
1480 const WebKit::WebTouchEvent& touch_event, InputEventAckState ack_result) {
1481 ScopedVector<ui::TouchEvent> events;
1482 if (!MakeUITouchEventsFromWebTouchEvents(touch_event, &events))
1483 return;
1485 aura::RootWindow* root = window_->GetRootWindow();
1486 // |root| is NULL during tests.
1487 if (!root)
1488 return;
1490 ui::EventResult result = (ack_result ==
1491 INPUT_EVENT_ACK_STATE_CONSUMED) ? ui::ER_HANDLED : ui::ER_UNHANDLED;
1492 for (ScopedVector<ui::TouchEvent>::iterator iter = events.begin(),
1493 end = events.end(); iter != end; ++iter) {
1494 root->ProcessedTouchEvent((*iter), window_, result);
1498 void RenderWidgetHostViewAura::SetHasHorizontalScrollbar(
1499 bool has_horizontal_scrollbar) {
1500 // Not needed. Mac-only.
1503 void RenderWidgetHostViewAura::SetScrollOffsetPinning(
1504 bool is_pinned_to_left, bool is_pinned_to_right) {
1505 // Not needed. Mac-only.
1508 void RenderWidgetHostViewAura::OnAccessibilityNotifications(
1509 const std::vector<AccessibilityHostMsg_NotificationParams>& params) {
1512 gfx::GLSurfaceHandle RenderWidgetHostViewAura::GetCompositingSurface() {
1513 if (shared_surface_handle_.is_null()) {
1514 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
1515 shared_surface_handle_ = factory->CreateSharedSurfaceHandle();
1516 factory->AddObserver(this);
1518 return shared_surface_handle_;
1521 bool RenderWidgetHostViewAura::LockMouse() {
1522 aura::RootWindow* root_window = window_->GetRootWindow();
1523 if (!root_window)
1524 return false;
1526 if (mouse_locked_)
1527 return true;
1529 mouse_locked_ = true;
1530 window_->SetCapture();
1531 aura::client::CursorClient* cursor_client =
1532 aura::client::GetCursorClient(root_window);
1533 if (cursor_client)
1534 cursor_client->HideCursor();
1535 synthetic_move_sent_ = true;
1536 window_->MoveCursorTo(gfx::Rect(window_->bounds().size()).CenterPoint());
1537 if (aura::client::GetTooltipClient(root_window))
1538 aura::client::GetTooltipClient(root_window)->SetTooltipsEnabled(false);
1539 return true;
1542 void RenderWidgetHostViewAura::UnlockMouse() {
1543 aura::RootWindow* root_window = window_->GetRootWindow();
1544 if (!mouse_locked_ || !root_window)
1545 return;
1547 mouse_locked_ = false;
1549 window_->ReleaseCapture();
1550 window_->MoveCursorTo(unlocked_mouse_position_);
1551 aura::client::CursorClient* cursor_client =
1552 aura::client::GetCursorClient(root_window);
1553 if (cursor_client)
1554 cursor_client->ShowCursor();
1555 if (aura::client::GetTooltipClient(root_window))
1556 aura::client::GetTooltipClient(root_window)->SetTooltipsEnabled(true);
1558 host_->LostMouseLock();
1561 ////////////////////////////////////////////////////////////////////////////////
1562 // RenderWidgetHostViewAura, ui::TextInputClient implementation:
1563 void RenderWidgetHostViewAura::SetCompositionText(
1564 const ui::CompositionText& composition) {
1565 if (!host_)
1566 return;
1568 // ui::CompositionUnderline should be identical to
1569 // WebKit::WebCompositionUnderline, so that we can do reinterpret_cast safely.
1570 COMPILE_ASSERT(sizeof(ui::CompositionUnderline) ==
1571 sizeof(WebKit::WebCompositionUnderline),
1572 ui_CompositionUnderline__WebKit_WebCompositionUnderline_diff);
1574 // TODO(suzhe): convert both renderer_host and renderer to use
1575 // ui::CompositionText.
1576 const std::vector<WebKit::WebCompositionUnderline>& underlines =
1577 reinterpret_cast<const std::vector<WebKit::WebCompositionUnderline>&>(
1578 composition.underlines);
1580 // TODO(suzhe): due to a bug of webkit, we can't use selection range with
1581 // composition string. See: https://bugs.webkit.org/show_bug.cgi?id=37788
1582 host_->ImeSetComposition(composition.text, underlines,
1583 composition.selection.end(),
1584 composition.selection.end());
1586 has_composition_text_ = !composition.text.empty();
1589 void RenderWidgetHostViewAura::ConfirmCompositionText() {
1590 if (host_ && has_composition_text_)
1591 host_->ImeConfirmComposition();
1592 has_composition_text_ = false;
1595 void RenderWidgetHostViewAura::ClearCompositionText() {
1596 if (host_ && has_composition_text_)
1597 host_->ImeCancelComposition();
1598 has_composition_text_ = false;
1601 void RenderWidgetHostViewAura::InsertText(const string16& text) {
1602 DCHECK(text_input_type_ != ui::TEXT_INPUT_TYPE_NONE);
1603 if (host_)
1604 host_->ImeConfirmComposition(text);
1605 has_composition_text_ = false;
1608 void RenderWidgetHostViewAura::InsertChar(char16 ch, int flags) {
1609 if (popup_child_host_view_ && popup_child_host_view_->NeedsInputGrab()) {
1610 popup_child_host_view_->InsertChar(ch, flags);
1611 return;
1614 if (host_) {
1615 double now = ui::EventTimeForNow().InSecondsF();
1616 // Send a WebKit::WebInputEvent::Char event to |host_|.
1617 NativeWebKeyboardEvent webkit_event(ui::ET_KEY_PRESSED,
1618 true /* is_char */,
1620 flags,
1621 now);
1622 host_->ForwardKeyboardEvent(webkit_event);
1626 ui::TextInputType RenderWidgetHostViewAura::GetTextInputType() const {
1627 return text_input_type_;
1630 bool RenderWidgetHostViewAura::CanComposeInline() const {
1631 return can_compose_inline_;
1634 gfx::Rect RenderWidgetHostViewAura::ConvertRectToScreen(const gfx::Rect& rect) {
1635 gfx::Point origin = rect.origin();
1636 gfx::Point end = gfx::Point(rect.right(), rect.bottom());
1638 aura::RootWindow* root_window = window_->GetRootWindow();
1639 if (root_window) {
1640 aura::client::ScreenPositionClient* screen_position_client =
1641 aura::client::GetScreenPositionClient(root_window);
1642 screen_position_client->ConvertPointToScreen(window_, &origin);
1643 screen_position_client->ConvertPointToScreen(window_, &end);
1644 return gfx::Rect(origin.x(),
1645 origin.y(),
1646 end.x() - origin.x(),
1647 end.y() - origin.y());
1650 return rect;
1653 gfx::Rect RenderWidgetHostViewAura::GetCaretBounds() {
1654 const gfx::Rect rect =
1655 gfx::UnionRects(selection_anchor_rect_, selection_focus_rect_);
1656 return ConvertRectToScreen(rect);
1659 bool RenderWidgetHostViewAura::GetCompositionCharacterBounds(uint32 index,
1660 gfx::Rect* rect) {
1661 DCHECK(rect);
1662 if (index >= composition_character_bounds_.size())
1663 return false;
1664 *rect = ConvertRectToScreen(composition_character_bounds_[index]);
1665 return true;
1668 bool RenderWidgetHostViewAura::HasCompositionText() {
1669 return has_composition_text_;
1672 bool RenderWidgetHostViewAura::GetTextRange(ui::Range* range) {
1673 range->set_start(selection_text_offset_);
1674 range->set_end(selection_text_offset_ + selection_text_.length());
1675 return true;
1678 bool RenderWidgetHostViewAura::GetCompositionTextRange(ui::Range* range) {
1679 // TODO(suzhe): implement this method when fixing http://crbug.com/55130.
1680 NOTIMPLEMENTED();
1681 return false;
1684 bool RenderWidgetHostViewAura::GetSelectionRange(ui::Range* range) {
1685 range->set_start(selection_range_.start());
1686 range->set_end(selection_range_.end());
1687 return true;
1690 bool RenderWidgetHostViewAura::SetSelectionRange(const ui::Range& range) {
1691 // TODO(suzhe): implement this method when fixing http://crbug.com/55130.
1692 NOTIMPLEMENTED();
1693 return false;
1696 bool RenderWidgetHostViewAura::DeleteRange(const ui::Range& range) {
1697 // TODO(suzhe): implement this method when fixing http://crbug.com/55130.
1698 NOTIMPLEMENTED();
1699 return false;
1702 bool RenderWidgetHostViewAura::GetTextFromRange(
1703 const ui::Range& range,
1704 string16* text) {
1705 ui::Range selection_text_range(selection_text_offset_,
1706 selection_text_offset_ + selection_text_.length());
1708 if (!selection_text_range.Contains(range)) {
1709 text->clear();
1710 return false;
1712 if (selection_text_range.EqualsIgnoringDirection(range)) {
1713 // Avoid calling substr whose performance is low.
1714 *text = selection_text_;
1715 } else {
1716 *text = selection_text_.substr(
1717 range.GetMin() - selection_text_offset_,
1718 range.length());
1720 return true;
1723 void RenderWidgetHostViewAura::OnInputMethodChanged() {
1724 if (!host_)
1725 return;
1727 if (GetInputMethod())
1728 host_->SetInputMethodActive(GetInputMethod()->IsActive());
1730 // TODO(suzhe): implement the newly added “locale” property of HTML DOM
1731 // TextEvent.
1734 bool RenderWidgetHostViewAura::ChangeTextDirectionAndLayoutAlignment(
1735 base::i18n::TextDirection direction) {
1736 if (!host_)
1737 return false;
1738 host_->UpdateTextDirection(
1739 direction == base::i18n::RIGHT_TO_LEFT ?
1740 WebKit::WebTextDirectionRightToLeft :
1741 WebKit::WebTextDirectionLeftToRight);
1742 host_->NotifyTextDirection();
1743 return true;
1746 void RenderWidgetHostViewAura::ExtendSelectionAndDelete(
1747 size_t before, size_t after) {
1748 // TODO(horo): implement this method if it is required.
1749 // http://crbug.com/149155
1750 NOTIMPLEMENTED();
1753 ////////////////////////////////////////////////////////////////////////////////
1754 // RenderWidgetHostViewAura, gfx::DisplayObserver implementation:
1756 void RenderWidgetHostViewAura::OnDisplayBoundsChanged(
1757 const gfx::Display& display) {
1758 gfx::Screen* screen = gfx::Screen::GetScreenFor(window_);
1759 if (display.id() == screen->GetDisplayNearestWindow(window_).id()) {
1760 UpdateScreenInfo(window_);
1764 void RenderWidgetHostViewAura::OnDisplayAdded(
1765 const gfx::Display& new_display) {
1768 void RenderWidgetHostViewAura::OnDisplayRemoved(
1769 const gfx::Display& old_display) {
1772 ////////////////////////////////////////////////////////////////////////////////
1773 // RenderWidgetHostViewAura, aura::WindowDelegate implementation:
1775 gfx::Size RenderWidgetHostViewAura::GetMinimumSize() const {
1776 return gfx::Size();
1779 gfx::Size RenderWidgetHostViewAura::GetMaximumSize() const {
1780 return gfx::Size();
1783 void RenderWidgetHostViewAura::OnBoundsChanged(const gfx::Rect& old_bounds,
1784 const gfx::Rect& new_bounds) {
1785 // We care about this only in fullscreen mode, where there is no
1786 // WebContentsViewAura. We are sized via SetSize() or SetBounds() by
1787 // WebContentsViewAura in other cases.
1788 if (is_fullscreen_)
1789 SetSize(new_bounds.size());
1792 gfx::NativeCursor RenderWidgetHostViewAura::GetCursor(const gfx::Point& point) {
1793 if (mouse_locked_)
1794 return ui::kCursorNone;
1795 return current_cursor_.GetNativeCursor();
1798 int RenderWidgetHostViewAura::GetNonClientComponent(
1799 const gfx::Point& point) const {
1800 return HTCLIENT;
1803 bool RenderWidgetHostViewAura::ShouldDescendIntoChildForEventHandling(
1804 aura::Window* child,
1805 const gfx::Point& location) {
1806 return true;
1809 bool RenderWidgetHostViewAura::CanFocus() {
1810 return popup_type_ == WebKit::WebPopupTypeNone;
1813 void RenderWidgetHostViewAura::OnCaptureLost() {
1814 host_->LostCapture();
1817 void RenderWidgetHostViewAura::OnPaint(gfx::Canvas* canvas) {
1818 paint_canvas_ = canvas;
1819 BackingStore* backing_store = host_->GetBackingStore(true);
1820 paint_canvas_ = NULL;
1821 if (backing_store) {
1822 static_cast<BackingStoreAura*>(backing_store)->SkiaShowRect(gfx::Point(),
1823 canvas);
1824 if (paint_observer_)
1825 paint_observer_->OnPaintComplete();
1826 } else if (aura::Env::GetInstance()->render_white_bg()) {
1827 canvas->DrawColor(SK_ColorWHITE);
1831 void RenderWidgetHostViewAura::OnDeviceScaleFactorChanged(
1832 float device_scale_factor) {
1833 if (!host_)
1834 return;
1836 device_scale_factor_ = device_scale_factor;
1837 BackingStoreAura* backing_store = static_cast<BackingStoreAura*>(
1838 host_->GetBackingStore(false));
1839 if (backing_store) // NULL in hardware path.
1840 backing_store->ScaleFactorChanged(device_scale_factor);
1842 UpdateScreenInfo(window_);
1843 host_->NotifyScreenInfoChanged();
1844 current_cursor_.SetDeviceScaleFactor(device_scale_factor);
1847 void RenderWidgetHostViewAura::OnWindowDestroying() {
1848 #if defined(OS_WIN)
1849 HWND parent = NULL;
1850 // If the tab was hidden and it's closed, host_->is_hidden would have been
1851 // reset to false in RenderWidgetHostImpl::RendererExited.
1852 if (!window_->GetRootWindow() || host_->is_hidden()) {
1853 parent = ui::GetHiddenWindow();
1854 } else {
1855 parent = window_->GetRootWindow()->GetAcceleratedWidget();
1857 LPARAM lparam = reinterpret_cast<LPARAM>(this);
1858 EnumChildWindows(parent, WindowDestroyingCallback, lparam);
1859 #endif
1862 void RenderWidgetHostViewAura::OnWindowDestroyed() {
1863 host_->ViewDestroyed();
1864 delete this;
1867 void RenderWidgetHostViewAura::OnWindowTargetVisibilityChanged(bool visible) {
1870 bool RenderWidgetHostViewAura::HasHitTestMask() const {
1871 return false;
1874 void RenderWidgetHostViewAura::GetHitTestMask(gfx::Path* mask) const {
1877 scoped_refptr<ui::Texture> RenderWidgetHostViewAura::CopyTexture() {
1878 if (!host_->is_accelerated_compositing_active())
1879 return scoped_refptr<ui::Texture>();
1881 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
1882 GLHelper* gl_helper = factory->GetGLHelper();
1883 if (!gl_helper)
1884 return scoped_refptr<ui::Texture>();
1886 if (!current_surface_)
1887 return scoped_refptr<ui::Texture>();
1889 WebKit::WebGLId texture_id =
1890 gl_helper->CopyTexture(current_surface_->PrepareTexture(),
1891 current_surface_->size());
1892 if (!texture_id)
1893 return scoped_refptr<ui::Texture>();
1895 return scoped_refptr<ui::Texture>(
1896 factory->CreateOwnedTexture(
1897 current_surface_->size(), device_scale_factor_, texture_id));
1900 ////////////////////////////////////////////////////////////////////////////////
1901 // RenderWidgetHostViewAura, ui::EventHandler implementation:
1903 void RenderWidgetHostViewAura::OnKeyEvent(ui::KeyEvent* event) {
1904 TRACE_EVENT0("browser", "RenderWidgetHostViewAura::OnKeyEvent");
1905 if (popup_child_host_view_ && popup_child_host_view_->NeedsInputGrab()) {
1906 popup_child_host_view_->OnKeyEvent(event);
1907 if (event->handled())
1908 return;
1911 // We need to handle the Escape key for Pepper Flash.
1912 if (is_fullscreen_ && event->key_code() == ui::VKEY_ESCAPE) {
1913 // Focus the window we were created from.
1914 if (host_tracker_.get() && !host_tracker_->windows().empty()) {
1915 aura::Window* host = *(host_tracker_->windows().begin());
1916 aura::client::FocusClient* client = aura::client::GetFocusClient(host);
1917 if (client)
1918 host->Focus();
1920 if (!in_shutdown_) {
1921 in_shutdown_ = true;
1922 host_->Shutdown();
1924 } else {
1925 // We don't have to communicate with an input method here.
1926 if (!event->HasNativeEvent()) {
1927 NativeWebKeyboardEvent webkit_event(
1928 event->type(),
1929 event->is_char(),
1930 event->is_char() ? event->GetCharacter() : event->key_code(),
1931 event->flags(),
1932 ui::EventTimeForNow().InSecondsF());
1933 host_->ForwardKeyboardEvent(webkit_event);
1934 } else {
1935 NativeWebKeyboardEvent webkit_event(event);
1936 host_->ForwardKeyboardEvent(webkit_event);
1939 event->SetHandled();
1942 void RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent* event) {
1943 TRACE_EVENT0("browser", "RenderWidgetHostViewAura::OnMouseEvent");
1945 if (mouse_locked_) {
1946 // Hide the cursor if someone else has shown it.
1947 aura::client::CursorClient* cursor_client =
1948 aura::client::GetCursorClient(window_->GetRootWindow());
1949 if (cursor_client && cursor_client->IsCursorVisible())
1950 cursor_client->DisableMouseEvents();
1952 WebKit::WebMouseEvent mouse_event = MakeWebMouseEvent(event);
1953 gfx::Point center(gfx::Rect(window_->bounds().size()).CenterPoint());
1955 bool is_move_to_center_event = (event->type() == ui::ET_MOUSE_MOVED ||
1956 event->type() == ui::ET_MOUSE_DRAGGED) &&
1957 mouse_event.x == center.x() && mouse_event.y == center.y();
1959 ModifyEventMovementAndCoords(&mouse_event);
1961 bool should_not_forward = is_move_to_center_event && synthetic_move_sent_;
1962 if (should_not_forward) {
1963 synthetic_move_sent_ = false;
1964 } else {
1965 // Check if the mouse has reached the border and needs to be centered.
1966 if (ShouldMoveToCenter()) {
1967 synthetic_move_sent_ = true;
1968 window_->MoveCursorTo(center);
1971 // Forward event to renderer.
1972 if (CanRendererHandleEvent(event) &&
1973 !(event->flags() & ui::EF_FROM_TOUCH))
1974 host_->ForwardMouseEvent(mouse_event);
1976 return;
1979 // As the overscroll is handled during scroll events from the trackpad, the
1980 // RWHVA window is transformed by the overscroll controller. This transform
1981 // triggers a synthetic mouse-move event to be generated (by the aura
1982 // RootWindow). But this event interferes with the overscroll gesture. So,
1983 // ignore such synthetic mouse-move events if an overscroll gesture is in
1984 // progress.
1985 if (host_->overscroll_controller() &&
1986 host_->overscroll_controller()->overscroll_mode() != OVERSCROLL_NONE &&
1987 event->flags() & ui::EF_IS_SYNTHESIZED &&
1988 (event->type() == ui::ET_MOUSE_ENTERED ||
1989 event->type() == ui::ET_MOUSE_EXITED ||
1990 event->type() == ui::ET_MOUSE_MOVED)) {
1991 event->StopPropagation();
1992 return;
1995 if (event->type() == ui::ET_MOUSEWHEEL) {
1996 #if defined(OS_WIN)
1997 // We get mouse wheel/scroll messages even if we are not in the foreground.
1998 // So here we check if we have any owned popup windows in the foreground and
1999 // dismiss them.
2000 aura::RootWindow* root_window = window_->GetRootWindow();
2001 if (root_window) {
2002 HWND parent = root_window->GetAcceleratedWidget();
2003 HWND toplevel_hwnd = ::GetAncestor(parent, GA_ROOT);
2004 EnumThreadWindows(GetCurrentThreadId(),
2005 DismissOwnedPopups,
2006 reinterpret_cast<LPARAM>(toplevel_hwnd));
2008 #endif
2009 WebKit::WebMouseWheelEvent mouse_wheel_event =
2010 MakeWebMouseWheelEvent(static_cast<ui::MouseWheelEvent*>(event));
2011 if (mouse_wheel_event.deltaX != 0 || mouse_wheel_event.deltaY != 0)
2012 host_->ForwardWheelEvent(mouse_wheel_event);
2013 } else if (CanRendererHandleEvent(event) &&
2014 !(event->flags() & ui::EF_FROM_TOUCH)) {
2015 WebKit::WebMouseEvent mouse_event = MakeWebMouseEvent(event);
2016 ModifyEventMovementAndCoords(&mouse_event);
2017 host_->ForwardMouseEvent(mouse_event);
2020 switch (event->type()) {
2021 case ui::ET_MOUSE_PRESSED:
2022 window_->SetCapture();
2023 // Confirm existing composition text on mouse click events, to make sure
2024 // the input caret won't be moved with an ongoing composition text.
2025 FinishImeCompositionSession();
2026 break;
2027 case ui::ET_MOUSE_RELEASED:
2028 window_->ReleaseCapture();
2029 break;
2030 default:
2031 break;
2034 // Needed to propagate mouse event to native_tab_contents_view_aura.
2035 // TODO(pkotwicz): Find a better way of doing this.
2036 if (window_->parent()->delegate() && !(event->flags() & ui::EF_FROM_TOUCH))
2037 window_->parent()->delegate()->OnMouseEvent(event);
2039 if (!IsXButtonUpEvent(event))
2040 event->SetHandled();
2043 void RenderWidgetHostViewAura::OnScrollEvent(ui::ScrollEvent* event) {
2044 TRACE_EVENT0("browser", "RenderWidgetHostViewAura::OnScrollEvent");
2045 if (event->type() == ui::ET_SCROLL) {
2046 if (event->finger_count() != 2)
2047 return;
2048 WebKit::WebGestureEvent gesture_event =
2049 MakeWebGestureEventFlingCancel();
2050 host_->ForwardGestureEvent(gesture_event);
2051 WebKit::WebMouseWheelEvent mouse_wheel_event =
2052 MakeWebMouseWheelEvent(static_cast<ui::ScrollEvent*>(event));
2053 host_->ForwardWheelEvent(mouse_wheel_event);
2054 RecordAction(UserMetricsAction("TrackpadScroll"));
2055 } else if (event->type() == ui::ET_SCROLL_FLING_START ||
2056 event->type() == ui::ET_SCROLL_FLING_CANCEL) {
2057 WebKit::WebGestureEvent gesture_event =
2058 MakeWebGestureEvent(static_cast<ui::ScrollEvent*>(event));
2059 host_->ForwardGestureEvent(gesture_event);
2060 if (event->type() == ui::ET_SCROLL_FLING_START)
2061 RecordAction(UserMetricsAction("TrackpadScrollFling"));
2064 event->SetHandled();
2067 void RenderWidgetHostViewAura::OnTouchEvent(ui::TouchEvent* event) {
2068 TRACE_EVENT0("browser", "RenderWidgetHostViewAura::OnTouchEvent");
2069 // Update the touch event first.
2070 WebKit::WebTouchPoint* point = UpdateWebTouchEventFromUIEvent(*event,
2071 &touch_event_);
2073 // Forward the touch event only if a touch point was updated, and there's a
2074 // touch-event handler in the page, and no other touch-event is in the queue.
2075 // It is important to always consume the event if there is a touch-event
2076 // handler in the page, or some touch-event is already in the queue, even if
2077 // no point has been updated, to make sure that this event does not get
2078 // processed by the gesture recognizer before the events in the queue.
2079 if (host_->ShouldForwardTouchEvent())
2080 event->StopPropagation();
2082 if (point) {
2083 if (host_->ShouldForwardTouchEvent())
2084 host_->ForwardTouchEvent(touch_event_);
2085 UpdateWebTouchEventAfterDispatch(&touch_event_, point);
2089 void RenderWidgetHostViewAura::OnGestureEvent(ui::GestureEvent* event) {
2090 TRACE_EVENT0("browser", "RenderWidgetHostViewAura::OnGestureEvent");
2091 // Pinch gestures are currently disabled by default. See crbug.com/128477.
2092 if ((event->type() == ui::ET_GESTURE_PINCH_BEGIN ||
2093 event->type() == ui::ET_GESTURE_PINCH_UPDATE ||
2094 event->type() == ui::ET_GESTURE_PINCH_END) && !ShouldSendPinchGesture()) {
2095 event->SetHandled();
2096 return;
2099 RenderViewHostDelegate* delegate = NULL;
2100 if (popup_type_ == WebKit::WebPopupTypeNone && !is_fullscreen_)
2101 delegate = RenderViewHost::From(host_)->GetDelegate();
2103 if (delegate && event->type() == ui::ET_GESTURE_BEGIN &&
2104 event->details().touch_points() == 1) {
2105 delegate->HandleGestureBegin();
2108 WebKit::WebGestureEvent gesture = MakeWebGestureEvent(event);
2109 if (event->type() == ui::ET_GESTURE_TAP_DOWN) {
2110 // Webkit does not stop a fling-scroll on tap-down. So explicitly send an
2111 // event to stop any in-progress flings.
2112 WebKit::WebGestureEvent fling_cancel = gesture;
2113 fling_cancel.type = WebKit::WebInputEvent::GestureFlingCancel;
2114 fling_cancel.sourceDevice = WebKit::WebGestureEvent::Touchscreen;
2115 host_->ForwardGestureEvent(fling_cancel);
2118 if (gesture.type != WebKit::WebInputEvent::Undefined) {
2119 host_->ForwardGestureEvent(gesture);
2121 if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN ||
2122 event->type() == ui::ET_GESTURE_SCROLL_UPDATE ||
2123 event->type() == ui::ET_GESTURE_SCROLL_END) {
2124 RecordAction(UserMetricsAction("TouchscreenScroll"));
2125 } else if (event->type() == ui::ET_SCROLL_FLING_START) {
2126 RecordAction(UserMetricsAction("TouchscreenScrollFling"));
2130 if (delegate && event->type() == ui::ET_GESTURE_END &&
2131 event->details().touch_points() == 1) {
2132 delegate->HandleGestureEnd();
2135 // If a gesture is not processed by the webpage, then WebKit processes it
2136 // (e.g. generates synthetic mouse events).
2137 event->SetHandled();
2140 ////////////////////////////////////////////////////////////////////////////////
2141 // RenderWidgetHostViewAura, aura::client::ActivationDelegate implementation:
2143 bool RenderWidgetHostViewAura::ShouldActivate() const {
2144 aura::RootWindow* root_window = window_->GetRootWindow();
2145 if (!root_window)
2146 return true;
2147 const ui::Event* event = root_window->current_event();
2148 if (!event)
2149 return true;
2150 return is_fullscreen_;
2153 ////////////////////////////////////////////////////////////////////////////////
2154 // RenderWidgetHostViewAura,
2155 // aura::client::ActivationChangeObserver implementation:
2157 void RenderWidgetHostViewAura::OnWindowActivated(aura::Window* gained_active,
2158 aura::Window* lost_active) {
2159 DCHECK(window_ == gained_active || window_ == lost_active);
2160 if (window_ == gained_active) {
2161 const ui::Event* event = window_->GetRootWindow()->current_event();
2162 if (event && PointerEventActivates(*event))
2163 host_->OnPointerEventActivate();
2167 ////////////////////////////////////////////////////////////////////////////////
2168 // RenderWidgetHostViewAura, aura::client::FocusChangeObserver implementation:
2170 void RenderWidgetHostViewAura::OnWindowFocused(aura::Window* gained_focus,
2171 aura::Window* lost_focus) {
2172 DCHECK(window_ == gained_focus || window_ == lost_focus);
2173 if (window_ == gained_focus) {
2174 // We need to honor input bypass if the associated tab is does not want
2175 // input. This gives the current focused window a chance to be the text
2176 // input client and handle events.
2177 if (host_->ignore_input_events())
2178 return;
2180 host_->GotFocus();
2181 host_->SetActive(true);
2183 ui::InputMethod* input_method = GetInputMethod();
2184 if (input_method) {
2185 // Ask the system-wide IME to send all TextInputClient messages to |this|
2186 // object.
2187 input_method->SetFocusedTextInputClient(this);
2188 host_->SetInputMethodActive(input_method->IsActive());
2190 // Often the application can set focus to the view in response to a key
2191 // down. However the following char event shouldn't be sent to the web
2192 // page.
2193 host_->SuppressNextCharEvents();
2194 } else {
2195 host_->SetInputMethodActive(false);
2197 } else if (window_ == lost_focus) {
2198 host_->SetActive(false);
2199 host_->Blur();
2201 DetachFromInputMethod();
2202 host_->SetInputMethodActive(false);
2204 // If we lose the focus while fullscreen, close the window; Pepper Flash
2205 // won't do it for us (unlike NPAPI Flash).
2206 if (is_fullscreen_ && !in_shutdown_) {
2207 in_shutdown_ = true;
2208 host_->Shutdown();
2213 ////////////////////////////////////////////////////////////////////////////////
2214 // RenderWidgetHostViewAura, aura::RootWindowObserver implementation:
2216 void RenderWidgetHostViewAura::OnRootWindowMoved(const aura::RootWindow* root,
2217 const gfx::Point& new_origin) {
2218 UpdateScreenInfo(window_);
2221 ////////////////////////////////////////////////////////////////////////////////
2222 // RenderWidgetHostViewAura, ui::CompositorObserver implementation:
2224 void RenderWidgetHostViewAura::OnCompositingDidCommit(
2225 ui::Compositor* compositor) {
2226 if (can_lock_compositor_ == NO_PENDING_COMMIT) {
2227 can_lock_compositor_ = YES;
2228 for (ResizeLockList::iterator it = resize_locks_.begin();
2229 it != resize_locks_.end(); ++it)
2230 if ((*it)->GrabDeferredLock())
2231 can_lock_compositor_ = YES_DID_LOCK;
2233 RunCompositingDidCommitCallbacks();
2234 locks_pending_commit_.clear();
2237 void RenderWidgetHostViewAura::OnCompositingStarted(
2238 ui::Compositor* compositor, base::TimeTicks start_time) {
2239 last_draw_ended_ = start_time;
2242 void RenderWidgetHostViewAura::OnCompositingEnded(
2243 ui::Compositor* compositor) {
2244 if (paint_observer_)
2245 paint_observer_->OnCompositingComplete();
2248 void RenderWidgetHostViewAura::OnCompositingAborted(
2249 ui::Compositor* compositor) {
2252 void RenderWidgetHostViewAura::OnCompositingLockStateChanged(
2253 ui::Compositor* compositor) {
2254 // A compositor lock that is part of a resize lock timed out. We
2255 // should display a renderer frame.
2256 if (!compositor->IsLocked() && can_lock_compositor_ == YES_DID_LOCK) {
2257 can_lock_compositor_ = NO_PENDING_RENDERER_FRAME;
2261 void RenderWidgetHostViewAura::OnUpdateVSyncParameters(
2262 ui::Compositor* compositor,
2263 base::TimeTicks timebase,
2264 base::TimeDelta interval) {
2265 if (IsShowing() && !last_draw_ended_.is_null())
2266 host_->UpdateVSyncParameters(last_draw_ended_, interval);
2269 ////////////////////////////////////////////////////////////////////////////////
2270 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation:
2272 void RenderWidgetHostViewAura::OnLostResources() {
2273 current_surface_ = NULL;
2274 UpdateExternalTexture();
2275 locks_pending_commit_.clear();
2277 // Make sure all ImageTransportClients are deleted now that the context those
2278 // are using is becoming invalid. This sends pending ACKs and needs to happen
2279 // after calling UpdateExternalTexture() which syncs with the impl thread.
2280 RunCompositingDidCommitCallbacks();
2282 DCHECK(!shared_surface_handle_.is_null());
2283 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
2284 factory->DestroySharedSurfaceHandle(shared_surface_handle_);
2285 shared_surface_handle_ = factory->CreateSharedSurfaceHandle();
2286 host_->CompositingSurfaceUpdated();
2287 host_->ScheduleComposite();
2290 ////////////////////////////////////////////////////////////////////////////////
2291 // RenderWidgetHostViewAura, private:
2293 RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
2294 if (paint_observer_)
2295 paint_observer_->OnViewDestroyed();
2296 if (!shared_surface_handle_.is_null()) {
2297 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
2298 factory->DestroySharedSurfaceHandle(shared_surface_handle_);
2299 factory->RemoveObserver(this);
2301 window_observer_.reset();
2302 #if defined(OS_WIN)
2303 transient_observer_.reset();
2304 #endif
2305 if (window_->GetRootWindow())
2306 window_->GetRootWindow()->RemoveRootWindowObserver(this);
2307 UnlockMouse();
2308 if (popup_type_ != WebKit::WebPopupTypeNone && popup_parent_host_view_) {
2309 DCHECK(popup_parent_host_view_->popup_child_host_view_ == NULL ||
2310 popup_parent_host_view_->popup_child_host_view_ == this);
2311 popup_parent_host_view_->popup_child_host_view_ = NULL;
2313 if (popup_child_host_view_) {
2314 DCHECK(popup_child_host_view_->popup_parent_host_view_ == NULL ||
2315 popup_child_host_view_->popup_parent_host_view_ == this);
2316 popup_child_host_view_->popup_parent_host_view_ = NULL;
2318 aura::client::SetTooltipText(window_, NULL);
2319 gfx::Screen::GetScreenFor(window_)->RemoveObserver(this);
2321 // This call is usually no-op since |this| object is already removed from the
2322 // Aura root window and we don't have a way to get an input method object
2323 // associated with the window, but just in case.
2324 DetachFromInputMethod();
2327 void RenderWidgetHostViewAura::UpdateCursorIfOverSelf() {
2328 const gfx::Point screen_point =
2329 gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint();
2330 aura::RootWindow* root_window = window_->GetRootWindow();
2331 if (!root_window)
2332 return;
2334 gfx::Rect screen_rect = GetViewBounds();
2335 gfx::Point local_point = screen_point;
2336 local_point.Offset(-screen_rect.x(), -screen_rect.y());
2338 if (root_window->GetEventHandlerForPoint(local_point) != window_)
2339 return;
2341 gfx::NativeCursor cursor = current_cursor_.GetNativeCursor();
2342 // Do not show loading cursor when the cursor is currently hidden.
2343 if (is_loading_ && cursor != ui::kCursorNone)
2344 cursor = ui::kCursorPointer;
2346 aura::client::CursorClient* cursor_client =
2347 aura::client::GetCursorClient(root_window);
2348 if (cursor_client)
2349 cursor_client->SetCursor(cursor);
2352 ui::InputMethod* RenderWidgetHostViewAura::GetInputMethod() const {
2353 aura::RootWindow* root_window = window_->GetRootWindow();
2354 if (!root_window)
2355 return NULL;
2356 return root_window->GetProperty(aura::client::kRootWindowInputMethodKey);
2359 bool RenderWidgetHostViewAura::NeedsInputGrab() {
2360 return popup_type_ == WebKit::WebPopupTypeSelect;
2363 void RenderWidgetHostViewAura::FinishImeCompositionSession() {
2364 if (!has_composition_text_)
2365 return;
2366 if (host_)
2367 host_->ImeConfirmComposition();
2368 ImeCancelComposition();
2371 void RenderWidgetHostViewAura::ModifyEventMovementAndCoords(
2372 WebKit::WebMouseEvent* event) {
2373 // If the mouse has just entered, we must report zero movementX/Y. Hence we
2374 // reset any global_mouse_position set previously.
2375 if (event->type == WebKit::WebInputEvent::MouseEnter ||
2376 event->type == WebKit::WebInputEvent::MouseLeave)
2377 global_mouse_position_.SetPoint(event->globalX, event->globalY);
2379 // Movement is computed by taking the difference of the new cursor position
2380 // and the previous. Under mouse lock the cursor will be warped back to the
2381 // center so that we are not limited by clipping boundaries.
2382 // We do not measure movement as the delta from cursor to center because
2383 // we may receive more mouse movement events before our warp has taken
2384 // effect.
2385 event->movementX = event->globalX - global_mouse_position_.x();
2386 event->movementY = event->globalY - global_mouse_position_.y();
2388 global_mouse_position_.SetPoint(event->globalX, event->globalY);
2390 // Under mouse lock, coordinates of mouse are locked to what they were when
2391 // mouse lock was entered.
2392 if (mouse_locked_) {
2393 event->x = unlocked_mouse_position_.x();
2394 event->y = unlocked_mouse_position_.y();
2395 event->windowX = unlocked_mouse_position_.x();
2396 event->windowY = unlocked_mouse_position_.y();
2397 event->globalX = unlocked_global_mouse_position_.x();
2398 event->globalY = unlocked_global_mouse_position_.y();
2399 } else {
2400 unlocked_mouse_position_.SetPoint(event->windowX, event->windowY);
2401 unlocked_global_mouse_position_.SetPoint(event->globalX, event->globalY);
2405 void RenderWidgetHostViewAura::SchedulePaintIfNotInClip(
2406 const gfx::Rect& rect,
2407 const gfx::Rect& clip) {
2408 if (!clip.IsEmpty()) {
2409 gfx::Rect to_paint = gfx::SubtractRects(rect, clip);
2410 if (!to_paint.IsEmpty())
2411 window_->SchedulePaintInRect(to_paint);
2412 } else {
2413 window_->SchedulePaintInRect(rect);
2417 bool RenderWidgetHostViewAura::ShouldMoveToCenter() {
2418 gfx::Rect rect = window_->bounds();
2419 int border_x = rect.width() * kMouseLockBorderPercentage / 100;
2420 int border_y = rect.height() * kMouseLockBorderPercentage / 100;
2422 return global_mouse_position_.x() < rect.x() + border_x ||
2423 global_mouse_position_.x() > rect.right() - border_x ||
2424 global_mouse_position_.y() < rect.y() + border_y ||
2425 global_mouse_position_.y() > rect.bottom() - border_y;
2428 void RenderWidgetHostViewAura::RunCompositingDidCommitCallbacks() {
2429 for (std::vector<base::Closure>::const_iterator
2430 it = on_compositing_did_commit_callbacks_.begin();
2431 it != on_compositing_did_commit_callbacks_.end(); ++it) {
2432 it->Run();
2434 on_compositing_did_commit_callbacks_.clear();
2437 void RenderWidgetHostViewAura::AddedToRootWindow() {
2438 window_->GetRootWindow()->AddRootWindowObserver(this);
2439 host_->ParentChanged(GetNativeViewId());
2440 UpdateScreenInfo(window_);
2441 if (popup_type_ != WebKit::WebPopupTypeNone)
2442 event_filter_for_popup_exit_.reset(new EventFilterForPopupExit(this));
2445 void RenderWidgetHostViewAura::RemovingFromRootWindow() {
2446 event_filter_for_popup_exit_.reset();
2447 window_->GetRootWindow()->RemoveRootWindowObserver(this);
2448 host_->ParentChanged(0);
2449 // We are about to disconnect ourselves from the compositor, we need to issue
2450 // the callbacks now, because we won't get notified when the frame is done.
2451 // TODO(piman): this might in theory cause a race where the GPU process starts
2452 // drawing to the buffer we haven't yet displayed. This will only show for 1
2453 // frame though, because we will reissue a new frame right away without that
2454 // composited data.
2455 ui::Compositor* compositor = GetCompositor();
2456 RunCompositingDidCommitCallbacks();
2457 locks_pending_commit_.clear();
2458 if (compositor && compositor->HasObserver(this))
2459 compositor->RemoveObserver(this);
2460 DetachFromInputMethod();
2463 ui::Compositor* RenderWidgetHostViewAura::GetCompositor() {
2464 aura::RootWindow* root_window = window_->GetRootWindow();
2465 return root_window ? root_window->compositor() : NULL;
2468 void RenderWidgetHostViewAura::DetachFromInputMethod() {
2469 ui::InputMethod* input_method = GetInputMethod();
2470 if (input_method && input_method->GetTextInputClient() == this)
2471 input_method->SetFocusedTextInputClient(NULL);
2474 ////////////////////////////////////////////////////////////////////////////////
2475 // RenderWidgetHostView, public:
2477 // static
2478 RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget(
2479 RenderWidgetHost* widget) {
2480 return new RenderWidgetHostViewAura(widget);
2483 // static
2484 void RenderWidgetHostViewPort::GetDefaultScreenInfo(WebScreenInfo* results) {
2485 GetScreenInfoForWindow(results, NULL);
2488 } // namespace content