1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
7 #include "base/auto_reset.h"
8 #include "base/basictypes.h"
10 #include "base/callback_helpers.h"
11 #include "base/debug/trace_event.h"
12 #include "base/logging.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "cc/output/copy_output_request.h"
16 #include "cc/output/copy_output_result.h"
17 #include "cc/resources/texture_mailbox.h"
18 #include "cc/trees/layer_tree_settings.h"
19 #include "content/browser/accessibility/browser_accessibility_manager.h"
20 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
21 #include "content/browser/frame_host/frame_tree.h"
22 #include "content/browser/frame_host/frame_tree_node.h"
23 #include "content/browser/frame_host/render_frame_host_impl.h"
24 #include "content/browser/gpu/compositor_util.h"
25 #include "content/browser/renderer_host/compositor_resize_lock_aura.h"
26 #include "content/browser/renderer_host/dip_util.h"
27 #include "content/browser/renderer_host/input/synthetic_gesture_target_aura.h"
28 #include "content/browser/renderer_host/overscroll_controller.h"
29 #include "content/browser/renderer_host/render_view_host_delegate.h"
30 #include "content/browser/renderer_host/render_view_host_impl.h"
31 #include "content/browser/renderer_host/render_widget_host_impl.h"
32 #include "content/browser/renderer_host/ui_events_helper.h"
33 #include "content/browser/renderer_host/web_input_event_aura.h"
34 #include "content/common/gpu/client/gl_helper.h"
35 #include "content/common/gpu/gpu_messages.h"
36 #include "content/common/view_messages.h"
37 #include "content/public/browser/content_browser_client.h"
38 #include "content/public/browser/render_view_host.h"
39 #include "content/public/browser/render_widget_host_view_frame_subscriber.h"
40 #include "content/public/browser/user_metrics.h"
41 #include "third_party/WebKit/public/platform/WebScreenInfo.h"
42 #include "third_party/WebKit/public/web/WebCompositionUnderline.h"
43 #include "third_party/WebKit/public/web/WebInputEvent.h"
44 #include "ui/aura/client/aura_constants.h"
45 #include "ui/aura/client/cursor_client.h"
46 #include "ui/aura/client/cursor_client_observer.h"
47 #include "ui/aura/client/focus_client.h"
48 #include "ui/aura/client/screen_position_client.h"
49 #include "ui/aura/client/window_tree_client.h"
50 #include "ui/aura/env.h"
51 #include "ui/aura/window.h"
52 #include "ui/aura/window_event_dispatcher.h"
53 #include "ui/aura/window_observer.h"
54 #include "ui/aura/window_tracker.h"
55 #include "ui/aura/window_tree_host.h"
56 #include "ui/base/clipboard/scoped_clipboard_writer.h"
57 #include "ui/base/hit_test.h"
58 #include "ui/base/ime/input_method.h"
59 #include "ui/base/ui_base_types.h"
60 #include "ui/compositor/compositor_vsync_manager.h"
61 #include "ui/events/event.h"
62 #include "ui/events/event_utils.h"
63 #include "ui/events/gestures/gesture_recognizer.h"
64 #include "ui/gfx/canvas.h"
65 #include "ui/gfx/display.h"
66 #include "ui/gfx/rect_conversions.h"
67 #include "ui/gfx/screen.h"
68 #include "ui/gfx/size_conversions.h"
69 #include "ui/gfx/skia_util.h"
70 #include "ui/wm/public/activation_client.h"
71 #include "ui/wm/public/scoped_tooltip_disabler.h"
72 #include "ui/wm/public/tooltip_client.h"
73 #include "ui/wm/public/transient_window_client.h"
74 #include "ui/wm/public/window_types.h"
77 #include "content/browser/accessibility/browser_accessibility_manager_win.h"
78 #include "content/browser/accessibility/browser_accessibility_win.h"
79 #include "content/browser/renderer_host/legacy_render_widget_host_win.h"
80 #include "content/common/plugin_constants_win.h"
81 #include "ui/base/win/hidden_window.h"
82 #include "ui/gfx/gdi_util.h"
83 #include "ui/gfx/win/dpi.h"
86 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
87 #include "content/common/input_messages.h"
88 #include "ui/events/linux/text_edit_command_auralinux.h"
89 #include "ui/events/linux/text_edit_key_bindings_delegate_auralinux.h"
92 using gfx::RectToSkIRect
;
93 using gfx::SkIRectToRect
;
95 using blink::WebScreenInfo
;
96 using blink::WebTouchEvent
;
102 // In mouse lock mode, we need to prevent the (invisible) cursor from hitting
103 // the border of the view, in order to get valid movement information. However,
104 // forcing the cursor back to the center of the view after each mouse move
105 // doesn't work well. It reduces the frequency of useful mouse move messages
106 // significantly. Therefore, we move the cursor to the center of the view only
107 // if it approaches the border. |kMouseLockBorderPercentage| specifies the width
108 // of the border area, in percentage of the corresponding dimension.
109 const int kMouseLockBorderPercentage
= 15;
111 // When accelerated compositing is enabled and a widget resize is pending,
112 // we delay further resizes of the UI. The following constant is the maximum
113 // length of time that we should delay further UI resizes while waiting for a
114 // resized frame from a renderer.
115 const int kResizeLockTimeoutMs
= 67;
118 // Used to associate a plugin HWND with its RenderWidgetHostViewAura instance.
119 const wchar_t kWidgetOwnerProperty
[] = L
"RenderWidgetHostViewAuraOwner";
121 BOOL CALLBACK
WindowDestroyingCallback(HWND window
, LPARAM param
) {
122 RenderWidgetHostViewAura
* widget
=
123 reinterpret_cast<RenderWidgetHostViewAura
*>(param
);
124 if (GetProp(window
, kWidgetOwnerProperty
) == widget
) {
125 // Properties set on HWNDs must be removed to avoid leaks.
126 RemoveProp(window
, kWidgetOwnerProperty
);
127 RenderWidgetHostViewBase::DetachPluginWindowsCallback(window
);
132 BOOL CALLBACK
HideWindowsCallback(HWND window
, LPARAM param
) {
133 RenderWidgetHostViewAura
* widget
=
134 reinterpret_cast<RenderWidgetHostViewAura
*>(param
);
135 if (GetProp(window
, kWidgetOwnerProperty
) == widget
)
136 SetParent(window
, ui::GetHiddenWindow());
140 BOOL CALLBACK
ShowWindowsCallback(HWND window
, LPARAM param
) {
141 RenderWidgetHostViewAura
* widget
=
142 reinterpret_cast<RenderWidgetHostViewAura
*>(param
);
144 if (GetProp(window
, kWidgetOwnerProperty
) == widget
&&
145 widget
->GetNativeView()->GetHost()) {
146 HWND parent
= widget
->GetNativeView()->GetHost()->GetAcceleratedWidget();
147 SetParent(window
, parent
);
152 struct CutoutRectsParams
{
153 RenderWidgetHostViewAura
* widget
;
154 std::vector
<gfx::Rect
> cutout_rects
;
155 std::map
<HWND
, WebPluginGeometry
>* geometry
;
158 // Used to update the region for the windowed plugin to draw in. We start with
159 // the clip rect from the renderer, then remove the cutout rects from the
160 // renderer, and then remove the transient windows from the root window and the
161 // constrained windows from the parent window.
162 BOOL CALLBACK
SetCutoutRectsCallback(HWND window
, LPARAM param
) {
163 CutoutRectsParams
* params
= reinterpret_cast<CutoutRectsParams
*>(param
);
165 if (GetProp(window
, kWidgetOwnerProperty
) == params
->widget
) {
166 // First calculate the offset of this plugin from the root window, since
167 // the cutouts are relative to the root window.
169 params
->widget
->GetNativeView()->GetHost()->GetAcceleratedWidget();
171 offset
.x
= offset
.y
= 0;
172 MapWindowPoints(window
, parent
, &offset
, 1);
174 // Now get the cached clip rect and cutouts for this plugin window that came
175 // from the renderer.
176 std::map
<HWND
, WebPluginGeometry
>::iterator i
= params
->geometry
->begin();
177 while (i
!= params
->geometry
->end() &&
178 i
->second
.window
!= window
&&
179 GetParent(i
->second
.window
) != window
) {
183 if (i
== params
->geometry
->end()) {
188 HRGN hrgn
= CreateRectRgn(i
->second
.clip_rect
.x(),
189 i
->second
.clip_rect
.y(),
190 i
->second
.clip_rect
.right(),
191 i
->second
.clip_rect
.bottom());
192 // We start with the cutout rects that came from the renderer, then add the
193 // ones that came from transient and constrained windows.
194 std::vector
<gfx::Rect
> cutout_rects
= i
->second
.cutout_rects
;
195 for (size_t i
= 0; i
< params
->cutout_rects
.size(); ++i
) {
196 gfx::Rect offset_cutout
= params
->cutout_rects
[i
];
197 offset_cutout
.Offset(-offset
.x
, -offset
.y
);
198 cutout_rects
.push_back(offset_cutout
);
200 gfx::SubtractRectanglesFromRegion(hrgn
, cutout_rects
);
201 // If we don't have any cutout rects then no point in messing with the
203 if (cutout_rects
.size())
204 SetWindowRgn(window
, hrgn
, TRUE
);
209 // A callback function for EnumThreadWindows to enumerate and dismiss
210 // any owned popup windows.
211 BOOL CALLBACK
DismissOwnedPopups(HWND window
, LPARAM arg
) {
212 const HWND toplevel_hwnd
= reinterpret_cast<HWND
>(arg
);
214 if (::IsWindowVisible(window
)) {
215 const HWND owner
= ::GetWindow(window
, GW_OWNER
);
216 if (toplevel_hwnd
== owner
) {
217 ::PostMessage(window
, WM_CANCELMODE
, 0, 0);
225 void UpdateWebTouchEventAfterDispatch(blink::WebTouchEvent
* event
,
226 blink::WebTouchPoint
* point
) {
227 if (point
->state
!= blink::WebTouchPoint::StateReleased
&&
228 point
->state
!= blink::WebTouchPoint::StateCancelled
)
230 --event
->touchesLength
;
231 for (unsigned i
= point
- event
->touches
;
232 i
< event
->touchesLength
;
234 event
->touches
[i
] = event
->touches
[i
+ 1];
238 bool CanRendererHandleEvent(const ui::MouseEvent
* event
) {
239 if (event
->type() == ui::ET_MOUSE_CAPTURE_CHANGED
)
243 // Renderer cannot handle WM_XBUTTON or NC events.
244 switch (event
->native_event().message
) {
247 case WM_XBUTTONDBLCLK
:
248 case WM_NCMOUSELEAVE
:
250 case WM_NCLBUTTONDOWN
:
252 case WM_NCLBUTTONDBLCLK
:
253 case WM_NCRBUTTONDOWN
:
255 case WM_NCRBUTTONDBLCLK
:
256 case WM_NCMBUTTONDOWN
:
258 case WM_NCMBUTTONDBLCLK
:
259 case WM_NCXBUTTONDOWN
:
261 case WM_NCXBUTTONDBLCLK
:
266 #elif defined(USE_X11)
267 // Renderer only supports standard mouse buttons, so ignore programmable
269 switch (event
->type()) {
270 case ui::ET_MOUSE_PRESSED
:
271 case ui::ET_MOUSE_RELEASED
:
272 return event
->IsAnyButton();
280 // We don't mark these as handled so that they're sent back to the
281 // DefWindowProc so it can generate WM_APPCOMMAND as necessary.
282 bool IsXButtonUpEvent(const ui::MouseEvent
* event
) {
284 switch (event
->native_event().message
) {
293 void GetScreenInfoForWindow(WebScreenInfo
* results
, aura::Window
* window
) {
294 const gfx::Display display
= window
?
295 gfx::Screen::GetScreenFor(window
)->GetDisplayNearestWindow(window
) :
296 gfx::Screen::GetScreenFor(window
)->GetPrimaryDisplay();
297 results
->rect
= display
.bounds();
298 results
->availableRect
= display
.work_area();
299 // TODO(derat|oshima): Don't hardcode this. Get this from display object.
301 results
->depthPerComponent
= 8;
302 results
->deviceScaleFactor
= display
.device_scale_factor();
303 results
->orientationAngle
= display
.RotationAsDegree();
306 bool PointerEventActivates(const ui::Event
& event
) {
307 if (event
.type() == ui::ET_MOUSE_PRESSED
)
310 if (event
.type() == ui::ET_GESTURE_BEGIN
) {
311 const ui::GestureEvent
& gesture
=
312 static_cast<const ui::GestureEvent
&>(event
);
313 return gesture
.details().touch_points() == 1;
321 // We need to watch for mouse events outside a Web Popup or its parent
322 // and dismiss the popup for certain events.
323 class RenderWidgetHostViewAura::EventFilterForPopupExit
324 : public ui::EventHandler
{
326 explicit EventFilterForPopupExit(RenderWidgetHostViewAura
* rwhva
)
329 aura::Env::GetInstance()->AddPreTargetHandler(this);
332 virtual ~EventFilterForPopupExit() {
333 aura::Env::GetInstance()->RemovePreTargetHandler(this);
336 // Overridden from ui::EventHandler
337 virtual void OnMouseEvent(ui::MouseEvent
* event
) OVERRIDE
{
338 rwhva_
->ApplyEventFilterForPopupExit(event
);
341 virtual void OnTouchEvent(ui::TouchEvent
* event
) OVERRIDE
{
342 rwhva_
->ApplyEventFilterForPopupExit(event
);
346 RenderWidgetHostViewAura
* rwhva_
;
348 DISALLOW_COPY_AND_ASSIGN(EventFilterForPopupExit
);
351 void RenderWidgetHostViewAura::ApplyEventFilterForPopupExit(
352 ui::LocatedEvent
* event
) {
353 if (in_shutdown_
|| is_fullscreen_
|| !event
->target())
356 if (event
->type() != ui::ET_MOUSE_PRESSED
&&
357 event
->type() != ui::ET_TOUCH_PRESSED
) {
361 aura::Window
* target
= static_cast<aura::Window
*>(event
->target());
362 if (target
!= window_
&&
363 (!popup_parent_host_view_
||
364 target
!= popup_parent_host_view_
->window_
)) {
365 // Note: popup_parent_host_view_ may be NULL when there are multiple
366 // popup children per view. See: RenderWidgetHostViewAura::InitAsPopup().
372 // We have to implement the WindowObserver interface on a separate object
373 // because clang doesn't like implementing multiple interfaces that have
374 // methods with the same name. This object is owned by the
375 // RenderWidgetHostViewAura.
376 class RenderWidgetHostViewAura::WindowObserver
: public aura::WindowObserver
{
378 explicit WindowObserver(RenderWidgetHostViewAura
* view
)
380 view_
->window_
->AddObserver(this);
383 virtual ~WindowObserver() {
384 view_
->window_
->RemoveObserver(this);
387 // Overridden from aura::WindowObserver:
388 virtual void OnWindowAddedToRootWindow(aura::Window
* window
) OVERRIDE
{
389 if (window
== view_
->window_
)
390 view_
->AddedToRootWindow();
393 virtual void OnWindowRemovingFromRootWindow(aura::Window
* window
,
394 aura::Window
* new_root
) OVERRIDE
{
395 if (window
== view_
->window_
)
396 view_
->RemovingFromRootWindow();
400 RenderWidgetHostViewAura
* view_
;
402 DISALLOW_COPY_AND_ASSIGN(WindowObserver
);
405 ////////////////////////////////////////////////////////////////////////////////
406 // RenderWidgetHostViewAura, public:
408 RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost
* host
)
409 : host_(RenderWidgetHostImpl::From(host
)),
410 window_(new aura::Window(this)),
411 delegated_frame_host_(new DelegatedFrameHost(this)),
413 in_bounds_changed_(false),
414 is_fullscreen_(false),
415 popup_parent_host_view_(NULL
),
416 popup_child_host_view_(NULL
),
418 text_input_type_(ui::TEXT_INPUT_TYPE_NONE
),
419 text_input_mode_(ui::TEXT_INPUT_MODE_DEFAULT
),
420 can_compose_inline_(true),
421 has_composition_text_(false),
422 accept_return_character_(false),
423 last_swapped_software_frame_scale_factor_(1.f
),
425 synthetic_move_sent_(false),
426 cursor_visibility_state_in_renderer_(UNKNOWN
),
427 touch_editing_client_(NULL
),
428 weak_ptr_factory_(this) {
429 host_
->SetView(this);
430 window_observer_
.reset(new WindowObserver(this));
431 aura::client::SetTooltipText(window_
, &tooltip_
);
432 aura::client::SetActivationDelegate(window_
, this);
433 aura::client::SetActivationChangeObserver(window_
, this);
434 aura::client::SetFocusChangeObserver(window_
, this);
435 window_
->set_layer_owner_delegate(delegated_frame_host_
.get());
436 gfx::Screen::GetScreenFor(window_
)->AddObserver(this);
439 ////////////////////////////////////////////////////////////////////////////////
440 // RenderWidgetHostViewAura, RenderWidgetHostView implementation:
442 bool RenderWidgetHostViewAura::OnMessageReceived(
443 const IPC::Message
& message
) {
445 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAura
, message
)
446 // TODO(kevers): Move to RenderWidgetHostViewImpl and consolidate IPC
447 // messages for TextInput<State|Type>Changed. Corresponding code in
448 // RenderWidgetHostViewAndroid should also be moved at the same time.
449 IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged
,
450 OnTextInputStateChanged
)
451 IPC_MESSAGE_UNHANDLED(handled
= false)
452 IPC_END_MESSAGE_MAP()
456 void RenderWidgetHostViewAura::InitAsChild(
457 gfx::NativeView parent_view
) {
458 window_
->SetType(ui::wm::WINDOW_TYPE_CONTROL
);
459 window_
->Init(aura::WINDOW_LAYER_TEXTURED
);
460 window_
->SetName("RenderWidgetHostViewAura");
463 void RenderWidgetHostViewAura::InitAsPopup(
464 RenderWidgetHostView
* parent_host_view
,
465 const gfx::Rect
& bounds_in_screen
) {
466 popup_parent_host_view_
=
467 static_cast<RenderWidgetHostViewAura
*>(parent_host_view
);
469 // TransientWindowClient may be NULL during tests.
470 aura::client::TransientWindowClient
* transient_window_client
=
471 aura::client::GetTransientWindowClient();
472 RenderWidgetHostViewAura
* old_child
=
473 popup_parent_host_view_
->popup_child_host_view_
;
475 // TODO(jhorwich): Allow multiple popup_child_host_view_ per view, or
476 // similar mechanism to ensure a second popup doesn't cause the first one
477 // to never get a chance to filter events. See crbug.com/160589.
478 DCHECK(old_child
->popup_parent_host_view_
== popup_parent_host_view_
);
479 if (transient_window_client
) {
480 transient_window_client
->RemoveTransientChild(
481 popup_parent_host_view_
->window_
, old_child
->window_
);
483 old_child
->popup_parent_host_view_
= NULL
;
485 popup_parent_host_view_
->popup_child_host_view_
= this;
486 window_
->SetType(ui::wm::WINDOW_TYPE_MENU
);
487 window_
->Init(aura::WINDOW_LAYER_TEXTURED
);
488 window_
->SetName("RenderWidgetHostViewAura");
490 aura::Window
* root
= popup_parent_host_view_
->window_
->GetRootWindow();
491 aura::client::ParentWindowWithContext(window_
, root
, bounds_in_screen
);
492 // Setting the transient child allows for the popup to get mouse events when
493 // in a system modal dialog.
494 // This fixes crbug.com/328593.
495 if (transient_window_client
) {
496 transient_window_client
->AddTransientChild(
497 popup_parent_host_view_
->window_
, window_
);
500 SetBounds(bounds_in_screen
);
502 #if !defined(OS_WIN) && !defined(OS_CHROMEOS)
503 if (NeedsInputGrab())
504 window_
->SetCapture();
507 event_filter_for_popup_exit_
.reset(new EventFilterForPopupExit(this));
510 void RenderWidgetHostViewAura::InitAsFullscreen(
511 RenderWidgetHostView
* reference_host_view
) {
512 is_fullscreen_
= true;
513 window_
->SetType(ui::wm::WINDOW_TYPE_NORMAL
);
514 window_
->Init(aura::WINDOW_LAYER_TEXTURED
);
515 window_
->SetName("RenderWidgetHostViewAura");
516 window_
->SetProperty(aura::client::kShowStateKey
, ui::SHOW_STATE_FULLSCREEN
);
518 aura::Window
* parent
= NULL
;
520 if (reference_host_view
) {
521 aura::Window
* reference_window
=
522 static_cast<RenderWidgetHostViewAura
*>(reference_host_view
)->window_
;
523 if (reference_window
) {
524 host_tracker_
.reset(new aura::WindowTracker
);
525 host_tracker_
->Add(reference_window
);
527 gfx::Display display
= gfx::Screen::GetScreenFor(window_
)->
528 GetDisplayNearestWindow(reference_window
);
529 parent
= reference_window
->GetRootWindow();
530 bounds
= display
.bounds();
532 aura::client::ParentWindowWithContext(window_
, parent
, bounds
);
537 RenderWidgetHost
* RenderWidgetHostViewAura::GetRenderWidgetHost() const {
541 void RenderWidgetHostViewAura::WasShown() {
543 if (!host_
->is_hidden())
547 aura::Window
* root
= window_
->GetRootWindow();
549 aura::client::CursorClient
* cursor_client
=
550 aura::client::GetCursorClient(root
);
552 NotifyRendererOfCursorVisibilityState(cursor_client
->IsCursorVisible());
555 delegated_frame_host_
->WasShown();
558 if (legacy_render_widget_host_HWND_
) {
559 // Reparent the legacy Chrome_RenderWidgetHostHWND window to the parent
560 // window before reparenting any plugins. This ensures that the plugin
561 // windows stay on top of the child Zorder in the parent and receive
562 // mouse events, etc.
563 legacy_render_widget_host_HWND_
->UpdateParent(
564 GetNativeView()->GetHost()->GetAcceleratedWidget());
565 legacy_render_widget_host_HWND_
->SetBounds(
566 window_
->GetBoundsInRootWindow());
568 LPARAM lparam
= reinterpret_cast<LPARAM
>(this);
569 EnumChildWindows(ui::GetHiddenWindow(), ShowWindowsCallback
, lparam
);
573 void RenderWidgetHostViewAura::WasHidden() {
574 if (!host_
|| host_
->is_hidden())
577 delegated_frame_host_
->WasHidden();
580 constrained_rects_
.clear();
581 aura::WindowTreeHost
* host
= window_
->GetHost();
583 HWND parent
= host
->GetAcceleratedWidget();
584 LPARAM lparam
= reinterpret_cast<LPARAM
>(this);
585 EnumChildWindows(parent
, HideWindowsCallback
, lparam
);
586 // We reparent the legacy Chrome_RenderWidgetHostHWND window to the global
587 // hidden window on the same lines as Windowed plugin windows.
588 if (legacy_render_widget_host_HWND_
)
589 legacy_render_widget_host_HWND_
->UpdateParent(ui::GetHiddenWindow());
594 void RenderWidgetHostViewAura::SetSize(const gfx::Size
& size
) {
595 // For a SetSize operation, we don't care what coordinate system the origin
596 // of the window is in, it's only important to make sure that the origin
597 // remains constant after the operation.
598 InternalSetBounds(gfx::Rect(window_
->bounds().origin(), size
));
601 void RenderWidgetHostViewAura::SetBounds(const gfx::Rect
& rect
) {
602 gfx::Point
relative_origin(rect
.origin());
604 // RenderWidgetHostViewAura::SetBounds() takes screen coordinates, but
605 // Window::SetBounds() takes parent coordinates, so do the conversion here.
606 aura::Window
* root
= window_
->GetRootWindow();
608 aura::client::ScreenPositionClient
* screen_position_client
=
609 aura::client::GetScreenPositionClient(root
);
610 if (screen_position_client
) {
611 screen_position_client
->ConvertPointFromScreen(
612 window_
->parent(), &relative_origin
);
616 InternalSetBounds(gfx::Rect(relative_origin
, rect
.size()));
619 gfx::NativeView
RenderWidgetHostViewAura::GetNativeView() const {
623 gfx::NativeViewId
RenderWidgetHostViewAura::GetNativeViewId() const {
625 aura::WindowTreeHost
* host
= window_
->GetHost();
627 return reinterpret_cast<gfx::NativeViewId
>(host
->GetAcceleratedWidget());
629 return static_cast<gfx::NativeViewId
>(NULL
);
632 gfx::NativeViewAccessible
RenderWidgetHostViewAura::GetNativeViewAccessible() {
634 aura::WindowTreeHost
* host
= window_
->GetHost();
636 return static_cast<gfx::NativeViewAccessible
>(NULL
);
637 HWND hwnd
= host
->GetAcceleratedWidget();
639 CreateBrowserAccessibilityManagerIfNeeded();
640 BrowserAccessibilityManager
* manager
= GetBrowserAccessibilityManager();
642 return manager
->GetRoot()->ToBrowserAccessibilityWin();
646 return static_cast<gfx::NativeViewAccessible
>(NULL
);
649 void RenderWidgetHostViewAura::SetKeyboardFocus() {
652 aura::WindowTreeHost
* host
= window_
->GetHost();
654 ::SetFocus(host
->GetAcceleratedWidget());
659 RenderFrameHostImpl
* RenderWidgetHostViewAura::GetFocusedFrame() {
660 if (!host_
->IsRenderView())
662 RenderViewHost
* rvh
= RenderViewHost::From(host_
);
663 FrameTreeNode
* focused_frame
=
664 rvh
->GetDelegate()->GetFrameTree()->GetFocusedFrame();
668 return focused_frame
->current_frame_host();
671 void RenderWidgetHostViewAura::MovePluginWindows(
672 const std::vector
<WebPluginGeometry
>& plugin_window_moves
) {
674 // We need to clip the rectangle to the tab's viewport, otherwise we will draw
675 // over the browser UI.
676 if (!window_
->GetRootWindow()) {
677 DCHECK(plugin_window_moves
.empty());
680 HWND parent
= window_
->GetHost()->GetAcceleratedWidget();
681 gfx::Rect view_bounds
= window_
->GetBoundsInRootWindow();
682 std::vector
<WebPluginGeometry
> moves
= plugin_window_moves
;
684 gfx::Rect
view_port(view_bounds
.size());
686 for (size_t i
= 0; i
< moves
.size(); ++i
) {
687 gfx::Rect
clip(moves
[i
].clip_rect
);
688 gfx::Vector2d
view_port_offset(
689 moves
[i
].window_rect
.OffsetFromOrigin());
690 clip
.Offset(view_port_offset
);
691 clip
.Intersect(view_port
);
692 clip
.Offset(-view_port_offset
);
693 moves
[i
].clip_rect
= clip
;
695 moves
[i
].window_rect
.Offset(view_bounds
.OffsetFromOrigin());
697 plugin_window_moves_
[moves
[i
].window
] = moves
[i
];
699 // constrained_rects_ are relative to the root window. We want to convert
700 // them to be relative to the plugin window.
701 for (size_t j
= 0; j
< constrained_rects_
.size(); ++j
) {
702 gfx::Rect offset_cutout
= constrained_rects_
[j
];
703 offset_cutout
-= moves
[i
].window_rect
.OffsetFromOrigin();
704 moves
[i
].cutout_rects
.push_back(offset_cutout
);
708 MovePluginWindowsHelper(parent
, moves
);
710 // Make sure each plugin window (or its wrapper if it exists) has a pointer to
712 for (size_t i
= 0; i
< moves
.size(); ++i
) {
713 HWND window
= moves
[i
].window
;
714 if (GetParent(window
) != parent
) {
715 window
= GetParent(window
);
717 if (!GetProp(window
, kWidgetOwnerProperty
))
718 SetProp(window
, kWidgetOwnerProperty
, this);
720 #endif // defined(OS_WIN)
723 void RenderWidgetHostViewAura::Focus() {
724 // Make sure we have a FocusClient before attempting to Focus(). In some
725 // situations we may not yet be in a valid Window hierarchy (such as reloading
726 // after out of memory discarded the tab).
727 aura::client::FocusClient
* client
= aura::client::GetFocusClient(window_
);
732 void RenderWidgetHostViewAura::Blur() {
736 bool RenderWidgetHostViewAura::HasFocus() const {
737 return window_
->HasFocus();
740 bool RenderWidgetHostViewAura::IsSurfaceAvailableForCopy() const {
741 return delegated_frame_host_
->CanCopyToBitmap();
744 void RenderWidgetHostViewAura::Show() {
748 if (legacy_render_widget_host_HWND_
)
749 legacy_render_widget_host_HWND_
->Show();
753 void RenderWidgetHostViewAura::Hide() {
757 if (legacy_render_widget_host_HWND_
)
758 legacy_render_widget_host_HWND_
->Hide();
762 bool RenderWidgetHostViewAura::IsShowing() {
763 return window_
->IsVisible();
766 gfx::Rect
RenderWidgetHostViewAura::GetViewBounds() const {
767 // This is the size that we want the renderer to produce. While we're waiting
768 // for the correct frame (i.e. during a resize), don't change the size so that
769 // we don't pipeline more resizes than we can handle.
770 gfx::Rect
bounds(window_
->GetBoundsInScreen());
771 return delegated_frame_host_
->GetViewBoundsWithResizeLock(bounds
);
774 void RenderWidgetHostViewAura::SetBackground(const SkBitmap
& background
) {
775 RenderWidgetHostViewBase::SetBackground(background
);
776 host_
->SetBackground(background
);
777 window_
->layer()->SetFillsBoundsOpaquely(background
.isOpaque());
780 gfx::Size
RenderWidgetHostViewAura::GetVisibleViewportSize() const {
781 gfx::Rect window_bounds
= window_
->bounds();
782 int viewport_width
= std::max(
783 0, window_bounds
.width() - insets_
.left() - insets_
.right());
784 int viewport_height
= std::max(
785 0, window_bounds
.height() - insets_
.top() - insets_
.bottom());
786 return gfx::Size(viewport_width
, viewport_height
);
789 void RenderWidgetHostViewAura::SetInsets(const gfx::Insets
& insets
) {
790 if (insets
!= insets_
) {
796 void RenderWidgetHostViewAura::UpdateCursor(const WebCursor
& cursor
) {
797 current_cursor_
= cursor
;
798 const gfx::Display display
= gfx::Screen::GetScreenFor(window_
)->
799 GetDisplayNearestWindow(window_
);
800 current_cursor_
.SetDisplayInfo(display
);
801 UpdateCursorIfOverSelf();
804 void RenderWidgetHostViewAura::SetIsLoading(bool is_loading
) {
805 is_loading_
= is_loading
;
806 UpdateCursorIfOverSelf();
809 void RenderWidgetHostViewAura::TextInputTypeChanged(
810 ui::TextInputType type
,
811 ui::TextInputMode input_mode
,
812 bool can_compose_inline
) {
813 if (text_input_type_
!= type
||
814 text_input_mode_
!= input_mode
||
815 can_compose_inline_
!= can_compose_inline
) {
816 text_input_type_
= type
;
817 text_input_mode_
= input_mode
;
818 can_compose_inline_
= can_compose_inline
;
819 if (GetInputMethod())
820 GetInputMethod()->OnTextInputTypeChanged(this);
821 if (touch_editing_client_
)
822 touch_editing_client_
->OnTextInputTypeChanged(text_input_type_
);
826 void RenderWidgetHostViewAura::OnTextInputStateChanged(
827 const ViewHostMsg_TextInputState_Params
& params
) {
828 if (params
.show_ime_if_needed
&& params
.type
!= ui::TEXT_INPUT_TYPE_NONE
) {
829 if (GetInputMethod())
830 GetInputMethod()->ShowImeIfNeeded();
834 void RenderWidgetHostViewAura::ImeCancelComposition() {
835 if (GetInputMethod())
836 GetInputMethod()->CancelComposition(this);
837 has_composition_text_
= false;
840 void RenderWidgetHostViewAura::ImeCompositionRangeChanged(
841 const gfx::Range
& range
,
842 const std::vector
<gfx::Rect
>& character_bounds
) {
843 composition_character_bounds_
= character_bounds
;
846 void RenderWidgetHostViewAura::RenderProcessGone(base::TerminationStatus status
,
848 UpdateCursorIfOverSelf();
852 void RenderWidgetHostViewAura::Destroy() {
853 // Beware, this function is not called on all destruction paths. It will
854 // implicitly end up calling ~RenderWidgetHostViewAura though, so all
855 // destruction/cleanup code should happen there, not here.
860 void RenderWidgetHostViewAura::SetTooltipText(
861 const base::string16
& tooltip_text
) {
862 tooltip_
= tooltip_text
;
863 aura::Window
* root_window
= window_
->GetRootWindow();
864 aura::client::TooltipClient
* tooltip_client
=
865 aura::client::GetTooltipClient(root_window
);
866 if (tooltip_client
) {
867 tooltip_client
->UpdateTooltip(window_
);
868 // Content tooltips should be visible indefinitely.
869 tooltip_client
->SetTooltipShownTimeout(window_
, 0);
873 void RenderWidgetHostViewAura::SelectionChanged(const base::string16
& text
,
875 const gfx::Range
& range
) {
876 RenderWidgetHostViewBase::SelectionChanged(text
, offset
, range
);
878 #if defined(USE_X11) && !defined(OS_CHROMEOS)
879 if (text
.empty() || range
.is_empty())
881 size_t pos
= range
.GetMin() - offset
;
882 size_t n
= range
.length();
884 DCHECK(pos
+ n
<= text
.length()) << "The text can not fully cover range.";
885 if (pos
>= text
.length()) {
886 NOTREACHED() << "The text can not cover range.";
890 // Set the CLIPBOARD_TYPE_SELECTION to the ui::Clipboard.
891 ui::ScopedClipboardWriter
clipboard_writer(
892 ui::Clipboard::GetForCurrentThread(),
893 ui::CLIPBOARD_TYPE_SELECTION
);
894 clipboard_writer
.WriteText(text
.substr(pos
, n
));
895 #endif // defined(USE_X11) && !defined(OS_CHROMEOS)
898 void RenderWidgetHostViewAura::SelectionBoundsChanged(
899 const ViewHostMsg_SelectionBounds_Params
& params
) {
900 if (selection_anchor_rect_
== params
.anchor_rect
&&
901 selection_focus_rect_
== params
.focus_rect
)
904 selection_anchor_rect_
= params
.anchor_rect
;
905 selection_focus_rect_
= params
.focus_rect
;
907 if (GetInputMethod())
908 GetInputMethod()->OnCaretBoundsChanged(this);
910 if (touch_editing_client_
) {
911 touch_editing_client_
->OnSelectionOrCursorChanged(selection_anchor_rect_
,
912 selection_focus_rect_
);
916 void RenderWidgetHostViewAura::ScrollOffsetChanged() {
917 aura::Window
* root
= window_
->GetRootWindow();
920 aura::client::CursorClient
* cursor_client
=
921 aura::client::GetCursorClient(root
);
922 if (cursor_client
&& !cursor_client
->IsCursorVisible())
923 cursor_client
->DisableMouseEvents();
926 void RenderWidgetHostViewAura::CopyFromCompositingSurface(
927 const gfx::Rect
& src_subrect
,
928 const gfx::Size
& dst_size
,
929 const base::Callback
<void(bool, const SkBitmap
&)>& callback
,
930 const SkBitmap::Config config
) {
931 delegated_frame_host_
->CopyFromCompositingSurface(
932 src_subrect
, dst_size
, callback
, config
);
935 void RenderWidgetHostViewAura::CopyFromCompositingSurfaceToVideoFrame(
936 const gfx::Rect
& src_subrect
,
937 const scoped_refptr
<media::VideoFrame
>& target
,
938 const base::Callback
<void(bool)>& callback
) {
939 delegated_frame_host_
->CopyFromCompositingSurfaceToVideoFrame(
940 src_subrect
, target
, callback
);
943 bool RenderWidgetHostViewAura::CanCopyToVideoFrame() const {
944 return delegated_frame_host_
->CanCopyToVideoFrame();
947 bool RenderWidgetHostViewAura::CanSubscribeFrame() const {
948 return delegated_frame_host_
->CanSubscribeFrame();
951 void RenderWidgetHostViewAura::BeginFrameSubscription(
952 scoped_ptr
<RenderWidgetHostViewFrameSubscriber
> subscriber
) {
953 delegated_frame_host_
->BeginFrameSubscription(subscriber
.Pass());
956 void RenderWidgetHostViewAura::EndFrameSubscription() {
957 delegated_frame_host_
->EndFrameSubscription();
960 void RenderWidgetHostViewAura::OnAcceleratedCompositingStateChange() {
963 void RenderWidgetHostViewAura::AcceleratedSurfaceInitialized(int host_id
,
967 void RenderWidgetHostViewAura::InternalSetBounds(const gfx::Rect
& rect
) {
968 if (HasDisplayPropertyChanged(window_
))
969 host_
->InvalidateScreenInfo();
971 // Don't recursively call SetBounds if this bounds update is the result of
972 // a Window::SetBoundsInternal call.
973 if (!in_bounds_changed_
)
974 window_
->SetBounds(rect
);
976 delegated_frame_host_
->WasResized();
977 if (touch_editing_client_
) {
978 touch_editing_client_
->OnSelectionOrCursorChanged(selection_anchor_rect_
,
979 selection_focus_rect_
);
982 // Create the legacy dummy window which corresponds to the bounds of the
983 // webcontents. This will be passed as the container window for windowless
985 // Plugins like Flash assume the container window which is returned via the
986 // NPNVnetscapeWindow property corresponds to the bounds of the webpage.
987 // This is not true in Aura where we have only HWND which is the main Aura
988 // window. If we return this window to plugins like Flash then it causes the
989 // coordinate translations done by these plugins to break.
990 // Additonally the legacy dummy window is needed for accessibility and for
991 // scrolling to work in legacy drivers for trackpoints/trackpads, etc.
992 if (GetNativeViewId()) {
993 if (!legacy_render_widget_host_HWND_
) {
994 legacy_render_widget_host_HWND_
= LegacyRenderWidgetHostHWND::Create(
995 reinterpret_cast<HWND
>(GetNativeViewId()));
997 if (legacy_render_widget_host_HWND_
) {
998 legacy_render_widget_host_HWND_
->SetBounds(
999 window_
->GetBoundsInRootWindow());
1004 UpdateMouseLockRegion();
1009 bool RenderWidgetHostViewAura::UsesNativeWindowFrame() const {
1010 return (legacy_render_widget_host_HWND_
!= NULL
);
1013 void RenderWidgetHostViewAura::UpdateConstrainedWindowRects(
1014 const std::vector
<gfx::Rect
>& rects
) {
1015 // Check this before setting constrained_rects_, so that next time they're set
1016 // and we have a root window we don't early return.
1017 if (!window_
->GetHost())
1020 if (rects
== constrained_rects_
)
1023 constrained_rects_
= rects
;
1025 HWND parent
= window_
->GetHost()->GetAcceleratedWidget();
1026 CutoutRectsParams params
;
1027 params
.widget
= this;
1028 params
.cutout_rects
= constrained_rects_
;
1029 params
.geometry
= &plugin_window_moves_
;
1030 LPARAM lparam
= reinterpret_cast<LPARAM
>(¶ms
);
1031 EnumChildWindows(parent
, SetCutoutRectsCallback
, lparam
);
1034 void RenderWidgetHostViewAura::UpdateMouseLockRegion() {
1035 // Clip the cursor if chrome is running on regular desktop.
1036 if (gfx::Screen::GetScreenFor(window_
) == gfx::Screen::GetNativeScreen()) {
1037 RECT window_rect
= window_
->GetBoundsInScreen().ToRECT();
1038 ::ClipCursor(&window_rect
);
1043 void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped(
1044 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params
& params_in_pixel
,
1046 // Oldschool composited mode is no longer supported.
1049 void RenderWidgetHostViewAura::OnSwapCompositorFrame(
1050 uint32 output_surface_id
,
1051 scoped_ptr
<cc::CompositorFrame
> frame
) {
1052 TRACE_EVENT0("content", "RenderWidgetHostViewAura::OnSwapCompositorFrame");
1053 if (frame
->delegated_frame_data
) {
1054 delegated_frame_host_
->SwapDelegatedFrame(
1056 frame
->delegated_frame_data
.Pass(),
1057 frame
->metadata
.device_scale_factor
,
1058 frame
->metadata
.latency_info
);
1062 if (frame
->software_frame_data
) {
1063 DLOG(ERROR
) << "Unable to use software frame in aura";
1065 base::UserMetricsAction("BadMessageTerminate_SharedMemoryAura"));
1066 host_
->GetProcess()->ReceivedBadMessage();
1072 void RenderWidgetHostViewAura::SetParentNativeViewAccessible(
1073 gfx::NativeViewAccessible accessible_parent
) {
1074 if (GetBrowserAccessibilityManager()) {
1075 GetBrowserAccessibilityManager()->ToBrowserAccessibilityManagerWin()
1076 ->set_parent_iaccessible(accessible_parent
);
1080 gfx::NativeViewId
RenderWidgetHostViewAura::GetParentForWindowlessPlugin()
1082 if (legacy_render_widget_host_HWND_
) {
1083 return reinterpret_cast<gfx::NativeViewId
>(
1084 legacy_render_widget_host_HWND_
->hwnd());
1090 void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer(
1091 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params
& params_in_pixel
,
1093 // Oldschool composited mode is no longer supported.
1096 void RenderWidgetHostViewAura::AcceleratedSurfaceSuspend() {
1099 void RenderWidgetHostViewAura::AcceleratedSurfaceRelease() {
1102 bool RenderWidgetHostViewAura::HasAcceleratedSurface(
1103 const gfx::Size
& desired_size
) {
1104 // Aura doesn't use GetBackingStore for accelerated pages, so it doesn't
1105 // matter what is returned here as GetBackingStore is the only caller of this
1106 // method. TODO(jbates) implement this if other Aura code needs it.
1110 void RenderWidgetHostViewAura::GetScreenInfo(WebScreenInfo
* results
) {
1111 GetScreenInfoForWindow(results
, window_
->GetRootWindow() ? window_
: NULL
);
1114 gfx::Rect
RenderWidgetHostViewAura::GetBoundsInRootWindow() {
1115 aura::Window
* top_level
= window_
->GetToplevelWindow();
1116 gfx::Rect
bounds(top_level
->GetBoundsInScreen());
1119 // TODO(zturner,iyengar): This will break when we remove support for NPAPI and
1120 // remove the legacy hwnd, so a better fix will need to be decided when that
1122 if (UsesNativeWindowFrame()) {
1123 // aura::Window doesn't take into account non-client area of native windows
1124 // (e.g. HWNDs), so for that case ask Windows directly what the bounds are.
1125 aura::WindowTreeHost
* host
= top_level
->GetHost();
1127 return top_level
->GetBoundsInScreen();
1128 RECT window_rect
= {0};
1129 HWND hwnd
= host
->GetAcceleratedWidget();
1130 ::GetWindowRect(hwnd
, &window_rect
);
1131 bounds
= gfx::Rect(window_rect
);
1133 // Maximized windows are outdented from the work area by the frame thickness
1134 // even though this "frame" is not painted. This confuses code (and people)
1135 // that think of a maximized window as corresponding exactly to the work
1136 // area. Correct for this by subtracting the frame thickness back off.
1137 if (::IsZoomed(hwnd
)) {
1138 bounds
.Inset(GetSystemMetrics(SM_CXSIZEFRAME
),
1139 GetSystemMetrics(SM_CYSIZEFRAME
));
1141 bounds
.Inset(GetSystemMetrics(SM_CXPADDEDBORDER
),
1142 GetSystemMetrics(SM_CXPADDEDBORDER
));
1146 bounds
= gfx::win::ScreenToDIPRect(bounds
);
1152 void RenderWidgetHostViewAura::GestureEventAck(
1153 const blink::WebGestureEvent
& event
,
1154 InputEventAckState ack_result
) {
1155 if (touch_editing_client_
)
1156 touch_editing_client_
->GestureEventAck(event
.type
);
1159 void RenderWidgetHostViewAura::ProcessAckedTouchEvent(
1160 const TouchEventWithLatencyInfo
& touch
, InputEventAckState ack_result
) {
1161 ScopedVector
<ui::TouchEvent
> events
;
1162 if (!MakeUITouchEventsFromWebTouchEvents(touch
, &events
,
1163 SCREEN_COORDINATES
))
1166 aura::WindowTreeHost
* host
= window_
->GetHost();
1167 // |host| is NULL during tests.
1171 ui::EventResult result
= (ack_result
==
1172 INPUT_EVENT_ACK_STATE_CONSUMED
) ? ui::ER_HANDLED
: ui::ER_UNHANDLED
;
1173 for (ScopedVector
<ui::TouchEvent
>::iterator iter
= events
.begin(),
1174 end
= events
.end(); iter
!= end
; ++iter
) {
1175 host
->dispatcher()->ProcessedTouchEvent((*iter
), window_
, result
);
1179 scoped_ptr
<SyntheticGestureTarget
>
1180 RenderWidgetHostViewAura::CreateSyntheticGestureTarget() {
1181 return scoped_ptr
<SyntheticGestureTarget
>(
1182 new SyntheticGestureTargetAura(host_
));
1185 void RenderWidgetHostViewAura::SetScrollOffsetPinning(
1186 bool is_pinned_to_left
, bool is_pinned_to_right
) {
1187 // Not needed. Mac-only.
1190 void RenderWidgetHostViewAura::CreateBrowserAccessibilityManagerIfNeeded() {
1191 if (GetBrowserAccessibilityManager())
1194 BrowserAccessibilityManager
* manager
= NULL
;
1196 aura::WindowTreeHost
* host
= window_
->GetHost();
1199 HWND hwnd
= host
->GetAcceleratedWidget();
1201 // The accessible_parent may be NULL at this point. The WebContents will pass
1202 // it down to this instance (by way of the RenderViewHost and
1203 // RenderWidgetHost) when it is known. This instance will then set it on its
1204 // BrowserAccessibilityManager.
1205 gfx::NativeViewAccessible accessible_parent
=
1206 host_
->GetParentNativeViewAccessible();
1208 if (legacy_render_widget_host_HWND_
) {
1209 manager
= new BrowserAccessibilityManagerWin(
1210 legacy_render_widget_host_HWND_
.get(), accessible_parent
,
1211 BrowserAccessibilityManagerWin::GetEmptyDocument(), host_
);
1214 manager
= BrowserAccessibilityManager::Create(
1215 BrowserAccessibilityManager::GetEmptyDocument(), host_
);
1217 SetBrowserAccessibilityManager(manager
);
1220 gfx::GLSurfaceHandle
RenderWidgetHostViewAura::GetCompositingSurface() {
1221 return ImageTransportFactory::GetInstance()->GetSharedSurfaceHandle();
1224 bool RenderWidgetHostViewAura::LockMouse() {
1225 aura::Window
* root_window
= window_
->GetRootWindow();
1232 mouse_locked_
= true;
1233 #if !defined(OS_WIN)
1234 window_
->SetCapture();
1236 UpdateMouseLockRegion();
1238 aura::client::CursorClient
* cursor_client
=
1239 aura::client::GetCursorClient(root_window
);
1240 if (cursor_client
) {
1241 cursor_client
->HideCursor();
1242 cursor_client
->LockCursor();
1245 if (ShouldMoveToCenter()) {
1246 synthetic_move_sent_
= true;
1247 window_
->MoveCursorTo(gfx::Rect(window_
->bounds().size()).CenterPoint());
1249 tooltip_disabler_
.reset(new aura::client::ScopedTooltipDisabler(root_window
));
1253 void RenderWidgetHostViewAura::UnlockMouse() {
1254 tooltip_disabler_
.reset();
1256 aura::Window
* root_window
= window_
->GetRootWindow();
1257 if (!mouse_locked_
|| !root_window
)
1260 mouse_locked_
= false;
1262 #if !defined(OS_WIN)
1263 window_
->ReleaseCapture();
1267 window_
->MoveCursorTo(unlocked_mouse_position_
);
1268 aura::client::CursorClient
* cursor_client
=
1269 aura::client::GetCursorClient(root_window
);
1270 if (cursor_client
) {
1271 cursor_client
->UnlockCursor();
1272 cursor_client
->ShowCursor();
1275 host_
->LostMouseLock();
1278 ////////////////////////////////////////////////////////////////////////////////
1279 // RenderWidgetHostViewAura, ui::TextInputClient implementation:
1280 void RenderWidgetHostViewAura::SetCompositionText(
1281 const ui::CompositionText
& composition
) {
1285 // ui::CompositionUnderline should be identical to
1286 // blink::WebCompositionUnderline, so that we can do reinterpret_cast safely.
1287 COMPILE_ASSERT(sizeof(ui::CompositionUnderline
) ==
1288 sizeof(blink::WebCompositionUnderline
),
1289 ui_CompositionUnderline__WebKit_WebCompositionUnderline_diff
);
1291 // TODO(suzhe): convert both renderer_host and renderer to use
1292 // ui::CompositionText.
1293 const std::vector
<blink::WebCompositionUnderline
>& underlines
=
1294 reinterpret_cast<const std::vector
<blink::WebCompositionUnderline
>&>(
1295 composition
.underlines
);
1297 // TODO(suzhe): due to a bug of webkit, we can't use selection range with
1298 // composition string. See: https://bugs.webkit.org/show_bug.cgi?id=37788
1299 host_
->ImeSetComposition(composition
.text
, underlines
,
1300 composition
.selection
.end(),
1301 composition
.selection
.end());
1303 has_composition_text_
= !composition
.text
.empty();
1306 void RenderWidgetHostViewAura::ConfirmCompositionText() {
1307 if (host_
&& has_composition_text_
) {
1308 host_
->ImeConfirmComposition(base::string16(), gfx::Range::InvalidRange(),
1311 has_composition_text_
= false;
1314 void RenderWidgetHostViewAura::ClearCompositionText() {
1315 if (host_
&& has_composition_text_
)
1316 host_
->ImeCancelComposition();
1317 has_composition_text_
= false;
1320 void RenderWidgetHostViewAura::InsertText(const base::string16
& text
) {
1321 DCHECK(text_input_type_
!= ui::TEXT_INPUT_TYPE_NONE
);
1323 host_
->ImeConfirmComposition(text
, gfx::Range::InvalidRange(), false);
1324 has_composition_text_
= false;
1327 void RenderWidgetHostViewAura::InsertChar(base::char16 ch
, int flags
) {
1328 if (popup_child_host_view_
&& popup_child_host_view_
->NeedsInputGrab()) {
1329 popup_child_host_view_
->InsertChar(ch
, flags
);
1333 // Ignore character messages for VKEY_RETURN sent on CTRL+M. crbug.com/315547
1334 if (host_
&& (accept_return_character_
|| ch
!= ui::VKEY_RETURN
)) {
1335 double now
= ui::EventTimeForNow().InSecondsF();
1336 // Send a blink::WebInputEvent::Char event to |host_|.
1337 NativeWebKeyboardEvent
webkit_event(ui::ET_KEY_PRESSED
,
1342 ForwardKeyboardEvent(webkit_event
);
1346 gfx::NativeWindow
RenderWidgetHostViewAura::GetAttachedWindow() const {
1350 ui::TextInputType
RenderWidgetHostViewAura::GetTextInputType() const {
1351 return text_input_type_
;
1354 ui::TextInputMode
RenderWidgetHostViewAura::GetTextInputMode() const {
1355 return text_input_mode_
;
1358 bool RenderWidgetHostViewAura::CanComposeInline() const {
1359 return can_compose_inline_
;
1362 gfx::Rect
RenderWidgetHostViewAura::ConvertRectToScreen(
1363 const gfx::Rect
& rect
) const {
1364 gfx::Point origin
= rect
.origin();
1365 gfx::Point end
= gfx::Point(rect
.right(), rect
.bottom());
1367 aura::Window
* root_window
= window_
->GetRootWindow();
1370 aura::client::ScreenPositionClient
* screen_position_client
=
1371 aura::client::GetScreenPositionClient(root_window
);
1372 if (!screen_position_client
)
1374 screen_position_client
->ConvertPointToScreen(window_
, &origin
);
1375 screen_position_client
->ConvertPointToScreen(window_
, &end
);
1376 return gfx::Rect(origin
.x(),
1378 end
.x() - origin
.x(),
1379 end
.y() - origin
.y());
1382 gfx::Rect
RenderWidgetHostViewAura::ConvertRectFromScreen(
1383 const gfx::Rect
& rect
) const {
1384 gfx::Point origin
= rect
.origin();
1385 gfx::Point end
= gfx::Point(rect
.right(), rect
.bottom());
1387 aura::Window
* root_window
= window_
->GetRootWindow();
1389 aura::client::ScreenPositionClient
* screen_position_client
=
1390 aura::client::GetScreenPositionClient(root_window
);
1391 screen_position_client
->ConvertPointFromScreen(window_
, &origin
);
1392 screen_position_client
->ConvertPointFromScreen(window_
, &end
);
1393 return gfx::Rect(origin
.x(),
1395 end
.x() - origin
.x(),
1396 end
.y() - origin
.y());
1402 gfx::Rect
RenderWidgetHostViewAura::GetCaretBounds() const {
1403 const gfx::Rect rect
=
1404 gfx::UnionRects(selection_anchor_rect_
, selection_focus_rect_
);
1405 return ConvertRectToScreen(rect
);
1408 bool RenderWidgetHostViewAura::GetCompositionCharacterBounds(
1410 gfx::Rect
* rect
) const {
1412 if (index
>= composition_character_bounds_
.size())
1414 *rect
= ConvertRectToScreen(composition_character_bounds_
[index
]);
1418 bool RenderWidgetHostViewAura::HasCompositionText() const {
1419 return has_composition_text_
;
1422 bool RenderWidgetHostViewAura::GetTextRange(gfx::Range
* range
) const {
1423 range
->set_start(selection_text_offset_
);
1424 range
->set_end(selection_text_offset_
+ selection_text_
.length());
1428 bool RenderWidgetHostViewAura::GetCompositionTextRange(
1429 gfx::Range
* range
) const {
1430 // TODO(suzhe): implement this method when fixing http://crbug.com/55130.
1435 bool RenderWidgetHostViewAura::GetSelectionRange(gfx::Range
* range
) const {
1436 range
->set_start(selection_range_
.start());
1437 range
->set_end(selection_range_
.end());
1441 bool RenderWidgetHostViewAura::SetSelectionRange(const gfx::Range
& range
) {
1442 // TODO(suzhe): implement this method when fixing http://crbug.com/55130.
1447 bool RenderWidgetHostViewAura::DeleteRange(const gfx::Range
& range
) {
1448 // TODO(suzhe): implement this method when fixing http://crbug.com/55130.
1453 bool RenderWidgetHostViewAura::GetTextFromRange(
1454 const gfx::Range
& range
,
1455 base::string16
* text
) const {
1456 gfx::Range
selection_text_range(selection_text_offset_
,
1457 selection_text_offset_
+ selection_text_
.length());
1459 if (!selection_text_range
.Contains(range
)) {
1463 if (selection_text_range
.EqualsIgnoringDirection(range
)) {
1464 // Avoid calling substr whose performance is low.
1465 *text
= selection_text_
;
1467 *text
= selection_text_
.substr(
1468 range
.GetMin() - selection_text_offset_
,
1474 void RenderWidgetHostViewAura::OnInputMethodChanged() {
1478 if (GetInputMethod())
1479 host_
->SetInputMethodActive(GetInputMethod()->IsActive());
1481 // TODO(suzhe): implement the newly added “locale” property of HTML DOM
1485 bool RenderWidgetHostViewAura::ChangeTextDirectionAndLayoutAlignment(
1486 base::i18n::TextDirection direction
) {
1489 host_
->UpdateTextDirection(
1490 direction
== base::i18n::RIGHT_TO_LEFT
?
1491 blink::WebTextDirectionRightToLeft
:
1492 blink::WebTextDirectionLeftToRight
);
1493 host_
->NotifyTextDirection();
1497 void RenderWidgetHostViewAura::ExtendSelectionAndDelete(
1498 size_t before
, size_t after
) {
1499 RenderFrameHostImpl
* rfh
= GetFocusedFrame();
1501 rfh
->ExtendSelectionAndDelete(before
, after
);
1504 void RenderWidgetHostViewAura::EnsureCaretInRect(const gfx::Rect
& rect
) {
1505 gfx::Rect
intersected_rect(
1506 gfx::IntersectRects(rect
, window_
->GetBoundsInScreen()));
1508 if (intersected_rect
.IsEmpty())
1511 host_
->ScrollFocusedEditableNodeIntoRect(
1512 ConvertRectFromScreen(intersected_rect
));
1515 void RenderWidgetHostViewAura::OnCandidateWindowShown() {
1516 host_
->CandidateWindowShown();
1519 void RenderWidgetHostViewAura::OnCandidateWindowUpdated() {
1520 host_
->CandidateWindowUpdated();
1523 void RenderWidgetHostViewAura::OnCandidateWindowHidden() {
1524 host_
->CandidateWindowHidden();
1527 ////////////////////////////////////////////////////////////////////////////////
1528 // RenderWidgetHostViewAura, gfx::DisplayObserver implementation:
1530 void RenderWidgetHostViewAura::OnDisplayBoundsChanged(
1531 const gfx::Display
& display
) {
1532 gfx::Screen
* screen
= gfx::Screen::GetScreenFor(window_
);
1533 if (display
.id() == screen
->GetDisplayNearestWindow(window_
).id()) {
1534 UpdateScreenInfo(window_
);
1535 current_cursor_
.SetDisplayInfo(display
);
1536 UpdateCursorIfOverSelf();
1540 void RenderWidgetHostViewAura::OnDisplayAdded(
1541 const gfx::Display
& new_display
) {
1544 void RenderWidgetHostViewAura::OnDisplayRemoved(
1545 const gfx::Display
& old_display
) {
1548 ////////////////////////////////////////////////////////////////////////////////
1549 // RenderWidgetHostViewAura, aura::WindowDelegate implementation:
1551 gfx::Size
RenderWidgetHostViewAura::GetMinimumSize() const {
1555 gfx::Size
RenderWidgetHostViewAura::GetMaximumSize() const {
1559 void RenderWidgetHostViewAura::OnBoundsChanged(const gfx::Rect
& old_bounds
,
1560 const gfx::Rect
& new_bounds
) {
1561 base::AutoReset
<bool> in_bounds_changed(&in_bounds_changed_
, true);
1562 // We care about this whenever RenderWidgetHostViewAura is not owned by a
1563 // WebContentsViewAura since changes to the Window's bounds need to be
1564 // messaged to the renderer. WebContentsViewAura invokes SetSize() or
1565 // SetBounds() itself. No matter how we got here, any redundant calls are
1567 SetSize(new_bounds
.size());
1569 if (GetInputMethod())
1570 GetInputMethod()->OnCaretBoundsChanged(this);
1573 gfx::NativeCursor
RenderWidgetHostViewAura::GetCursor(const gfx::Point
& point
) {
1575 return ui::kCursorNone
;
1576 return current_cursor_
.GetNativeCursor();
1579 int RenderWidgetHostViewAura::GetNonClientComponent(
1580 const gfx::Point
& point
) const {
1584 bool RenderWidgetHostViewAura::ShouldDescendIntoChildForEventHandling(
1585 aura::Window
* child
,
1586 const gfx::Point
& location
) {
1590 bool RenderWidgetHostViewAura::CanFocus() {
1591 return popup_type_
== blink::WebPopupTypeNone
;
1594 void RenderWidgetHostViewAura::OnCaptureLost() {
1595 host_
->LostCapture();
1596 if (touch_editing_client_
)
1597 touch_editing_client_
->EndTouchEditing(false);
1600 void RenderWidgetHostViewAura::OnPaint(gfx::Canvas
* canvas
) {
1601 // For non-opaque windows, we don't draw anything, since we depend on the
1602 // canvas coming from the compositor to already be initialized as
1604 if (window_
->layer()->fills_bounds_opaquely())
1605 canvas
->DrawColor(SK_ColorWHITE
);
1608 void RenderWidgetHostViewAura::OnDeviceScaleFactorChanged(
1609 float device_scale_factor
) {
1613 UpdateScreenInfo(window_
);
1615 const gfx::Display display
= gfx::Screen::GetScreenFor(window_
)->
1616 GetDisplayNearestWindow(window_
);
1617 DCHECK_EQ(device_scale_factor
, display
.device_scale_factor());
1618 current_cursor_
.SetDisplayInfo(display
);
1621 void RenderWidgetHostViewAura::OnWindowDestroying(aura::Window
* window
) {
1624 // If the tab was hidden and it's closed, host_->is_hidden would have been
1625 // reset to false in RenderWidgetHostImpl::RendererExited.
1626 if (!window_
->GetRootWindow() || host_
->is_hidden()) {
1627 parent
= ui::GetHiddenWindow();
1629 parent
= window_
->GetHost()->GetAcceleratedWidget();
1631 LPARAM lparam
= reinterpret_cast<LPARAM
>(this);
1632 EnumChildWindows(parent
, WindowDestroyingCallback
, lparam
);
1635 // Make sure that the input method no longer references to this object before
1636 // this object is removed from the root window (i.e. this object loses access
1637 // to the input method).
1638 ui::InputMethod
* input_method
= GetInputMethod();
1640 input_method
->DetachTextInputClient(this);
1643 void RenderWidgetHostViewAura::OnWindowDestroyed(aura::Window
* window
) {
1644 host_
->ViewDestroyed();
1648 void RenderWidgetHostViewAura::OnWindowTargetVisibilityChanged(bool visible
) {
1651 bool RenderWidgetHostViewAura::HasHitTestMask() const {
1655 void RenderWidgetHostViewAura::GetHitTestMask(gfx::Path
* mask
) const {
1658 ////////////////////////////////////////////////////////////////////////////////
1659 // RenderWidgetHostViewAura, ui::EventHandler implementation:
1661 void RenderWidgetHostViewAura::OnKeyEvent(ui::KeyEvent
* event
) {
1662 TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnKeyEvent");
1663 if (touch_editing_client_
&& touch_editing_client_
->HandleInputEvent(event
))
1666 if (popup_child_host_view_
&& popup_child_host_view_
->NeedsInputGrab()) {
1667 popup_child_host_view_
->OnKeyEvent(event
);
1668 if (event
->handled())
1672 // We need to handle the Escape key for Pepper Flash.
1673 if (is_fullscreen_
&& event
->key_code() == ui::VKEY_ESCAPE
) {
1674 // Focus the window we were created from.
1675 if (host_tracker_
.get() && !host_tracker_
->windows().empty()) {
1676 aura::Window
* host
= *(host_tracker_
->windows().begin());
1677 aura::client::FocusClient
* client
= aura::client::GetFocusClient(host
);
1679 // Calling host->Focus() may delete |this|. We create a local observer
1680 // for that. In that case we exit without further access to any members.
1681 aura::WindowTracker tracker
;
1682 aura::Window
* window
= window_
;
1683 tracker
.Add(window
);
1685 if (!tracker
.Contains(window
)) {
1686 event
->SetHandled();
1691 if (!in_shutdown_
) {
1692 in_shutdown_
= true;
1696 if (event
->key_code() == ui::VKEY_RETURN
) {
1697 // Do not forward return key release events if no press event was handled.
1698 if (event
->type() == ui::ET_KEY_RELEASED
&& !accept_return_character_
)
1700 // Accept return key character events between press and release events.
1701 accept_return_character_
= event
->type() == ui::ET_KEY_PRESSED
;
1704 // We don't have to communicate with an input method here.
1705 if (!event
->HasNativeEvent()) {
1706 NativeWebKeyboardEvent
webkit_event(
1709 event
->is_char() ? event
->GetCharacter() : event
->key_code(),
1711 ui::EventTimeForNow().InSecondsF());
1712 ForwardKeyboardEvent(webkit_event
);
1714 NativeWebKeyboardEvent
webkit_event(event
);
1715 ForwardKeyboardEvent(webkit_event
);
1718 event
->SetHandled();
1721 void RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent
* event
) {
1722 TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnMouseEvent");
1724 if (touch_editing_client_
&& touch_editing_client_
->HandleInputEvent(event
))
1727 if (mouse_locked_
) {
1728 aura::client::CursorClient
* cursor_client
=
1729 aura::client::GetCursorClient(window_
->GetRootWindow());
1730 DCHECK(!cursor_client
|| !cursor_client
->IsCursorVisible());
1732 if (event
->type() == ui::ET_MOUSEWHEEL
) {
1733 blink::WebMouseWheelEvent mouse_wheel_event
=
1734 MakeWebMouseWheelEvent(static_cast<ui::MouseWheelEvent
*>(event
));
1735 if (mouse_wheel_event
.deltaX
!= 0 || mouse_wheel_event
.deltaY
!= 0)
1736 host_
->ForwardWheelEvent(mouse_wheel_event
);
1740 gfx::Point
center(gfx::Rect(window_
->bounds().size()).CenterPoint());
1742 // If we receive non client mouse messages while we are in the locked state
1743 // it probably means that the mouse left the borders of our window and
1744 // needs to be moved back to the center.
1745 if (event
->flags() & ui::EF_IS_NON_CLIENT
) {
1746 synthetic_move_sent_
= true;
1747 window_
->MoveCursorTo(center
);
1751 blink::WebMouseEvent mouse_event
= MakeWebMouseEvent(event
);
1753 bool is_move_to_center_event
= (event
->type() == ui::ET_MOUSE_MOVED
||
1754 event
->type() == ui::ET_MOUSE_DRAGGED
) &&
1755 mouse_event
.x
== center
.x() && mouse_event
.y
== center
.y();
1757 ModifyEventMovementAndCoords(&mouse_event
);
1759 bool should_not_forward
= is_move_to_center_event
&& synthetic_move_sent_
;
1760 if (should_not_forward
) {
1761 synthetic_move_sent_
= false;
1763 // Check if the mouse has reached the border and needs to be centered.
1764 if (ShouldMoveToCenter()) {
1765 synthetic_move_sent_
= true;
1766 window_
->MoveCursorTo(center
);
1768 // Forward event to renderer.
1769 if (CanRendererHandleEvent(event
) &&
1770 !(event
->flags() & ui::EF_FROM_TOUCH
)) {
1771 host_
->ForwardMouseEvent(mouse_event
);
1772 // Ensure that we get keyboard focus on mouse down as a plugin window
1773 // may have grabbed keyboard focus.
1774 if (event
->type() == ui::ET_MOUSE_PRESSED
)
1781 // As the overscroll is handled during scroll events from the trackpad, the
1782 // RWHVA window is transformed by the overscroll controller. This transform
1783 // triggers a synthetic mouse-move event to be generated (by the aura
1784 // RootWindow). But this event interferes with the overscroll gesture. So,
1785 // ignore such synthetic mouse-move events if an overscroll gesture is in
1787 if (host_
->overscroll_controller() &&
1788 host_
->overscroll_controller()->overscroll_mode() != OVERSCROLL_NONE
&&
1789 event
->flags() & ui::EF_IS_SYNTHESIZED
&&
1790 (event
->type() == ui::ET_MOUSE_ENTERED
||
1791 event
->type() == ui::ET_MOUSE_EXITED
||
1792 event
->type() == ui::ET_MOUSE_MOVED
)) {
1793 event
->StopPropagation();
1797 if (event
->type() == ui::ET_MOUSEWHEEL
) {
1799 // We get mouse wheel/scroll messages even if we are not in the foreground.
1800 // So here we check if we have any owned popup windows in the foreground and
1802 aura::WindowTreeHost
* host
= window_
->GetHost();
1804 HWND parent
= host
->GetAcceleratedWidget();
1805 HWND toplevel_hwnd
= ::GetAncestor(parent
, GA_ROOT
);
1806 EnumThreadWindows(GetCurrentThreadId(),
1808 reinterpret_cast<LPARAM
>(toplevel_hwnd
));
1811 blink::WebMouseWheelEvent mouse_wheel_event
=
1812 MakeWebMouseWheelEvent(static_cast<ui::MouseWheelEvent
*>(event
));
1813 if (mouse_wheel_event
.deltaX
!= 0 || mouse_wheel_event
.deltaY
!= 0)
1814 host_
->ForwardWheelEvent(mouse_wheel_event
);
1815 } else if (CanRendererHandleEvent(event
) &&
1816 !(event
->flags() & ui::EF_FROM_TOUCH
)) {
1817 blink::WebMouseEvent mouse_event
= MakeWebMouseEvent(event
);
1818 ModifyEventMovementAndCoords(&mouse_event
);
1819 host_
->ForwardMouseEvent(mouse_event
);
1820 // Ensure that we get keyboard focus on mouse down as a plugin window may
1821 // have grabbed keyboard focus.
1822 if (event
->type() == ui::ET_MOUSE_PRESSED
)
1826 switch (event
->type()) {
1827 case ui::ET_MOUSE_PRESSED
:
1828 window_
->SetCapture();
1829 // Confirm existing composition text on mouse click events, to make sure
1830 // the input caret won't be moved with an ongoing composition text.
1831 FinishImeCompositionSession();
1833 case ui::ET_MOUSE_RELEASED
:
1834 window_
->ReleaseCapture();
1840 // Needed to propagate mouse event to |window_->parent()->delegate()|, but
1841 // note that it might be something other than a WebContentsViewAura instance.
1842 // TODO(pkotwicz): Find a better way of doing this.
1843 // In fullscreen mode which is typically used by flash, don't forward
1844 // the mouse events to the parent. The renderer and the plugin process
1845 // handle these events.
1846 if (!is_fullscreen_
&& window_
->parent()->delegate() &&
1847 !(event
->flags() & ui::EF_FROM_TOUCH
)) {
1848 event
->ConvertLocationToTarget(window_
, window_
->parent());
1849 window_
->parent()->delegate()->OnMouseEvent(event
);
1852 if (!IsXButtonUpEvent(event
))
1853 event
->SetHandled();
1856 void RenderWidgetHostViewAura::OnScrollEvent(ui::ScrollEvent
* event
) {
1857 TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnScrollEvent");
1858 if (touch_editing_client_
&& touch_editing_client_
->HandleInputEvent(event
))
1861 if (event
->type() == ui::ET_SCROLL
) {
1862 #if !defined(OS_WIN)
1864 // Investigate if this is true for Windows 8 Metro ASH as well.
1865 if (event
->finger_count() != 2)
1868 blink::WebGestureEvent gesture_event
=
1869 MakeWebGestureEventFlingCancel();
1870 host_
->ForwardGestureEvent(gesture_event
);
1871 blink::WebMouseWheelEvent mouse_wheel_event
=
1872 MakeWebMouseWheelEvent(event
);
1873 host_
->ForwardWheelEvent(mouse_wheel_event
);
1874 RecordAction(base::UserMetricsAction("TrackpadScroll"));
1875 } else if (event
->type() == ui::ET_SCROLL_FLING_START
||
1876 event
->type() == ui::ET_SCROLL_FLING_CANCEL
) {
1877 blink::WebGestureEvent gesture_event
=
1878 MakeWebGestureEvent(event
);
1879 host_
->ForwardGestureEvent(gesture_event
);
1880 if (event
->type() == ui::ET_SCROLL_FLING_START
)
1881 RecordAction(base::UserMetricsAction("TrackpadScrollFling"));
1884 event
->SetHandled();
1887 void RenderWidgetHostViewAura::OnTouchEvent(ui::TouchEvent
* event
) {
1888 TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnTouchEvent");
1889 if (touch_editing_client_
&& touch_editing_client_
->HandleInputEvent(event
))
1892 // Update the touch event first.
1893 blink::WebTouchPoint
* point
= UpdateWebTouchEventFromUIEvent(*event
,
1896 // Forward the touch event only if a touch point was updated, and there's a
1897 // touch-event handler in the page, and no other touch-event is in the queue.
1898 // It is important to always consume the event if there is a touch-event
1899 // handler in the page, or some touch-event is already in the queue, even if
1900 // no point has been updated, to make sure that this event does not get
1901 // processed by the gesture recognizer before the events in the queue.
1902 if (host_
->ShouldForwardTouchEvent())
1903 event
->StopPropagation();
1906 if (host_
->ShouldForwardTouchEvent())
1907 host_
->ForwardTouchEventWithLatencyInfo(touch_event_
, *event
->latency());
1908 UpdateWebTouchEventAfterDispatch(&touch_event_
, point
);
1912 void RenderWidgetHostViewAura::OnGestureEvent(ui::GestureEvent
* event
) {
1913 TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnGestureEvent");
1914 if ((event
->type() == ui::ET_GESTURE_PINCH_BEGIN
||
1915 event
->type() == ui::ET_GESTURE_PINCH_UPDATE
||
1916 event
->type() == ui::ET_GESTURE_PINCH_END
) && !pinch_zoom_enabled_
) {
1917 event
->SetHandled();
1921 if (touch_editing_client_
&& touch_editing_client_
->HandleInputEvent(event
))
1924 RenderViewHostDelegate
* delegate
= NULL
;
1925 if (host_
->IsRenderView())
1926 delegate
= RenderViewHost::From(host_
)->GetDelegate();
1928 if (delegate
&& event
->type() == ui::ET_GESTURE_BEGIN
&&
1929 event
->details().touch_points() == 1) {
1930 delegate
->HandleGestureBegin();
1933 blink::WebGestureEvent gesture
= MakeWebGestureEvent(event
);
1934 if (event
->type() == ui::ET_GESTURE_TAP_DOWN
) {
1935 // Webkit does not stop a fling-scroll on tap-down. So explicitly send an
1936 // event to stop any in-progress flings.
1937 blink::WebGestureEvent fling_cancel
= gesture
;
1938 fling_cancel
.type
= blink::WebInputEvent::GestureFlingCancel
;
1939 fling_cancel
.sourceDevice
= blink::WebGestureEvent::Touchscreen
;
1940 host_
->ForwardGestureEvent(fling_cancel
);
1943 if (gesture
.type
!= blink::WebInputEvent::Undefined
) {
1944 host_
->ForwardGestureEventWithLatencyInfo(gesture
, *event
->latency());
1946 if (event
->type() == ui::ET_GESTURE_SCROLL_BEGIN
||
1947 event
->type() == ui::ET_GESTURE_SCROLL_UPDATE
||
1948 event
->type() == ui::ET_GESTURE_SCROLL_END
) {
1949 RecordAction(base::UserMetricsAction("TouchscreenScroll"));
1950 } else if (event
->type() == ui::ET_SCROLL_FLING_START
) {
1951 RecordAction(base::UserMetricsAction("TouchscreenScrollFling"));
1955 if (delegate
&& event
->type() == ui::ET_GESTURE_END
&&
1956 event
->details().touch_points() == 1) {
1957 delegate
->HandleGestureEnd();
1960 // If a gesture is not processed by the webpage, then WebKit processes it
1961 // (e.g. generates synthetic mouse events).
1962 event
->SetHandled();
1965 ////////////////////////////////////////////////////////////////////////////////
1966 // RenderWidgetHostViewAura, aura::client::ActivationDelegate implementation:
1968 bool RenderWidgetHostViewAura::ShouldActivate() const {
1969 aura::WindowTreeHost
* host
= window_
->GetHost();
1972 const ui::Event
* event
= host
->dispatcher()->current_event();
1975 return is_fullscreen_
;
1978 ////////////////////////////////////////////////////////////////////////////////
1979 // RenderWidgetHostViewAura,
1980 // aura::client::ActivationChangeObserver implementation:
1982 void RenderWidgetHostViewAura::OnWindowActivated(aura::Window
* gained_active
,
1983 aura::Window
* lost_active
) {
1984 DCHECK(window_
== gained_active
|| window_
== lost_active
);
1985 if (window_
== gained_active
) {
1986 const ui::Event
* event
= window_
->GetHost()->dispatcher()->current_event();
1987 if (event
&& PointerEventActivates(*event
))
1988 host_
->OnPointerEventActivate();
1992 ////////////////////////////////////////////////////////////////////////////////
1993 // RenderWidgetHostViewAura, aura::client::CursorClientObserver implementation:
1995 void RenderWidgetHostViewAura::OnCursorVisibilityChanged(bool is_visible
) {
1996 NotifyRendererOfCursorVisibilityState(is_visible
);
1999 ////////////////////////////////////////////////////////////////////////////////
2000 // RenderWidgetHostViewAura, aura::client::FocusChangeObserver implementation:
2002 void RenderWidgetHostViewAura::OnWindowFocused(aura::Window
* gained_focus
,
2003 aura::Window
* lost_focus
) {
2004 DCHECK(window_
== gained_focus
|| window_
== lost_focus
);
2005 if (window_
== gained_focus
) {
2006 // We need to honor input bypass if the associated tab is does not want
2007 // input. This gives the current focused window a chance to be the text
2008 // input client and handle events.
2009 if (host_
->ignore_input_events())
2013 host_
->SetActive(true);
2015 ui::InputMethod
* input_method
= GetInputMethod();
2017 // Ask the system-wide IME to send all TextInputClient messages to |this|
2019 input_method
->SetFocusedTextInputClient(this);
2020 host_
->SetInputMethodActive(input_method
->IsActive());
2022 // Often the application can set focus to the view in response to a key
2023 // down. However the following char event shouldn't be sent to the web
2025 host_
->SuppressNextCharEvents();
2027 host_
->SetInputMethodActive(false);
2030 BrowserAccessibilityManager
* manager
= GetBrowserAccessibilityManager();
2032 manager
->OnWindowFocused();
2033 } else if (window_
== lost_focus
) {
2034 host_
->SetActive(false);
2037 DetachFromInputMethod();
2038 host_
->SetInputMethodActive(false);
2040 if (touch_editing_client_
)
2041 touch_editing_client_
->EndTouchEditing(false);
2043 BrowserAccessibilityManager
* manager
= GetBrowserAccessibilityManager();
2045 manager
->OnWindowBlurred();
2047 // If we lose the focus while fullscreen, close the window; Pepper Flash
2048 // won't do it for us (unlike NPAPI Flash). However, we do not close the
2049 // window if we lose the focus to a window on another display.
2050 gfx::Screen
* screen
= gfx::Screen::GetScreenFor(window_
);
2051 bool focusing_other_display
=
2052 gained_focus
&& screen
->GetNumDisplays() > 1 &&
2053 (screen
->GetDisplayNearestWindow(window_
).id() !=
2054 screen
->GetDisplayNearestWindow(gained_focus
).id());
2055 if (is_fullscreen_
&& !in_shutdown_
&& !focusing_other_display
) {
2057 // On Windows, if we are switching to a non Aura Window on a different
2058 // screen we should not close the fullscreen window.
2059 if (!gained_focus
) {
2061 ::GetCursorPos(&point
);
2062 if (screen
->GetDisplayNearestWindow(window_
).id() !=
2063 screen
->GetDisplayNearestPoint(gfx::Point(point
)).id())
2067 in_shutdown_
= true;
2073 ////////////////////////////////////////////////////////////////////////////////
2074 // RenderWidgetHostViewAura, aura::WindowTreeHostObserver implementation:
2076 void RenderWidgetHostViewAura::OnHostMoved(const aura::WindowTreeHost
* host
,
2077 const gfx::Point
& new_origin
) {
2078 TRACE_EVENT1("ui", "RenderWidgetHostViewAura::OnHostMoved",
2079 "new_origin", new_origin
.ToString());
2081 UpdateScreenInfo(window_
);
2084 ////////////////////////////////////////////////////////////////////////////////
2085 // RenderWidgetHostViewAura, private:
2087 RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
2088 if (touch_editing_client_
)
2089 touch_editing_client_
->OnViewDestroyed();
2091 delegated_frame_host_
.reset();
2092 window_observer_
.reset();
2093 if (window_
->GetHost())
2094 window_
->GetHost()->RemoveObserver(this);
2096 if (popup_parent_host_view_
) {
2097 DCHECK(popup_parent_host_view_
->popup_child_host_view_
== NULL
||
2098 popup_parent_host_view_
->popup_child_host_view_
== this);
2099 popup_parent_host_view_
->popup_child_host_view_
= NULL
;
2101 if (popup_child_host_view_
) {
2102 DCHECK(popup_child_host_view_
->popup_parent_host_view_
== NULL
||
2103 popup_child_host_view_
->popup_parent_host_view_
== this);
2104 popup_child_host_view_
->popup_parent_host_view_
= NULL
;
2106 event_filter_for_popup_exit_
.reset();
2107 aura::client::SetTooltipText(window_
, NULL
);
2108 gfx::Screen::GetScreenFor(window_
)->RemoveObserver(this);
2110 // This call is usually no-op since |this| object is already removed from the
2111 // Aura root window and we don't have a way to get an input method object
2112 // associated with the window, but just in case.
2113 DetachFromInputMethod();
2116 legacy_render_widget_host_HWND_
.reset(NULL
);
2120 void RenderWidgetHostViewAura::UpdateCursorIfOverSelf() {
2121 const gfx::Point screen_point
=
2122 gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint();
2123 aura::Window
* root_window
= window_
->GetRootWindow();
2127 gfx::Point root_window_point
= screen_point
;
2128 aura::client::ScreenPositionClient
* screen_position_client
=
2129 aura::client::GetScreenPositionClient(root_window
);
2130 if (screen_position_client
) {
2131 screen_position_client
->ConvertPointFromScreen(
2132 root_window
, &root_window_point
);
2135 if (root_window
->GetEventHandlerForPoint(root_window_point
) != window_
)
2138 gfx::NativeCursor cursor
= current_cursor_
.GetNativeCursor();
2139 // Do not show loading cursor when the cursor is currently hidden.
2140 if (is_loading_
&& cursor
!= ui::kCursorNone
)
2141 cursor
= ui::kCursorPointer
;
2143 aura::client::CursorClient
* cursor_client
=
2144 aura::client::GetCursorClient(root_window
);
2145 if (cursor_client
) {
2146 cursor_client
->SetCursor(cursor
);
2150 ui::InputMethod
* RenderWidgetHostViewAura::GetInputMethod() const {
2151 aura::Window
* root_window
= window_
->GetRootWindow();
2154 return root_window
->GetProperty(aura::client::kRootWindowInputMethodKey
);
2157 bool RenderWidgetHostViewAura::NeedsInputGrab() {
2158 return popup_type_
== blink::WebPopupTypeSelect
;
2161 void RenderWidgetHostViewAura::FinishImeCompositionSession() {
2162 if (!has_composition_text_
)
2165 host_
->ImeConfirmComposition(base::string16(), gfx::Range::InvalidRange(),
2168 ImeCancelComposition();
2171 void RenderWidgetHostViewAura::ModifyEventMovementAndCoords(
2172 blink::WebMouseEvent
* event
) {
2173 // If the mouse has just entered, we must report zero movementX/Y. Hence we
2174 // reset any global_mouse_position set previously.
2175 if (event
->type
== blink::WebInputEvent::MouseEnter
||
2176 event
->type
== blink::WebInputEvent::MouseLeave
)
2177 global_mouse_position_
.SetPoint(event
->globalX
, event
->globalY
);
2179 // Movement is computed by taking the difference of the new cursor position
2180 // and the previous. Under mouse lock the cursor will be warped back to the
2181 // center so that we are not limited by clipping boundaries.
2182 // We do not measure movement as the delta from cursor to center because
2183 // we may receive more mouse movement events before our warp has taken
2185 event
->movementX
= event
->globalX
- global_mouse_position_
.x();
2186 event
->movementY
= event
->globalY
- global_mouse_position_
.y();
2188 global_mouse_position_
.SetPoint(event
->globalX
, event
->globalY
);
2190 // Under mouse lock, coordinates of mouse are locked to what they were when
2191 // mouse lock was entered.
2192 if (mouse_locked_
) {
2193 event
->x
= unlocked_mouse_position_
.x();
2194 event
->y
= unlocked_mouse_position_
.y();
2195 event
->windowX
= unlocked_mouse_position_
.x();
2196 event
->windowY
= unlocked_mouse_position_
.y();
2197 event
->globalX
= unlocked_global_mouse_position_
.x();
2198 event
->globalY
= unlocked_global_mouse_position_
.y();
2200 unlocked_mouse_position_
.SetPoint(event
->windowX
, event
->windowY
);
2201 unlocked_global_mouse_position_
.SetPoint(event
->globalX
, event
->globalY
);
2205 void RenderWidgetHostViewAura::NotifyRendererOfCursorVisibilityState(
2207 if (host_
->is_hidden() ||
2208 (cursor_visibility_state_in_renderer_
== VISIBLE
&& is_visible
) ||
2209 (cursor_visibility_state_in_renderer_
== NOT_VISIBLE
&& !is_visible
))
2212 cursor_visibility_state_in_renderer_
= is_visible
? VISIBLE
: NOT_VISIBLE
;
2213 host_
->SendCursorVisibilityState(is_visible
);
2216 void RenderWidgetHostViewAura::SchedulePaintIfNotInClip(
2217 const gfx::Rect
& rect
,
2218 const gfx::Rect
& clip
) {
2219 if (!clip
.IsEmpty()) {
2220 gfx::Rect to_paint
= gfx::SubtractRects(rect
, clip
);
2221 if (!to_paint
.IsEmpty())
2222 window_
->SchedulePaintInRect(to_paint
);
2224 window_
->SchedulePaintInRect(rect
);
2228 bool RenderWidgetHostViewAura::ShouldMoveToCenter() {
2229 gfx::Rect rect
= window_
->bounds();
2230 rect
= ConvertRectToScreen(rect
);
2231 int border_x
= rect
.width() * kMouseLockBorderPercentage
/ 100;
2232 int border_y
= rect
.height() * kMouseLockBorderPercentage
/ 100;
2234 return global_mouse_position_
.x() < rect
.x() + border_x
||
2235 global_mouse_position_
.x() > rect
.right() - border_x
||
2236 global_mouse_position_
.y() < rect
.y() + border_y
||
2237 global_mouse_position_
.y() > rect
.bottom() - border_y
;
2240 void RenderWidgetHostViewAura::AddedToRootWindow() {
2241 window_
->GetHost()->AddObserver(this);
2242 UpdateScreenInfo(window_
);
2244 aura::client::CursorClient
* cursor_client
=
2245 aura::client::GetCursorClient(window_
->GetRootWindow());
2246 if (cursor_client
) {
2247 cursor_client
->AddObserver(this);
2248 NotifyRendererOfCursorVisibilityState(cursor_client
->IsCursorVisible());
2251 ui::InputMethod
* input_method
= GetInputMethod();
2253 input_method
->SetFocusedTextInputClient(this);
2257 // The parent may have changed here. Ensure that the legacy window is
2258 // reparented accordingly.
2259 if (legacy_render_widget_host_HWND_
)
2260 legacy_render_widget_host_HWND_
->UpdateParent(
2261 reinterpret_cast<HWND
>(GetNativeViewId()));
2264 delegated_frame_host_
->AddedToWindow();
2267 void RenderWidgetHostViewAura::RemovingFromRootWindow() {
2268 aura::client::CursorClient
* cursor_client
=
2269 aura::client::GetCursorClient(window_
->GetRootWindow());
2271 cursor_client
->RemoveObserver(this);
2273 DetachFromInputMethod();
2275 window_
->GetHost()->RemoveObserver(this);
2276 delegated_frame_host_
->RemovingFromWindow();
2279 // Update the legacy window's parent temporarily to the desktop window. It
2280 // will eventually get reparented to the right root.
2281 if (legacy_render_widget_host_HWND_
)
2282 legacy_render_widget_host_HWND_
->UpdateParent(::GetDesktopWindow());
2286 void RenderWidgetHostViewAura::DetachFromInputMethod() {
2287 ui::InputMethod
* input_method
= GetInputMethod();
2288 if (input_method
&& input_method
->GetTextInputClient() == this)
2289 input_method
->SetFocusedTextInputClient(NULL
);
2292 void RenderWidgetHostViewAura::ForwardKeyboardEvent(
2293 const NativeWebKeyboardEvent
& event
) {
2294 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
2295 ui::TextEditKeyBindingsDelegateAuraLinux
* keybinding_delegate
=
2296 ui::GetTextEditKeyBindingsDelegate();
2297 std::vector
<ui::TextEditCommandAuraLinux
> commands
;
2298 if (!event
.skip_in_browser
&&
2299 keybinding_delegate
&&
2301 keybinding_delegate
->MatchEvent(*event
.os_event
, &commands
)) {
2302 // Transform from ui/ types to content/ types.
2303 EditCommands edit_commands
;
2304 for (std::vector
<ui::TextEditCommandAuraLinux
>::const_iterator it
=
2305 commands
.begin(); it
!= commands
.end(); ++it
) {
2306 edit_commands
.push_back(EditCommand(it
->GetCommandString(),
2309 host_
->Send(new InputMsg_SetEditCommandsForNextKeyEvent(
2310 host_
->GetRoutingID(), edit_commands
));
2311 NativeWebKeyboardEvent
copy_event(event
);
2312 copy_event
.match_edit_command
= true;
2313 host_
->ForwardKeyboardEvent(copy_event
);
2318 host_
->ForwardKeyboardEvent(event
);
2321 SkBitmap::Config
RenderWidgetHostViewAura::PreferredReadbackFormat() {
2322 return SkBitmap::kARGB_8888_Config
;
2325 ////////////////////////////////////////////////////////////////////////////////
2326 // DelegatedFrameHost, public:
2328 ui::Compositor
* RenderWidgetHostViewAura::GetCompositor() const {
2329 aura::WindowTreeHost
* host
= window_
->GetHost();
2330 return host
? host
->compositor() : NULL
;
2333 ui::Layer
* RenderWidgetHostViewAura::GetLayer() {
2334 return window_
->layer();
2337 RenderWidgetHostImpl
* RenderWidgetHostViewAura::GetHost() {
2341 void RenderWidgetHostViewAura::SchedulePaintInRect(
2342 const gfx::Rect
& damage_rect_in_dip
) {
2343 window_
->SchedulePaintInRect(damage_rect_in_dip
);
2346 bool RenderWidgetHostViewAura::IsVisible() {
2350 gfx::Size
RenderWidgetHostViewAura::DesiredFrameSize() {
2351 return window_
->bounds().size();
2354 float RenderWidgetHostViewAura::CurrentDeviceScaleFactor() {
2355 return current_device_scale_factor_
;
2358 gfx::Size
RenderWidgetHostViewAura::ConvertViewSizeToPixel(
2359 const gfx::Size
& size
) {
2360 return content::ConvertViewSizeToPixel(this, size
);
2363 scoped_ptr
<ResizeLock
> RenderWidgetHostViewAura::CreateResizeLock(
2364 bool defer_compositor_lock
) {
2365 gfx::Size desired_size
= window_
->bounds().size();
2366 return scoped_ptr
<ResizeLock
>(new CompositorResizeLock(
2369 defer_compositor_lock
,
2370 base::TimeDelta::FromMilliseconds(kResizeLockTimeoutMs
)));
2371 ResizeLock
* lock
= NULL
;
2372 return scoped_ptr
<ResizeLock
>(lock
);
2375 DelegatedFrameHost
* RenderWidgetHostViewAura::GetDelegatedFrameHost() const {
2376 return delegated_frame_host_
.get();
2379 ////////////////////////////////////////////////////////////////////////////////
2380 // RenderWidgetHostViewBase, public:
2383 void RenderWidgetHostViewBase::GetDefaultScreenInfo(WebScreenInfo
* results
) {
2384 GetScreenInfoForWindow(results
, NULL
);
2387 } // namespace content