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
96using gfx::RectToSkIRect;
97using gfx::SkIRectToRect;
98
99using blink::WebScreenInfo;
100using blink::WebInputEvent;
101using blink::WebGestureEvent;
102using blink::WebTouchEvent;
103
104namespace content {
105
106namespace {
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.
115const 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.
121const int kResizeLockTimeoutMs = 67;
122
123#if defined(OS_WIN)
124// Used to associate a plugin HWND with its RenderWidgetHostViewAura instance.
125const wchar_t kWidgetOwnerProperty[] = L"RenderWidgetHostViewAuraOwner";
126
127BOOL 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
138BOOL 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
146BOOL 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
158struct 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.
168BOOL 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.
217BOOL 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
231void 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
244bool 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.
288bool 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
299void 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
321bool 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.
338class 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
366void 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.
391class 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
423RenderWidgetHostViewAura::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
461void 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
468void 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
515void 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
542RenderWidgetHost* RenderWidgetHostViewAura::GetRenderWidgetHost() const {
543  return host_;
544}
545
546void 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
578void 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
599void 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
606void 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
624gfx::NativeView RenderWidgetHostViewAura::GetNativeView() const {
625  return window_;
626}
627
628gfx::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
637gfx::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
654ui::TextInputClient* RenderWidgetHostViewAura::GetTextInputClient() {
655  return this;
656}
657
658void 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
668RenderFrameHostImpl* 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
680void 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
732void 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
741void RenderWidgetHostViewAura::Blur() {
742  window_->Blur();
743}
744
745bool RenderWidgetHostViewAura::HasFocus() const {
746  return window_->HasFocus();
747}
748
749bool RenderWidgetHostViewAura::IsSurfaceAvailableForCopy() const {
750  return delegated_frame_host_->CanCopyToBitmap();
751}
752
753void 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
762void 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
771bool RenderWidgetHostViewAura::IsShowing() {
772  return window_->IsVisible();
773}
774
775gfx::Rect RenderWidgetHostViewAura::GetViewBounds() const {
776  return window_->GetBoundsInScreen();
777}
778
779void RenderWidgetHostViewAura::SetBackgroundOpaque(bool opaque) {
780  RenderWidgetHostViewBase::SetBackgroundOpaque(opaque);
781  host_->SetBackgroundOpaque(opaque);
782  window_->layer()->SetFillsBoundsOpaquely(opaque);
783}
784
785gfx::Size RenderWidgetHostViewAura::GetVisibleViewportSize() const {
786  gfx::Rect requested_rect(GetRequestedRendererSize());
787  requested_rect.Inset(insets_);
788  return requested_rect.size();
789}
790
791void RenderWidgetHostViewAura::SetInsets(const gfx::Insets& insets) {
792  if (insets != insets_) {
793    insets_ = insets;
794    host_->WasResized();
795  }
796}
797
798void 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
806void RenderWidgetHostViewAura::SetIsLoading(bool is_loading) {
807  is_loading_ = is_loading;
808  UpdateCursorIfOverSelf();
809}
810
811void 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
830void RenderWidgetHostViewAura::ImeCancelComposition() {
831  if (GetInputMethod())
832    GetInputMethod()->CancelComposition(this);
833  has_composition_text_ = false;
834}
835
836void RenderWidgetHostViewAura::ImeCompositionRangeChanged(
837    const gfx::Range& range,
838    const std::vector<gfx::Rect>& character_bounds) {
839  composition_character_bounds_ = character_bounds;
840}
841
842void RenderWidgetHostViewAura::RenderProcessGone(base::TerminationStatus status,
843                                                 int error_code) {
844  UpdateCursorIfOverSelf();
845  Destroy();
846}
847
848void 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
856void 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
869void 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
894gfx::Size RenderWidgetHostViewAura::GetRequestedRendererSize() const {
895  return delegated_frame_host_->GetRequestedRendererSize();
896}
897
898void 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
916void 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
926void 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
935void 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
943bool RenderWidgetHostViewAura::CanCopyToVideoFrame() const {
944  return delegated_frame_host_->CanCopyToVideoFrame();
945}
946
947bool RenderWidgetHostViewAura::CanSubscribeFrame() const {
948  return delegated_frame_host_->CanSubscribeFrame();
949}
950
951void RenderWidgetHostViewAura::BeginFrameSubscription(
952    scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) {
953  delegated_frame_host_->BeginFrameSubscription(subscriber.Pass());
954}
955
956void RenderWidgetHostViewAura::EndFrameSubscription() {
957  delegated_frame_host_->EndFrameSubscription();
958}
959
960void RenderWidgetHostViewAura::AcceleratedSurfaceInitialized(int host_id,
961                                                             int route_id) {
962}
963
964void 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
981void 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)
1029bool RenderWidgetHostViewAura::UsesNativeWindowFrame() const {
1030  return (legacy_render_widget_host_HWND_ != NULL);
1031}
1032
1033void 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
1054void 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
1063void 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
1069void 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)
1092void RenderWidgetHostViewAura::SetParentNativeViewAccessible(
1093    gfx::NativeViewAccessible accessible_parent) {
1094  if (GetBrowserAccessibilityManager()) {
1095    GetBrowserAccessibilityManager()->ToBrowserAccessibilityManagerWin()
1096        ->set_parent_iaccessible(accessible_parent);
1097  }
1098}
1099
1100gfx::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
1110void 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
1116void RenderWidgetHostViewAura::AcceleratedSurfaceSuspend() {
1117}
1118
1119void RenderWidgetHostViewAura::AcceleratedSurfaceRelease() {
1120}
1121
1122bool 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
1130void RenderWidgetHostViewAura::GetScreenInfo(WebScreenInfo* results) {
1131  GetScreenInfoForWindow(results, window_->GetRootWindow() ? window_ : NULL);
1132}
1133
1134gfx::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
1172void 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
1181void 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
1193void 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
1213scoped_ptr<SyntheticGestureTarget>
1214RenderWidgetHostViewAura::CreateSyntheticGestureTarget() {
1215  return scoped_ptr<SyntheticGestureTarget>(
1216      new SyntheticGestureTargetAura(host_));
1217}
1218
1219InputEventAckState 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
1242void 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
1262gfx::GLSurfaceHandle RenderWidgetHostViewAura::GetCompositingSurface() {
1263  return ImageTransportFactory::GetInstance()->GetSharedSurfaceHandle();
1264}
1265
1266bool 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
1295void 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:
1322void 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
1351void 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
1359void RenderWidgetHostViewAura::ClearCompositionText() {
1360  if (host_ && has_composition_text_)
1361    host_->ImeCancelComposition();
1362  has_composition_text_ = false;
1363}
1364
1365void 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
1372void 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
1391gfx::NativeWindow RenderWidgetHostViewAura::GetAttachedWindow() const {
1392  return window_;
1393}
1394
1395ui::TextInputType RenderWidgetHostViewAura::GetTextInputType() const {
1396  return text_input_type_;
1397}
1398
1399ui::TextInputMode RenderWidgetHostViewAura::GetTextInputMode() const {
1400  return text_input_mode_;
1401}
1402
1403bool RenderWidgetHostViewAura::CanComposeInline() const {
1404  return can_compose_inline_;
1405}
1406
1407gfx::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
1427gfx::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
1447gfx::Rect RenderWidgetHostViewAura::GetCaretBounds() const {
1448  const gfx::Rect rect =
1449      gfx::UnionRects(selection_anchor_rect_, selection_focus_rect_);
1450  return ConvertRectToScreen(rect);
1451}
1452
1453bool 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
1463bool RenderWidgetHostViewAura::HasCompositionText() const {
1464  return has_composition_text_;
1465}
1466
1467bool 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
1473bool 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
1480bool 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
1486bool 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
1492bool 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
1498bool 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
1519void 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
1530bool 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
1542void RenderWidgetHostViewAura::ExtendSelectionAndDelete(
1543    size_t before, size_t after) {
1544  RenderFrameHostImpl* rfh = GetFocusedFrame();
1545  if (rfh)
1546    rfh->ExtendSelectionAndDelete(before, after);
1547}
1548
1549void 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
1560void RenderWidgetHostViewAura::OnCandidateWindowShown() {
1561  host_->CandidateWindowShown();
1562}
1563
1564void RenderWidgetHostViewAura::OnCandidateWindowUpdated() {
1565  host_->CandidateWindowUpdated();
1566}
1567
1568void RenderWidgetHostViewAura::OnCandidateWindowHidden() {
1569  host_->CandidateWindowHidden();
1570}
1571
1572bool RenderWidgetHostViewAura::IsEditingCommandEnabled(int command_id) {
1573  return false;
1574}
1575
1576void RenderWidgetHostViewAura::ExecuteEditingCommand(int command_id) {
1577}
1578
1579////////////////////////////////////////////////////////////////////////////////
1580// RenderWidgetHostViewAura, gfx::DisplayObserver implementation:
1581
1582void RenderWidgetHostViewAura::OnDisplayAdded(
1583    const gfx::Display& new_display) {
1584}
1585
1586void RenderWidgetHostViewAura::OnDisplayRemoved(
1587    const gfx::Display& old_display) {
1588}
1589
1590void 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
1604gfx::Size RenderWidgetHostViewAura::GetMinimumSize() const {
1605  return gfx::Size();
1606}
1607
1608gfx::Size RenderWidgetHostViewAura::GetMaximumSize() const {
1609  return gfx::Size();
1610}
1611
1612void 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
1626gfx::NativeCursor RenderWidgetHostViewAura::GetCursor(const gfx::Point& point) {
1627  if (mouse_locked_)
1628    return ui::kCursorNone;
1629  return current_cursor_.GetNativeCursor();
1630}
1631
1632int RenderWidgetHostViewAura::GetNonClientComponent(
1633    const gfx::Point& point) const {
1634  return HTCLIENT;
1635}
1636
1637bool RenderWidgetHostViewAura::ShouldDescendIntoChildForEventHandling(
1638    aura::Window* child,
1639    const gfx::Point& location) {
1640  return true;
1641}
1642
1643bool RenderWidgetHostViewAura::CanFocus() {
1644  return popup_type_ == blink::WebPopupTypeNone;
1645}
1646
1647void RenderWidgetHostViewAura::OnCaptureLost() {
1648  host_->LostCapture();
1649  if (touch_editing_client_)
1650    touch_editing_client_->EndTouchEditing(false);
1651}
1652
1653void 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
1661void 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
1674void 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
1699void RenderWidgetHostViewAura::OnWindowDestroyed(aura::Window* window) {
1700  host_->ViewDestroyed();
1701  delete this;
1702}
1703
1704void RenderWidgetHostViewAura::OnWindowTargetVisibilityChanged(bool visible) {
1705}
1706
1707bool RenderWidgetHostViewAura::HasHitTestMask() const {
1708  return false;
1709}
1710
1711void RenderWidgetHostViewAura::GetHitTestMask(gfx::Path* mask) const {
1712}
1713
1714////////////////////////////////////////////////////////////////////////////////
1715// RenderWidgetHostViewAura, ui::EventHandler implementation:
1716
1717void 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
1777void 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
1912void 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
1943void 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
1968void 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
2024bool 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
2038void 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
2051void RenderWidgetHostViewAura::OnCursorVisibilityChanged(bool is_visible) {
2052  NotifyRendererOfCursorVisibilityState(is_visible);
2053}
2054
2055////////////////////////////////////////////////////////////////////////////////
2056// RenderWidgetHostViewAura, aura::client::FocusChangeObserver implementation:
2057
2058void 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
2135void 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
2146RenderWidgetHostViewAura::~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
2179void 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
2209ui::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
2216bool RenderWidgetHostViewAura::NeedsInputGrab() {
2217  return popup_type_ == blink::WebPopupTypeSelect;
2218}
2219
2220void 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
2230void 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
2264void 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
2275void RenderWidgetHostViewAura::SetOverscrollControllerEnabled(bool enabled) {
2276  if (!enabled)
2277    overscroll_controller_.reset();
2278  else if (!overscroll_controller_)
2279    overscroll_controller_.reset(new OverscrollController());
2280}
2281
2282void 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
2294bool 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
2306void 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
2333void 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
2352void RenderWidgetHostViewAura::DetachFromInputMethod() {
2353  ui::InputMethod* input_method = GetInputMethod();
2354  if (input_method && input_method->GetTextInputClient() == this)
2355    input_method->SetFocusedTextInputClient(NULL);
2356}
2357
2358void 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
2387SkBitmap::Config RenderWidgetHostViewAura::PreferredReadbackFormat() {
2388  return SkBitmap::kARGB_8888_Config;
2389}
2390
2391////////////////////////////////////////////////////////////////////////////////
2392// DelegatedFrameHost, public:
2393
2394ui::Compositor* RenderWidgetHostViewAura::GetCompositor() const {
2395  aura::WindowTreeHost* host = window_->GetHost();
2396  return host ? host->compositor() : NULL;
2397}
2398
2399ui::Layer* RenderWidgetHostViewAura::GetLayer() {
2400  return window_->layer();
2401}
2402
2403RenderWidgetHostImpl* RenderWidgetHostViewAura::GetHost() {
2404  return host_;
2405}
2406
2407void RenderWidgetHostViewAura::SchedulePaintInRect(
2408    const gfx::Rect& damage_rect_in_dip) {
2409  window_->SchedulePaintInRect(damage_rect_in_dip);
2410}
2411
2412bool RenderWidgetHostViewAura::IsVisible() {
2413  return IsShowing();
2414}
2415
2416gfx::Size RenderWidgetHostViewAura::DesiredFrameSize() {
2417  return window_->bounds().size();
2418}
2419
2420float RenderWidgetHostViewAura::CurrentDeviceScaleFactor() {
2421  return current_device_scale_factor_;
2422}
2423
2424gfx::Size RenderWidgetHostViewAura::ConvertViewSizeToPixel(
2425    const gfx::Size& size) {
2426  return content::ConvertViewSizeToPixel(this, size);
2427}
2428
2429scoped_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
2439DelegatedFrameHost* RenderWidgetHostViewAura::GetDelegatedFrameHost() const {
2440  return delegated_frame_host_.get();
2441}
2442
2443////////////////////////////////////////////////////////////////////////////////
2444// RenderWidgetHostViewBase, public:
2445
2446// static
2447void RenderWidgetHostViewBase::GetDefaultScreenInfo(WebScreenInfo* results) {
2448  GetScreenInfoForWindow(results, NULL);
2449}
2450
2451}  // namespace content
2452