Home | History | Annotate | Download | only in renderer_host
      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/renderer_host/render_widget_host_view_aura.h"
      6 
      7 #include "base/auto_reset.h"
      8 #include "base/basictypes.h"
      9 #include "base/bind.h"
     10 #include "base/callback_helpers.h"
     11 #include "base/command_line.h"
     12 #include "base/debug/trace_event.h"
     13 #include "base/logging.h"
     14 #include "base/message_loop/message_loop.h"
     15 #include "base/strings/string_number_conversions.h"
     16 #include "cc/layers/layer.h"
     17 #include "cc/output/copy_output_request.h"
     18 #include "cc/output/copy_output_result.h"
     19 #include "cc/resources/texture_mailbox.h"
     20 #include "cc/trees/layer_tree_settings.h"
     21 #include "content/browser/accessibility/browser_accessibility_manager.h"
     22 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
     23 #include "content/browser/frame_host/frame_tree.h"
     24 #include "content/browser/frame_host/frame_tree_node.h"
     25 #include "content/browser/frame_host/render_frame_host_impl.h"
     26 #include "content/browser/gpu/compositor_util.h"
     27 #include "content/browser/renderer_host/compositor_resize_lock_aura.h"
     28 #include "content/browser/renderer_host/dip_util.h"
     29 #include "content/browser/renderer_host/input/synthetic_gesture_target_aura.h"
     30 #include "content/browser/renderer_host/overscroll_controller.h"
     31 #include "content/browser/renderer_host/render_view_host_delegate.h"
     32 #include "content/browser/renderer_host/render_view_host_impl.h"
     33 #include "content/browser/renderer_host/render_widget_host_impl.h"
     34 #include "content/browser/renderer_host/ui_events_helper.h"
     35 #include "content/browser/renderer_host/web_input_event_aura.h"
     36 #include "content/common/gpu/client/gl_helper.h"
     37 #include "content/common/gpu/gpu_messages.h"
     38 #include "content/common/view_messages.h"
     39 #include "content/public/browser/content_browser_client.h"
     40 #include "content/public/browser/overscroll_configuration.h"
     41 #include "content/public/browser/render_view_host.h"
     42 #include "content/public/browser/render_widget_host_view_frame_subscriber.h"
     43 #include "content/public/browser/user_metrics.h"
     44 #include "content/public/common/content_switches.h"
     45 #include "third_party/WebKit/public/platform/WebScreenInfo.h"
     46 #include "third_party/WebKit/public/web/WebCompositionUnderline.h"
     47 #include "third_party/WebKit/public/web/WebInputEvent.h"
     48 #include "ui/aura/client/aura_constants.h"
     49 #include "ui/aura/client/cursor_client.h"
     50 #include "ui/aura/client/cursor_client_observer.h"
     51 #include "ui/aura/client/focus_client.h"
     52 #include "ui/aura/client/screen_position_client.h"
     53 #include "ui/aura/client/window_tree_client.h"
     54 #include "ui/aura/env.h"
     55 #include "ui/aura/window.h"
     56 #include "ui/aura/window_event_dispatcher.h"
     57 #include "ui/aura/window_observer.h"
     58 #include "ui/aura/window_tracker.h"
     59 #include "ui/aura/window_tree_host.h"
     60 #include "ui/base/clipboard/scoped_clipboard_writer.h"
     61 #include "ui/base/hit_test.h"
     62 #include "ui/base/ime/input_method.h"
     63 #include "ui/base/ui_base_types.h"
     64 #include "ui/compositor/compositor_vsync_manager.h"
     65 #include "ui/events/event.h"
     66 #include "ui/events/event_utils.h"
     67 #include "ui/events/gestures/gesture_recognizer.h"
     68 #include "ui/gfx/canvas.h"
     69 #include "ui/gfx/display.h"
     70 #include "ui/gfx/rect_conversions.h"
     71 #include "ui/gfx/screen.h"
     72 #include "ui/gfx/size_conversions.h"
     73 #include "ui/gfx/skia_util.h"
     74 #include "ui/wm/public/activation_client.h"
     75 #include "ui/wm/public/scoped_tooltip_disabler.h"
     76 #include "ui/wm/public/tooltip_client.h"
     77 #include "ui/wm/public/transient_window_client.h"
     78 #include "ui/wm/public/window_types.h"
     79 
     80 #if defined(OS_WIN)
     81 #include "content/browser/accessibility/browser_accessibility_manager_win.h"
     82 #include "content/browser/accessibility/browser_accessibility_win.h"
     83 #include "content/browser/renderer_host/legacy_render_widget_host_win.h"
     84 #include "content/common/plugin_constants_win.h"
     85 #include "ui/base/win/hidden_window.h"
     86 #include "ui/gfx/gdi_util.h"
     87 #include "ui/gfx/win/dpi.h"
     88 #endif
     89 
     90 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
     91 #include "content/common/input_messages.h"
     92 #include "ui/events/linux/text_edit_command_auralinux.h"
     93 #include "ui/events/linux/text_edit_key_bindings_delegate_auralinux.h"
     94 #endif
     95 
     96 using gfx::RectToSkIRect;
     97 using gfx::SkIRectToRect;
     98 
     99 using blink::WebScreenInfo;
    100 using blink::WebInputEvent;
    101 using blink::WebGestureEvent;
    102 using blink::WebTouchEvent;
    103 
    104 namespace content {
    105 
    106 namespace {
    107 
    108 // In mouse lock mode, we need to prevent the (invisible) cursor from hitting
    109 // the border of the view, in order to get valid movement information. However,
    110 // forcing the cursor back to the center of the view after each mouse move
    111 // doesn't work well. It reduces the frequency of useful mouse move messages
    112 // significantly. Therefore, we move the cursor to the center of the view only
    113 // if it approaches the border. |kMouseLockBorderPercentage| specifies the width
    114 // of the border area, in percentage of the corresponding dimension.
    115 const int kMouseLockBorderPercentage = 15;
    116 
    117 // When accelerated compositing is enabled and a widget resize is pending,
    118 // we delay further resizes of the UI. The following constant is the maximum
    119 // length of time that we should delay further UI resizes while waiting for a
    120 // resized frame from a renderer.
    121 const int kResizeLockTimeoutMs = 67;
    122 
    123 #if defined(OS_WIN)
    124 // Used to associate a plugin HWND with its RenderWidgetHostViewAura instance.
    125 const wchar_t kWidgetOwnerProperty[] = L"RenderWidgetHostViewAuraOwner";
    126 
    127 BOOL CALLBACK WindowDestroyingCallback(HWND window, LPARAM param) {
    128   RenderWidgetHostViewAura* widget =
    129       reinterpret_cast<RenderWidgetHostViewAura*>(param);
    130   if (GetProp(window, kWidgetOwnerProperty) == widget) {
    131     // Properties set on HWNDs must be removed to avoid leaks.
    132     RemoveProp(window, kWidgetOwnerProperty);
    133     RenderWidgetHostViewBase::DetachPluginWindowsCallback(window);
    134   }
    135   return TRUE;
    136 }
    137 
    138 BOOL CALLBACK HideWindowsCallback(HWND window, LPARAM param) {
    139   RenderWidgetHostViewAura* widget =
    140       reinterpret_cast<RenderWidgetHostViewAura*>(param);
    141   if (GetProp(window, kWidgetOwnerProperty) == widget)
    142     SetParent(window, ui::GetHiddenWindow());
    143   return TRUE;
    144 }
    145 
    146 BOOL CALLBACK ShowWindowsCallback(HWND window, LPARAM param) {
    147   RenderWidgetHostViewAura* widget =
    148       reinterpret_cast<RenderWidgetHostViewAura*>(param);
    149 
    150   if (GetProp(window, kWidgetOwnerProperty) == widget &&
    151       widget->GetNativeView()->GetHost()) {
    152     HWND parent = widget->GetNativeView()->GetHost()->GetAcceleratedWidget();
    153     SetParent(window, parent);
    154   }
    155   return TRUE;
    156 }
    157 
    158 struct CutoutRectsParams {
    159   RenderWidgetHostViewAura* widget;
    160   std::vector<gfx::Rect> cutout_rects;
    161   std::map<HWND, WebPluginGeometry>* geometry;
    162 };
    163 
    164 // Used to update the region for the windowed plugin to draw in. We start with
    165 // the clip rect from the renderer, then remove the cutout rects from the
    166 // renderer, and then remove the transient windows from the root window and the
    167 // constrained windows from the parent window.
    168 BOOL CALLBACK SetCutoutRectsCallback(HWND window, LPARAM param) {
    169   CutoutRectsParams* params = reinterpret_cast<CutoutRectsParams*>(param);
    170 
    171   if (GetProp(window, kWidgetOwnerProperty) == params->widget) {
    172     // First calculate the offset of this plugin from the root window, since
    173     // the cutouts are relative to the root window.
    174     HWND parent =
    175         params->widget->GetNativeView()->GetHost()->GetAcceleratedWidget();
    176     POINT offset;
    177     offset.x = offset.y = 0;
    178     MapWindowPoints(window, parent, &offset, 1);
    179 
    180     // Now get the cached clip rect and cutouts for this plugin window that came
    181     // from the renderer.
    182     std::map<HWND, WebPluginGeometry>::iterator i = params->geometry->begin();
    183     while (i != params->geometry->end() &&
    184            i->second.window != window &&
    185            GetParent(i->second.window) != window) {
    186       ++i;
    187     }
    188 
    189     if (i == params->geometry->end()) {
    190       NOTREACHED();
    191       return TRUE;
    192     }
    193 
    194     HRGN hrgn = CreateRectRgn(i->second.clip_rect.x(),
    195                               i->second.clip_rect.y(),
    196                               i->second.clip_rect.right(),
    197                               i->second.clip_rect.bottom());
    198     // We start with the cutout rects that came from the renderer, then add the
    199     // ones that came from transient and constrained windows.
    200     std::vector<gfx::Rect> cutout_rects = i->second.cutout_rects;
    201     for (size_t i = 0; i < params->cutout_rects.size(); ++i) {
    202       gfx::Rect offset_cutout = params->cutout_rects[i];
    203       offset_cutout.Offset(-offset.x, -offset.y);
    204       cutout_rects.push_back(offset_cutout);
    205     }
    206     gfx::SubtractRectanglesFromRegion(hrgn, cutout_rects);
    207     // If we don't have any cutout rects then no point in messing with the
    208     // window region.
    209     if (cutout_rects.size())
    210       SetWindowRgn(window, hrgn, TRUE);
    211   }
    212   return TRUE;
    213 }
    214 
    215 // A callback function for EnumThreadWindows to enumerate and dismiss
    216 // any owned popup windows.
    217 BOOL CALLBACK DismissOwnedPopups(HWND window, LPARAM arg) {
    218   const HWND toplevel_hwnd = reinterpret_cast<HWND>(arg);
    219 
    220   if (::IsWindowVisible(window)) {
    221     const HWND owner = ::GetWindow(window, GW_OWNER);
    222     if (toplevel_hwnd == owner) {
    223       ::PostMessage(window, WM_CANCELMODE, 0, 0);
    224     }
    225   }
    226 
    227   return TRUE;
    228 }
    229 #endif
    230 
    231 void UpdateWebTouchEventAfterDispatch(blink::WebTouchEvent* event,
    232                                       blink::WebTouchPoint* point) {
    233   if (point->state != blink::WebTouchPoint::StateReleased &&
    234       point->state != blink::WebTouchPoint::StateCancelled)
    235     return;
    236   --event->touchesLength;
    237   for (unsigned i = point - event->touches;
    238        i < event->touchesLength;
    239        ++i) {
    240     event->touches[i] = event->touches[i + 1];
    241   }
    242 }
    243 
    244 bool CanRendererHandleEvent(const ui::MouseEvent* event) {
    245   if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED)
    246     return false;
    247 
    248 #if defined(OS_WIN)
    249   // Renderer cannot handle WM_XBUTTON or NC events.
    250   switch (event->native_event().message) {
    251     case WM_XBUTTONDOWN:
    252     case WM_XBUTTONUP:
    253     case WM_XBUTTONDBLCLK:
    254     case WM_NCMOUSELEAVE:
    255     case WM_NCMOUSEMOVE:
    256     case WM_NCLBUTTONDOWN:
    257     case WM_NCLBUTTONUP:
    258     case WM_NCLBUTTONDBLCLK:
    259     case WM_NCRBUTTONDOWN:
    260     case WM_NCRBUTTONUP:
    261     case WM_NCRBUTTONDBLCLK:
    262     case WM_NCMBUTTONDOWN:
    263     case WM_NCMBUTTONUP:
    264     case WM_NCMBUTTONDBLCLK:
    265     case WM_NCXBUTTONDOWN:
    266     case WM_NCXBUTTONUP:
    267     case WM_NCXBUTTONDBLCLK:
    268       return false;
    269     default:
    270       break;
    271   }
    272 #elif defined(USE_X11)
    273   // Renderer only supports standard mouse buttons, so ignore programmable
    274   // buttons.
    275   switch (event->type()) {
    276     case ui::ET_MOUSE_PRESSED:
    277     case ui::ET_MOUSE_RELEASED:
    278       return event->IsAnyButton();
    279     default:
    280       break;
    281   }
    282 #endif
    283   return true;
    284 }
    285 
    286 // We don't mark these as handled so that they're sent back to the
    287 // DefWindowProc so it can generate WM_APPCOMMAND as necessary.
    288 bool IsXButtonUpEvent(const ui::MouseEvent* event) {
    289 #if defined(OS_WIN)
    290   switch (event->native_event().message) {
    291     case WM_XBUTTONUP:
    292     case WM_NCXBUTTONUP:
    293       return true;
    294   }
    295 #endif
    296   return false;
    297 }
    298 
    299 void GetScreenInfoForWindow(WebScreenInfo* results, aura::Window* window) {
    300   const gfx::Display display = window ?
    301       gfx::Screen::GetScreenFor(window)->GetDisplayNearestWindow(window) :
    302       gfx::Screen::GetScreenFor(window)->GetPrimaryDisplay();
    303   results->rect = display.bounds();
    304   results->availableRect = display.work_area();
    305   // TODO(derat|oshima): Don't hardcode this. Get this from display object.
    306   results->depth = 24;
    307   results->depthPerComponent = 8;
    308   results->deviceScaleFactor = display.device_scale_factor();
    309 
    310   // The Display rotation and the WebScreenInfo orientation are not the same
    311   // angle. The former is the physical display rotation while the later is the
    312   // rotation required by the content to be shown properly on the screen, in
    313   // other words, relative to the physical display.
    314   results->orientationAngle = display.RotationAsDegree();
    315   if (results->orientationAngle == 90)
    316     results->orientationAngle = 270;
    317   else if (results->orientationAngle == 270)
    318     results->orientationAngle = 90;
    319 }
    320 
    321 bool PointerEventActivates(const ui::Event& event) {
    322   if (event.type() == ui::ET_MOUSE_PRESSED)
    323     return true;
    324 
    325   if (event.type() == ui::ET_GESTURE_BEGIN) {
    326     const ui::GestureEvent& gesture =
    327         static_cast<const ui::GestureEvent&>(event);
    328     return gesture.details().touch_points() == 1;
    329   }
    330 
    331   return false;
    332 }
    333 
    334 }  // namespace
    335 
    336 // We need to watch for mouse events outside a Web Popup or its parent
    337 // and dismiss the popup for certain events.
    338 class RenderWidgetHostViewAura::EventFilterForPopupExit
    339     : public ui::EventHandler {
    340  public:
    341   explicit EventFilterForPopupExit(RenderWidgetHostViewAura* rwhva)
    342       : rwhva_(rwhva) {
    343     DCHECK(rwhva_);
    344     aura::Env::GetInstance()->AddPreTargetHandler(this);
    345   }
    346 
    347   virtual ~EventFilterForPopupExit() {
    348     aura::Env::GetInstance()->RemovePreTargetHandler(this);
    349   }
    350 
    351   // Overridden from ui::EventHandler
    352   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
    353     rwhva_->ApplyEventFilterForPopupExit(event);
    354   }
    355 
    356   virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
    357     rwhva_->ApplyEventFilterForPopupExit(event);
    358   }
    359 
    360  private:
    361   RenderWidgetHostViewAura* rwhva_;
    362 
    363   DISALLOW_COPY_AND_ASSIGN(EventFilterForPopupExit);
    364 };
    365 
    366 void RenderWidgetHostViewAura::ApplyEventFilterForPopupExit(
    367     ui::LocatedEvent* event) {
    368   if (in_shutdown_ || is_fullscreen_ || !event->target())
    369     return;
    370 
    371   if (event->type() != ui::ET_MOUSE_PRESSED &&
    372       event->type() != ui::ET_TOUCH_PRESSED) {
    373     return;
    374   }
    375 
    376   aura::Window* target = static_cast<aura::Window*>(event->target());
    377   if (target != window_ &&
    378       (!popup_parent_host_view_ ||
    379        target != popup_parent_host_view_->window_)) {
    380     // Note: popup_parent_host_view_ may be NULL when there are multiple
    381     // popup children per view. See: RenderWidgetHostViewAura::InitAsPopup().
    382     in_shutdown_ = true;
    383     host_->Shutdown();
    384   }
    385 }
    386 
    387 // We have to implement the WindowObserver interface on a separate object
    388 // because clang doesn't like implementing multiple interfaces that have
    389 // methods with the same name. This object is owned by the
    390 // RenderWidgetHostViewAura.
    391 class RenderWidgetHostViewAura::WindowObserver : public aura::WindowObserver {
    392  public:
    393   explicit WindowObserver(RenderWidgetHostViewAura* view)
    394       : view_(view) {
    395     view_->window_->AddObserver(this);
    396   }
    397 
    398   virtual ~WindowObserver() {
    399     view_->window_->RemoveObserver(this);
    400   }
    401 
    402   // Overridden from aura::WindowObserver:
    403   virtual void OnWindowAddedToRootWindow(aura::Window* window) OVERRIDE {
    404     if (window == view_->window_)
    405       view_->AddedToRootWindow();
    406   }
    407 
    408   virtual void OnWindowRemovingFromRootWindow(aura::Window* window,
    409                                               aura::Window* new_root) OVERRIDE {
    410     if (window == view_->window_)
    411       view_->RemovingFromRootWindow();
    412   }
    413 
    414  private:
    415   RenderWidgetHostViewAura* view_;
    416 
    417   DISALLOW_COPY_AND_ASSIGN(WindowObserver);
    418 };
    419 
    420 ////////////////////////////////////////////////////////////////////////////////
    421 // RenderWidgetHostViewAura, public:
    422 
    423 RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host)
    424     : host_(RenderWidgetHostImpl::From(host)),
    425       window_(new aura::Window(this)),
    426       delegated_frame_host_(new DelegatedFrameHost(this)),
    427       in_shutdown_(false),
    428       in_bounds_changed_(false),
    429       is_fullscreen_(false),
    430       popup_parent_host_view_(NULL),
    431       popup_child_host_view_(NULL),
    432       is_loading_(false),
    433       text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
    434       text_input_mode_(ui::TEXT_INPUT_MODE_DEFAULT),
    435       can_compose_inline_(true),
    436       has_composition_text_(false),
    437       accept_return_character_(false),
    438       last_swapped_software_frame_scale_factor_(1.f),
    439       paint_canvas_(NULL),
    440       synthetic_move_sent_(false),
    441       cursor_visibility_state_in_renderer_(UNKNOWN),
    442       touch_editing_client_(NULL),
    443       weak_ptr_factory_(this) {
    444   host_->SetView(this);
    445   window_observer_.reset(new WindowObserver(this));
    446   aura::client::SetTooltipText(window_, &tooltip_);
    447   aura::client::SetActivationDelegate(window_, this);
    448   aura::client::SetActivationChangeObserver(window_, this);
    449   aura::client::SetFocusChangeObserver(window_, this);
    450   window_->set_layer_owner_delegate(delegated_frame_host_.get());
    451   gfx::Screen::GetScreenFor(window_)->AddObserver(this);
    452 
    453   bool overscroll_enabled = CommandLine::ForCurrentProcess()->
    454       GetSwitchValueASCII(switches::kOverscrollHistoryNavigation) != "0";
    455   SetOverscrollControllerEnabled(overscroll_enabled);
    456 }
    457 
    458 ////////////////////////////////////////////////////////////////////////////////
    459 // RenderWidgetHostViewAura, RenderWidgetHostView implementation:
    460 
    461 void RenderWidgetHostViewAura::InitAsChild(
    462     gfx::NativeView parent_view) {
    463   window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
    464   window_->Init(aura::WINDOW_LAYER_TEXTURED);
    465   window_->SetName("RenderWidgetHostViewAura");
    466 }
    467 
    468 void RenderWidgetHostViewAura::InitAsPopup(
    469     RenderWidgetHostView* parent_host_view,
    470     const gfx::Rect& bounds_in_screen) {
    471   popup_parent_host_view_ =
    472       static_cast<RenderWidgetHostViewAura*>(parent_host_view);
    473 
    474   // TransientWindowClient may be NULL during tests.
    475   aura::client::TransientWindowClient* transient_window_client =
    476       aura::client::GetTransientWindowClient();
    477   RenderWidgetHostViewAura* old_child =
    478       popup_parent_host_view_->popup_child_host_view_;
    479   if (old_child) {
    480     // TODO(jhorwich): Allow multiple popup_child_host_view_ per view, or
    481     // similar mechanism to ensure a second popup doesn't cause the first one
    482     // to never get a chance to filter events. See crbug.com/160589.
    483     DCHECK(old_child->popup_parent_host_view_ == popup_parent_host_view_);
    484     if (transient_window_client) {
    485       transient_window_client->RemoveTransientChild(
    486         popup_parent_host_view_->window_, old_child->window_);
    487     }
    488     old_child->popup_parent_host_view_ = NULL;
    489   }
    490   popup_parent_host_view_->popup_child_host_view_ = this;
    491   window_->SetType(ui::wm::WINDOW_TYPE_MENU);
    492   window_->Init(aura::WINDOW_LAYER_TEXTURED);
    493   window_->SetName("RenderWidgetHostViewAura");
    494 
    495   aura::Window* root = popup_parent_host_view_->window_->GetRootWindow();
    496   aura::client::ParentWindowWithContext(window_, root, bounds_in_screen);
    497   // Setting the transient child allows for the popup to get mouse events when
    498   // in a system modal dialog.
    499   // This fixes crbug.com/328593.
    500   if (transient_window_client) {
    501     transient_window_client->AddTransientChild(
    502         popup_parent_host_view_->window_, window_);
    503   }
    504 
    505   SetBounds(bounds_in_screen);
    506   Show();
    507 #if !defined(OS_WIN) && !defined(OS_CHROMEOS)
    508   if (NeedsInputGrab())
    509     window_->SetCapture();
    510 #endif
    511 
    512   event_filter_for_popup_exit_.reset(new EventFilterForPopupExit(this));
    513 }
    514 
    515 void RenderWidgetHostViewAura::InitAsFullscreen(
    516     RenderWidgetHostView* reference_host_view) {
    517   is_fullscreen_ = true;
    518   window_->SetType(ui::wm::WINDOW_TYPE_NORMAL);
    519   window_->Init(aura::WINDOW_LAYER_TEXTURED);
    520   window_->SetName("RenderWidgetHostViewAura");
    521   window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
    522 
    523   aura::Window* parent = NULL;
    524   gfx::Rect bounds;
    525   if (reference_host_view) {
    526     aura::Window* reference_window =
    527         static_cast<RenderWidgetHostViewAura*>(reference_host_view)->window_;
    528     if (reference_window) {
    529       host_tracker_.reset(new aura::WindowTracker);
    530       host_tracker_->Add(reference_window);
    531     }
    532     gfx::Display display = gfx::Screen::GetScreenFor(window_)->
    533         GetDisplayNearestWindow(reference_window);
    534     parent = reference_window->GetRootWindow();
    535     bounds = display.bounds();
    536   }
    537   aura::client::ParentWindowWithContext(window_, parent, bounds);
    538   Show();
    539   Focus();
    540 }
    541 
    542 RenderWidgetHost* RenderWidgetHostViewAura::GetRenderWidgetHost() const {
    543   return host_;
    544 }
    545 
    546 void RenderWidgetHostViewAura::WasShown() {
    547   DCHECK(host_);
    548   if (!host_->is_hidden())
    549     return;
    550   host_->WasShown();
    551 
    552   aura::Window* root = window_->GetRootWindow();
    553   if (root) {
    554     aura::client::CursorClient* cursor_client =
    555         aura::client::GetCursorClient(root);
    556     if (cursor_client)
    557       NotifyRendererOfCursorVisibilityState(cursor_client->IsCursorVisible());
    558   }
    559 
    560   delegated_frame_host_->WasShown();
    561 
    562 #if defined(OS_WIN)
    563   if (legacy_render_widget_host_HWND_) {
    564     // Reparent the legacy Chrome_RenderWidgetHostHWND window to the parent
    565     // window before reparenting any plugins. This ensures that the plugin
    566     // windows stay on top of the child Zorder in the parent and receive
    567     // mouse events, etc.
    568     legacy_render_widget_host_HWND_->UpdateParent(
    569         GetNativeView()->GetHost()->GetAcceleratedWidget());
    570     legacy_render_widget_host_HWND_->SetBounds(
    571         window_->GetBoundsInRootWindow());
    572   }
    573   LPARAM lparam = reinterpret_cast<LPARAM>(this);
    574   EnumChildWindows(ui::GetHiddenWindow(), ShowWindowsCallback, lparam);
    575 #endif
    576 }
    577 
    578 void RenderWidgetHostViewAura::WasHidden() {
    579   if (!host_ || host_->is_hidden())
    580     return;
    581   host_->WasHidden();
    582   delegated_frame_host_->WasHidden();
    583 
    584 #if defined(OS_WIN)
    585   constrained_rects_.clear();
    586   aura::WindowTreeHost* host = window_->GetHost();
    587   if (host) {
    588     HWND parent = host->GetAcceleratedWidget();
    589     LPARAM lparam = reinterpret_cast<LPARAM>(this);
    590     EnumChildWindows(parent, HideWindowsCallback, lparam);
    591     // We reparent the legacy Chrome_RenderWidgetHostHWND window to the global
    592     // hidden window on the same lines as Windowed plugin windows.
    593     if (legacy_render_widget_host_HWND_)
    594       legacy_render_widget_host_HWND_->UpdateParent(ui::GetHiddenWindow());
    595   }
    596 #endif
    597 }
    598 
    599 void RenderWidgetHostViewAura::SetSize(const gfx::Size& size) {
    600   // For a SetSize operation, we don't care what coordinate system the origin
    601   // of the window is in, it's only important to make sure that the origin
    602   // remains constant after the operation.
    603   InternalSetBounds(gfx::Rect(window_->bounds().origin(), size));
    604 }
    605 
    606 void RenderWidgetHostViewAura::SetBounds(const gfx::Rect& rect) {
    607   gfx::Point relative_origin(rect.origin());
    608 
    609   // RenderWidgetHostViewAura::SetBounds() takes screen coordinates, but
    610   // Window::SetBounds() takes parent coordinates, so do the conversion here.
    611   aura::Window* root = window_->GetRootWindow();
    612   if (root) {
    613     aura::client::ScreenPositionClient* screen_position_client =
    614         aura::client::GetScreenPositionClient(root);
    615     if (screen_position_client) {
    616       screen_position_client->ConvertPointFromScreen(
    617           window_->parent(), &relative_origin);
    618     }
    619   }
    620 
    621   InternalSetBounds(gfx::Rect(relative_origin, rect.size()));
    622 }
    623 
    624 gfx::NativeView RenderWidgetHostViewAura::GetNativeView() const {
    625   return window_;
    626 }
    627 
    628 gfx::NativeViewId RenderWidgetHostViewAura::GetNativeViewId() const {
    629 #if defined(OS_WIN)
    630   aura::WindowTreeHost* host = window_->GetHost();
    631   if (host)
    632     return reinterpret_cast<gfx::NativeViewId>(host->GetAcceleratedWidget());
    633 #endif
    634   return static_cast<gfx::NativeViewId>(NULL);
    635 }
    636 
    637 gfx::NativeViewAccessible RenderWidgetHostViewAura::GetNativeViewAccessible() {
    638 #if defined(OS_WIN)
    639   aura::WindowTreeHost* host = window_->GetHost();
    640   if (!host)
    641     return static_cast<gfx::NativeViewAccessible>(NULL);
    642   HWND hwnd = host->GetAcceleratedWidget();
    643 
    644   CreateBrowserAccessibilityManagerIfNeeded();
    645   BrowserAccessibilityManager* manager = GetBrowserAccessibilityManager();
    646   if (manager)
    647     return manager->GetRoot()->ToBrowserAccessibilityWin();
    648 #endif
    649 
    650   NOTIMPLEMENTED();
    651   return static_cast<gfx::NativeViewAccessible>(NULL);
    652 }
    653 
    654 ui::TextInputClient* RenderWidgetHostViewAura::GetTextInputClient() {
    655   return this;
    656 }
    657 
    658 void RenderWidgetHostViewAura::SetKeyboardFocus() {
    659 #if defined(OS_WIN)
    660   if (CanFocus()) {
    661     aura::WindowTreeHost* host = window_->GetHost();
    662     if (host)
    663       ::SetFocus(host->GetAcceleratedWidget());
    664   }
    665 #endif
    666 }
    667 
    668 RenderFrameHostImpl* RenderWidgetHostViewAura::GetFocusedFrame() {
    669   if (!host_->IsRenderView())
    670     return NULL;
    671   RenderViewHost* rvh = RenderViewHost::From(host_);
    672   FrameTreeNode* focused_frame =
    673       rvh->GetDelegate()->GetFrameTree()->GetFocusedFrame();
    674   if (!focused_frame)
    675     return NULL;
    676 
    677   return focused_frame->current_frame_host();
    678 }
    679 
    680 void RenderWidgetHostViewAura::MovePluginWindows(
    681     const std::vector<WebPluginGeometry>& plugin_window_moves) {
    682 #if defined(OS_WIN)
    683   // We need to clip the rectangle to the tab's viewport, otherwise we will draw
    684   // over the browser UI.
    685   if (!window_->GetRootWindow()) {
    686     DCHECK(plugin_window_moves.empty());
    687     return;
    688   }
    689   HWND parent = window_->GetHost()->GetAcceleratedWidget();
    690   gfx::Rect view_bounds = window_->GetBoundsInRootWindow();
    691   std::vector<WebPluginGeometry> moves = plugin_window_moves;
    692 
    693   gfx::Rect view_port(view_bounds.size());
    694 
    695   for (size_t i = 0; i < moves.size(); ++i) {
    696     gfx::Rect clip(moves[i].clip_rect);
    697     gfx::Vector2d view_port_offset(
    698         moves[i].window_rect.OffsetFromOrigin());
    699     clip.Offset(view_port_offset);
    700     clip.Intersect(view_port);
    701     clip.Offset(-view_port_offset);
    702     moves[i].clip_rect = clip;
    703 
    704     moves[i].window_rect.Offset(view_bounds.OffsetFromOrigin());
    705 
    706     plugin_window_moves_[moves[i].window] = moves[i];
    707 
    708     // constrained_rects_ are relative to the root window. We want to convert
    709     // them to be relative to the plugin window.
    710     for (size_t j = 0; j < constrained_rects_.size(); ++j) {
    711       gfx::Rect offset_cutout = constrained_rects_[j];
    712       offset_cutout -= moves[i].window_rect.OffsetFromOrigin();
    713       moves[i].cutout_rects.push_back(offset_cutout);
    714     }
    715   }
    716 
    717   MovePluginWindowsHelper(parent, moves);
    718 
    719   // Make sure each plugin window (or its wrapper if it exists) has a pointer to
    720   // |this|.
    721   for (size_t i = 0; i < moves.size(); ++i) {
    722     HWND window = moves[i].window;
    723     if (GetParent(window) != parent) {
    724       window = GetParent(window);
    725     }
    726     if (!GetProp(window, kWidgetOwnerProperty))
    727       SetProp(window, kWidgetOwnerProperty, this);
    728   }
    729 #endif  // defined(OS_WIN)
    730 }
    731 
    732 void RenderWidgetHostViewAura::Focus() {
    733   // Make sure we have a FocusClient before attempting to Focus(). In some
    734   // situations we may not yet be in a valid Window hierarchy (such as reloading
    735   // after out of memory discarded the tab).
    736   aura::client::FocusClient* client = aura::client::GetFocusClient(window_);
    737   if (client)
    738     window_->Focus();
    739 }
    740 
    741 void RenderWidgetHostViewAura::Blur() {
    742   window_->Blur();
    743 }
    744 
    745 bool RenderWidgetHostViewAura::HasFocus() const {
    746   return window_->HasFocus();
    747 }
    748 
    749 bool RenderWidgetHostViewAura::IsSurfaceAvailableForCopy() const {
    750   return delegated_frame_host_->CanCopyToBitmap();
    751 }
    752 
    753 void RenderWidgetHostViewAura::Show() {
    754   window_->Show();
    755   WasShown();
    756 #if defined(OS_WIN)
    757   if (legacy_render_widget_host_HWND_)
    758     legacy_render_widget_host_HWND_->Show();
    759 #endif
    760 }
    761 
    762 void RenderWidgetHostViewAura::Hide() {
    763   window_->Hide();
    764   WasHidden();
    765 #if defined(OS_WIN)
    766   if (legacy_render_widget_host_HWND_)
    767     legacy_render_widget_host_HWND_->Hide();
    768 #endif
    769 }
    770 
    771 bool RenderWidgetHostViewAura::IsShowing() {
    772   return window_->IsVisible();
    773 }
    774 
    775 gfx::Rect RenderWidgetHostViewAura::GetViewBounds() const {
    776   return window_->GetBoundsInScreen();
    777 }
    778 
    779 void RenderWidgetHostViewAura::SetBackgroundOpaque(bool opaque) {
    780   RenderWidgetHostViewBase::SetBackgroundOpaque(opaque);
    781   host_->SetBackgroundOpaque(opaque);
    782   window_->layer()->SetFillsBoundsOpaquely(opaque);
    783 }
    784 
    785 gfx::Size RenderWidgetHostViewAura::GetVisibleViewportSize() const {
    786   gfx::Rect requested_rect(GetRequestedRendererSize());
    787   requested_rect.Inset(insets_);
    788   return requested_rect.size();
    789 }
    790 
    791 void RenderWidgetHostViewAura::SetInsets(const gfx::Insets& insets) {
    792   if (insets != insets_) {
    793     insets_ = insets;
    794     host_->WasResized();
    795   }
    796 }
    797 
    798 void RenderWidgetHostViewAura::UpdateCursor(const WebCursor& cursor) {
    799   current_cursor_ = cursor;
    800   const gfx::Display display = gfx::Screen::GetScreenFor(window_)->
    801       GetDisplayNearestWindow(window_);
    802   current_cursor_.SetDisplayInfo(display);
    803   UpdateCursorIfOverSelf();
    804 }
    805 
    806 void RenderWidgetHostViewAura::SetIsLoading(bool is_loading) {
    807   is_loading_ = is_loading;
    808   UpdateCursorIfOverSelf();
    809 }
    810 
    811 void RenderWidgetHostViewAura::TextInputStateChanged(
    812     const ViewHostMsg_TextInputState_Params& params) {
    813   if (text_input_type_ != params.type ||
    814       text_input_mode_ != params.mode ||
    815       can_compose_inline_ != params.can_compose_inline) {
    816     text_input_type_ = params.type;
    817     text_input_mode_ = params.mode;
    818     can_compose_inline_ = params.can_compose_inline;
    819     if (GetInputMethod())
    820       GetInputMethod()->OnTextInputTypeChanged(this);
    821     if (touch_editing_client_)
    822       touch_editing_client_->OnTextInputTypeChanged(text_input_type_);
    823   }
    824   if (params.show_ime_if_needed && params.type != ui::TEXT_INPUT_TYPE_NONE) {
    825     if (GetInputMethod())
    826       GetInputMethod()->ShowImeIfNeeded();
    827   }
    828 }
    829 
    830 void RenderWidgetHostViewAura::ImeCancelComposition() {
    831   if (GetInputMethod())
    832     GetInputMethod()->CancelComposition(this);
    833   has_composition_text_ = false;
    834 }
    835 
    836 void RenderWidgetHostViewAura::ImeCompositionRangeChanged(
    837     const gfx::Range& range,
    838     const std::vector<gfx::Rect>& character_bounds) {
    839   composition_character_bounds_ = character_bounds;
    840 }
    841 
    842 void RenderWidgetHostViewAura::RenderProcessGone(base::TerminationStatus status,
    843                                                  int error_code) {
    844   UpdateCursorIfOverSelf();
    845   Destroy();
    846 }
    847 
    848 void RenderWidgetHostViewAura::Destroy() {
    849   // Beware, this function is not called on all destruction paths. It will
    850   // implicitly end up calling ~RenderWidgetHostViewAura though, so all
    851   // destruction/cleanup code should happen there, not here.
    852   in_shutdown_ = true;
    853   delete window_;
    854 }
    855 
    856 void RenderWidgetHostViewAura::SetTooltipText(
    857     const base::string16& tooltip_text) {
    858   tooltip_ = tooltip_text;
    859   aura::Window* root_window = window_->GetRootWindow();
    860   aura::client::TooltipClient* tooltip_client =
    861       aura::client::GetTooltipClient(root_window);
    862   if (tooltip_client) {
    863     tooltip_client->UpdateTooltip(window_);
    864     // Content tooltips should be visible indefinitely.
    865     tooltip_client->SetTooltipShownTimeout(window_, 0);
    866   }
    867 }
    868 
    869 void RenderWidgetHostViewAura::SelectionChanged(const base::string16& text,
    870                                                 size_t offset,
    871                                                 const gfx::Range& range) {
    872   RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
    873 
    874 #if defined(USE_X11) && !defined(OS_CHROMEOS)
    875   if (text.empty() || range.is_empty())
    876     return;
    877   size_t pos = range.GetMin() - offset;
    878   size_t n = range.length();
    879 
    880   DCHECK(pos + n <= text.length()) << "The text can not fully cover range.";
    881   if (pos >= text.length()) {
    882     NOTREACHED() << "The text can not cover range.";
    883     return;
    884   }
    885 
    886   // Set the CLIPBOARD_TYPE_SELECTION to the ui::Clipboard.
    887   ui::ScopedClipboardWriter clipboard_writer(
    888       ui::Clipboard::GetForCurrentThread(),
    889       ui::CLIPBOARD_TYPE_SELECTION);
    890   clipboard_writer.WriteText(text.substr(pos, n));
    891 #endif  // defined(USE_X11) && !defined(OS_CHROMEOS)
    892 }
    893 
    894 gfx::Size RenderWidgetHostViewAura::GetRequestedRendererSize() const {
    895   return delegated_frame_host_->GetRequestedRendererSize();
    896 }
    897 
    898 void RenderWidgetHostViewAura::SelectionBoundsChanged(
    899     const ViewHostMsg_SelectionBounds_Params& params) {
    900   if (selection_anchor_rect_ == params.anchor_rect &&
    901       selection_focus_rect_ == params.focus_rect)
    902     return;
    903 
    904   selection_anchor_rect_ = params.anchor_rect;
    905   selection_focus_rect_ = params.focus_rect;
    906 
    907   if (GetInputMethod())
    908     GetInputMethod()->OnCaretBoundsChanged(this);
    909 
    910   if (touch_editing_client_) {
    911     touch_editing_client_->OnSelectionOrCursorChanged(selection_anchor_rect_,
    912         selection_focus_rect_);
    913   }
    914 }
    915 
    916 void RenderWidgetHostViewAura::ScrollOffsetChanged() {
    917   aura::Window* root = window_->GetRootWindow();
    918   if (!root)
    919     return;
    920   aura::client::CursorClient* cursor_client =
    921       aura::client::GetCursorClient(root);
    922   if (cursor_client && !cursor_client->IsCursorVisible())
    923     cursor_client->DisableMouseEvents();
    924 }
    925 
    926 void RenderWidgetHostViewAura::CopyFromCompositingSurface(
    927     const gfx::Rect& src_subrect,
    928     const gfx::Size& dst_size,
    929     const base::Callback<void(bool, const SkBitmap&)>& callback,
    930     const SkBitmap::Config config) {
    931   delegated_frame_host_->CopyFromCompositingSurface(
    932       src_subrect, dst_size, callback, config);
    933 }
    934 
    935 void RenderWidgetHostViewAura::CopyFromCompositingSurfaceToVideoFrame(
    936       const gfx::Rect& src_subrect,
    937       const scoped_refptr<media::VideoFrame>& target,
    938       const base::Callback<void(bool)>& callback) {
    939   delegated_frame_host_->CopyFromCompositingSurfaceToVideoFrame(
    940       src_subrect, target, callback);
    941 }
    942 
    943 bool RenderWidgetHostViewAura::CanCopyToVideoFrame() const {
    944   return delegated_frame_host_->CanCopyToVideoFrame();
    945 }
    946 
    947 bool RenderWidgetHostViewAura::CanSubscribeFrame() const {
    948   return delegated_frame_host_->CanSubscribeFrame();
    949 }
    950 
    951 void RenderWidgetHostViewAura::BeginFrameSubscription(
    952     scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) {
    953   delegated_frame_host_->BeginFrameSubscription(subscriber.Pass());
    954 }
    955 
    956 void RenderWidgetHostViewAura::EndFrameSubscription() {
    957   delegated_frame_host_->EndFrameSubscription();
    958 }
    959 
    960 void RenderWidgetHostViewAura::AcceleratedSurfaceInitialized(int host_id,
    961                                                              int route_id) {
    962 }
    963 
    964 void RenderWidgetHostViewAura::SnapToPhysicalPixelBoundary() {
    965   // The top left corner of our view in window coordinates might not land on a
    966   // device pixel boundary if we have a non-integer device scale. In that case,
    967   // to avoid the web contents area looking blurry we translate the web contents
    968   // in the +x, +y direction to land on the nearest pixel boundary. This may
    969   // cause the bottom and right edges to be clipped slightly, but that's ok.
    970   gfx::Point view_offset_dips = window_->GetBoundsInRootWindow().origin();
    971   gfx::PointF view_offset = view_offset_dips;
    972   view_offset.Scale(current_device_scale_factor_);
    973   gfx::PointF view_offset_snapped(std::ceil(view_offset.x()),
    974                                   std::ceil(view_offset.y()));
    975 
    976   gfx::Vector2dF fudge = view_offset_snapped - view_offset;
    977   fudge.Scale(1.0 / current_device_scale_factor_);
    978   GetLayer()->SetSubpixelPositionOffset(fudge);
    979 }
    980 
    981 void RenderWidgetHostViewAura::InternalSetBounds(const gfx::Rect& rect) {
    982   if (HasDisplayPropertyChanged(window_))
    983     host_->InvalidateScreenInfo();
    984 
    985   SnapToPhysicalPixelBoundary();
    986   // Don't recursively call SetBounds if this bounds update is the result of
    987   // a Window::SetBoundsInternal call.
    988   if (!in_bounds_changed_)
    989     window_->SetBounds(rect);
    990   host_->WasResized();
    991   delegated_frame_host_->WasResized();
    992   if (touch_editing_client_) {
    993     touch_editing_client_->OnSelectionOrCursorChanged(selection_anchor_rect_,
    994       selection_focus_rect_);
    995   }
    996 #if defined(OS_WIN)
    997   // Create the legacy dummy window which corresponds to the bounds of the
    998   // webcontents. This will be passed as the container window for windowless
    999   // plugins.
   1000   // Plugins like Flash assume the container window which is returned via the
   1001   // NPNVnetscapeWindow property corresponds to the bounds of the webpage.
   1002   // This is not true in Aura where we have only HWND which is the main Aura
   1003   // window. If we return this window to plugins like Flash then it causes the
   1004   // coordinate translations done by these plugins to break.
   1005   // Additonally the legacy dummy window is needed for accessibility and for
   1006   // scrolling to work in legacy drivers for trackpoints/trackpads, etc.
   1007   if (GetNativeViewId()) {
   1008     if (!legacy_render_widget_host_HWND_) {
   1009       legacy_render_widget_host_HWND_ = LegacyRenderWidgetHostHWND::Create(
   1010           reinterpret_cast<HWND>(GetNativeViewId()));
   1011       BrowserAccessibilityManagerWin* manager =
   1012           static_cast<BrowserAccessibilityManagerWin*>(
   1013               GetBrowserAccessibilityManager());
   1014       if (manager)
   1015         manager->SetAccessibleHWND(legacy_render_widget_host_HWND_.get());
   1016     }
   1017     if (legacy_render_widget_host_HWND_) {
   1018       legacy_render_widget_host_HWND_->SetBounds(
   1019           window_->GetBoundsInRootWindow());
   1020     }
   1021   }
   1022 
   1023   if (mouse_locked_)
   1024     UpdateMouseLockRegion();
   1025 #endif
   1026 }
   1027 
   1028 #if defined(OS_WIN)
   1029 bool RenderWidgetHostViewAura::UsesNativeWindowFrame() const {
   1030   return (legacy_render_widget_host_HWND_ != NULL);
   1031 }
   1032 
   1033 void RenderWidgetHostViewAura::UpdateConstrainedWindowRects(
   1034     const std::vector<gfx::Rect>& rects) {
   1035   // Check this before setting constrained_rects_, so that next time they're set
   1036   // and we have a root window we don't early return.
   1037   if (!window_->GetHost())
   1038     return;
   1039 
   1040   if (rects == constrained_rects_)
   1041     return;
   1042 
   1043   constrained_rects_ = rects;
   1044 
   1045   HWND parent = window_->GetHost()->GetAcceleratedWidget();
   1046   CutoutRectsParams params;
   1047   params.widget = this;
   1048   params.cutout_rects = constrained_rects_;
   1049   params.geometry = &plugin_window_moves_;
   1050   LPARAM lparam = reinterpret_cast<LPARAM>(&params);
   1051   EnumChildWindows(parent, SetCutoutRectsCallback, lparam);
   1052 }
   1053 
   1054 void RenderWidgetHostViewAura::UpdateMouseLockRegion() {
   1055   // Clip the cursor if chrome is running on regular desktop.
   1056   if (gfx::Screen::GetScreenFor(window_) == gfx::Screen::GetNativeScreen()) {
   1057     RECT window_rect = window_->GetBoundsInScreen().ToRECT();
   1058     ::ClipCursor(&window_rect);
   1059   }
   1060 }
   1061 #endif
   1062 
   1063 void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped(
   1064     const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params_in_pixel,
   1065     int gpu_host_id) {
   1066   // Oldschool composited mode is no longer supported.
   1067 }
   1068 
   1069 void RenderWidgetHostViewAura::OnSwapCompositorFrame(
   1070     uint32 output_surface_id,
   1071     scoped_ptr<cc::CompositorFrame> frame) {
   1072   TRACE_EVENT0("content", "RenderWidgetHostViewAura::OnSwapCompositorFrame");
   1073   if (frame->delegated_frame_data) {
   1074     delegated_frame_host_->SwapDelegatedFrame(
   1075         output_surface_id,
   1076         frame->delegated_frame_data.Pass(),
   1077         frame->metadata.device_scale_factor,
   1078         frame->metadata.latency_info);
   1079     return;
   1080   }
   1081 
   1082   if (frame->software_frame_data) {
   1083     DLOG(ERROR) << "Unable to use software frame in aura";
   1084     RecordAction(
   1085         base::UserMetricsAction("BadMessageTerminate_SharedMemoryAura"));
   1086     host_->GetProcess()->ReceivedBadMessage();
   1087     return;
   1088   }
   1089 }
   1090 
   1091 #if defined(OS_WIN)
   1092 void RenderWidgetHostViewAura::SetParentNativeViewAccessible(
   1093     gfx::NativeViewAccessible accessible_parent) {
   1094   if (GetBrowserAccessibilityManager()) {
   1095     GetBrowserAccessibilityManager()->ToBrowserAccessibilityManagerWin()
   1096         ->set_parent_iaccessible(accessible_parent);
   1097   }
   1098 }
   1099 
   1100 gfx::NativeViewId RenderWidgetHostViewAura::GetParentForWindowlessPlugin()
   1101     const {
   1102   if (legacy_render_widget_host_HWND_) {
   1103     return reinterpret_cast<gfx::NativeViewId>(
   1104         legacy_render_widget_host_HWND_->hwnd());
   1105   }
   1106   return NULL;
   1107 }
   1108 #endif
   1109 
   1110 void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer(
   1111     const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params_in_pixel,
   1112     int gpu_host_id) {
   1113   // Oldschool composited mode is no longer supported.
   1114 }
   1115 
   1116 void RenderWidgetHostViewAura::AcceleratedSurfaceSuspend() {
   1117 }
   1118 
   1119 void RenderWidgetHostViewAura::AcceleratedSurfaceRelease() {
   1120 }
   1121 
   1122 bool RenderWidgetHostViewAura::HasAcceleratedSurface(
   1123     const gfx::Size& desired_size) {
   1124   // Aura doesn't use GetBackingStore for accelerated pages, so it doesn't
   1125   // matter what is returned here as GetBackingStore is the only caller of this
   1126   // method. TODO(jbates) implement this if other Aura code needs it.
   1127   return false;
   1128 }
   1129 
   1130 void RenderWidgetHostViewAura::GetScreenInfo(WebScreenInfo* results) {
   1131   GetScreenInfoForWindow(results, window_->GetRootWindow() ? window_ : NULL);
   1132 }
   1133 
   1134 gfx::Rect RenderWidgetHostViewAura::GetBoundsInRootWindow() {
   1135   aura::Window* top_level = window_->GetToplevelWindow();
   1136   gfx::Rect bounds(top_level->GetBoundsInScreen());
   1137 
   1138 #if defined(OS_WIN)
   1139   // TODO(zturner,iyengar): This will break when we remove support for NPAPI and
   1140   // remove the legacy hwnd, so a better fix will need to be decided when that
   1141   // happens.
   1142   if (UsesNativeWindowFrame()) {
   1143     // aura::Window doesn't take into account non-client area of native windows
   1144     // (e.g. HWNDs), so for that case ask Windows directly what the bounds are.
   1145     aura::WindowTreeHost* host = top_level->GetHost();
   1146     if (!host)
   1147       return top_level->GetBoundsInScreen();
   1148     RECT window_rect = {0};
   1149     HWND hwnd = host->GetAcceleratedWidget();
   1150     ::GetWindowRect(hwnd, &window_rect);
   1151     bounds = gfx::Rect(window_rect);
   1152 
   1153     // Maximized windows are outdented from the work area by the frame thickness
   1154     // even though this "frame" is not painted.  This confuses code (and people)
   1155     // that think of a maximized window as corresponding exactly to the work
   1156     // area.  Correct for this by subtracting the frame thickness back off.
   1157     if (::IsZoomed(hwnd)) {
   1158       bounds.Inset(GetSystemMetrics(SM_CXSIZEFRAME),
   1159                    GetSystemMetrics(SM_CYSIZEFRAME));
   1160 
   1161       bounds.Inset(GetSystemMetrics(SM_CXPADDEDBORDER),
   1162                    GetSystemMetrics(SM_CXPADDEDBORDER));
   1163     }
   1164   }
   1165 
   1166   bounds = gfx::win::ScreenToDIPRect(bounds);
   1167 #endif
   1168 
   1169   return bounds;
   1170 }
   1171 
   1172 void RenderWidgetHostViewAura::WheelEventAck(
   1173     const blink::WebMouseWheelEvent& event,
   1174     InputEventAckState ack_result) {
   1175   if (overscroll_controller_) {
   1176     overscroll_controller_->ReceivedEventACK(
   1177         event, (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result));
   1178   }
   1179 }
   1180 
   1181 void RenderWidgetHostViewAura::GestureEventAck(
   1182     const blink::WebGestureEvent& event,
   1183     InputEventAckState ack_result) {
   1184   if (touch_editing_client_)
   1185     touch_editing_client_->GestureEventAck(event.type);
   1186 
   1187   if (overscroll_controller_) {
   1188     overscroll_controller_->ReceivedEventACK(
   1189         event, (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result));
   1190   }
   1191 }
   1192 
   1193 void RenderWidgetHostViewAura::ProcessAckedTouchEvent(
   1194     const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) {
   1195   ScopedVector<ui::TouchEvent> events;
   1196   if (!MakeUITouchEventsFromWebTouchEvents(touch, &events,
   1197                                            SCREEN_COORDINATES))
   1198     return;
   1199 
   1200   aura::WindowTreeHost* host = window_->GetHost();
   1201   // |host| is NULL during tests.
   1202   if (!host)
   1203     return;
   1204 
   1205   ui::EventResult result = (ack_result ==
   1206       INPUT_EVENT_ACK_STATE_CONSUMED) ? ui::ER_HANDLED : ui::ER_UNHANDLED;
   1207   for (ScopedVector<ui::TouchEvent>::iterator iter = events.begin(),
   1208       end = events.end(); iter != end; ++iter) {
   1209     host->dispatcher()->ProcessedTouchEvent((*iter), window_, result);
   1210   }
   1211 }
   1212 
   1213 scoped_ptr<SyntheticGestureTarget>
   1214 RenderWidgetHostViewAura::CreateSyntheticGestureTarget() {
   1215   return scoped_ptr<SyntheticGestureTarget>(
   1216       new SyntheticGestureTargetAura(host_));
   1217 }
   1218 
   1219 InputEventAckState RenderWidgetHostViewAura::FilterInputEvent(
   1220     const blink::WebInputEvent& input_event) {
   1221   bool consumed = false;
   1222   if (input_event.type == WebInputEvent::GestureFlingStart) {
   1223     const WebGestureEvent& gesture_event =
   1224         static_cast<const WebGestureEvent&>(input_event);
   1225     // Zero-velocity touchpad flings are an Aura-specific signal that the
   1226     // touchpad scroll has ended, and should not be forwarded to the renderer.
   1227     if (gesture_event.sourceDevice == blink::WebGestureDeviceTouchpad &&
   1228         !gesture_event.data.flingStart.velocityX &&
   1229         !gesture_event.data.flingStart.velocityY) {
   1230       consumed = true;
   1231     }
   1232   }
   1233 
   1234   if (overscroll_controller_)
   1235     consumed |= overscroll_controller_->WillHandleEvent(input_event);
   1236 
   1237   return consumed && !WebTouchEvent::isTouchEventType(input_event.type)
   1238              ? INPUT_EVENT_ACK_STATE_CONSUMED
   1239              : INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
   1240 }
   1241 
   1242 void RenderWidgetHostViewAura::CreateBrowserAccessibilityManagerIfNeeded() {
   1243 #if defined(OS_WIN)
   1244   if (!GetBrowserAccessibilityManager()) {
   1245     gfx::NativeViewAccessible accessible_parent =
   1246         host_->GetParentNativeViewAccessible();
   1247     LegacyRenderWidgetHostHWND* parent_hwnd =
   1248         legacy_render_widget_host_HWND_.get();
   1249     SetBrowserAccessibilityManager(new BrowserAccessibilityManagerWin(
   1250         legacy_render_widget_host_HWND_.get(), accessible_parent,
   1251         BrowserAccessibilityManagerWin::GetEmptyDocument(), host_));
   1252   }
   1253 #else
   1254   if (!GetBrowserAccessibilityManager()) {
   1255     SetBrowserAccessibilityManager(
   1256         BrowserAccessibilityManager::Create(
   1257             BrowserAccessibilityManager::GetEmptyDocument(), host_));
   1258   }
   1259 #endif
   1260 }
   1261 
   1262 gfx::GLSurfaceHandle RenderWidgetHostViewAura::GetCompositingSurface() {
   1263   return ImageTransportFactory::GetInstance()->GetSharedSurfaceHandle();
   1264 }
   1265 
   1266 bool RenderWidgetHostViewAura::LockMouse() {
   1267   aura::Window* root_window = window_->GetRootWindow();
   1268   if (!root_window)
   1269     return false;
   1270 
   1271   if (mouse_locked_)
   1272     return true;
   1273 
   1274   mouse_locked_ = true;
   1275 #if !defined(OS_WIN)
   1276   window_->SetCapture();
   1277 #else
   1278   UpdateMouseLockRegion();
   1279 #endif
   1280   aura::client::CursorClient* cursor_client =
   1281       aura::client::GetCursorClient(root_window);
   1282   if (cursor_client) {
   1283     cursor_client->HideCursor();
   1284     cursor_client->LockCursor();
   1285   }
   1286 
   1287   if (ShouldMoveToCenter()) {
   1288     synthetic_move_sent_ = true;
   1289     window_->MoveCursorTo(gfx::Rect(window_->bounds().size()).CenterPoint());
   1290   }
   1291   tooltip_disabler_.reset(new aura::client::ScopedTooltipDisabler(root_window));
   1292   return true;
   1293 }
   1294 
   1295 void RenderWidgetHostViewAura::UnlockMouse() {
   1296   tooltip_disabler_.reset();
   1297 
   1298   aura::Window* root_window = window_->GetRootWindow();
   1299   if (!mouse_locked_ || !root_window)
   1300     return;
   1301 
   1302   mouse_locked_ = false;
   1303 
   1304 #if !defined(OS_WIN)
   1305   window_->ReleaseCapture();
   1306 #else
   1307   ::ClipCursor(NULL);
   1308 #endif
   1309   window_->MoveCursorTo(unlocked_mouse_position_);
   1310   aura::client::CursorClient* cursor_client =
   1311       aura::client::GetCursorClient(root_window);
   1312   if (cursor_client) {
   1313     cursor_client->UnlockCursor();
   1314     cursor_client->ShowCursor();
   1315   }
   1316 
   1317   host_->LostMouseLock();
   1318 }
   1319 
   1320 ////////////////////////////////////////////////////////////////////////////////
   1321 // RenderWidgetHostViewAura, ui::TextInputClient implementation:
   1322 void RenderWidgetHostViewAura::SetCompositionText(
   1323     const ui::CompositionText& composition) {
   1324   if (!host_)
   1325     return;
   1326 
   1327   // TODO(suzhe): convert both renderer_host and renderer to use
   1328   // ui::CompositionText.
   1329   std::vector<blink::WebCompositionUnderline> underlines;
   1330   underlines.reserve(composition.underlines.size());
   1331   for (std::vector<ui::CompositionUnderline>::const_iterator it =
   1332            composition.underlines.begin();
   1333        it != composition.underlines.end(); ++it) {
   1334     underlines.push_back(
   1335         blink::WebCompositionUnderline(static_cast<unsigned>(it->start_offset),
   1336                                        static_cast<unsigned>(it->end_offset),
   1337                                        it->color,
   1338                                        it->thick,
   1339                                        it->background_color));
   1340   }
   1341 
   1342   // TODO(suzhe): due to a bug of webkit, we can't use selection range with
   1343   // composition string. See: https://bugs.webkit.org/show_bug.cgi?id=37788
   1344   host_->ImeSetComposition(composition.text, underlines,
   1345                            composition.selection.end(),
   1346                            composition.selection.end());
   1347 
   1348   has_composition_text_ = !composition.text.empty();
   1349 }
   1350 
   1351 void RenderWidgetHostViewAura::ConfirmCompositionText() {
   1352   if (host_ && has_composition_text_) {
   1353     host_->ImeConfirmComposition(base::string16(), gfx::Range::InvalidRange(),
   1354                                  false);
   1355   }
   1356   has_composition_text_ = false;
   1357 }
   1358 
   1359 void RenderWidgetHostViewAura::ClearCompositionText() {
   1360   if (host_ && has_composition_text_)
   1361     host_->ImeCancelComposition();
   1362   has_composition_text_ = false;
   1363 }
   1364 
   1365 void RenderWidgetHostViewAura::InsertText(const base::string16& text) {
   1366   DCHECK(text_input_type_ != ui::TEXT_INPUT_TYPE_NONE);
   1367   if (host_)
   1368     host_->ImeConfirmComposition(text, gfx::Range::InvalidRange(), false);
   1369   has_composition_text_ = false;
   1370 }
   1371 
   1372 void RenderWidgetHostViewAura::InsertChar(base::char16 ch, int flags) {
   1373   if (popup_child_host_view_ && popup_child_host_view_->NeedsInputGrab()) {
   1374     popup_child_host_view_->InsertChar(ch, flags);
   1375     return;
   1376   }
   1377 
   1378   // Ignore character messages for VKEY_RETURN sent on CTRL+M. crbug.com/315547
   1379   if (host_ && (accept_return_character_ || ch != ui::VKEY_RETURN)) {
   1380     double now = ui::EventTimeForNow().InSecondsF();
   1381     // Send a blink::WebInputEvent::Char event to |host_|.
   1382     NativeWebKeyboardEvent webkit_event(ui::ET_KEY_PRESSED,
   1383                                         true /* is_char */,
   1384                                         ch,
   1385                                         flags,
   1386                                         now);
   1387     ForwardKeyboardEvent(webkit_event);
   1388   }
   1389 }
   1390 
   1391 gfx::NativeWindow RenderWidgetHostViewAura::GetAttachedWindow() const {
   1392   return window_;
   1393 }
   1394 
   1395 ui::TextInputType RenderWidgetHostViewAura::GetTextInputType() const {
   1396   return text_input_type_;
   1397 }
   1398 
   1399 ui::TextInputMode RenderWidgetHostViewAura::GetTextInputMode() const {
   1400   return text_input_mode_;
   1401 }
   1402 
   1403 bool RenderWidgetHostViewAura::CanComposeInline() const {
   1404   return can_compose_inline_;
   1405 }
   1406 
   1407 gfx::Rect RenderWidgetHostViewAura::ConvertRectToScreen(
   1408     const gfx::Rect& rect) const {
   1409   gfx::Point origin = rect.origin();
   1410   gfx::Point end = gfx::Point(rect.right(), rect.bottom());
   1411 
   1412   aura::Window* root_window = window_->GetRootWindow();
   1413   if (!root_window)
   1414     return rect;
   1415   aura::client::ScreenPositionClient* screen_position_client =
   1416       aura::client::GetScreenPositionClient(root_window);
   1417   if (!screen_position_client)
   1418     return rect;
   1419   screen_position_client->ConvertPointToScreen(window_, &origin);
   1420   screen_position_client->ConvertPointToScreen(window_, &end);
   1421   return gfx::Rect(origin.x(),
   1422                    origin.y(),
   1423                    end.x() - origin.x(),
   1424                    end.y() - origin.y());
   1425 }
   1426 
   1427 gfx::Rect RenderWidgetHostViewAura::ConvertRectFromScreen(
   1428     const gfx::Rect& rect) const {
   1429   gfx::Point origin = rect.origin();
   1430   gfx::Point end = gfx::Point(rect.right(), rect.bottom());
   1431 
   1432   aura::Window* root_window = window_->GetRootWindow();
   1433   if (root_window) {
   1434     aura::client::ScreenPositionClient* screen_position_client =
   1435         aura::client::GetScreenPositionClient(root_window);
   1436     screen_position_client->ConvertPointFromScreen(window_, &origin);
   1437     screen_position_client->ConvertPointFromScreen(window_, &end);
   1438     return gfx::Rect(origin.x(),
   1439                      origin.y(),
   1440                      end.x() - origin.x(),
   1441                      end.y() - origin.y());
   1442   }
   1443 
   1444   return rect;
   1445 }
   1446 
   1447 gfx::Rect RenderWidgetHostViewAura::GetCaretBounds() const {
   1448   const gfx::Rect rect =
   1449       gfx::UnionRects(selection_anchor_rect_, selection_focus_rect_);
   1450   return ConvertRectToScreen(rect);
   1451 }
   1452 
   1453 bool RenderWidgetHostViewAura::GetCompositionCharacterBounds(
   1454     uint32 index,
   1455     gfx::Rect* rect) const {
   1456   DCHECK(rect);
   1457   if (index >= composition_character_bounds_.size())
   1458     return false;
   1459   *rect = ConvertRectToScreen(composition_character_bounds_[index]);
   1460   return true;
   1461 }
   1462 
   1463 bool RenderWidgetHostViewAura::HasCompositionText() const {
   1464   return has_composition_text_;
   1465 }
   1466 
   1467 bool RenderWidgetHostViewAura::GetTextRange(gfx::Range* range) const {
   1468   range->set_start(selection_text_offset_);
   1469   range->set_end(selection_text_offset_ + selection_text_.length());
   1470   return true;
   1471 }
   1472 
   1473 bool RenderWidgetHostViewAura::GetCompositionTextRange(
   1474     gfx::Range* range) const {
   1475   // TODO(suzhe): implement this method when fixing http://crbug.com/55130.
   1476   NOTIMPLEMENTED();
   1477   return false;
   1478 }
   1479 
   1480 bool RenderWidgetHostViewAura::GetSelectionRange(gfx::Range* range) const {
   1481   range->set_start(selection_range_.start());
   1482   range->set_end(selection_range_.end());
   1483   return true;
   1484 }
   1485 
   1486 bool RenderWidgetHostViewAura::SetSelectionRange(const gfx::Range& range) {
   1487   // TODO(suzhe): implement this method when fixing http://crbug.com/55130.
   1488   NOTIMPLEMENTED();
   1489   return false;
   1490 }
   1491 
   1492 bool RenderWidgetHostViewAura::DeleteRange(const gfx::Range& range) {
   1493   // TODO(suzhe): implement this method when fixing http://crbug.com/55130.
   1494   NOTIMPLEMENTED();
   1495   return false;
   1496 }
   1497 
   1498 bool RenderWidgetHostViewAura::GetTextFromRange(
   1499     const gfx::Range& range,
   1500     base::string16* text) const {
   1501   gfx::Range selection_text_range(selection_text_offset_,
   1502       selection_text_offset_ + selection_text_.length());
   1503 
   1504   if (!selection_text_range.Contains(range)) {
   1505     text->clear();
   1506     return false;
   1507   }
   1508   if (selection_text_range.EqualsIgnoringDirection(range)) {
   1509     // Avoid calling substr whose performance is low.
   1510     *text = selection_text_;
   1511   } else {
   1512     *text = selection_text_.substr(
   1513         range.GetMin() - selection_text_offset_,
   1514         range.length());
   1515   }
   1516   return true;
   1517 }
   1518 
   1519 void RenderWidgetHostViewAura::OnInputMethodChanged() {
   1520   if (!host_)
   1521     return;
   1522 
   1523   if (GetInputMethod())
   1524     host_->SetInputMethodActive(GetInputMethod()->IsActive());
   1525 
   1526   // TODO(suzhe): implement the newly added locale property of HTML DOM
   1527   // TextEvent.
   1528 }
   1529 
   1530 bool RenderWidgetHostViewAura::ChangeTextDirectionAndLayoutAlignment(
   1531       base::i18n::TextDirection direction) {
   1532   if (!host_)
   1533     return false;
   1534   host_->UpdateTextDirection(
   1535       direction == base::i18n::RIGHT_TO_LEFT ?
   1536       blink::WebTextDirectionRightToLeft :
   1537       blink::WebTextDirectionLeftToRight);
   1538   host_->NotifyTextDirection();
   1539   return true;
   1540 }
   1541 
   1542 void RenderWidgetHostViewAura::ExtendSelectionAndDelete(
   1543     size_t before, size_t after) {
   1544   RenderFrameHostImpl* rfh = GetFocusedFrame();
   1545   if (rfh)
   1546     rfh->ExtendSelectionAndDelete(before, after);
   1547 }
   1548 
   1549 void RenderWidgetHostViewAura::EnsureCaretInRect(const gfx::Rect& rect) {
   1550   gfx::Rect intersected_rect(
   1551       gfx::IntersectRects(rect, window_->GetBoundsInScreen()));
   1552 
   1553   if (intersected_rect.IsEmpty())
   1554     return;
   1555 
   1556   host_->ScrollFocusedEditableNodeIntoRect(
   1557       ConvertRectFromScreen(intersected_rect));
   1558 }
   1559 
   1560 void RenderWidgetHostViewAura::OnCandidateWindowShown() {
   1561   host_->CandidateWindowShown();
   1562 }
   1563 
   1564 void RenderWidgetHostViewAura::OnCandidateWindowUpdated() {
   1565   host_->CandidateWindowUpdated();
   1566 }
   1567 
   1568 void RenderWidgetHostViewAura::OnCandidateWindowHidden() {
   1569   host_->CandidateWindowHidden();
   1570 }
   1571 
   1572 bool RenderWidgetHostViewAura::IsEditingCommandEnabled(int command_id) {
   1573   return false;
   1574 }
   1575 
   1576 void RenderWidgetHostViewAura::ExecuteEditingCommand(int command_id) {
   1577 }
   1578 
   1579 ////////////////////////////////////////////////////////////////////////////////
   1580 // RenderWidgetHostViewAura, gfx::DisplayObserver implementation:
   1581 
   1582 void RenderWidgetHostViewAura::OnDisplayAdded(
   1583     const gfx::Display& new_display) {
   1584 }
   1585 
   1586 void RenderWidgetHostViewAura::OnDisplayRemoved(
   1587     const gfx::Display& old_display) {
   1588 }
   1589 
   1590 void RenderWidgetHostViewAura::OnDisplayMetricsChanged(
   1591     const gfx::Display& display, uint32_t metrics) {
   1592   // The screen info should be updated regardless of the metric change.
   1593   gfx::Screen* screen = gfx::Screen::GetScreenFor(window_);
   1594   if (display.id() == screen->GetDisplayNearestWindow(window_).id()) {
   1595     UpdateScreenInfo(window_);
   1596     current_cursor_.SetDisplayInfo(display);
   1597     UpdateCursorIfOverSelf();
   1598   }
   1599 }
   1600 
   1601 ////////////////////////////////////////////////////////////////////////////////
   1602 // RenderWidgetHostViewAura, aura::WindowDelegate implementation:
   1603 
   1604 gfx::Size RenderWidgetHostViewAura::GetMinimumSize() const {
   1605   return gfx::Size();
   1606 }
   1607 
   1608 gfx::Size RenderWidgetHostViewAura::GetMaximumSize() const {
   1609   return gfx::Size();
   1610 }
   1611 
   1612 void RenderWidgetHostViewAura::OnBoundsChanged(const gfx::Rect& old_bounds,
   1613                                                const gfx::Rect& new_bounds) {
   1614   base::AutoReset<bool> in_bounds_changed(&in_bounds_changed_, true);
   1615   // We care about this whenever RenderWidgetHostViewAura is not owned by a
   1616   // WebContentsViewAura since changes to the Window's bounds need to be
   1617   // messaged to the renderer.  WebContentsViewAura invokes SetSize() or
   1618   // SetBounds() itself.  No matter how we got here, any redundant calls are
   1619   // harmless.
   1620   SetSize(new_bounds.size());
   1621 
   1622   if (GetInputMethod())
   1623     GetInputMethod()->OnCaretBoundsChanged(this);
   1624 }
   1625 
   1626 gfx::NativeCursor RenderWidgetHostViewAura::GetCursor(const gfx::Point& point) {
   1627   if (mouse_locked_)
   1628     return ui::kCursorNone;
   1629   return current_cursor_.GetNativeCursor();
   1630 }
   1631 
   1632 int RenderWidgetHostViewAura::GetNonClientComponent(
   1633     const gfx::Point& point) const {
   1634   return HTCLIENT;
   1635 }
   1636 
   1637 bool RenderWidgetHostViewAura::ShouldDescendIntoChildForEventHandling(
   1638     aura::Window* child,
   1639     const gfx::Point& location) {
   1640   return true;
   1641 }
   1642 
   1643 bool RenderWidgetHostViewAura::CanFocus() {
   1644   return popup_type_ == blink::WebPopupTypeNone;
   1645 }
   1646 
   1647 void RenderWidgetHostViewAura::OnCaptureLost() {
   1648   host_->LostCapture();
   1649   if (touch_editing_client_)
   1650     touch_editing_client_->EndTouchEditing(false);
   1651 }
   1652 
   1653 void RenderWidgetHostViewAura::OnPaint(gfx::Canvas* canvas) {
   1654   // For non-opaque windows, we don't draw anything, since we depend on the
   1655   // canvas coming from the compositor to already be initialized as
   1656   // transparent.
   1657   if (window_->layer()->fills_bounds_opaquely())
   1658     canvas->DrawColor(SK_ColorWHITE);
   1659 }
   1660 
   1661 void RenderWidgetHostViewAura::OnDeviceScaleFactorChanged(
   1662     float device_scale_factor) {
   1663   if (!host_)
   1664     return;
   1665 
   1666   UpdateScreenInfo(window_);
   1667 
   1668   const gfx::Display display = gfx::Screen::GetScreenFor(window_)->
   1669       GetDisplayNearestWindow(window_);
   1670   DCHECK_EQ(device_scale_factor, display.device_scale_factor());
   1671   current_cursor_.SetDisplayInfo(display);
   1672 }
   1673 
   1674 void RenderWidgetHostViewAura::OnWindowDestroying(aura::Window* window) {
   1675 #if defined(OS_WIN)
   1676   HWND parent = NULL;
   1677   // If the tab was hidden and it's closed, host_->is_hidden would have been
   1678   // reset to false in RenderWidgetHostImpl::RendererExited.
   1679   if (!window_->GetRootWindow() || host_->is_hidden()) {
   1680     parent = ui::GetHiddenWindow();
   1681   } else {
   1682     parent = window_->GetHost()->GetAcceleratedWidget();
   1683   }
   1684   LPARAM lparam = reinterpret_cast<LPARAM>(this);
   1685   EnumChildWindows(parent, WindowDestroyingCallback, lparam);
   1686 #endif
   1687 
   1688   // Make sure that the input method no longer references to this object before
   1689   // this object is removed from the root window (i.e. this object loses access
   1690   // to the input method).
   1691   ui::InputMethod* input_method = GetInputMethod();
   1692   if (input_method)
   1693     input_method->DetachTextInputClient(this);
   1694 
   1695   if (overscroll_controller_)
   1696     overscroll_controller_->Reset();
   1697 }
   1698 
   1699 void RenderWidgetHostViewAura::OnWindowDestroyed(aura::Window* window) {
   1700   host_->ViewDestroyed();
   1701   delete this;
   1702 }
   1703 
   1704 void RenderWidgetHostViewAura::OnWindowTargetVisibilityChanged(bool visible) {
   1705 }
   1706 
   1707 bool RenderWidgetHostViewAura::HasHitTestMask() const {
   1708   return false;
   1709 }
   1710 
   1711 void RenderWidgetHostViewAura::GetHitTestMask(gfx::Path* mask) const {
   1712 }
   1713 
   1714 ////////////////////////////////////////////////////////////////////////////////
   1715 // RenderWidgetHostViewAura, ui::EventHandler implementation:
   1716 
   1717 void RenderWidgetHostViewAura::OnKeyEvent(ui::KeyEvent* event) {
   1718   TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnKeyEvent");
   1719   if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event))
   1720     return;
   1721 
   1722   if (popup_child_host_view_ && popup_child_host_view_->NeedsInputGrab()) {
   1723     popup_child_host_view_->OnKeyEvent(event);
   1724     if (event->handled())
   1725       return;
   1726   }
   1727 
   1728   // We need to handle the Escape key for Pepper Flash.
   1729   if (is_fullscreen_ && event->key_code() == ui::VKEY_ESCAPE) {
   1730     // Focus the window we were created from.
   1731     if (host_tracker_.get() && !host_tracker_->windows().empty()) {
   1732       aura::Window* host = *(host_tracker_->windows().begin());
   1733       aura::client::FocusClient* client = aura::client::GetFocusClient(host);
   1734       if (client) {
   1735         // Calling host->Focus() may delete |this|. We create a local observer
   1736         // for that. In that case we exit without further access to any members.
   1737         aura::WindowTracker tracker;
   1738         aura::Window* window = window_;
   1739         tracker.Add(window);
   1740         host->Focus();
   1741         if (!tracker.Contains(window)) {
   1742           event->SetHandled();
   1743           return;
   1744         }
   1745       }
   1746     }
   1747     if (!in_shutdown_) {
   1748       in_shutdown_ = true;
   1749       host_->Shutdown();
   1750     }
   1751   } else {
   1752     if (event->key_code() == ui::VKEY_RETURN) {
   1753       // Do not forward return key release events if no press event was handled.
   1754       if (event->type() == ui::ET_KEY_RELEASED && !accept_return_character_)
   1755         return;
   1756       // Accept return key character events between press and release events.
   1757       accept_return_character_ = event->type() == ui::ET_KEY_PRESSED;
   1758     }
   1759 
   1760     // We don't have to communicate with an input method here.
   1761     if (!event->HasNativeEvent()) {
   1762       NativeWebKeyboardEvent webkit_event(
   1763           event->type(),
   1764           event->is_char(),
   1765           event->is_char() ? event->GetCharacter() : event->key_code(),
   1766           event->flags(),
   1767           ui::EventTimeForNow().InSecondsF());
   1768       ForwardKeyboardEvent(webkit_event);
   1769     } else {
   1770       NativeWebKeyboardEvent webkit_event(event);
   1771       ForwardKeyboardEvent(webkit_event);
   1772     }
   1773   }
   1774   event->SetHandled();
   1775 }
   1776 
   1777 void RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent* event) {
   1778   TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnMouseEvent");
   1779 
   1780   if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event))
   1781     return;
   1782 
   1783   if (mouse_locked_) {
   1784     aura::client::CursorClient* cursor_client =
   1785         aura::client::GetCursorClient(window_->GetRootWindow());
   1786     DCHECK(!cursor_client || !cursor_client->IsCursorVisible());
   1787 
   1788     if (event->type() == ui::ET_MOUSEWHEEL) {
   1789       blink::WebMouseWheelEvent mouse_wheel_event =
   1790           MakeWebMouseWheelEvent(static_cast<ui::MouseWheelEvent*>(event));
   1791       if (mouse_wheel_event.deltaX != 0 || mouse_wheel_event.deltaY != 0)
   1792         host_->ForwardWheelEvent(mouse_wheel_event);
   1793       return;
   1794     }
   1795 
   1796     gfx::Point center(gfx::Rect(window_->bounds().size()).CenterPoint());
   1797 
   1798     // If we receive non client mouse messages while we are in the locked state
   1799     // it probably means that the mouse left the borders of our window and
   1800     // needs to be moved back to the center.
   1801     if (event->flags() & ui::EF_IS_NON_CLIENT) {
   1802       synthetic_move_sent_ = true;
   1803       window_->MoveCursorTo(center);
   1804       return;
   1805     }
   1806 
   1807     blink::WebMouseEvent mouse_event = MakeWebMouseEvent(event);
   1808 
   1809     bool is_move_to_center_event = (event->type() == ui::ET_MOUSE_MOVED ||
   1810         event->type() == ui::ET_MOUSE_DRAGGED) &&
   1811         mouse_event.x == center.x() && mouse_event.y == center.y();
   1812 
   1813     ModifyEventMovementAndCoords(&mouse_event);
   1814 
   1815     bool should_not_forward = is_move_to_center_event && synthetic_move_sent_;
   1816     if (should_not_forward) {
   1817       synthetic_move_sent_ = false;
   1818     } else {
   1819       // Check if the mouse has reached the border and needs to be centered.
   1820       if (ShouldMoveToCenter()) {
   1821         synthetic_move_sent_ = true;
   1822         window_->MoveCursorTo(center);
   1823       }
   1824       // Forward event to renderer.
   1825       if (CanRendererHandleEvent(event) &&
   1826           !(event->flags() & ui::EF_FROM_TOUCH)) {
   1827         host_->ForwardMouseEvent(mouse_event);
   1828         // Ensure that we get keyboard focus on mouse down as a plugin window
   1829         // may have grabbed keyboard focus.
   1830         if (event->type() == ui::ET_MOUSE_PRESSED)
   1831           SetKeyboardFocus();
   1832       }
   1833     }
   1834     return;
   1835   }
   1836 
   1837   // As the overscroll is handled during scroll events from the trackpad, the
   1838   // RWHVA window is transformed by the overscroll controller. This transform
   1839   // triggers a synthetic mouse-move event to be generated (by the aura
   1840   // RootWindow). But this event interferes with the overscroll gesture. So,
   1841   // ignore such synthetic mouse-move events if an overscroll gesture is in
   1842   // progress.
   1843   if (overscroll_controller_ &&
   1844       overscroll_controller_->overscroll_mode() != OVERSCROLL_NONE &&
   1845       event->flags() & ui::EF_IS_SYNTHESIZED &&
   1846       (event->type() == ui::ET_MOUSE_ENTERED ||
   1847        event->type() == ui::ET_MOUSE_EXITED ||
   1848        event->type() == ui::ET_MOUSE_MOVED)) {
   1849     event->StopPropagation();
   1850     return;
   1851   }
   1852 
   1853   if (event->type() == ui::ET_MOUSEWHEEL) {
   1854 #if defined(OS_WIN)
   1855     // We get mouse wheel/scroll messages even if we are not in the foreground.
   1856     // So here we check if we have any owned popup windows in the foreground and
   1857     // dismiss them.
   1858     aura::WindowTreeHost* host = window_->GetHost();
   1859     if (host) {
   1860       HWND parent = host->GetAcceleratedWidget();
   1861       HWND toplevel_hwnd = ::GetAncestor(parent, GA_ROOT);
   1862       EnumThreadWindows(GetCurrentThreadId(),
   1863                         DismissOwnedPopups,
   1864                         reinterpret_cast<LPARAM>(toplevel_hwnd));
   1865     }
   1866 #endif
   1867     blink::WebMouseWheelEvent mouse_wheel_event =
   1868         MakeWebMouseWheelEvent(static_cast<ui::MouseWheelEvent*>(event));
   1869     if (mouse_wheel_event.deltaX != 0 || mouse_wheel_event.deltaY != 0)
   1870       host_->ForwardWheelEvent(mouse_wheel_event);
   1871   } else if (CanRendererHandleEvent(event) &&
   1872              !(event->flags() & ui::EF_FROM_TOUCH)) {
   1873     blink::WebMouseEvent mouse_event = MakeWebMouseEvent(event);
   1874     ModifyEventMovementAndCoords(&mouse_event);
   1875     host_->ForwardMouseEvent(mouse_event);
   1876     // Ensure that we get keyboard focus on mouse down as a plugin window may
   1877     // have grabbed keyboard focus.
   1878     if (event->type() == ui::ET_MOUSE_PRESSED)
   1879       SetKeyboardFocus();
   1880   }
   1881 
   1882   switch (event->type()) {
   1883     case ui::ET_MOUSE_PRESSED:
   1884       window_->SetCapture();
   1885       // Confirm existing composition text on mouse click events, to make sure
   1886       // the input caret won't be moved with an ongoing composition text.
   1887       FinishImeCompositionSession();
   1888       break;
   1889     case ui::ET_MOUSE_RELEASED:
   1890       window_->ReleaseCapture();
   1891       break;
   1892     default:
   1893       break;
   1894   }
   1895 
   1896   // Needed to propagate mouse event to |window_->parent()->delegate()|, but
   1897   // note that it might be something other than a WebContentsViewAura instance.
   1898   // TODO(pkotwicz): Find a better way of doing this.
   1899   // In fullscreen mode which is typically used by flash, don't forward
   1900   // the mouse events to the parent. The renderer and the plugin process
   1901   // handle these events.
   1902   if (!is_fullscreen_ && window_->parent()->delegate() &&
   1903       !(event->flags() & ui::EF_FROM_TOUCH)) {
   1904     event->ConvertLocationToTarget(window_, window_->parent());
   1905     window_->parent()->delegate()->OnMouseEvent(event);
   1906   }
   1907 
   1908   if (!IsXButtonUpEvent(event))
   1909     event->SetHandled();
   1910 }
   1911 
   1912 void RenderWidgetHostViewAura::OnScrollEvent(ui::ScrollEvent* event) {
   1913   TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnScrollEvent");
   1914   if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event))
   1915     return;
   1916 
   1917   if (event->type() == ui::ET_SCROLL) {
   1918 #if !defined(OS_WIN)
   1919     // TODO(ananta)
   1920     // Investigate if this is true for Windows 8 Metro ASH as well.
   1921     if (event->finger_count() != 2)
   1922       return;
   1923 #endif
   1924     blink::WebGestureEvent gesture_event =
   1925         MakeWebGestureEventFlingCancel();
   1926     host_->ForwardGestureEvent(gesture_event);
   1927     blink::WebMouseWheelEvent mouse_wheel_event =
   1928         MakeWebMouseWheelEvent(event);
   1929     host_->ForwardWheelEvent(mouse_wheel_event);
   1930     RecordAction(base::UserMetricsAction("TrackpadScroll"));
   1931   } else if (event->type() == ui::ET_SCROLL_FLING_START ||
   1932              event->type() == ui::ET_SCROLL_FLING_CANCEL) {
   1933     blink::WebGestureEvent gesture_event =
   1934         MakeWebGestureEvent(event);
   1935     host_->ForwardGestureEvent(gesture_event);
   1936     if (event->type() == ui::ET_SCROLL_FLING_START)
   1937       RecordAction(base::UserMetricsAction("TrackpadScrollFling"));
   1938   }
   1939 
   1940   event->SetHandled();
   1941 }
   1942 
   1943 void RenderWidgetHostViewAura::OnTouchEvent(ui::TouchEvent* event) {
   1944   TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnTouchEvent");
   1945   if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event))
   1946     return;
   1947 
   1948   // Update the touch event first.
   1949   blink::WebTouchPoint* point = UpdateWebTouchEventFromUIEvent(*event,
   1950                                                                 &touch_event_);
   1951 
   1952   // Forward the touch event only if a touch point was updated, and there's a
   1953   // touch-event handler in the page, and no other touch-event is in the queue.
   1954   // It is important to always consume the event if there is a touch-event
   1955   // handler in the page, or some touch-event is already in the queue, even if
   1956   // no point has been updated, to make sure that this event does not get
   1957   // processed by the gesture recognizer before the events in the queue.
   1958   if (host_->ShouldForwardTouchEvent())
   1959     event->StopPropagation();
   1960 
   1961   if (point) {
   1962     if (host_->ShouldForwardTouchEvent())
   1963       host_->ForwardTouchEventWithLatencyInfo(touch_event_, *event->latency());
   1964     UpdateWebTouchEventAfterDispatch(&touch_event_, point);
   1965   }
   1966 }
   1967 
   1968 void RenderWidgetHostViewAura::OnGestureEvent(ui::GestureEvent* event) {
   1969   TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnGestureEvent");
   1970   if ((event->type() == ui::ET_GESTURE_PINCH_BEGIN ||
   1971       event->type() == ui::ET_GESTURE_PINCH_UPDATE ||
   1972       event->type() == ui::ET_GESTURE_PINCH_END) && !pinch_zoom_enabled_) {
   1973     event->SetHandled();
   1974     return;
   1975   }
   1976 
   1977   if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event))
   1978     return;
   1979 
   1980   RenderViewHostDelegate* delegate = NULL;
   1981   if (host_->IsRenderView())
   1982     delegate = RenderViewHost::From(host_)->GetDelegate();
   1983 
   1984   if (delegate && event->type() == ui::ET_GESTURE_BEGIN &&
   1985       event->details().touch_points() == 1) {
   1986     delegate->HandleGestureBegin();
   1987   }
   1988 
   1989   blink::WebGestureEvent gesture = MakeWebGestureEvent(event);
   1990   if (event->type() == ui::ET_GESTURE_TAP_DOWN) {
   1991     // Webkit does not stop a fling-scroll on tap-down. So explicitly send an
   1992     // event to stop any in-progress flings.
   1993     blink::WebGestureEvent fling_cancel = gesture;
   1994     fling_cancel.type = blink::WebInputEvent::GestureFlingCancel;
   1995     fling_cancel.sourceDevice = blink::WebGestureDeviceTouchscreen;
   1996     host_->ForwardGestureEvent(fling_cancel);
   1997   }
   1998 
   1999   if (gesture.type != blink::WebInputEvent::Undefined) {
   2000     host_->ForwardGestureEventWithLatencyInfo(gesture, *event->latency());
   2001 
   2002     if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN ||
   2003         event->type() == ui::ET_GESTURE_SCROLL_UPDATE ||
   2004         event->type() == ui::ET_GESTURE_SCROLL_END) {
   2005       RecordAction(base::UserMetricsAction("TouchscreenScroll"));
   2006     } else if (event->type() == ui::ET_SCROLL_FLING_START) {
   2007       RecordAction(base::UserMetricsAction("TouchscreenScrollFling"));
   2008     }
   2009   }
   2010 
   2011   if (delegate && event->type() == ui::ET_GESTURE_END &&
   2012       event->details().touch_points() == 1) {
   2013     delegate->HandleGestureEnd();
   2014   }
   2015 
   2016   // If a gesture is not processed by the webpage, then WebKit processes it
   2017   // (e.g. generates synthetic mouse events).
   2018   event->SetHandled();
   2019 }
   2020 
   2021 ////////////////////////////////////////////////////////////////////////////////
   2022 // RenderWidgetHostViewAura, aura::client::ActivationDelegate implementation:
   2023 
   2024 bool RenderWidgetHostViewAura::ShouldActivate() const {
   2025   aura::WindowTreeHost* host = window_->GetHost();
   2026   if (!host)
   2027     return true;
   2028   const ui::Event* event = host->dispatcher()->current_event();
   2029   if (!event)
   2030     return true;
   2031   return is_fullscreen_;
   2032 }
   2033 
   2034 ////////////////////////////////////////////////////////////////////////////////
   2035 // RenderWidgetHostViewAura,
   2036 //     aura::client::ActivationChangeObserver implementation:
   2037 
   2038 void RenderWidgetHostViewAura::OnWindowActivated(aura::Window* gained_active,
   2039                                                  aura::Window* lost_active) {
   2040   DCHECK(window_ == gained_active || window_ == lost_active);
   2041   if (window_ == gained_active) {
   2042     const ui::Event* event = window_->GetHost()->dispatcher()->current_event();
   2043     if (event && PointerEventActivates(*event))
   2044       host_->OnPointerEventActivate();
   2045   }
   2046 }
   2047 
   2048 ////////////////////////////////////////////////////////////////////////////////
   2049 // RenderWidgetHostViewAura, aura::client::CursorClientObserver implementation:
   2050 
   2051 void RenderWidgetHostViewAura::OnCursorVisibilityChanged(bool is_visible) {
   2052   NotifyRendererOfCursorVisibilityState(is_visible);
   2053 }
   2054 
   2055 ////////////////////////////////////////////////////////////////////////////////
   2056 // RenderWidgetHostViewAura, aura::client::FocusChangeObserver implementation:
   2057 
   2058 void RenderWidgetHostViewAura::OnWindowFocused(aura::Window* gained_focus,
   2059                                                aura::Window* lost_focus) {
   2060   DCHECK(window_ == gained_focus || window_ == lost_focus);
   2061   if (window_ == gained_focus) {
   2062     // We need to honor input bypass if the associated tab is does not want
   2063     // input. This gives the current focused window a chance to be the text
   2064     // input client and handle events.
   2065     if (host_->ignore_input_events())
   2066       return;
   2067 
   2068     host_->GotFocus();
   2069     host_->SetActive(true);
   2070 
   2071     ui::InputMethod* input_method = GetInputMethod();
   2072     if (input_method) {
   2073       // Ask the system-wide IME to send all TextInputClient messages to |this|
   2074       // object.
   2075       input_method->SetFocusedTextInputClient(this);
   2076       host_->SetInputMethodActive(input_method->IsActive());
   2077 
   2078       // Often the application can set focus to the view in response to a key
   2079       // down. However the following char event shouldn't be sent to the web
   2080       // page.
   2081       host_->SuppressNextCharEvents();
   2082     } else {
   2083       host_->SetInputMethodActive(false);
   2084     }
   2085 
   2086     BrowserAccessibilityManager* manager = GetBrowserAccessibilityManager();
   2087     if (manager)
   2088       manager->OnWindowFocused();
   2089   } else if (window_ == lost_focus) {
   2090     host_->SetActive(false);
   2091     host_->Blur();
   2092 
   2093     DetachFromInputMethod();
   2094     host_->SetInputMethodActive(false);
   2095 
   2096     if (touch_editing_client_)
   2097       touch_editing_client_->EndTouchEditing(false);
   2098 
   2099     if (overscroll_controller_)
   2100       overscroll_controller_->Cancel();
   2101 
   2102     BrowserAccessibilityManager* manager = GetBrowserAccessibilityManager();
   2103     if (manager)
   2104       manager->OnWindowBlurred();
   2105 
   2106     // If we lose the focus while fullscreen, close the window; Pepper Flash
   2107     // won't do it for us (unlike NPAPI Flash). However, we do not close the
   2108     // window if we lose the focus to a window on another display.
   2109     gfx::Screen* screen = gfx::Screen::GetScreenFor(window_);
   2110     bool focusing_other_display =
   2111         gained_focus && screen->GetNumDisplays() > 1 &&
   2112         (screen->GetDisplayNearestWindow(window_).id() !=
   2113          screen->GetDisplayNearestWindow(gained_focus).id());
   2114     if (is_fullscreen_ && !in_shutdown_ && !focusing_other_display) {
   2115 #if defined(OS_WIN)
   2116       // On Windows, if we are switching to a non Aura Window on a different
   2117       // screen we should not close the fullscreen window.
   2118       if (!gained_focus) {
   2119         POINT point = {0};
   2120         ::GetCursorPos(&point);
   2121         if (screen->GetDisplayNearestWindow(window_).id() !=
   2122             screen->GetDisplayNearestPoint(gfx::Point(point)).id())
   2123           return;
   2124       }
   2125 #endif
   2126       in_shutdown_ = true;
   2127       host_->Shutdown();
   2128     }
   2129   }
   2130 }
   2131 
   2132 ////////////////////////////////////////////////////////////////////////////////
   2133 // RenderWidgetHostViewAura, aura::WindowTreeHostObserver implementation:
   2134 
   2135 void RenderWidgetHostViewAura::OnHostMoved(const aura::WindowTreeHost* host,
   2136                                            const gfx::Point& new_origin) {
   2137   TRACE_EVENT1("ui", "RenderWidgetHostViewAura::OnHostMoved",
   2138                "new_origin", new_origin.ToString());
   2139 
   2140   UpdateScreenInfo(window_);
   2141 }
   2142 
   2143 ////////////////////////////////////////////////////////////////////////////////
   2144 // RenderWidgetHostViewAura, private:
   2145 
   2146 RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
   2147   if (touch_editing_client_)
   2148     touch_editing_client_->OnViewDestroyed();
   2149 
   2150   delegated_frame_host_.reset();
   2151   window_observer_.reset();
   2152   if (window_->GetHost())
   2153     window_->GetHost()->RemoveObserver(this);
   2154   UnlockMouse();
   2155   if (popup_parent_host_view_) {
   2156     DCHECK(popup_parent_host_view_->popup_child_host_view_ == NULL ||
   2157            popup_parent_host_view_->popup_child_host_view_ == this);
   2158     popup_parent_host_view_->popup_child_host_view_ = NULL;
   2159   }
   2160   if (popup_child_host_view_) {
   2161     DCHECK(popup_child_host_view_->popup_parent_host_view_ == NULL ||
   2162            popup_child_host_view_->popup_parent_host_view_ == this);
   2163     popup_child_host_view_->popup_parent_host_view_ = NULL;
   2164   }
   2165   event_filter_for_popup_exit_.reset();
   2166   aura::client::SetTooltipText(window_, NULL);
   2167   gfx::Screen::GetScreenFor(window_)->RemoveObserver(this);
   2168 
   2169   // This call is usually no-op since |this| object is already removed from the
   2170   // Aura root window and we don't have a way to get an input method object
   2171   // associated with the window, but just in case.
   2172   DetachFromInputMethod();
   2173 
   2174 #if defined(OS_WIN)
   2175   legacy_render_widget_host_HWND_.reset(NULL);
   2176 #endif
   2177 }
   2178 
   2179 void RenderWidgetHostViewAura::UpdateCursorIfOverSelf() {
   2180   const gfx::Point screen_point =
   2181       gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint();
   2182   aura::Window* root_window = window_->GetRootWindow();
   2183   if (!root_window)
   2184     return;
   2185 
   2186   gfx::Point root_window_point = screen_point;
   2187   aura::client::ScreenPositionClient* screen_position_client =
   2188       aura::client::GetScreenPositionClient(root_window);
   2189   if (screen_position_client) {
   2190     screen_position_client->ConvertPointFromScreen(
   2191         root_window, &root_window_point);
   2192   }
   2193 
   2194   if (root_window->GetEventHandlerForPoint(root_window_point) != window_)
   2195     return;
   2196 
   2197   gfx::NativeCursor cursor = current_cursor_.GetNativeCursor();
   2198   // Do not show loading cursor when the cursor is currently hidden.
   2199   if (is_loading_ && cursor != ui::kCursorNone)
   2200     cursor = ui::kCursorPointer;
   2201 
   2202   aura::client::CursorClient* cursor_client =
   2203       aura::client::GetCursorClient(root_window);
   2204   if (cursor_client) {
   2205     cursor_client->SetCursor(cursor);
   2206   }
   2207 }
   2208 
   2209 ui::InputMethod* RenderWidgetHostViewAura::GetInputMethod() const {
   2210   aura::Window* root_window = window_->GetRootWindow();
   2211   if (!root_window)
   2212     return NULL;
   2213   return root_window->GetProperty(aura::client::kRootWindowInputMethodKey);
   2214 }
   2215 
   2216 bool RenderWidgetHostViewAura::NeedsInputGrab() {
   2217   return popup_type_ == blink::WebPopupTypeSelect;
   2218 }
   2219 
   2220 void RenderWidgetHostViewAura::FinishImeCompositionSession() {
   2221   if (!has_composition_text_)
   2222     return;
   2223   if (host_) {
   2224     host_->ImeConfirmComposition(base::string16(), gfx::Range::InvalidRange(),
   2225                                  false);
   2226   }
   2227   ImeCancelComposition();
   2228 }
   2229 
   2230 void RenderWidgetHostViewAura::ModifyEventMovementAndCoords(
   2231     blink::WebMouseEvent* event) {
   2232   // If the mouse has just entered, we must report zero movementX/Y. Hence we
   2233   // reset any global_mouse_position set previously.
   2234   if (event->type == blink::WebInputEvent::MouseEnter ||
   2235       event->type == blink::WebInputEvent::MouseLeave)
   2236     global_mouse_position_.SetPoint(event->globalX, event->globalY);
   2237 
   2238   // Movement is computed by taking the difference of the new cursor position
   2239   // and the previous. Under mouse lock the cursor will be warped back to the
   2240   // center so that we are not limited by clipping boundaries.
   2241   // We do not measure movement as the delta from cursor to center because
   2242   // we may receive more mouse movement events before our warp has taken
   2243   // effect.
   2244   event->movementX = event->globalX - global_mouse_position_.x();
   2245   event->movementY = event->globalY - global_mouse_position_.y();
   2246 
   2247   global_mouse_position_.SetPoint(event->globalX, event->globalY);
   2248 
   2249   // Under mouse lock, coordinates of mouse are locked to what they were when
   2250   // mouse lock was entered.
   2251   if (mouse_locked_) {
   2252     event->x = unlocked_mouse_position_.x();
   2253     event->y = unlocked_mouse_position_.y();
   2254     event->windowX = unlocked_mouse_position_.x();
   2255     event->windowY = unlocked_mouse_position_.y();
   2256     event->globalX = unlocked_global_mouse_position_.x();
   2257     event->globalY = unlocked_global_mouse_position_.y();
   2258   } else {
   2259     unlocked_mouse_position_.SetPoint(event->windowX, event->windowY);
   2260     unlocked_global_mouse_position_.SetPoint(event->globalX, event->globalY);
   2261   }
   2262 }
   2263 
   2264 void RenderWidgetHostViewAura::NotifyRendererOfCursorVisibilityState(
   2265     bool is_visible) {
   2266   if (host_->is_hidden() ||
   2267       (cursor_visibility_state_in_renderer_ == VISIBLE && is_visible) ||
   2268       (cursor_visibility_state_in_renderer_ == NOT_VISIBLE && !is_visible))
   2269     return;
   2270 
   2271   cursor_visibility_state_in_renderer_ = is_visible ? VISIBLE : NOT_VISIBLE;
   2272   host_->SendCursorVisibilityState(is_visible);
   2273 }
   2274 
   2275 void RenderWidgetHostViewAura::SetOverscrollControllerEnabled(bool enabled) {
   2276   if (!enabled)
   2277     overscroll_controller_.reset();
   2278   else if (!overscroll_controller_)
   2279     overscroll_controller_.reset(new OverscrollController());
   2280 }
   2281 
   2282 void RenderWidgetHostViewAura::SchedulePaintIfNotInClip(
   2283     const gfx::Rect& rect,
   2284     const gfx::Rect& clip) {
   2285   if (!clip.IsEmpty()) {
   2286     gfx::Rect to_paint = gfx::SubtractRects(rect, clip);
   2287     if (!to_paint.IsEmpty())
   2288       window_->SchedulePaintInRect(to_paint);
   2289   } else {
   2290     window_->SchedulePaintInRect(rect);
   2291   }
   2292 }
   2293 
   2294 bool RenderWidgetHostViewAura::ShouldMoveToCenter() {
   2295   gfx::Rect rect = window_->bounds();
   2296   rect = ConvertRectToScreen(rect);
   2297   int border_x = rect.width() * kMouseLockBorderPercentage / 100;
   2298   int border_y = rect.height() * kMouseLockBorderPercentage / 100;
   2299 
   2300   return global_mouse_position_.x() < rect.x() + border_x ||
   2301       global_mouse_position_.x() > rect.right() - border_x ||
   2302       global_mouse_position_.y() < rect.y() + border_y ||
   2303       global_mouse_position_.y() > rect.bottom() - border_y;
   2304 }
   2305 
   2306 void RenderWidgetHostViewAura::AddedToRootWindow() {
   2307   window_->GetHost()->AddObserver(this);
   2308   UpdateScreenInfo(window_);
   2309 
   2310   aura::client::CursorClient* cursor_client =
   2311       aura::client::GetCursorClient(window_->GetRootWindow());
   2312   if (cursor_client) {
   2313     cursor_client->AddObserver(this);
   2314     NotifyRendererOfCursorVisibilityState(cursor_client->IsCursorVisible());
   2315   }
   2316   if (HasFocus()) {
   2317     ui::InputMethod* input_method = GetInputMethod();
   2318     if (input_method)
   2319       input_method->SetFocusedTextInputClient(this);
   2320   }
   2321 
   2322 #if defined(OS_WIN)
   2323   // The parent may have changed here. Ensure that the legacy window is
   2324   // reparented accordingly.
   2325   if (legacy_render_widget_host_HWND_)
   2326     legacy_render_widget_host_HWND_->UpdateParent(
   2327         reinterpret_cast<HWND>(GetNativeViewId()));
   2328 #endif
   2329 
   2330   delegated_frame_host_->AddedToWindow();
   2331 }
   2332 
   2333 void RenderWidgetHostViewAura::RemovingFromRootWindow() {
   2334   aura::client::CursorClient* cursor_client =
   2335       aura::client::GetCursorClient(window_->GetRootWindow());
   2336   if (cursor_client)
   2337     cursor_client->RemoveObserver(this);
   2338 
   2339   DetachFromInputMethod();
   2340 
   2341   window_->GetHost()->RemoveObserver(this);
   2342   delegated_frame_host_->RemovingFromWindow();
   2343 
   2344 #if defined(OS_WIN)
   2345   // Update the legacy window's parent temporarily to the desktop window. It
   2346   // will eventually get reparented to the right root.
   2347   if (legacy_render_widget_host_HWND_)
   2348     legacy_render_widget_host_HWND_->UpdateParent(::GetDesktopWindow());
   2349 #endif
   2350 }
   2351 
   2352 void RenderWidgetHostViewAura::DetachFromInputMethod() {
   2353   ui::InputMethod* input_method = GetInputMethod();
   2354   if (input_method && input_method->GetTextInputClient() == this)
   2355     input_method->SetFocusedTextInputClient(NULL);
   2356 }
   2357 
   2358 void RenderWidgetHostViewAura::ForwardKeyboardEvent(
   2359     const NativeWebKeyboardEvent& event) {
   2360 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
   2361   ui::TextEditKeyBindingsDelegateAuraLinux* keybinding_delegate =
   2362       ui::GetTextEditKeyBindingsDelegate();
   2363   std::vector<ui::TextEditCommandAuraLinux> commands;
   2364   if (!event.skip_in_browser &&
   2365       keybinding_delegate &&
   2366       event.os_event &&
   2367       keybinding_delegate->MatchEvent(*event.os_event, &commands)) {
   2368     // Transform from ui/ types to content/ types.
   2369     EditCommands edit_commands;
   2370     for (std::vector<ui::TextEditCommandAuraLinux>::const_iterator it =
   2371              commands.begin(); it != commands.end(); ++it) {
   2372       edit_commands.push_back(EditCommand(it->GetCommandString(),
   2373                                           it->argument()));
   2374     }
   2375     host_->Send(new InputMsg_SetEditCommandsForNextKeyEvent(
   2376         host_->GetRoutingID(), edit_commands));
   2377     NativeWebKeyboardEvent copy_event(event);
   2378     copy_event.match_edit_command = true;
   2379     host_->ForwardKeyboardEvent(copy_event);
   2380     return;
   2381   }
   2382 #endif
   2383 
   2384   host_->ForwardKeyboardEvent(event);
   2385 }
   2386 
   2387 SkBitmap::Config RenderWidgetHostViewAura::PreferredReadbackFormat() {
   2388   return SkBitmap::kARGB_8888_Config;
   2389 }
   2390 
   2391 ////////////////////////////////////////////////////////////////////////////////
   2392 // DelegatedFrameHost, public:
   2393 
   2394 ui::Compositor* RenderWidgetHostViewAura::GetCompositor() const {
   2395   aura::WindowTreeHost* host = window_->GetHost();
   2396   return host ? host->compositor() : NULL;
   2397 }
   2398 
   2399 ui::Layer* RenderWidgetHostViewAura::GetLayer() {
   2400   return window_->layer();
   2401 }
   2402 
   2403 RenderWidgetHostImpl* RenderWidgetHostViewAura::GetHost() {
   2404   return host_;
   2405 }
   2406 
   2407 void RenderWidgetHostViewAura::SchedulePaintInRect(
   2408     const gfx::Rect& damage_rect_in_dip) {
   2409   window_->SchedulePaintInRect(damage_rect_in_dip);
   2410 }
   2411 
   2412 bool RenderWidgetHostViewAura::IsVisible() {
   2413   return IsShowing();
   2414 }
   2415 
   2416 gfx::Size RenderWidgetHostViewAura::DesiredFrameSize() {
   2417   return window_->bounds().size();
   2418 }
   2419 
   2420 float RenderWidgetHostViewAura::CurrentDeviceScaleFactor() {
   2421   return current_device_scale_factor_;
   2422 }
   2423 
   2424 gfx::Size RenderWidgetHostViewAura::ConvertViewSizeToPixel(
   2425     const gfx::Size& size) {
   2426   return content::ConvertViewSizeToPixel(this, size);
   2427 }
   2428 
   2429 scoped_ptr<ResizeLock> RenderWidgetHostViewAura::CreateResizeLock(
   2430     bool defer_compositor_lock) {
   2431   gfx::Size desired_size = window_->bounds().size();
   2432   return scoped_ptr<ResizeLock>(new CompositorResizeLock(
   2433       window_->GetHost(),
   2434       desired_size,
   2435       defer_compositor_lock,
   2436       base::TimeDelta::FromMilliseconds(kResizeLockTimeoutMs)));
   2437 }
   2438 
   2439 DelegatedFrameHost* RenderWidgetHostViewAura::GetDelegatedFrameHost() const {
   2440   return delegated_frame_host_.get();
   2441 }
   2442 
   2443 ////////////////////////////////////////////////////////////////////////////////
   2444 // RenderWidgetHostViewBase, public:
   2445 
   2446 // static
   2447 void RenderWidgetHostViewBase::GetDefaultScreenInfo(WebScreenInfo* results) {
   2448   GetScreenInfoForWindow(results, NULL);
   2449 }
   2450 
   2451 }  // namespace content
   2452