1 // Copyright 2012 The Chromium Authors
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"
12 #include "base/auto_reset.h"
13 #include "base/command_line.h"
14 #include "base/feature_list.h"
15 #include "base/functional/bind.h"
16 #include "base/functional/callback_helpers.h"
17 #include "base/logging.h"
18 #include "base/memory/raw_ptr.h"
19 #include "base/metrics/histogram_functions.h"
20 #include "base/strings/strcat.h"
21 #include "base/strings/string_number_conversions.h"
22 #include "base/strings/utf_string_conversions.h"
23 #include "base/trace_event/trace_event.h"
24 #include "build/build_config.h"
25 #include "build/chromeos_buildflags.h"
26 #include "cc/layers/layer.h"
27 #include "cc/trees/layer_tree_settings.h"
28 #include "components/viz/common/features.h"
29 #include "components/viz/common/frame_sinks/copy_output_request.h"
30 #include "components/viz/common/frame_sinks/copy_output_result.h"
31 #include "components/viz/common/surfaces/local_surface_id.h"
32 #include "content/browser/accessibility/browser_accessibility_manager.h"
33 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
34 #include "content/browser/bad_message.h"
35 #include "content/browser/gpu/compositor_util.h"
36 #include "content/browser/renderer_host/cursor_manager.h"
37 #include "content/browser/renderer_host/delegated_frame_host_client_aura.h"
38 #include "content/browser/renderer_host/dip_util.h"
39 #include "content/browser/renderer_host/frame_tree.h"
40 #include "content/browser/renderer_host/frame_tree_node.h"
41 #include "content/browser/renderer_host/input/synthetic_gesture_target_aura.h"
42 #include "content/browser/renderer_host/input/touch_selection_controller_client_aura.h"
43 #include "content/browser/renderer_host/overscroll_controller.h"
44 #include "content/browser/renderer_host/render_frame_host_impl.h"
45 #include "content/browser/renderer_host/render_view_host_delegate.h"
46 #include "content/browser/renderer_host/render_view_host_delegate_view.h"
47 #include "content/browser/renderer_host/render_view_host_impl.h"
48 #include "content/browser/renderer_host/render_widget_host_delegate.h"
49 #include "content/browser/renderer_host/render_widget_host_impl.h"
50 #include "content/browser/renderer_host/render_widget_host_input_event_router.h"
51 #include "content/browser/renderer_host/render_widget_host_view_event_handler.h"
52 #include "content/browser/renderer_host/ui_events_helper.h"
53 #include "content/browser/renderer_host/visible_time_request_trigger.h"
54 #include "content/public/browser/content_browser_client.h"
55 #include "content/public/browser/device_service.h"
56 #include "content/public/browser/render_view_host.h"
57 #include "content/public/common/content_features.h"
58 #include "content/public/common/page_visibility_state.h"
59 #include "services/service_manager/public/cpp/interface_provider.h"
60 #include "third_party/blink/public/common/input/web_input_event.h"
61 #include "third_party/blink/public/mojom/input/input_handler.mojom-forward.h"
62 #include "third_party/blink/public/mojom/widget/record_content_to_visible_time_request.mojom.h"
63 #include "ui/accessibility/aura/aura_window_properties.h"
64 #include "ui/accessibility/platform/ax_platform_node.h"
65 #include "ui/aura/client/aura_constants.h"
66 #include "ui/aura/client/cursor_client.h"
67 #include "ui/aura/client/cursor_client_observer.h"
68 #include "ui/aura/client/focus_client.h"
69 #include "ui/aura/client/screen_position_client.h"
70 #include "ui/aura/client/transient_window_client.h"
71 #include "ui/aura/client/window_parenting_client.h"
72 #include "ui/aura/env.h"
73 #include "ui/aura/window.h"
74 #include "ui/aura/window_event_dispatcher.h"
75 #include "ui/aura/window_observer.h"
76 #include "ui/aura/window_tree_host.h"
77 #include "ui/aura_extra/window_position_in_root_monitor.h"
78 #include "ui/base/clipboard/clipboard.h"
79 #include "ui/base/clipboard/scoped_clipboard_writer.h"
80 #include "ui/base/cursor/cursor.h"
81 #include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
82 #include "ui/base/hit_test.h"
83 #include "ui/base/ime/input_method.h"
84 #include "ui/base/ime/mojom/text_input_state.mojom.h"
85 #include "ui/base/owned_window_anchor.h"
86 #include "ui/base/ui_base_features.h"
87 #include "ui/base/ui_base_switches.h"
88 #include "ui/base/ui_base_types.h"
89 #include "ui/display/screen.h"
90 #include "ui/events/blink/blink_event_util.h"
91 #include "ui/events/blink/did_overscroll_params.h"
92 #include "ui/events/blink/web_input_event.h"
93 #include "ui/events/event.h"
94 #include "ui/events/event_observer.h"
95 #include "ui/events/event_utils.h"
96 #include "ui/events/gesture_detection/gesture_configuration.h"
97 #include "ui/events/gestures/gesture_recognizer.h"
98 #include "ui/events/keycodes/dom/dom_code.h"
99 #include "ui/gfx/canvas.h"
100 #include "ui/gfx/color_palette.h"
101 #include "ui/gfx/geometry/dip_util.h"
102 #include "ui/gfx/geometry/rect_conversions.h"
103 #include "ui/gfx/geometry/size_conversions.h"
104 #include "ui/gfx/geometry/skia_conversions.h"
105 #include "ui/touch_selection/touch_selection_controller.h"
106 #include "ui/wm/core/coordinate_conversion.h"
107 #include "ui/wm/public/activation_client.h"
108 #include "ui/wm/public/scoped_tooltip_disabler.h"
109 #include "ui/wm/public/tooltip_client.h"
111 #if BUILDFLAG(IS_WIN)
112 #include "base/time/time.h"
113 #include "content/browser/accessibility/browser_accessibility_manager_win.h"
114 #include "content/browser/accessibility/browser_accessibility_win.h"
115 #include "content/browser/renderer_host/legacy_render_widget_host_win.h"
116 #include "ui/accessibility/platform/ax_fragment_root_win.h"
117 #include "ui/base/ime/virtual_keyboard_controller.h"
118 #include "ui/base/ime/virtual_keyboard_controller_observer.h"
119 #include "ui/base/win/hidden_window.h"
120 #include "ui/display/win/screen_win.h"
121 #include "ui/gfx/gdi_util.h"
124 #if BUILDFLAG(IS_LINUX)
125 #include "content/browser/accessibility/browser_accessibility_auralinux.h"
126 #include "ui/base/ime/linux/text_edit_command_auralinux.h"
127 #include "ui/base/ime/text_input_flags.h"
128 #include "ui/linux/linux_ui.h"
131 #if BUILDFLAG(IS_CHROMEOS_ASH)
132 #include "ui/wm/core/ime_util_chromeos.h"
135 #if BUILDFLAG(IS_CHROMEOS_ASH)
136 #include "ui/base/ime/ash/extension_ime_util.h"
137 #include "ui/base/ime/ash/input_method_manager.h"
140 #if BUILDFLAG(IS_CHROMEOS)
141 #include "ui/base/ime/mojom/virtual_keyboard_types.mojom.h"
144 #if BUILDFLAG(IS_EFL)
145 #include "base/base_switches.h"
148 #if BUILDFLAG(IS_TIZEN)
149 #include <vconf/vconf.h>
150 #include "base/json/json_reader.h"
151 #include "ui/display/device_display_info_efl.h"
154 using gfx::RectToSkIRect;
155 using gfx::SkIRectToRect;
157 using blink::WebInputEvent;
158 using blink::WebGestureEvent;
159 using blink::WebTouchEvent;
163 // We need to watch for mouse events outside a Web Popup or its parent
164 // and dismiss the popup for certain events.
165 class RenderWidgetHostViewAura::EventObserverForPopupExit
166 : public ui::EventObserver {
168 explicit EventObserverForPopupExit(RenderWidgetHostViewAura* rwhva)
170 aura::Env* env = aura::Env::GetInstance();
171 env->AddEventObserver(this, env,
172 {ui::ET_MOUSE_PRESSED, ui::ET_TOUCH_PRESSED});
175 EventObserverForPopupExit(const EventObserverForPopupExit&) = delete;
176 EventObserverForPopupExit& operator=(const EventObserverForPopupExit&) =
179 ~EventObserverForPopupExit() override {
180 aura::Env::GetInstance()->RemoveEventObserver(this);
183 // ui::EventObserver:
184 void OnEvent(const ui::Event& event) override {
185 rwhva_->ApplyEventObserverForPopupExit(*event.AsLocatedEvent());
189 raw_ptr<RenderWidgetHostViewAura> rwhva_;
192 void RenderWidgetHostViewAura::ApplyEventObserverForPopupExit(
193 const ui::LocatedEvent& event) {
194 DCHECK(event.type() == ui::ET_MOUSE_PRESSED ||
195 event.type() == ui::ET_TOUCH_PRESSED);
200 // |target| may be null.
201 aura::Window* target = static_cast<aura::Window*>(event.target());
202 if (target != window_ &&
203 (!popup_parent_host_view_ ||
204 target != popup_parent_host_view_->window_)) {
205 // If we enter this code path it means that we did not receive any focus
206 // lost notifications for the popup window. Ensure that blink is aware
207 // of the fact that focus was lost for the host window by sending a Blur
208 // notification. We also set a flag in the view indicating that we need
209 // to force a Focus notification on the next mouse down.
210 if (popup_parent_host_view_ && popup_parent_host_view_->host()) {
211 popup_parent_host_view_->event_handler()
212 ->set_focus_on_mouse_down_or_key_event(true);
213 popup_parent_host_view_->host()->Blur();
215 // Note: popup_parent_host_view_ may be NULL when there are multiple
216 // popup children per view. See: RenderWidgetHostViewAura::InitAsPopup().
221 // We have to implement the WindowObserver interface on a separate object
222 // because clang doesn't like implementing multiple interfaces that have
223 // methods with the same name. This object is owned by the
224 // RenderWidgetHostViewAura.
225 class RenderWidgetHostViewAura::WindowObserver : public aura::WindowObserver {
227 explicit WindowObserver(RenderWidgetHostViewAura* view)
229 view_->window_->AddObserver(this);
232 WindowObserver(const WindowObserver&) = delete;
233 WindowObserver& operator=(const WindowObserver&) = delete;
235 ~WindowObserver() override { view_->window_->RemoveObserver(this); }
237 // Overridden from aura::WindowObserver:
238 void OnWindowAddedToRootWindow(aura::Window* window) override {
239 if (window == view_->window_)
240 view_->AddedToRootWindow();
243 void OnWindowRemovingFromRootWindow(aura::Window* window,
244 aura::Window* new_root) override {
245 if (window == view_->window_)
246 view_->RemovingFromRootWindow();
249 void OnWindowHierarchyChanged(const HierarchyChangeParams& params) override {
250 view_->ParentHierarchyChanged();
253 void OnWindowTitleChanged(aura::Window* window) override {
254 if (window == view_->window_)
255 view_->WindowTitleChanged();
259 raw_ptr<RenderWidgetHostViewAura> view_;
262 ////////////////////////////////////////////////////////////////////////////////
263 // RenderWidgetHostViewAura, public:
265 RenderWidgetHostViewAura::RenderWidgetHostViewAura(
266 RenderWidgetHost* widget_host,
267 WebContents& web_contents)
268 : RenderWidgetHostViewBase(widget_host),
271 in_bounds_changed_(false),
272 popup_parent_host_view_(nullptr),
273 popup_child_host_view_(nullptr),
275 has_composition_text_(false),
276 added_frame_observer_(false),
277 cursor_visibility_state_in_renderer_(UNKNOWN),
278 #if BUILDFLAG(IS_WIN)
279 legacy_render_widget_host_HWND_(nullptr),
280 legacy_window_destroyed_(false),
282 device_scale_factor_(0.0f),
283 event_handler_(new RenderWidgetHostViewEventHandler(host(), this, this)),
284 frame_sink_id_(host()->GetFrameSinkId()),
285 visibility_(host()->is_hidden() ? Visibility::HIDDEN
286 : Visibility::VISIBLE) {
287 // CreateDelegatedFrameHostClient() and CreateAuraWindow() assume that the
288 // FrameSinkId is valid. RenderWidgetHostImpl::GetFrameSinkId() always returns
289 // a valid FrameSinkId.
290 DCHECK(frame_sink_id_.is_valid());
292 CreateDelegatedFrameHostClient();
294 host()->SetView(this);
296 // We should start observing the TextInputManager for IME-related events as
297 // well as monitoring its lifetime.
298 if (GetTextInputManager())
299 GetTextInputManager()->AddObserver(this);
301 cursor_manager_ = std::make_unique<CursorManager>(this);
303 selection_controller_client_ =
304 std::make_unique<TouchSelectionControllerClientAura>(this);
305 CreateSelectionController();
307 RenderWidgetHostOwnerDelegate* owner_delegate = host()->owner_delegate();
308 if (owner_delegate) {
309 // NOTE: This will not be run for child frame widgets, which do not have
310 // an owner delegate and won't get a RenderViewHost here.
311 double_tap_to_zoom_enabled_ =
312 owner_delegate->GetWebkitPreferencesForWidget()
313 .double_tap_to_zoom_enabled;
316 host()->render_frame_metadata_provider()->AddObserver(this);
318 #if BUILDFLAG(IS_EFL)
320 base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableOffscreenRendering)
321 ? std::make_unique<RWHVAuraOffscreenHelperEfl>(this, &web_contents)
322 : std::make_unique<RWHVAuraCommonHelperEfl>(this, &web_contents);
324 #if BUILDFLAG(IS_TIZEN)
325 display::DeviceDisplayInfoEfl display_info;
326 rotation_ = display_info.GetRotationDegrees();
327 LOG(INFO) << "Rotation_ " << rotation_;
328 if (aura_efl_helper())
329 aura_efl_helper()->SetOrientation(rotation_);
333 ////////////////////////////////////////////////////////////////////////////////
334 // RenderWidgetHostViewAura, RenderWidgetHostView implementation:
336 void RenderWidgetHostViewAura::InitAsChild(gfx::NativeView parent_view) {
337 DCHECK_EQ(widget_type_, WidgetType::kFrame);
338 CreateAuraWindow(aura::client::WINDOW_TYPE_CONTROL);
341 parent_view->AddChild(GetNativeView());
343 #if BUILDFLAG(IS_EFL)
344 efl_helper_->SetAuraParentWindow(parent_view);
347 device_scale_factor_ = GetDeviceScaleFactor();
349 aura::Window* root = window_->GetRootWindow();
351 auto* cursor_client = aura::client::GetCursorClient(root);
353 UpdateSystemCursorSize(cursor_client->GetSystemCursorSize());
356 #if BUILDFLAG(IS_WIN)
357 // This will fetch and set the display features.
358 EnsureDevicePostureServiceConnection();
362 void RenderWidgetHostViewAura::InitAsPopup(
363 RenderWidgetHostView* parent_host_view,
364 const gfx::Rect& bounds_in_screen,
365 const gfx::Rect& anchor_rect) {
366 DCHECK_EQ(widget_type_, WidgetType::kPopup);
367 DCHECK(!static_cast<RenderWidgetHostViewBase*>(parent_host_view)
368 ->IsRenderWidgetHostViewChildFrame());
370 popup_parent_host_view_ =
371 static_cast<RenderWidgetHostViewAura*>(parent_host_view);
373 // TransientWindowClient may be NULL during tests.
374 aura::client::TransientWindowClient* transient_window_client =
375 aura::client::GetTransientWindowClient();
376 RenderWidgetHostViewAura* old_child =
377 popup_parent_host_view_->popup_child_host_view_;
379 // TODO(jhorwich): Allow multiple popup_child_host_view_ per view, or
380 // similar mechanism to ensure a second popup doesn't cause the first one
381 // to never get a chance to filter events. See crbug.com/160589.
382 DCHECK(old_child->popup_parent_host_view_ == popup_parent_host_view_);
383 if (transient_window_client) {
384 transient_window_client->RemoveTransientChild(
385 popup_parent_host_view_->window_, old_child->window_);
387 old_child->popup_parent_host_view_ = nullptr;
389 popup_parent_host_view_->SetPopupChild(this);
390 CreateAuraWindow(aura::client::WINDOW_TYPE_MENU);
391 // Use transparent background color for the popup in order to avoid flashing
392 // the white background on popup open when dark color-scheme is used.
393 SetContentBackgroundColor(SK_ColorTRANSPARENT);
395 // Setting the transient child allows for the popup to get mouse events when
396 // in a system modal dialog. Do this before calling ParentWindowWithContext
397 // below so that the transient parent is visible to WindowTreeClient.
398 // This fixes crbug.com/328593.
399 if (transient_window_client) {
400 transient_window_client->AddTransientChild(
401 popup_parent_host_view_->window_, window_);
404 ui::OwnedWindowAnchor owned_window_anchor = {
405 anchor_rect, ui::OwnedWindowAnchorPosition::kBottomLeft,
406 ui::OwnedWindowAnchorGravity::kBottomRight,
407 ui::OwnedWindowConstraintAdjustment::kAdjustmentFlipY};
408 window_->SetProperty(aura::client::kOwnedWindowAnchor, owned_window_anchor);
410 aura::Window* root = popup_parent_host_view_->window_->GetRootWindow();
411 aura::client::ParentWindowWithContext(window_, root, bounds_in_screen,
412 display::kInvalidDisplayId);
414 SetBounds(bounds_in_screen);
416 if (NeedsMouseCapture())
417 window_->SetCapture();
419 event_observer_for_popup_exit_ =
420 std::make_unique<EventObserverForPopupExit>(this);
422 device_scale_factor_ = GetDeviceScaleFactor();
424 // If HiDPI capture mode is active for the parent, propagate the scale
425 // override to the popup window also. Its content was created assuming
426 // that the new window will share the parent window's scale. See
427 // https://crbug.com/1354703 .
428 SetScaleOverrideForCapture(
429 popup_parent_host_view_->GetScaleOverrideForCapture());
431 auto* cursor_client = aura::client::GetCursorClient(root);
433 UpdateSystemCursorSize(cursor_client->GetSystemCursorSize());
435 #if BUILDFLAG(IS_WIN)
436 // This will fetch and set the display features.
437 EnsureDevicePostureServiceConnection();
441 #if BUILDFLAG(IS_TIZEN_TV)
442 void RenderWidgetHostViewAura::VideoPlayingStatusReceived(bool is_playing,
444 if (aura_efl_helper())
445 aura_efl_helper()->VideoPlayingStatusReceived(is_playing, callback_id);
447 LOG(ERROR) << "aura_efl_helper() is false";
451 void RenderWidgetHostViewAura::Hide() {
453 visibility_ = Visibility::HIDDEN;
457 #if BUILDFLAG(IS_TIZEN)
458 void RenderWidgetHostViewAura::UpdateRotationDegrees(int rotation_degrees) {
459 rotation_ = rotation_degrees;
460 LOG(INFO) << "Rotation_degrees " << rotation_degrees;
461 TRACE_EVENT1("viz", "RenderWidgetHostViewAura::UpdateRotationDegrees",
462 "rotation_", rotation_);
463 if (aura_efl_helper())
464 aura_efl_helper()->SetOrientation(rotation_);
465 if (IsMultiviewMode())
469 bool RenderWidgetHostViewAura::IsMultiviewMode() {
470 const char vconf_multiview_info[] = "memory/multiscreen/info";
472 char* multiview_info = vconf_get_str(vconf_multiview_info);
473 if (multiview_info) {
474 auto multiview_info_value = base::JSONReader::Read(multiview_info);
475 free(multiview_info);
476 if (!multiview_info_value || !multiview_info_value->is_dict()) {
480 const std::string* mode_value =
481 multiview_info_value->GetDict().FindString("mode");
482 if (mode_value && *mode_value == "on") {
483 LOG(INFO) << "It is in multiview mode.";
491 void RenderWidgetHostViewAura::DidMoveWebView() {
492 #if defined(TIZEN_VIDEO_HOLE)
493 if (!on_webview_moved_callback_.is_null())
494 on_webview_moved_callback_.Run();
499 void RenderWidgetHostViewAura::SetSize(const gfx::Size& size) {
500 // For a SetSize operation, we don't care what coordinate system the origin
501 // of the window is in, it's only important to make sure that the origin
502 // remains constant after the operation.
503 InternalSetBounds(gfx::Rect(window_->bounds().origin(), size));
506 void RenderWidgetHostViewAura::SetBounds(const gfx::Rect& rect) {
507 gfx::Point relative_origin(rect.origin());
508 LOG(INFO) << "rect " << rect.ToString();
509 // RenderWidgetHostViewAura::SetBounds() takes screen coordinates, but
510 // Window::SetBounds() takes parent coordinates, so do the conversion here.
511 aura::Window* root = window_->GetRootWindow();
513 aura::client::ScreenPositionClient* screen_position_client =
514 aura::client::GetScreenPositionClient(root);
515 if (screen_position_client) {
516 screen_position_client->ConvertPointFromScreen(window_->parent(),
521 InternalSetBounds(gfx::Rect(relative_origin, rect.size()));
524 gfx::NativeView RenderWidgetHostViewAura::GetNativeView() {
528 #if BUILDFLAG(IS_WIN)
529 HWND RenderWidgetHostViewAura::GetHostWindowHWND() const {
530 aura::WindowTreeHost* host = window_->GetHost();
531 return host ? host->GetAcceleratedWidget() : nullptr;
535 gfx::NativeViewAccessible RenderWidgetHostViewAura::GetNativeViewAccessible() {
536 #if BUILDFLAG(IS_WIN)
537 aura::WindowTreeHost* window_host = window_->GetHost();
539 return static_cast<gfx::NativeViewAccessible>(NULL);
541 BrowserAccessibilityManager* manager =
542 host()->GetOrCreateRootBrowserAccessibilityManager();
544 return ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot())
547 #elif BUILDFLAG(IS_LINUX)
548 BrowserAccessibilityManager* manager =
549 host()->GetOrCreateRootBrowserAccessibilityManager();
550 if (manager && manager->GetBrowserAccessibilityRoot())
551 return manager->GetBrowserAccessibilityRoot()->GetNativeViewAccessible();
554 NOTIMPLEMENTED_LOG_ONCE();
555 return static_cast<gfx::NativeViewAccessible>(nullptr);
558 ui::TextInputClient* RenderWidgetHostViewAura::GetTextInputClient() {
562 RenderFrameHostImpl* RenderWidgetHostViewAura::GetFocusedFrame() const {
563 FrameTreeNode* focused_frame = host()->frame_tree()->GetFocusedFrame();
566 return focused_frame->current_frame_host();
569 void RenderWidgetHostViewAura::HandleBoundsInRootChanged() {
570 #if BUILDFLAG(IS_WIN)
571 if (legacy_render_widget_host_HWND_) {
572 legacy_render_widget_host_HWND_->SetBounds(
573 window_->GetBoundsInRootWindow());
577 // Send screen rects through the delegate if there is one. Not every
578 // RenderWidgetHost has a delegate (for example, drop-down widgets).
579 if (host_->delegate())
580 host_->delegate()->SendScreenRects();
582 host_->SendScreenRects();
585 UpdateInsetsWithVirtualKeyboardEnabled();
588 void RenderWidgetHostViewAura::ParentHierarchyChanged() {
589 if (window_->parent()) {
590 // Track changes of the window relative to the root. This is done to snap
591 // `window_` to a pixel boundary, which could change when the bounds
592 // relative to the root changes. An example where this happens:
593 // The fast resize code path for bookmarks where in the parent of RWHVA
594 // which is WCV has its bounds changed before the bookmark is hidden. This
595 // results in the traditional bounds change notification for the WCV
596 // reporting the old bounds as the bookmark is still around. Observing all
597 // the ancestors of the RWHVA window enables us to know when the bounds of
598 // the window relative to root changes and allows us to snap accordingly.
599 position_in_root_observer_ =
600 std::make_unique<aura_extra::WindowPositionInRootMonitor>(
603 &RenderWidgetHostViewAura::HandleBoundsInRootChanged,
604 base::Unretained(this)));
606 position_in_root_observer_.reset();
608 // Snap when we receive a hierarchy changed. http://crbug.com/388908.
609 HandleBoundsInRootChanged();
612 void RenderWidgetHostViewAura::Focus() {
613 // Make sure we have a FocusClient before attempting to Focus(). In some
614 // situations we may not yet be in a valid Window hierarchy (such as reloading
615 // after out of memory discarded the tab).
616 aura::client::FocusClient* client = aura::client::GetFocusClient(window_);
620 #if BUILDFLAG(IS_EFL)
621 if (!efl_helper_->HasFocus())
622 efl_helper_->Focus(true);
626 bool RenderWidgetHostViewAura::HasFocus() {
627 return window_->HasFocus();
630 bool RenderWidgetHostViewAura::IsSurfaceAvailableForCopy() {
631 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
632 return delegated_frame_host_->CanCopyFromCompositingSurface();
635 #if BUILDFLAG(IS_EFL)
636 void RenderWidgetHostViewAura::BackgroundColorReceived(int callback_id,
638 efl_helper_->BackgroundColorReceived(callback_id, bg_color);
641 void RenderWidgetHostViewAura::DidGetContentSnapshot(const SkBitmap& bitmap,
643 efl_helper_->DidGetContentSnapshot(bitmap, request_id);
646 void RenderWidgetHostViewAura::DidHandleKeyEvent(
647 blink::WebInputEvent::Type input_event_type,
649 efl_helper_->DidHandleKeyEvent(input_event_type, processed);
652 void RenderWidgetHostViewAura::SelectionChanged(const std::u16string& text,
654 const gfx::Range& range) {
655 RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
656 efl_helper_->SelectionChanged(text, offset, range);
659 void RenderWidgetHostViewAura::TextInputStateChanged(
660 const ui::mojom::TextInputState& params) {
661 RenderWidgetHostViewBase::TextInputStateChanged(params);
662 efl_helper_->TextInputStateChanged(params);
666 void RenderWidgetHostViewAura::EnsureSurfaceSynchronizedForWebTest() {
667 ++latest_capture_sequence_number_;
668 SynchronizeVisualProperties(cc::DeadlinePolicy::UseInfiniteDeadline(),
672 bool RenderWidgetHostViewAura::IsShowing() {
673 return window_->IsVisible();
676 void RenderWidgetHostViewAura::WasUnOccluded() {
677 ShowImpl(PageVisibilityState::kVisible);
680 void RenderWidgetHostViewAura::ShowImpl(PageVisibilityState page_visibility) {
681 // OnShowWithPageVisibility will not call NotifyHostAndDelegateOnWasShown,
682 // which updates `visibility_`, unless the host is hidden. Make sure no update
684 DCHECK(host_->is_hidden() || visibility_ == Visibility::VISIBLE);
685 OnShowWithPageVisibility(page_visibility);
688 void RenderWidgetHostViewAura::NotifyHostAndDelegateOnWasShown(
689 blink::mojom::RecordContentToVisibleTimeRequestPtr tab_switch_start_state) {
690 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
691 DCHECK(host_->is_hidden());
692 DCHECK_NE(visibility_, Visibility::VISIBLE);
694 auto* wth = window()->GetHost();
695 if (wth && allocate_local_surface_id_on_next_show_) {
696 wth->window()->AllocateLocalSurfaceId();
697 wth->compositor()->SetLocalSurfaceIdFromParent(
698 wth->window()->GetLocalSurfaceId());
700 allocate_local_surface_id_on_next_show_ = false;
702 visibility_ = Visibility::VISIBLE;
704 bool has_saved_frame = delegated_frame_host_->HasSavedFrame();
706 bool show_reason_bfcache_restore =
707 tab_switch_start_state
708 ? tab_switch_start_state->show_reason_bfcache_restore
711 // No need to check for saved frames for the case of bfcache restore.
712 if (show_reason_bfcache_restore) {
713 host()->WasShown(tab_switch_start_state.Clone());
715 host()->WasShown(has_saved_frame
716 ? blink::mojom::RecordContentToVisibleTimeRequestPtr()
717 : tab_switch_start_state.Clone());
719 aura::Window* root = window_->GetRootWindow();
721 aura::client::CursorClient* cursor_client =
722 aura::client::GetCursorClient(root);
724 NotifyRendererOfCursorVisibilityState(cursor_client->IsCursorVisible());
728 // If the frame for the renderer is already available, then the
729 // tab-switching time is the presentation time for the browser-compositor.
730 delegated_frame_host_->WasShown(
731 GetLocalSurfaceId(), window_->bounds().size(),
732 has_saved_frame ? std::move(tab_switch_start_state)
733 : blink::mojom::RecordContentToVisibleTimeRequestPtr());
735 #if BUILDFLAG(IS_WIN)
740 void RenderWidgetHostViewAura::HideImpl() {
741 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
742 DCHECK(visibility_ == Visibility::HIDDEN ||
743 visibility_ == Visibility::OCCLUDED);
745 #if BUILDFLAG(IS_EFL)
749 if (!host()->is_hidden()) {
751 aura::WindowTreeHost* host = window_->GetHost();
752 aura::Window* parent = window_->parent();
753 aura::Window::OcclusionState parent_occl_state =
754 parent ? parent->GetOcclusionState()
755 : aura::Window::OcclusionState::UNKNOWN;
756 aura::Window::OcclusionState native_win_occlusion_state =
757 host ? host->GetNativeWindowOcclusionState()
758 : aura::Window::OcclusionState::UNKNOWN;
759 DelegatedFrameHost::HiddenCause cause;
760 if (parent_occl_state == aura::Window::OcclusionState::OCCLUDED &&
761 native_win_occlusion_state ==
762 aura::Window::OcclusionState::OCCLUDED) {
763 cause = DelegatedFrameHost::HiddenCause::kOccluded;
765 cause = DelegatedFrameHost::HiddenCause::kOther;
767 delegated_frame_host_->WasHidden(cause);
768 #if BUILDFLAG(IS_WIN)
770 // We reparent the legacy Chrome_RenderWidgetHostHWND window to the
771 // global hidden window on the same lines as Windowed plugin windows.
772 if (legacy_render_widget_host_HWND_)
773 legacy_render_widget_host_HWND_->UpdateParent(ui::GetHiddenWindow());
778 #if BUILDFLAG(IS_WIN)
779 if (legacy_render_widget_host_HWND_)
780 legacy_render_widget_host_HWND_->Hide();
784 void RenderWidgetHostViewAura::WasOccluded() {
785 visibility_ = Visibility::OCCLUDED;
789 void RenderWidgetHostViewAura::
790 RequestSuccessfulPresentationTimeFromHostOrDelegate(
791 blink::mojom::RecordContentToVisibleTimeRequestPtr
792 visible_time_request) {
793 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
794 DCHECK(!host_->is_hidden());
795 DCHECK_EQ(visibility_, Visibility::VISIBLE);
796 DCHECK(visible_time_request);
798 bool has_saved_frame = delegated_frame_host_->HasSavedFrame();
800 // No need to check for saved frames for the case of bfcache restore.
801 if (visible_time_request->show_reason_bfcache_restore || !has_saved_frame) {
802 host()->RequestSuccessfulPresentationTimeForNextFrame(
803 visible_time_request.Clone());
806 // If the frame for the renderer is already available, then the
807 // tab-switching time is the presentation time for the browser-compositor.
808 if (has_saved_frame) {
809 delegated_frame_host_->RequestSuccessfulPresentationTimeForNextFrame(
810 std::move(visible_time_request));
814 void RenderWidgetHostViewAura::
815 CancelSuccessfulPresentationTimeRequestForHostAndDelegate() {
816 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
817 DCHECK(!host_->is_hidden());
818 DCHECK_EQ(visibility_, Visibility::VISIBLE);
820 host()->CancelSuccessfulPresentationTimeRequest();
821 delegated_frame_host_->CancelSuccessfulPresentationTimeRequest();
824 bool RenderWidgetHostViewAura::ShouldSkipCursorUpdate() const {
825 aura::Window* root_window = window_->GetRootWindow();
827 display::Screen* screen = display::Screen::GetScreen();
830 // Ignore cursor update messages if the window under the cursor is not us.
831 #if BUILDFLAG(IS_WIN)
832 gfx::Point cursor_screen_point = screen->GetCursorScreenPoint();
833 aura::Window* window_at_screen_point =
834 screen->GetWindowAtScreenPoint(cursor_screen_point);
835 // On Windows we may fail to retrieve the aura Window at the current cursor
836 // position. This is because the WindowFromPoint API may return the legacy
837 // window which is not associated with an aura Window. In this case we need
838 // to get the aura window for the parent of the legacy window.
839 if (!window_at_screen_point && legacy_render_widget_host_HWND_) {
840 HWND hwnd_at_point = ::WindowFromPoint(cursor_screen_point.ToPOINT());
842 if (hwnd_at_point == legacy_render_widget_host_HWND_->hwnd())
843 hwnd_at_point = legacy_render_widget_host_HWND_->GetParent();
845 display::win::ScreenWin* screen_win =
846 static_cast<display::win::ScreenWin*>(screen);
847 window_at_screen_point = screen_win->GetNativeWindowFromHWND(hwnd_at_point);
849 if (!window_at_screen_point ||
850 (window_at_screen_point->GetRootWindow() != root_window)) {
853 #elif !BUILDFLAG(IS_CHROMEOS_ASH)
854 if (!screen->IsWindowUnderCursor(root_window))
856 #endif // !BUILDFLAG(IS_CHROMEOS_ASH)
860 bool RenderWidgetHostViewAura::ShouldShowStaleContentOnEviction() {
861 return host() && host()->ShouldShowStaleContentOnEviction();
864 gfx::Rect RenderWidgetHostViewAura::GetViewBounds() {
865 #if BUILDFLAG(IS_EFL)
866 if (offscreen_helper())
867 return offscreen_helper()->GetViewBounds();
869 return window_->GetBoundsInScreen();
872 void RenderWidgetHostViewAura::UpdateBackgroundColor() {
873 DCHECK(GetBackgroundColor());
875 SkColor color = *GetBackgroundColor();
876 // Set transparent bg for Browser process
877 if (color == SK_ColorTRANSPARENT && GetCompositor()) {
878 GetCompositor()->SetBackgroundColor(SK_ColorTRANSPARENT);
881 bool opaque = SkColorGetA(color) == SK_AlphaOPAQUE;
882 window_->layer()->SetFillsBoundsOpaquely(opaque);
883 window_->layer()->SetColor(color);
886 #if BUILDFLAG(IS_WIN)
887 void RenderWidgetHostViewAura::EnsureDevicePostureServiceConnection() {
888 if (device_posture_provider_.is_bound() &&
889 device_posture_provider_.is_connected()) {
892 GetDeviceService().BindDevicePostureProvider(
893 device_posture_provider_.BindNewPipeAndPassReceiver());
894 device_posture_provider_->AddListenerAndGetCurrentViewportSegments(
895 device_posture_receiver_.BindNewPipeAndPassRemote(),
896 base::BindOnce(&RenderWidgetHostViewAura::OnViewportSegmentsChanged,
897 base::Unretained(this)));
901 void RenderWidgetHostViewAura::OnViewportSegmentsChanged(
902 const std::vector<gfx::Rect>& segments) {
903 display_feature_ = absl::nullopt;
904 viewport_segments_.clear();
905 if (segments.empty()) {
906 SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
907 window_->GetLocalSurfaceId());
911 if (segments.size() >= 2) {
912 viewport_segments_ = std::move(segments);
913 ComputeDisplayFeature();
915 SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
916 window_->GetLocalSurfaceId());
919 void RenderWidgetHostViewAura::ComputeDisplayFeature() {
920 if (viewport_segments_.size() < 2) {
924 display_feature_ = absl::nullopt;
925 if (!window_->GetRootWindow()) {
929 const display::Display display =
930 display::Screen::GetScreen()->GetDisplayNearestWindow(window_);
931 // Set the display feature only if the browser window is maximized or
933 if (window_->GetRootWindow()->GetBoundsInScreen() != display.work_area() &&
934 window_->GetRootWindow()->GetBoundsInScreen() != display.bounds()) {
938 float dip_scale = 1 / device_scale_factor_;
939 // Segments coming from the platform are in native resolution.
940 gfx::Rect transformed_display_feature =
941 gfx::ScaleToRoundedRect(viewport_segments_[1], dip_scale);
942 transformed_display_feature.Offset(-GetViewBounds().x(),
943 -GetViewBounds().y());
944 transformed_display_feature.Intersect(gfx::Rect(GetVisibleViewportSize()));
945 if (transformed_display_feature.x() == 0) {
946 display_feature_ = {DisplayFeature::Orientation::kHorizontal,
947 transformed_display_feature.y(),
948 transformed_display_feature.height()};
949 } else if (transformed_display_feature.y() == 0) {
950 display_feature_ = {DisplayFeature::Orientation::kVertical,
951 transformed_display_feature.x(),
952 transformed_display_feature.width()};
956 absl::optional<DisplayFeature> RenderWidgetHostViewAura::GetDisplayFeature() {
957 return display_feature_;
960 void RenderWidgetHostViewAura::SetDisplayFeatureForTesting(
961 const DisplayFeature* display_feature) {
963 display_feature_ = *display_feature;
965 display_feature_ = absl::nullopt;
968 void RenderWidgetHostViewAura::WindowTitleChanged() {
969 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
970 delegated_frame_host_->WindowTitleChanged(
971 base::UTF16ToUTF8(window_->GetTitle()));
974 bool RenderWidgetHostViewAura::IsMouseLocked() {
975 return event_handler_->mouse_locked();
978 gfx::Size RenderWidgetHostViewAura::GetVisibleViewportSize() {
979 #if BUILDFLAG(IS_EFL)
980 if (efl_helper_->IsOffscreenMode())
981 return efl_helper_->GetVisibleViewportSize();
983 gfx::Rect requested_rect(GetRequestedRendererSize());
984 requested_rect.Inset(insets_);
985 return requested_rect.size();
988 void RenderWidgetHostViewAura::SetInsets(const gfx::Insets& insets) {
989 TRACE_EVENT0("vk", "RenderWidgetHostViewAura::SetInsets");
990 if (insets != insets_) {
992 window_->AllocateLocalSurfaceId();
993 if (!insets.IsEmpty()) {
994 inset_surface_id_ = window_->GetLocalSurfaceId();
996 inset_surface_id_ = viz::LocalSurfaceId();
998 SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
999 window_->GetLocalSurfaceId());
1003 void RenderWidgetHostViewAura::UpdateCursor(const ui::Cursor& cursor) {
1004 GetCursorManager()->UpdateCursor(this, cursor);
1007 void RenderWidgetHostViewAura::DisplayCursor(const ui::Cursor& cursor) {
1008 current_cursor_ = WebCursor(cursor);
1009 const display::Display display =
1010 display::Screen::GetScreen()->GetDisplayNearestWindow(window_);
1011 current_cursor_.SetDisplayInfo(display);
1012 UpdateCursorIfOverSelf();
1015 CursorManager* RenderWidgetHostViewAura::GetCursorManager() {
1016 return cursor_manager_.get();
1019 void RenderWidgetHostViewAura::SetIsLoading(bool is_loading) {
1020 is_loading_ = is_loading;
1021 UpdateCursorIfOverSelf();
1024 void RenderWidgetHostViewAura::RenderProcessGone() {
1025 UpdateCursorIfOverSelf();
1029 void RenderWidgetHostViewAura::ShowWithVisibility(
1030 PageVisibilityState page_visibility) {
1031 // Make sure we grab updated ScreenInfos before synchronizing visual
1032 // properties, in case they have changed or this is the initial show.
1035 #if BUILDFLAG(IS_EFL)
1036 efl_helper_->Show();
1039 // If the viz::LocalSurfaceId is invalid, we may have been evicted,
1040 // and no other visual properties have since been changed. Allocate a new id
1041 // and start synchronizing.
1042 if (!window_->GetLocalSurfaceId().is_valid()) {
1043 window_->AllocateLocalSurfaceId();
1044 SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
1045 window_->GetLocalSurfaceId());
1049 ShowImpl(page_visibility);
1050 #if BUILDFLAG(IS_WIN)
1051 if (page_visibility != PageVisibilityState::kVisible &&
1052 legacy_render_widget_host_HWND_) {
1053 legacy_render_widget_host_HWND_->Hide();
1055 #endif // BUILDFLAG(IS_WIN)
1058 void RenderWidgetHostViewAura::Destroy() {
1059 // Beware, this function is not called on all destruction paths. If |window_|
1060 // has been created, then it will implicitly end up calling
1061 // ~RenderWidgetHostViewAura when |window_| is destroyed. Otherwise, The
1062 // destructor is invoked directly from here. So all destruction/cleanup code
1063 // should happen there, not here.
1064 in_shutdown_ = true;
1065 // Call this here in case any observers need access to `this` before we
1066 // destruct the derived class.
1067 NotifyObserversAboutShutdown();
1075 void RenderWidgetHostViewAura::UpdateTooltipUnderCursor(
1076 const std::u16string& tooltip_text) {
1077 if (GetCursorManager()->IsViewUnderCursor(this))
1078 UpdateTooltip(tooltip_text);
1081 void RenderWidgetHostViewAura::UpdateTooltip(
1082 const std::u16string& tooltip_text) {
1083 SetTooltipText(tooltip_text);
1085 wm::TooltipClient* tooltip_client =
1086 wm::GetTooltipClient(window_->GetRootWindow());
1087 if (tooltip_client) {
1088 // Content tooltips should be visible indefinitely.
1089 tooltip_client->SetHideTooltipTimeout(window_, {});
1090 tooltip_client->UpdateTooltip(window_);
1094 void RenderWidgetHostViewAura::UpdateTooltipFromKeyboard(
1095 const std::u16string& tooltip_text,
1096 const gfx::Rect& bounds) {
1097 SetTooltipText(tooltip_text);
1099 wm::TooltipClient* tooltip_client =
1100 wm::GetTooltipClient(window_->GetRootWindow());
1101 if (tooltip_client) {
1102 // Content tooltips should be visible indefinitely.
1103 tooltip_client->SetHideTooltipTimeout(window_, {});
1104 tooltip_client->UpdateTooltipFromKeyboard(bounds, window_);
1108 void RenderWidgetHostViewAura::ClearKeyboardTriggeredTooltip() {
1109 if (!window_ || !window_->GetHost())
1112 wm::TooltipClient* tooltip_client =
1113 wm::GetTooltipClient(window_->GetRootWindow());
1114 if (!tooltip_client || !tooltip_client->IsTooltipSetFromKeyboard(window_))
1117 SetTooltipText(std::u16string());
1118 tooltip_client->UpdateTooltipFromKeyboard(gfx::Rect(), window_);
1121 uint32_t RenderWidgetHostViewAura::GetCaptureSequenceNumber() const {
1122 return latest_capture_sequence_number_;
1125 void RenderWidgetHostViewAura::CopyFromSurface(
1126 const gfx::Rect& src_subrect,
1127 const gfx::Size& dst_size,
1128 base::OnceCallback<void(const SkBitmap&)> callback) {
1129 base::WeakPtr<RenderWidgetHostImpl> popup_host;
1130 base::WeakPtr<DelegatedFrameHost> popup_frame_host;
1131 if (popup_child_host_view_) {
1132 popup_host = popup_child_host_view_->host()->GetWeakPtr();
1134 popup_child_host_view_->GetDelegatedFrameHost()->GetWeakPtr();
1136 RenderWidgetHostViewBase::CopyMainAndPopupFromSurface(
1137 host()->GetWeakPtr(), delegated_frame_host_->GetWeakPtr(), popup_host,
1138 popup_frame_host, src_subrect, dst_size, device_scale_factor_,
1139 std::move(callback));
1142 #if BUILDFLAG(IS_WIN)
1143 bool RenderWidgetHostViewAura::UsesNativeWindowFrame() const {
1144 return (legacy_render_widget_host_HWND_ != nullptr);
1147 void RenderWidgetHostViewAura::UpdateMouseLockRegion() {
1149 display::Screen::GetScreen()
1150 ->DIPToScreenRectInWindow(window_, window_->GetBoundsInScreen())
1152 ::ClipCursor(&window_rect);
1155 void RenderWidgetHostViewAura::OnLegacyWindowDestroyed() {
1156 legacy_render_widget_host_HWND_ = nullptr;
1157 legacy_window_destroyed_ = true;
1161 gfx::NativeViewAccessible
1162 RenderWidgetHostViewAura::GetParentNativeViewAccessible() {
1163 // If a popup_parent_host_view_ exists, that means we are in a popup (such as
1164 // datetime) and our accessible parent window is popup_parent_host_view_
1165 if (popup_parent_host_view_) {
1166 DCHECK_EQ(widget_type_, WidgetType::kPopup);
1167 return popup_parent_host_view_->GetParentNativeViewAccessible();
1170 if (window_->parent()) {
1171 return window_->parent()->GetProperty(
1172 aura::client::kParentNativeViewAccessibleKey);
1178 void RenderWidgetHostViewAura::ClearFallbackSurfaceForCommitPending() {
1179 delegated_frame_host_->ClearFallbackSurfaceForCommitPending();
1180 window_->InvalidateLocalSurfaceId();
1183 void RenderWidgetHostViewAura::ResetFallbackToFirstNavigationSurface() {
1184 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
1185 delegated_frame_host_->ResetFallbackToFirstNavigationSurface();
1188 bool RenderWidgetHostViewAura::RequestRepaintForTesting() {
1189 return SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
1193 void RenderWidgetHostViewAura::DidStopFlinging() {
1194 selection_controller_client_->OnScrollCompleted();
1197 void RenderWidgetHostViewAura::TransformPointToRootSurface(gfx::PointF* point) {
1198 aura::Window* root = window_->GetRootWindow();
1199 aura::Window::ConvertPointToTarget(window_, root, point);
1200 *point = root->GetRootWindow()->transform().MapPoint(*point);
1203 gfx::Rect RenderWidgetHostViewAura::GetBoundsInRootWindow() {
1204 aura::Window* top_level = window_->GetToplevelWindow();
1205 gfx::Rect bounds(top_level->GetBoundsInScreen());
1207 #if BUILDFLAG(IS_WIN)
1208 // TODO(zturner,iyengar): This will break when we remove support for NPAPI and
1209 // remove the legacy hwnd, so a better fix will need to be decided when that
1211 if (UsesNativeWindowFrame()) {
1212 // aura::Window doesn't take into account non-client area of native windows
1213 // (e.g. HWNDs), so for that case ask Windows directly what the bounds are.
1214 aura::WindowTreeHost* host = top_level->GetHost();
1216 return top_level->GetBoundsInScreen();
1218 // If this is a headless window return the headless window bounds stored in
1219 // Aura window properties instead of the actual platform window bounds which
1220 // may be different.
1221 if (gfx::Rect* headless_bounds =
1222 host->window()->GetProperty(aura::client::kHeadlessBoundsKey)) {
1223 return *headless_bounds;
1226 RECT window_rect = {0};
1227 HWND hwnd = host->GetAcceleratedWidget();
1228 ::GetWindowRect(hwnd, &window_rect);
1229 bounds = gfx::Rect(window_rect);
1231 // Maximized windows are outdented from the work area by the frame thickness
1232 // even though this "frame" is not painted. This confuses code (and people)
1233 // that think of a maximized window as corresponding exactly to the work
1234 // area. Correct for this by subtracting the frame thickness back off.
1235 if (::IsZoomed(hwnd)) {
1236 bounds.Inset(gfx::Insets::VH(GetSystemMetrics(SM_CYSIZEFRAME),
1237 GetSystemMetrics(SM_CXSIZEFRAME)));
1238 bounds.Inset(GetSystemMetrics(SM_CXPADDEDBORDER));
1241 // Pixels come back from GetWindowHost, so we need to convert those back to
1243 bounds = display::Screen::GetScreen()->ScreenToDIPRectInWindow(top_level,
1252 void RenderWidgetHostViewAura::WheelEventAck(
1253 const blink::WebMouseWheelEvent& event,
1254 blink::mojom::InputEventResultState ack_result) {
1255 if (overscroll_controller_) {
1256 overscroll_controller_->ReceivedEventACK(
1257 event, (blink::mojom::InputEventResultState::kConsumed == ack_result));
1261 void RenderWidgetHostViewAura::DidOverscroll(
1262 const ui::DidOverscrollParams& params) {
1263 if (overscroll_controller_)
1264 overscroll_controller_->OnDidOverscroll(params);
1265 #if BUILDFLAG(IS_EFL)
1266 efl_helper_->DidOverscroll(params);
1270 void RenderWidgetHostViewAura::GestureEventAck(
1271 const blink::WebGestureEvent& event,
1272 blink::mojom::InputEventResultState ack_result,
1273 blink::mojom::ScrollResultDataPtr scroll_result_data) {
1274 const blink::WebInputEvent::Type event_type = event.GetType();
1275 if (event_type == blink::WebGestureEvent::Type::kGestureScrollBegin ||
1276 event_type == blink::WebGestureEvent::Type::kGestureScrollEnd) {
1277 if (host()->delegate()) {
1278 host()->delegate()->SetTopControlsGestureScrollInProgress(
1279 event_type == blink::WebGestureEvent::Type::kGestureScrollBegin);
1283 if (overscroll_controller_) {
1284 overscroll_controller_->ReceivedEventACK(
1285 event, (blink::mojom::InputEventResultState::kConsumed == ack_result));
1286 // Terminate an active fling when the ACK for a GSU generated from the fling
1287 // progress (GSU with inertial state) is consumed and the overscrolling mode
1288 // is not |OVERSCROLL_NONE|. The early fling termination generates a GSE
1289 // which completes the overscroll action. Without this change the overscroll
1290 // action would complete at the end of the active fling progress which
1291 // causes noticeable delay in cases that the fling velocity is large.
1292 // https://crbug.com/797855
1293 if (event_type == blink::WebInputEvent::Type::kGestureScrollUpdate &&
1294 event.data.scroll_update.inertial_phase ==
1295 blink::WebGestureEvent::InertialPhaseState::kMomentum &&
1296 overscroll_controller_->overscroll_mode() != OVERSCROLL_NONE) {
1301 // Stop flinging if a GSU event with momentum phase is sent to the renderer
1302 // but not consumed.
1303 StopFlingingIfNecessary(event, ack_result);
1305 event_handler_->GestureEventAck(event, ack_result);
1307 ForwardTouchpadZoomEventIfNecessary(event, ack_result);
1310 void RenderWidgetHostViewAura::ProcessAckedTouchEvent(
1311 const TouchEventWithLatencyInfo& touch,
1312 blink::mojom::InputEventResultState ack_result) {
1313 aura::WindowTreeHost* window_host = window_->GetHost();
1314 // |host| is NULL during tests.
1318 // The TouchScrollStarted event is generated & consumed downstream from the
1319 // TouchEventQueue. So we don't expect an ACK up here.
1320 DCHECK(touch.event.GetType() !=
1321 blink::WebInputEvent::Type::kTouchScrollStarted);
1323 ui::EventResult result =
1324 (ack_result == blink::mojom::InputEventResultState::kConsumed)
1328 blink::WebTouchPoint::State required_state;
1329 switch (touch.event.GetType()) {
1330 case blink::WebInputEvent::Type::kTouchStart:
1331 required_state = blink::WebTouchPoint::State::kStatePressed;
1333 case blink::WebInputEvent::Type::kTouchEnd:
1334 required_state = blink::WebTouchPoint::State::kStateReleased;
1336 case blink::WebInputEvent::Type::kTouchMove:
1337 required_state = blink::WebTouchPoint::State::kStateMoved;
1339 case blink::WebInputEvent::Type::kTouchCancel:
1340 required_state = blink::WebTouchPoint::State::kStateCancelled;
1343 required_state = blink::WebTouchPoint::State::kStateUndefined;
1348 #if BUILDFLAG(IS_EFL)
1349 if (touch.event.GetType() == blink::WebInputEvent::Type::kTouchStart)
1350 efl_helper_->SetTouchStartConsumed(result == ui::ER_HANDLED);
1352 if (touch.event.GetType() == blink::WebInputEvent::Type::kTouchEnd)
1353 efl_helper_->SetTouchEndConsumed(result == ui::ER_HANDLED);
1356 // Only send acks for one changed touch point.
1357 bool sent_ack = false;
1358 for (size_t i = 0; i < touch.event.touches_length; ++i) {
1359 if (touch.event.touches[i].state == required_state) {
1361 window_host->dispatcher()->ProcessedTouchEvent(
1362 touch.event.unique_touch_event_id, window_, result,
1363 InputEventResultStateIsSetBlocking(ack_result));
1364 if (touch.event.touch_start_or_first_touch_move &&
1365 result == ui::ER_HANDLED && host()->delegate() &&
1366 host()->delegate()->GetInputEventRouter()) {
1369 ->GetInputEventRouter()
1370 ->OnHandledTouchStartOrFirstTouchMove(
1371 touch.event.unique_touch_event_id);
1378 std::unique_ptr<SyntheticGestureTarget>
1379 RenderWidgetHostViewAura::CreateSyntheticGestureTarget() {
1380 return std::unique_ptr<SyntheticGestureTarget>(
1381 new SyntheticGestureTargetAura(host()));
1384 blink::mojom::InputEventResultState RenderWidgetHostViewAura::FilterInputEvent(
1385 const blink::WebInputEvent& input_event) {
1386 bool consumed = false;
1387 if (input_event.GetType() == WebInputEvent::Type::kGestureFlingStart) {
1388 const WebGestureEvent& gesture_event =
1389 static_cast<const WebGestureEvent&>(input_event);
1390 // Zero-velocity touchpad flings are an Aura-specific signal that the
1391 // touchpad scroll has ended, and should not be forwarded to the renderer.
1392 if (gesture_event.SourceDevice() == blink::WebGestureDevice::kTouchpad &&
1393 !gesture_event.data.fling_start.velocity_x &&
1394 !gesture_event.data.fling_start.velocity_y) {
1399 if (overscroll_controller_)
1400 consumed |= overscroll_controller_->WillHandleEvent(input_event);
1402 // Touch events should always propagate to the renderer.
1403 if (WebTouchEvent::IsTouchEventType(input_event.GetType()))
1404 return blink::mojom::InputEventResultState::kNotConsumed;
1407 input_event.GetType() == blink::WebInputEvent::Type::kGestureFlingStart) {
1408 // Here we indicate that there was no consumer for this event, as
1409 // otherwise the fling animation system will try to run an animation
1410 // and will also expect a notification when the fling ends. Since
1411 // CrOS just uses the GestureFlingStart with zero-velocity as a means
1412 // of indicating that touchpad scroll has ended, we don't actually want
1413 // a fling animation. Note: Similar code exists in
1414 // RenderWidgetHostViewChildFrame::FilterInputEvent()
1415 return blink::mojom::InputEventResultState::kNoConsumerExists;
1418 return consumed ? blink::mojom::InputEventResultState::kConsumed
1419 : blink::mojom::InputEventResultState::kNotConsumed;
1422 gfx::AcceleratedWidget
1423 RenderWidgetHostViewAura::AccessibilityGetAcceleratedWidget() {
1424 #if BUILDFLAG(IS_WIN)
1425 if (legacy_render_widget_host_HWND_)
1426 return legacy_render_widget_host_HWND_->hwnd();
1428 return gfx::kNullAcceleratedWidget;
1431 gfx::NativeViewAccessible
1432 RenderWidgetHostViewAura::AccessibilityGetNativeViewAccessible() {
1433 #if BUILDFLAG(IS_WIN)
1434 if (legacy_render_widget_host_HWND_) {
1435 return legacy_render_widget_host_HWND_->window_accessible();
1439 if (window_->parent()) {
1440 return window_->parent()->GetProperty(
1441 aura::client::kParentNativeViewAccessibleKey);
1447 void RenderWidgetHostViewAura::SetMainFrameAXTreeID(ui::AXTreeID id) {
1448 window_->SetProperty(ui::kChildAXTreeID, id.ToString());
1451 blink::mojom::PointerLockResult RenderWidgetHostViewAura::LockMouse(
1452 bool request_unadjusted_movement) {
1453 return event_handler_->LockMouse(request_unadjusted_movement);
1456 blink::mojom::PointerLockResult RenderWidgetHostViewAura::ChangeMouseLock(
1457 bool request_unadjusted_movement) {
1458 return event_handler_->ChangeMouseLock(request_unadjusted_movement);
1461 void RenderWidgetHostViewAura::UnlockMouse() {
1462 event_handler_->UnlockMouse();
1465 bool RenderWidgetHostViewAura::GetIsMouseLockedUnadjustedMovementForTesting() {
1466 return event_handler_->mouse_locked_unadjusted_movement();
1469 bool RenderWidgetHostViewAura::LockKeyboard(
1470 absl::optional<base::flat_set<ui::DomCode>> codes) {
1471 return event_handler_->LockKeyboard(std::move(codes));
1474 void RenderWidgetHostViewAura::UnlockKeyboard() {
1475 event_handler_->UnlockKeyboard();
1478 bool RenderWidgetHostViewAura::IsKeyboardLocked() {
1479 return event_handler_->IsKeyboardLocked();
1482 base::flat_map<std::string, std::string>
1483 RenderWidgetHostViewAura::GetKeyboardLayoutMap() {
1484 aura::WindowTreeHost* host = window_->GetHost();
1486 return host->GetKeyboardLayoutMap();
1490 ////////////////////////////////////////////////////////////////////////////////
1491 // RenderWidgetHostViewAura, ui::TextInputClient implementation:
1492 void RenderWidgetHostViewAura::SetCompositionText(
1493 const ui::CompositionText& composition) {
1494 if (!text_input_manager_ || !text_input_manager_->GetActiveWidget())
1497 // TODO(suzhe): due to a bug of webkit, we can't use selection range with
1498 // composition string. See: https://bugs.webkit.org/show_bug.cgi?id=37788
1499 text_input_manager_->GetActiveWidget()->ImeSetComposition(
1500 composition.text, composition.ime_text_spans, gfx::Range::InvalidRange(),
1501 composition.selection.end(), composition.selection.end());
1503 has_composition_text_ = !composition.text.empty();
1506 size_t RenderWidgetHostViewAura::ConfirmCompositionText(bool keep_selection) {
1507 if (text_input_manager_ && text_input_manager_->GetActiveWidget() &&
1508 has_composition_text_) {
1509 text_input_manager_->GetActiveWidget()->ImeFinishComposingText(
1512 has_composition_text_ = false;
1513 // TODO(crbug/1109604): Return the number of characters committed by this
1515 return std::numeric_limits<size_t>::max();
1518 void RenderWidgetHostViewAura::ClearCompositionText() {
1519 if (text_input_manager_ && text_input_manager_->GetActiveWidget() &&
1520 has_composition_text_)
1521 text_input_manager_->GetActiveWidget()->ImeCancelComposition();
1522 has_composition_text_ = false;
1525 void RenderWidgetHostViewAura::InsertText(
1526 const std::u16string& text,
1527 InsertTextCursorBehavior cursor_behavior) {
1528 DCHECK_NE(GetTextInputType(), ui::TEXT_INPUT_TYPE_NONE);
1530 if (text_input_manager_ && text_input_manager_->GetActiveWidget()) {
1531 const int relative_cursor_position =
1532 cursor_behavior == InsertTextCursorBehavior::kMoveCursorBeforeText
1535 text_input_manager_->GetActiveWidget()->ImeCommitText(
1536 text, std::vector<ui::ImeTextSpan>(), gfx::Range::InvalidRange(),
1537 relative_cursor_position);
1539 has_composition_text_ = false;
1542 void RenderWidgetHostViewAura::InsertChar(const ui::KeyEvent& event) {
1543 if (popup_child_host_view_ && popup_child_host_view_->NeedsInputGrab()) {
1544 popup_child_host_view_->InsertChar(event);
1548 // Ignore character messages for VKEY_RETURN sent on CTRL+M. crbug.com/315547
1549 if (event_handler_->accept_return_character() ||
1550 event.GetCharacter() != ui::VKEY_RETURN) {
1551 // Send a blink::WebInputEvent::Char event to |host_|.
1552 ForwardKeyboardEventWithLatencyInfo(
1553 NativeWebKeyboardEvent(event, event.GetCharacter()), *event.latency(),
1558 bool RenderWidgetHostViewAura::CanInsertImage() {
1559 RenderFrameHostImpl* render_frame_host = GetFocusedFrame();
1561 if (!render_frame_host) {
1565 return render_frame_host->has_focused_richly_editable_element();
1568 void RenderWidgetHostViewAura::InsertImage(const GURL& src) {
1569 auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1571 if (!input_handler) {
1575 input_handler->ExecuteEditCommand("PasteFromImageURL",
1576 base::UTF8ToUTF16(src.spec()));
1579 ui::TextInputType RenderWidgetHostViewAura::GetTextInputType() const {
1580 if (text_input_manager_ && text_input_manager_->GetTextInputState())
1581 return text_input_manager_->GetTextInputState()->type;
1582 return ui::TEXT_INPUT_TYPE_NONE;
1585 ui::TextInputMode RenderWidgetHostViewAura::GetTextInputMode() const {
1586 if (text_input_manager_ && text_input_manager_->GetTextInputState())
1587 return text_input_manager_->GetTextInputState()->mode;
1588 return ui::TEXT_INPUT_MODE_DEFAULT;
1591 base::i18n::TextDirection RenderWidgetHostViewAura::GetTextDirection() const {
1592 NOTIMPLEMENTED_LOG_ONCE();
1593 return base::i18n::UNKNOWN_DIRECTION;
1596 int RenderWidgetHostViewAura::GetTextInputFlags() const {
1597 if (text_input_manager_ && text_input_manager_->GetTextInputState())
1598 return text_input_manager_->GetTextInputState()->flags;
1602 bool RenderWidgetHostViewAura::CanComposeInline() const {
1603 if (text_input_manager_ && text_input_manager_->GetTextInputState())
1604 return text_input_manager_->GetTextInputState()->can_compose_inline;
1608 gfx::Rect RenderWidgetHostViewAura::ConvertRectToScreen(
1609 const gfx::Rect& rect) const {
1610 gfx::Point origin = rect.origin();
1611 gfx::Point end = gfx::Point(rect.right(), rect.bottom());
1613 aura::Window* root_window = window_->GetRootWindow();
1616 aura::client::ScreenPositionClient* screen_position_client =
1617 aura::client::GetScreenPositionClient(root_window);
1618 if (!screen_position_client)
1620 screen_position_client->ConvertPointToScreen(window_, &origin);
1621 screen_position_client->ConvertPointToScreen(window_, &end);
1622 return gfx::Rect(origin.x(), origin.y(), base::ClampSub(end.x(), origin.x()),
1623 base::ClampSub(end.y(), origin.y()));
1626 gfx::Rect RenderWidgetHostViewAura::ConvertRectFromScreen(
1627 const gfx::Rect& rect) const {
1628 gfx::Rect result = rect;
1629 if (window_->GetRootWindow() &&
1630 aura::client::GetScreenPositionClient(window_->GetRootWindow()))
1631 wm::ConvertRectFromScreen(window_, &result);
1635 gfx::Rect RenderWidgetHostViewAura::GetCaretBounds() const {
1636 if (!text_input_manager_ || !text_input_manager_->GetActiveWidget())
1639 // Check selection bound first (currently populated only for EditContext)
1640 const absl::optional<gfx::Rect> text_selection_bound =
1641 text_input_manager_->GetTextSelectionBounds();
1642 if (text_selection_bound)
1643 return ConvertRectToScreen(text_selection_bound.value());
1645 // If no selection bound, we fall back to use selection region.
1646 const TextInputManager::SelectionRegion* region =
1647 text_input_manager_->GetSelectionRegion();
1648 gfx::Rect caret_rect = ConvertRectToScreen(
1649 gfx::RectBetweenSelectionBounds(region->anchor, region->focus));
1650 TRACE_EVENT1("ime", "RenderWidgetHostViewAura::GetCaretBounds", "caret_rect",
1651 caret_rect.ToString());
1655 gfx::Rect RenderWidgetHostViewAura::GetSelectionBoundingBox() const {
1656 auto* focused_view = GetFocusedViewForTextSelection();
1660 const gfx::Rect bounding_box =
1661 text_input_manager_->GetSelectionRegion(focused_view)->bounding_box;
1662 if (bounding_box.IsEmpty())
1665 return ConvertRectToScreen(bounding_box);
1668 bool RenderWidgetHostViewAura::GetCompositionCharacterBounds(
1670 gfx::Rect* rect) const {
1673 if (!text_input_manager_ || !text_input_manager_->GetActiveWidget())
1676 const TextInputManager::CompositionRangeInfo* composition_range_info =
1677 text_input_manager_->GetCompositionRangeInfo();
1679 if (index >= composition_range_info->character_bounds.size())
1681 *rect = ConvertRectToScreen(composition_range_info->character_bounds[index]);
1682 TRACE_EVENT1("ime", "RenderWidgetHostViewAura::GetCompositionCharacterBounds",
1683 "comp_char_rect", rect->ToString());
1687 bool RenderWidgetHostViewAura::HasCompositionText() const {
1688 return has_composition_text_;
1691 ui::TextInputClient::FocusReason RenderWidgetHostViewAura::GetFocusReason()
1693 if (!window_->HasFocus())
1694 return ui::TextInputClient::FOCUS_REASON_NONE;
1696 switch (last_pointer_type_before_focus_) {
1697 case ui::EventPointerType::kMouse:
1698 return ui::TextInputClient::FOCUS_REASON_MOUSE;
1699 case ui::EventPointerType::kPen:
1700 return ui::TextInputClient::FOCUS_REASON_PEN;
1701 case ui::EventPointerType::kTouch:
1702 return ui::TextInputClient::FOCUS_REASON_TOUCH;
1704 return ui::TextInputClient::FOCUS_REASON_OTHER;
1708 bool RenderWidgetHostViewAura::GetTextRange(gfx::Range* range) const {
1709 if (!text_input_manager_ || !GetFocusedWidget())
1712 const ui::mojom::TextInputState* state =
1713 text_input_manager_->GetTextInputState();
1717 range->set_start(0);
1718 range->set_end(state->value ? state->value->length() : 0);
1722 bool RenderWidgetHostViewAura::GetCompositionTextRange(
1723 gfx::Range* range) const {
1724 if (!text_input_manager_ || !GetFocusedWidget())
1727 const ui::mojom::TextInputState* state =
1728 text_input_manager_->GetTextInputState();
1729 // Return false when there is no composition.
1730 if (!state || !state->composition)
1733 *range = state->composition.value();
1737 bool RenderWidgetHostViewAura::GetEditableSelectionRange(
1738 gfx::Range* range) const {
1739 if (!text_input_manager_ || !GetFocusedWidget())
1742 const ui::mojom::TextInputState* state =
1743 text_input_manager_->GetTextInputState();
1747 *range = state->selection;
1751 bool RenderWidgetHostViewAura::SetEditableSelectionRange(
1752 const gfx::Range& range) {
1753 // TODO(crbug.com/915630): Write an unit test for this method.
1754 auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1757 input_handler->SetEditableSelectionOffsets(range.start(), range.end());
1761 bool RenderWidgetHostViewAura::GetTextFromRange(const gfx::Range& range,
1762 std::u16string* text) const {
1763 if (!text_input_manager_ || !GetFocusedWidget())
1766 const ui::mojom::TextInputState* state =
1767 text_input_manager_->GetTextInputState();
1771 gfx::Range text_range;
1772 GetTextRange(&text_range);
1774 if (!text_range.Contains(range)) {
1778 if (!state->value) {
1782 if (text_range.EqualsIgnoringDirection(range)) {
1783 // Avoid calling substr whose performance is low.
1784 *text = *state->value;
1786 *text = state->value->substr(range.GetMin(), range.length());
1791 void RenderWidgetHostViewAura::OnInputMethodChanged() {
1792 // TODO(suzhe): implement the newly added "locale" property of HTML DOM
1796 bool RenderWidgetHostViewAura::ChangeTextDirectionAndLayoutAlignment(
1797 base::i18n::TextDirection direction) {
1798 if (!GetTextInputManager() && !GetTextInputManager()->GetActiveWidget())
1801 GetTextInputManager()->GetActiveWidget()->UpdateTextDirection(direction);
1802 GetTextInputManager()->GetActiveWidget()->NotifyTextDirection();
1806 void RenderWidgetHostViewAura::ExtendSelectionAndDelete(
1807 size_t before, size_t after) {
1808 auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1811 input_handler->ExtendSelectionAndDelete(before, after);
1814 #if BUILDFLAG(IS_CHROMEOS)
1815 void RenderWidgetHostViewAura::ExtendSelectionAndReplace(
1818 const base::StringPiece16 replacement_text) {
1819 auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1820 if (!input_handler) {
1823 input_handler->ExtendSelectionAndReplace(before, after,
1824 std::u16string(replacement_text));
1828 void RenderWidgetHostViewAura::EnsureCaretNotInRect(
1829 const gfx::Rect& rect_in_screen) {
1830 keyboard_occluded_bounds_ = rect_in_screen;
1832 // If keyboard is disabled, reset the insets_.
1833 if (keyboard_occluded_bounds_.IsEmpty()) {
1834 SetInsets(gfx::Insets());
1836 UpdateInsetsWithVirtualKeyboardEnabled();
1839 aura::Window* top_level_window = window_->GetToplevelWindow();
1840 #if BUILDFLAG(IS_CHROMEOS_ASH)
1841 wm::EnsureWindowNotInRect(top_level_window, keyboard_occluded_bounds_);
1844 // Perform overscroll if the caret is still hidden by the keyboard.
1845 const gfx::Rect hidden_window_bounds_in_screen = gfx::IntersectRects(
1846 keyboard_occluded_bounds_, top_level_window->GetBoundsInScreen());
1848 if (hidden_window_bounds_in_screen.IsEmpty())
1851 ScrollFocusedEditableNodeIntoView();
1854 bool RenderWidgetHostViewAura::IsTextEditCommandEnabled(
1855 ui::TextEditCommand command) const {
1859 void RenderWidgetHostViewAura::SetTextEditCommandForNextKeyEvent(
1860 ui::TextEditCommand command) {}
1862 ukm::SourceId RenderWidgetHostViewAura::GetClientSourceForMetrics() const {
1863 RenderFrameHostImpl* frame = GetFocusedFrame();
1864 // ukm::SourceId is not available while prerendering.
1865 if (frame && !frame->IsInLifecycleState(
1866 RenderFrameHost::LifecycleState::kPrerendering)) {
1867 return frame->GetPageUkmSourceId();
1869 return ukm::SourceId();
1872 bool RenderWidgetHostViewAura::ShouldDoLearning() {
1873 return GetTextInputManager() && GetTextInputManager()->should_do_learning();
1876 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
1877 bool RenderWidgetHostViewAura::SetCompositionFromExistingText(
1878 const gfx::Range& range,
1879 const std::vector<ui::ImeTextSpan>& ui_ime_text_spans) {
1880 auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1883 input_handler->SetCompositionFromExistingText(range.start(), range.end(),
1885 has_composition_text_ = true;
1891 #if BUILDFLAG(IS_CHROMEOS)
1892 gfx::Range RenderWidgetHostViewAura::GetAutocorrectRange() const {
1893 if (!text_input_manager_ || !text_input_manager_->GetActiveWidget())
1894 return gfx::Range();
1895 return text_input_manager_->GetAutocorrectRange();
1898 gfx::Rect RenderWidgetHostViewAura::GetAutocorrectCharacterBounds() const {
1899 if (!text_input_manager_ || !text_input_manager_->GetActiveWidget())
1902 const std::vector<ui::mojom::ImeTextSpanInfoPtr>& ime_text_spans_info =
1903 text_input_manager_->GetTextInputState()->ime_text_spans_info;
1905 unsigned autocorrect_span_found = 0;
1907 for (const auto& ime_text_span_info : ime_text_spans_info) {
1908 if (ime_text_span_info->span.type == ui::ImeTextSpan::Type::kAutocorrect) {
1909 bounds = ConvertRectToScreen(ime_text_span_info->bounds);
1910 autocorrect_span_found++;
1913 // Assuming there is only one autocorrect span at any point in time.
1914 DCHECK_LE(autocorrect_span_found, 1u);
1918 bool RenderWidgetHostViewAura::SetAutocorrectRange(
1919 const gfx::Range& range) {
1920 if (!range.is_empty()) {
1921 base::UmaHistogramEnumeration(
1922 "InputMethod.Assistive.Autocorrect.Count",
1923 TextInputClient::SubClass::kRenderWidgetHostViewAura);
1925 #if BUILDFLAG(IS_CHROMEOS_ASH)
1926 auto* input_method_manager = ash::input_method::InputMethodManager::Get();
1927 if (input_method_manager &&
1928 ash::extension_ime_util::IsExperimentalMultilingual(
1929 input_method_manager->GetActiveIMEState()
1930 ->GetCurrentInputMethod()
1932 base::UmaHistogramEnumeration(
1933 "InputMethod.MultilingualExperiment.Autocorrect.Count",
1934 TextInputClient::SubClass::kRenderWidgetHostViewAura);
1939 auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1943 input_handler->ClearImeTextSpansByType(0,
1944 std::numeric_limits<uint32_t>::max(),
1945 ui::ImeTextSpan::Type::kAutocorrect);
1947 if (range.is_empty())
1950 ui::ImeTextSpan ui_ime_text_span;
1951 ui_ime_text_span.type = ui::ImeTextSpan::Type::kAutocorrect;
1952 ui_ime_text_span.start_offset = 0;
1953 ui_ime_text_span.end_offset = range.length();
1954 ui_ime_text_span.underline_style = ui::ImeTextSpan::UnderlineStyle::kDot;
1955 ui_ime_text_span.underline_color =
1956 SkColorSetA(gfx::kGoogleGrey700, SK_AlphaOPAQUE * 0.7);
1957 ui_ime_text_span.thickness = ui::ImeTextSpan::Thickness::kThick;
1959 input_handler->AddImeTextSpansToExistingText(range.start(), range.end(),
1960 {ui_ime_text_span});
1964 absl::optional<ui::GrammarFragment>
1965 RenderWidgetHostViewAura::GetGrammarFragmentAtCursor() const {
1966 if (!text_input_manager_ || !text_input_manager_->GetActiveWidget())
1967 return absl::nullopt;
1968 gfx::Range selection_range;
1969 if (GetEditableSelectionRange(&selection_range)) {
1970 return text_input_manager_->GetGrammarFragment(selection_range);
1972 return absl::nullopt;
1976 bool RenderWidgetHostViewAura::ClearGrammarFragments(const gfx::Range& range) {
1977 auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1981 input_handler->ClearImeTextSpansByType(
1982 range.start(), range.end(), ui::ImeTextSpan::Type::kGrammarSuggestion);
1986 bool RenderWidgetHostViewAura::AddGrammarFragments(
1987 const std::vector<ui::GrammarFragment>& fragments) {
1988 if (!fragments.empty()) {
1989 base::UmaHistogramEnumeration(
1990 "InputMethod.Assistive.Grammar.Count",
1991 TextInputClient::SubClass::kRenderWidgetHostViewAura);
1994 auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1995 if (!input_handler || fragments.empty())
1998 unsigned max_fragment_end = 0;
1999 std::vector<::ui::ImeTextSpan> ime_text_spans;
2000 ime_text_spans.reserve(fragments.size());
2001 for (auto& fragment : fragments) {
2002 ui::ImeTextSpan ui_ime_text_span;
2003 ui_ime_text_span.type = ui::ImeTextSpan::Type::kGrammarSuggestion;
2004 ui_ime_text_span.start_offset = fragment.range.start();
2005 ui_ime_text_span.end_offset = fragment.range.end();
2006 ui_ime_text_span.thickness = ui::ImeTextSpan::Thickness::kThick;
2007 ui_ime_text_span.underline_style = ui::ImeTextSpan::UnderlineStyle::kDot;
2008 ui_ime_text_span.underline_color = gfx::kGoogleBlue400;
2009 ui_ime_text_span.suggestions = {fragment.suggestion};
2011 ime_text_spans.push_back(ui_ime_text_span);
2012 if (fragment.range.end() > max_fragment_end) {
2013 max_fragment_end = fragment.range.end();
2016 input_handler->AddImeTextSpansToExistingText(0, max_fragment_end,
2024 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS)
2025 void RenderWidgetHostViewAura::GetActiveTextInputControlLayoutBounds(
2026 absl::optional<gfx::Rect>* control_bounds,
2027 absl::optional<gfx::Rect>* selection_bounds) {
2028 if (text_input_manager_) {
2029 const absl::optional<gfx::Rect> text_control_bounds =
2030 text_input_manager_->GetTextControlBounds();
2031 if (text_control_bounds) {
2032 *control_bounds = ConvertRectToScreen(text_control_bounds.value());
2035 "RenderWidgetHostViewAura::GetActiveTextInputControlLayoutBounds",
2036 "control_bounds_rect", control_bounds->value().ToString());
2038 // Selection bounds are currently populated only for EditContext.
2039 // For editable elements we use GetCompositionCharacterBounds.
2040 const absl::optional<gfx::Rect> text_selection_bounds =
2041 text_input_manager_->GetTextSelectionBounds();
2042 if (text_selection_bounds) {
2043 *selection_bounds = ConvertRectToScreen(text_selection_bounds.value());
2049 #if BUILDFLAG(IS_WIN)
2050 void RenderWidgetHostViewAura::SetActiveCompositionForAccessibility(
2051 const gfx::Range& range,
2052 const std::u16string& active_composition_text,
2053 bool is_composition_committed) {
2054 BrowserAccessibilityManager* manager =
2055 host()->GetRootBrowserAccessibilityManager();
2057 ui::AXPlatformNodeWin* focus_node = static_cast<ui::AXPlatformNodeWin*>(
2058 ui::AXPlatformNode::FromNativeViewAccessible(
2059 manager->GetFocus()->GetNativeViewAccessible()));
2061 // Notify accessibility object about this composition
2062 focus_node->OnActiveComposition(range, active_composition_text,
2063 is_composition_committed);
2069 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH)
2070 ui::TextInputClient::EditingContext
2071 RenderWidgetHostViewAura::GetTextEditingContext() {
2072 ui::TextInputClient::EditingContext editing_context;
2073 // We use the focused frame's URL here and not the main frame because
2074 // TSF(Windows Text Service Framework) works on the active editable element
2075 // context and it uses this information to assist the UIA(Microsoft UI
2076 // Automation) service to determine the character that is being typed by the
2077 // user via IME composition, the URL of the site that the user is typing on
2078 // and other text related services that are used by the UIA clients to power
2079 // accessibility features on Windows. We want to expose the focused frame's
2080 // URL to TSF that notifies the UIA service which uses this info and the
2081 // focused element's data to provide better screen reading capabilities.
2082 RenderFrameHostImpl* frame = GetFocusedFrame();
2084 editing_context.page_url = frame->GetLastCommittedURL();
2085 return editing_context;
2089 #if BUILDFLAG(IS_WIN)
2090 void RenderWidgetHostViewAura::NotifyOnFrameFocusChanged() {
2091 if (GetInputMethod()) {
2092 GetInputMethod()->OnUrlChanged();
2097 ////////////////////////////////////////////////////////////////////////////////
2098 // RenderWidgetHostViewAura, display::DisplayObserver implementation:
2100 void RenderWidgetHostViewAura::OnDisplayMetricsChanged(
2101 const display::Display& display,
2103 display::Screen* screen = display::Screen::GetScreen();
2104 if (display.id() != screen->GetDisplayNearestWindow(window_).id())
2107 if (window_->GetHost() && window_->GetHost()->device_scale_factor() !=
2108 display.device_scale_factor()) {
2109 // The DisplayMetrics changed, but the Compositor hasn't been updated yet.
2110 // Delay updating until the Compositor is updated as well, otherwise we
2111 // are likely to hit surface invariants (LocalSurfaceId generated with a
2112 // size/scale-factor that differs from scale-factor used by Compositor).
2113 needs_to_update_display_metrics_ = true;
2116 ProcessDisplayMetricsChanged();
2119 ////////////////////////////////////////////////////////////////////////////////
2120 // RenderWidgetHostViewAura, aura::WindowDelegate implementation:
2122 gfx::Size RenderWidgetHostViewAura::GetMinimumSize() const {
2126 gfx::Size RenderWidgetHostViewAura::GetMaximumSize() const {
2130 void RenderWidgetHostViewAura::OnBoundsChanged(const gfx::Rect& old_bounds,
2131 const gfx::Rect& new_bounds) {
2132 base::AutoReset<bool> in_bounds_changed(&in_bounds_changed_, true);
2133 // We care about this whenever RenderWidgetHostViewAura is not owned by a
2134 // WebContentsViewAura since changes to the Window's bounds need to be
2135 // messaged to the renderer. WebContentsViewAura invokes SetSize() or
2136 // SetBounds() itself. No matter how we got here, any redundant calls are
2138 SetSize(new_bounds.size());
2140 if (GetInputMethod()) {
2141 GetInputMethod()->OnCaretBoundsChanged(this);
2142 UpdateInsetsWithVirtualKeyboardEnabled();
2146 gfx::NativeCursor RenderWidgetHostViewAura::GetCursor(const gfx::Point& point) {
2147 if (IsMouseLocked())
2148 return ui::mojom::CursorType::kNone;
2149 return current_cursor_.GetNativeCursor();
2152 int RenderWidgetHostViewAura::GetNonClientComponent(
2153 const gfx::Point& point) const {
2157 bool RenderWidgetHostViewAura::ShouldDescendIntoChildForEventHandling(
2158 aura::Window* child,
2159 const gfx::Point& location) {
2163 bool RenderWidgetHostViewAura::CanFocus() {
2164 return widget_type_ == WidgetType::kFrame;
2167 void RenderWidgetHostViewAura::OnCaptureLost() {
2168 host()->LostCapture();
2171 void RenderWidgetHostViewAura::OnPaint(const ui::PaintContext& context) {
2175 void RenderWidgetHostViewAura::OnDeviceScaleFactorChanged(
2176 float old_device_scale_factor,
2177 float new_device_scale_factor) {
2178 if (!window_->GetRootWindow())
2181 // TODO(crbug.com/1446142): Add unittest for lacros.
2182 if (needs_to_update_display_metrics_ ||
2183 old_device_scale_factor != new_device_scale_factor) {
2184 ProcessDisplayMetricsChanged();
2187 SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
2188 window_->GetLocalSurfaceId());
2190 device_scale_factor_ = new_device_scale_factor;
2191 const display::Display display =
2192 display::Screen::GetScreen()->GetDisplayNearestWindow(window_);
2193 // Sometimes GetDisplayNearestWindow returns the default monitor. We don't
2194 // want to use that here.
2195 if (display.is_valid()) {
2196 DCHECK_EQ(new_device_scale_factor, display.device_scale_factor());
2197 current_cursor_.SetDisplayInfo(display);
2201 void RenderWidgetHostViewAura::OnWindowDestroying(aura::Window* window) {
2202 #if BUILDFLAG(IS_WIN)
2203 // The LegacyRenderWidgetHostHWND instance is destroyed when its window is
2204 // destroyed. Normally we control when that happens via the Destroy call
2205 // in the dtor. However there may be cases where the window is destroyed
2206 // by Windows, i.e. the parent window is destroyed before the
2207 // RenderWidgetHostViewAura instance goes away etc. To avoid that we
2208 // destroy the LegacyRenderWidgetHostHWND instance here.
2209 if (legacy_render_widget_host_HWND_) {
2210 // The Destroy call below will delete the LegacyRenderWidgetHostHWND
2212 legacy_render_widget_host_HWND_.ExtractAsDangling()->Destroy();
2216 // Make sure that the input method no longer references to this object before
2217 // this object is removed from the root window (i.e. this object loses access
2218 // to the input method).
2219 DetachFromInputMethod(true);
2221 if (overscroll_controller_)
2222 overscroll_controller_->Reset();
2225 void RenderWidgetHostViewAura::OnWindowDestroyed(aura::Window* window) {
2226 // This is not called on all destruction paths (e.g. if this view was never
2227 // inialized properly to create the window). So the destruction/cleanup code
2228 // that do not depend on |window_| should happen in the destructor, not here.
2232 void RenderWidgetHostViewAura::OnWindowTargetVisibilityChanged(bool visible) {
2235 bool RenderWidgetHostViewAura::HasHitTestMask() const {
2239 void RenderWidgetHostViewAura::GetHitTestMask(SkPath* mask) const {}
2241 bool RenderWidgetHostViewAura::RequiresDoubleTapGestureEvents() const {
2242 RenderWidgetHostOwnerDelegate* owner_delegate = host()->owner_delegate();
2243 // TODO(crbug.com/916715): Child local roots do not work here?
2244 if (!owner_delegate)
2246 return double_tap_to_zoom_enabled_;
2249 ////////////////////////////////////////////////////////////////////////////////
2250 // RenderWidgetHostViewAura, ui::EventHandler implementation:
2252 void RenderWidgetHostViewAura::OnKeyEvent(ui::KeyEvent* event) {
2253 last_pointer_type_ = ui::EventPointerType::kUnknown;
2254 event_handler_->OnKeyEvent(event);
2257 void RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent* event) {
2258 #if BUILDFLAG(IS_WIN)
2259 if (event->type() == ui::ET_MOUSE_MOVED) {
2260 if (event->location() == last_mouse_move_location_ &&
2261 event->movement().IsZero()) {
2262 event->SetHandled();
2265 last_mouse_move_location_ = event->location();
2268 #if BUILDFLAG(IS_EFL)
2270 efl_helper_->OnMouseOrTouchEvent(event);
2272 last_pointer_type_ = ui::EventPointerType::kMouse;
2273 event_handler_->OnMouseEvent(event);
2276 bool RenderWidgetHostViewAura::HasFallbackSurface() const {
2277 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2278 return delegated_frame_host_->HasFallbackSurface();
2281 bool RenderWidgetHostViewAura::TransformPointToCoordSpaceForView(
2282 const gfx::PointF& point,
2283 RenderWidgetHostViewBase* target_view,
2284 gfx::PointF* transformed_point) {
2285 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2287 if (target_view == this) {
2288 *transformed_point = point;
2292 // In TransformPointToLocalCoordSpace() there is a Point-to-Pixel conversion,
2293 // but it is not necessary here because the final target view is responsible
2294 // for converting before computing the final transform.
2295 return target_view->TransformPointToLocalCoordSpace(
2296 point, GetCurrentSurfaceId(), transformed_point);
2299 viz::FrameSinkId RenderWidgetHostViewAura::GetRootFrameSinkId() {
2300 if (!GetCompositor())
2301 return viz::FrameSinkId();
2303 return GetCompositor()->frame_sink_id();
2306 viz::SurfaceId RenderWidgetHostViewAura::GetCurrentSurfaceId() const {
2307 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2308 return delegated_frame_host_->GetCurrentSurfaceId();
2311 void RenderWidgetHostViewAura::FocusedNodeChanged(
2313 const gfx::Rect& node_bounds_in_screen
2314 #if BUILDFLAG(IS_TIZEN_TV)
2316 bool is_radio_or_checkbox,
2317 int password_input_minlength,
2320 #if BUILDFLAG(IS_EFL)
2322 bool is_content_editable
2325 // The last gesture most likely caused the focus change. The focus reason will
2326 // be incorrect if the focus was triggered without a user gesture.
2327 // TODO(https://crbug.com/824604): Get the focus reason from the renderer
2328 // process instead to get the true focus reason.
2329 last_pointer_type_before_focus_ = last_pointer_type_;
2331 auto* input_method = GetInputMethod();
2333 input_method->CancelComposition(this);
2334 has_composition_text_ = false;
2336 #if defined(USE_EFL)
2337 efl_helper_->FocusedNodeChanged(
2339 #if BUILDFLAG(IS_TIZEN_TV)
2341 is_radio_or_checkbox, password_input_minlength, input_maxlength
2344 is_content_editable);
2347 #if BUILDFLAG(IS_WIN)
2348 if (window_ && virtual_keyboard_controller_win_) {
2349 virtual_keyboard_controller_win_->FocusedNodeChanged(editable);
2354 #if defined(TIZEN_VIDEO_HOLE)
2355 void RenderWidgetHostViewAura::SetWebViewMovedCallback(
2356 const base::RepeatingClosure on_webview_moved) {
2357 on_webview_moved_callback_ = std::move(on_webview_moved);
2361 #if BUILDFLAG(IS_TIZEN_TV)
2362 void RenderWidgetHostViewAura::DidEdgeScrollBy(const gfx::Point& offset,
2364 efl_helper_->DidEdgeScrollBy(offset, handled);
2367 void RenderWidgetHostViewAura::MoveFocusToBrowser(int direction) {
2368 if (aura_efl_helper()) {
2369 aura_efl_helper()->MoveFocusToBrowser(direction);
2373 void RenderWidgetHostViewAura::NotifyTrackInfoToBrowser(
2374 int active_track_id,
2375 const std::string& url,
2376 const std::string& lang) {
2377 if (!aura_efl_helper()) {
2378 LOG(ERROR) << "aura_efl_helper() is null";
2381 aura_efl_helper()->NotifyTrackInfoToBrowser(active_track_id, url, lang);
2385 void RenderWidgetHostViewAura::OnScrollEvent(ui::ScrollEvent* event) {
2386 event_handler_->OnScrollEvent(event);
2389 void RenderWidgetHostViewAura::OnTouchEvent(ui::TouchEvent* event) {
2390 #if BUILDFLAG(IS_EFL)
2392 efl_helper_->OnMouseOrTouchEvent(event);
2394 last_pointer_type_ = event->pointer_details().pointer_type;
2395 ui::InputMethod* input_method = GetInputMethod();
2396 if (window_ && window_->HasFocus() && input_method) {
2397 input_method->OnTouch(event->pointer_details().pointer_type);
2399 event_handler_->OnTouchEvent(event);
2402 void RenderWidgetHostViewAura::OnGestureEvent(ui::GestureEvent* event) {
2403 last_pointer_type_ = event->details().primary_pointer_type();
2404 #if BUILDFLAG(IS_EFL)
2405 // Gesture event will be processed and forwarded via efl helper.
2406 efl_helper_->OnGestureEvent(event);
2409 event_handler_->OnGestureEvent(event);
2412 base::StringPiece RenderWidgetHostViewAura::GetLogContext() const {
2413 return "RenderWidgetHostViewAura";
2416 ////////////////////////////////////////////////////////////////////////////////
2417 // RenderWidgetHostViewAura, wm::ActivationDelegate implementation:
2419 bool RenderWidgetHostViewAura::ShouldActivate() const {
2420 aura::WindowTreeHost* host = window_->GetHost();
2423 const ui::Event* event = host->dispatcher()->current_event();
2427 ////////////////////////////////////////////////////////////////////////////////
2428 // RenderWidgetHostViewAura, aura::client::CursorClientObserver implementation:
2430 void RenderWidgetHostViewAura::OnCursorVisibilityChanged(bool is_visible) {
2431 NotifyRendererOfCursorVisibilityState(is_visible);
2434 void RenderWidgetHostViewAura::OnSystemCursorSizeChanged(
2435 const gfx::Size& system_cursor_size) {
2436 UpdateSystemCursorSize(system_cursor_size);
2439 ////////////////////////////////////////////////////////////////////////////////
2440 // RenderWidgetHostViewAura, aura::client::FocusChangeObserver implementation:
2442 void RenderWidgetHostViewAura::OnWindowFocused(aura::Window* gained_focus,
2443 aura::Window* lost_focus) {
2444 LOG(INFO) << "OnWindowFocused, Gained : " << gained_focus
2445 << ", Lost : " << lost_focus;
2446 if (window_ == gained_focus) {
2447 #if !BUILDFLAG(IS_TIZEN_TV)
2448 // We need to honor input bypass if the associated tab does not want input.
2449 // This gives the current focused window a chance to be the text input
2450 // client and handle events.
2451 if (host()->IsIgnoringInputEvents())
2456 UpdateActiveState(true);
2458 ui::InputMethod* input_method = GetInputMethod();
2460 // Ask the system-wide IME to send all TextInputClient messages to |this|
2462 input_method->SetFocusedTextInputClient(this);
2465 BrowserAccessibilityManager* manager =
2466 host()->GetRootBrowserAccessibilityManager();
2468 manager->OnWindowFocused();
2472 if (window_ != lost_focus) {
2477 UpdateActiveState(false);
2478 host()->LostFocus();
2480 DetachFromInputMethod(false);
2482 // TODO(wjmaclean): Do we need to let TouchSelectionControllerClientAura
2483 // handle this, just in case it stomps on a new highlight in another view
2484 // that has just become focused? So far it doesn't appear to be a problem,
2485 // but we should keep an eye on it.
2486 selection_controller_->HideAndDisallowShowingAutomatically();
2488 if (overscroll_controller_)
2489 overscroll_controller_->Cancel();
2491 BrowserAccessibilityManager* manager =
2492 host()->GetRootBrowserAccessibilityManager();
2494 manager->OnWindowBlurred();
2496 // Close the child popup window if we lose focus (e.g. due to a JS alert or
2497 // system modal dialog). This is particularly important if
2498 // |popup_child_host_view_| has mouse capture.
2499 if (popup_child_host_view_)
2500 popup_child_host_view_->Shutdown();
2503 ////////////////////////////////////////////////////////////////////////////////
2504 // RenderWidgetHostViewAura, aura::WindowTreeHostObserver implementation:
2506 void RenderWidgetHostViewAura::OnHostMovedInPixels(aura::WindowTreeHost* host) {
2507 TRACE_EVENT0("ui", "RenderWidgetHostViewAura::OnHostMovedInPixels");
2512 ////////////////////////////////////////////////////////////////////////////////
2513 // RenderWidgetHostViewAura, RenderFrameMetadataProvider::Observer
2515 void RenderWidgetHostViewAura::OnRenderFrameMetadataChangedAfterActivation(
2516 base::TimeTicks activation_time) {
2517 const cc::RenderFrameMetadata& metadata =
2518 host()->render_frame_metadata_provider()->LastRenderFrameMetadata();
2520 // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
2521 SetContentBackgroundColor(metadata.root_background_color.toSkColor());
2522 if (inset_surface_id_.is_valid() && metadata.local_surface_id &&
2523 metadata.local_surface_id.value().is_valid() &&
2524 metadata.local_surface_id.value().IsSameOrNewerThan(inset_surface_id_)) {
2525 inset_surface_id_ = viz::LocalSurfaceId();
2526 ScrollFocusedEditableNodeIntoView();
2529 if (metadata.selection.start != selection_start_ ||
2530 metadata.selection.end != selection_end_) {
2531 selection_start_ = metadata.selection.start;
2532 selection_end_ = metadata.selection.end;
2533 selection_controller_client_->UpdateClientSelectionBounds(selection_start_,
2538 #if BUILDFLAG(IS_EFL)
2539 RWHVAuraOffscreenHelperEfl* RenderWidgetHostViewAura::offscreen_helper() {
2540 if (!efl_helper_->IsOffscreenMode()) {
2541 DLOG(INFO) << "Onscreen rendering mode is set";
2545 return static_cast<RWHVAuraOffscreenHelperEfl*>(efl_helper_.get());
2548 void RenderWidgetHostViewAura::DidChangeInputType(bool is_password_field) {
2549 efl_helper_->DidChangeInputType(is_password_field);
2552 void RenderWidgetHostViewAura::OnGetFocusedNodeBounds(const gfx::RectF& rect) {
2553 efl_helper_->OnGetFocusedNodeBounds(rect);
2556 void RenderWidgetHostViewAura::OnGetMainFrameScrollbarVisible(int callback_id,
2558 efl_helper_->OnGetMainFrameScrollbarVisible(callback_id, visible);
2561 void RenderWidgetHostViewAura::NotifySwap(const size_t texture_id) {
2562 if (texture_id <= 0) {
2563 LOG(ERROR) << __FUNCTION__ << " invalid texture id ";
2569 efl_helper_->NotifySwap(texture_id);
2573 ////////////////////////////////////////////////////////////////////////////////
2574 // RenderWidgetHostViewAura, private:
2576 RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
2577 host()->render_frame_metadata_provider()->RemoveObserver(this);
2579 // Ask the RWH to drop reference to us.
2580 host()->ViewDestroyed();
2582 // Dismiss any visible touch selection handles or touch selection menu.
2583 selection_controller_->HideAndDisallowShowingAutomatically();
2584 selection_controller_.reset();
2585 selection_controller_client_.reset();
2587 GetCursorManager()->ViewBeingDestroyed(this);
2589 delegated_frame_host_.reset();
2590 window_observer_.reset();
2592 if (window_->GetHost())
2593 window_->GetHost()->RemoveObserver(this);
2595 wm::SetTooltipText(window_, nullptr);
2597 // This call is usually no-op since |this| object is already removed from
2598 // the Aura root window and we don't have a way to get an input method
2599 // object associated with the window, but just in case.
2600 DetachFromInputMethod(true);
2602 if (popup_parent_host_view_) {
2603 DCHECK(!popup_parent_host_view_->popup_child_host_view_ ||
2604 popup_parent_host_view_->popup_child_host_view_ == this);
2605 popup_parent_host_view_->SetPopupChild(nullptr);
2607 if (popup_child_host_view_) {
2608 DCHECK(!popup_child_host_view_->popup_parent_host_view_ ||
2609 popup_child_host_view_->popup_parent_host_view_ == this);
2610 popup_child_host_view_->popup_parent_host_view_ = nullptr;
2612 event_observer_for_popup_exit_.reset();
2614 #if BUILDFLAG(IS_WIN)
2615 // The LegacyRenderWidgetHostHWND window should have been destroyed in
2616 // RenderWidgetHostViewAura::OnWindowDestroying and the pointer should
2618 DCHECK(!legacy_render_widget_host_HWND_);
2621 if (text_input_manager_)
2622 text_input_manager_->RemoveObserver(this);
2625 void RenderWidgetHostViewAura::CreateAuraWindow(aura::client::WindowType type) {
2627 window_ = new aura::Window(this);
2628 window_->SetName("RenderWidgetHostViewAura");
2629 event_handler_->set_window(window_);
2630 window_observer_ = std::make_unique<WindowObserver>(this);
2632 wm::SetTooltipText(window_, &tooltip_);
2633 wm::SetActivationDelegate(window_, this);
2634 aura::client::SetFocusChangeObserver(window_, this);
2635 display_observer_.emplace(this);
2637 window_->SetType(type);
2638 window_->Init(ui::LAYER_SOLID_COLOR);
2639 window_->layer()->SetColor(GetBackgroundColor() ? *GetBackgroundColor()
2641 // This needs to happen only after |window_| has been initialized using
2642 // Init(), because it needs to have the layer.
2643 window_->SetEmbedFrameSinkId(frame_sink_id_);
2646 void RenderWidgetHostViewAura::CreateDelegatedFrameHostClient() {
2647 delegated_frame_host_client_ =
2648 std::make_unique<DelegatedFrameHostClientAura>(this);
2649 delegated_frame_host_ = std::make_unique<DelegatedFrameHost>(
2650 frame_sink_id_, delegated_frame_host_client_.get(),
2651 false /* should_register_frame_sink_id */);
2654 void RenderWidgetHostViewAura::UpdateCursorIfOverSelf() {
2655 if (host()->GetProcess()->FastShutdownStarted())
2658 aura::Window* root_window = window_->GetRootWindow();
2662 if (ShouldSkipCursorUpdate())
2665 display::Screen* screen = display::Screen::GetScreen();
2667 gfx::Point root_window_point = screen->GetCursorScreenPoint();
2668 aura::client::ScreenPositionClient* screen_position_client =
2669 aura::client::GetScreenPositionClient(root_window);
2670 if (screen_position_client) {
2671 screen_position_client->ConvertPointFromScreen(
2672 root_window, &root_window_point);
2675 if (root_window->GetEventHandlerForPoint(root_window_point) != window_)
2678 gfx::NativeCursor cursor = current_cursor_.GetNativeCursor();
2679 // Do not show loading cursor when the cursor is currently hidden.
2680 if (is_loading_ && cursor != ui::mojom::CursorType::kNone)
2681 cursor = ui::Cursor(ui::mojom::CursorType::kPointer);
2683 aura::client::CursorClient* cursor_client =
2684 aura::client::GetCursorClient(root_window);
2685 if (cursor_client) {
2686 cursor_client->SetCursor(cursor);
2690 bool RenderWidgetHostViewAura::SynchronizeVisualProperties(
2691 const cc::DeadlinePolicy& deadline_policy,
2692 const absl::optional<viz::LocalSurfaceId>& child_local_surface_id) {
2694 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2696 window_->UpdateLocalSurfaceIdFromEmbeddedClient(child_local_surface_id);
2697 // If the viz::LocalSurfaceId is invalid, we may have been evicted,
2698 // allocate a new one to establish bounds.
2699 if (!GetLocalSurfaceId().is_valid())
2700 window_->AllocateLocalSurfaceId();
2702 delegated_frame_host_->EmbedSurface(
2703 GetLocalSurfaceId(), window_->bounds().size(), deadline_policy);
2705 return host()->SynchronizeVisualProperties();
2708 void RenderWidgetHostViewAura::OnDidUpdateVisualPropertiesComplete(
2709 const cc::RenderFrameMetadata& metadata) {
2712 if (host()->delegate()) {
2713 host()->delegate()->SetTopControlsShownRatio(
2714 host(), metadata.top_controls_shown_ratio);
2717 if (host()->is_hidden()) {
2718 // When an embedded child responds, we want to accept its changes to the
2719 // viz::LocalSurfaceId. However we do not want to embed surfaces while
2720 // hidden. Nor do we want to embed invalid ids when we are evicted. Becoming
2721 // visible will generate a new id, if necessary, and begin embedding.
2722 window_->UpdateLocalSurfaceIdFromEmbeddedClient(metadata.local_surface_id);
2724 SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
2725 metadata.local_surface_id);
2729 ui::InputMethod* RenderWidgetHostViewAura::GetInputMethod() const {
2732 aura::Window* root_window = window_->GetRootWindow();
2735 return root_window->GetHost()->GetInputMethod();
2738 RenderWidgetHostViewBase*
2739 RenderWidgetHostViewAura::GetFocusedViewForTextSelection() const {
2740 // We obtain the TextSelection from focused RWH which is obtained from the
2742 return GetFocusedWidget() ? GetFocusedWidget()->GetView() : nullptr;
2745 void RenderWidgetHostViewAura::Shutdown() {
2746 if (!in_shutdown_) {
2747 in_shutdown_ = true;
2748 host()->ShutdownAndDestroyWidget(true);
2752 ui::mojom::VirtualKeyboardMode
2753 RenderWidgetHostViewAura::GetVirtualKeyboardMode() {
2754 // overlaycontent flag can only be set from main frame.
2755 RenderFrameHostImpl* frame = host()->frame_tree()->GetMainFrame();
2757 return ui::mojom::VirtualKeyboardMode::kUnset;
2759 return frame->GetPage().virtual_keyboard_mode();
2762 void RenderWidgetHostViewAura::NotifyVirtualKeyboardOverlayRect(
2763 const gfx::Rect& keyboard_rect) {
2764 // geometrychange event can only be fired on main frame and not focused frame
2765 // which could be an iframe.
2766 RenderFrameHostImpl* frame = host()->frame_tree()->GetMainFrame();
2770 if (GetVirtualKeyboardMode() !=
2771 ui::mojom::VirtualKeyboardMode::kOverlaysContent) {
2774 gfx::Rect keyboard_root_relative_rect = keyboard_rect;
2775 if (!keyboard_root_relative_rect.IsEmpty()) {
2776 // If the rect is non-empty, we need to transform it to be widget-relative
2777 // window (DIP coordinates). The input is client coordinates for the root
2779 // Transform the widget rect origin to root relative coords.
2780 gfx::PointF root_widget_origin(0.f, 0.f);
2781 TransformPointToRootSurface(&root_widget_origin);
2782 gfx::Rect root_widget_rect =
2783 gfx::Rect(root_widget_origin.x(), root_widget_origin.y(),
2784 GetViewBounds().width(), GetViewBounds().height());
2785 // Intersect the keyboard rect with the root widget bounds and transform
2786 // back to widget-relative coordinates, which will be sent to the renderer.
2787 keyboard_root_relative_rect.Intersect(root_widget_rect);
2788 keyboard_root_relative_rect.Offset(-root_widget_origin.x(),
2789 -root_widget_origin.y());
2791 frame->GetPage().NotifyVirtualKeyboardOverlayRect(
2792 keyboard_root_relative_rect);
2795 bool RenderWidgetHostViewAura::IsHTMLFormPopup() const {
2796 return !!popup_parent_host_view_;
2799 bool RenderWidgetHostViewAura::FocusedFrameHasStickyActivation() const {
2800 // Unless user has interacted with the iframe, we shouldn't be displaying VK
2801 // or fire geometrychange event.
2802 RenderFrameHostImpl* frame = GetFocusedFrame();
2806 return frame->frame_tree_node()->HasStickyUserActivation();
2809 TouchSelectionControllerClientManager*
2810 RenderWidgetHostViewAura::GetTouchSelectionControllerClientManager() {
2811 return selection_controller_client_.get();
2814 bool RenderWidgetHostViewAura::NeedsInputGrab() {
2815 return widget_type_ == WidgetType::kPopup;
2818 bool RenderWidgetHostViewAura::NeedsMouseCapture() {
2819 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
2820 return NeedsInputGrab();
2826 void RenderWidgetHostViewAura::SetTooltipsEnabled(bool enable) {
2828 tooltip_disabler_.reset();
2831 std::make_unique<wm::ScopedTooltipDisabler>(window_->GetRootWindow());
2835 void RenderWidgetHostViewAura::NotifyRendererOfCursorVisibilityState(
2837 if (host()->is_hidden() ||
2838 (cursor_visibility_state_in_renderer_ == VISIBLE && is_visible) ||
2839 (cursor_visibility_state_in_renderer_ == NOT_VISIBLE && !is_visible))
2842 cursor_visibility_state_in_renderer_ = is_visible ? VISIBLE : NOT_VISIBLE;
2843 host()->OnCursorVisibilityStateChanged(is_visible);
2846 void RenderWidgetHostViewAura::SetOverscrollControllerEnabled(bool enabled) {
2848 overscroll_controller_.reset();
2849 else if (!overscroll_controller_)
2850 overscroll_controller_ = std::make_unique<OverscrollController>();
2853 void RenderWidgetHostViewAura::SetSelectionControllerClientForTest(
2854 std::unique_ptr<TouchSelectionControllerClientAura> client) {
2855 selection_controller_client_.swap(client);
2856 CreateSelectionController();
2859 void RenderWidgetHostViewAura::InternalSetBounds(const gfx::Rect& rect) {
2860 // Don't recursively call SetBounds if this bounds update is the result of
2861 // a Window::SetBoundsInternal call.
2862 if (!in_bounds_changed_) {
2863 LOG(INFO) << "set bounds for aura " << rect.ToString();
2864 window_->SetBounds(rect);
2867 if (!viewport_segments_.empty()) {
2868 // The view bounds have changed so if we have viewport segments from the
2869 // platform we need to make sure display_feature_ is updated considering the
2871 ComputeDisplayFeature();
2874 // Even if not showing yet, we need to synchronize on size. As the renderer
2875 // needs to begin layout. Waiting until we show to start layout leads to
2876 // significant delays in embedding the first shown surface (500+ ms.)
2877 SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
2878 window_->GetLocalSurfaceId());
2880 #if BUILDFLAG(IS_WIN)
2883 if (IsMouseLocked())
2884 UpdateMouseLockRegion();
2888 void RenderWidgetHostViewAura::UpdateInsetsWithVirtualKeyboardEnabled() {
2889 // Update insets if the keyboard is shown.
2890 if (!keyboard_occluded_bounds_.IsEmpty()) {
2891 SetInsets(gfx::Insets::TLBR(
2893 gfx::IntersectRects(GetViewBounds(), keyboard_occluded_bounds_)
2899 #if BUILDFLAG(IS_WIN)
2900 void RenderWidgetHostViewAura::UpdateLegacyWin() {
2901 if (legacy_window_destroyed_ || !GetHostWindowHWND())
2904 if (!legacy_render_widget_host_HWND_) {
2905 legacy_render_widget_host_HWND_ =
2906 LegacyRenderWidgetHostHWND::Create(GetHostWindowHWND(), this);
2909 if (legacy_render_widget_host_HWND_) {
2910 legacy_render_widget_host_HWND_->UpdateParent(GetHostWindowHWND());
2911 legacy_render_widget_host_HWND_->SetBounds(
2912 window_->GetBoundsInRootWindow());
2913 // There are cases where the parent window is created, made visible and
2914 // the associated RenderWidget is also visible before the
2915 // LegacyRenderWidgetHostHWND instace is created. Ensure that it is shown
2917 if (!host()->is_hidden())
2918 legacy_render_widget_host_HWND_->Show();
2923 void RenderWidgetHostViewAura::AddedToRootWindow() {
2924 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2926 #if BUILDFLAG(IS_EFL)
2927 efl_helper_->AuraChildWindowAdded();
2930 window_->GetHost()->AddObserver(this);
2933 aura::client::CursorClient* cursor_client =
2934 aura::client::GetCursorClient(window_->GetRootWindow());
2935 if (cursor_client) {
2936 cursor_client->AddObserver(this);
2937 NotifyRendererOfCursorVisibilityState(cursor_client->IsCursorVisible());
2940 ui::InputMethod* input_method = GetInputMethod();
2942 input_method->SetFocusedTextInputClient(this);
2945 #if BUILDFLAG(IS_WIN)
2949 delegated_frame_host_->AttachToCompositor(GetCompositor());
2952 void RenderWidgetHostViewAura::RemovingFromRootWindow() {
2953 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2955 aura::client::CursorClient* cursor_client =
2956 aura::client::GetCursorClient(window_->GetRootWindow());
2958 cursor_client->RemoveObserver(this);
2960 DetachFromInputMethod(true);
2962 window_->GetHost()->RemoveObserver(this);
2963 delegated_frame_host_->DetachFromCompositor();
2965 #if BUILDFLAG(IS_WIN)
2966 // Update the legacy window's parent temporarily to the hidden window. It
2967 // will eventually get reparented to the right root.
2968 if (legacy_render_widget_host_HWND_)
2969 legacy_render_widget_host_HWND_->UpdateParent(ui::GetHiddenWindow());
2973 void RenderWidgetHostViewAura::DetachFromInputMethod(bool is_removed) {
2974 ui::InputMethod* input_method = GetInputMethod();
2976 input_method->DetachTextInputClient(this);
2977 #if BUILDFLAG(IS_CHROMEOS_ASH)
2978 wm::RestoreWindowBoundsOnClientFocusLost(window_->GetToplevelWindow());
2979 #endif // BUILDFLAG(IS_CHROMEOS_ASH)
2982 #if BUILDFLAG(IS_WIN)
2983 // If window is getting destroyed, then reset the VK controller, else,
2984 // dismiss the VK and notify about the keyboard inset since window has lost
2986 if (virtual_keyboard_controller_win_) {
2988 virtual_keyboard_controller_win_.reset();
2990 virtual_keyboard_controller_win_->HideAndNotifyKeyboardInset();
2992 #endif // BUILDFLAG(IS_WIN)
2995 void RenderWidgetHostViewAura::ForwardKeyboardEventWithLatencyInfo(
2996 const NativeWebKeyboardEvent& event,
2997 const ui::LatencyInfo& latency,
2998 bool* update_event) {
2999 RenderWidgetHostImpl* target_host = host();
3001 // If there are multiple widgets on the page (such as when there are
3002 // out-of-process iframes), pick the one that should process this event.
3003 if (host()->delegate())
3004 target_host = host()->delegate()->GetFocusedRenderWidgetHost(host());
3008 #if BUILDFLAG(IS_LINUX)
3009 auto* linux_ui = ui::LinuxUi::instance();
3010 std::vector<ui::TextEditCommandAuraLinux> commands;
3011 if (!event.skip_if_unhandled && linux_ui && event.os_event &&
3012 linux_ui->GetTextEditCommandsForEvent(
3014 base::FeatureList::IsEnabled(
3015 blink::features::kArrowKeysInVerticalWritingModes)
3016 ? GetTextInputFlags()
3017 : ui::TEXT_INPUT_FLAG_NONE,
3019 // Transform from ui/ types to content/ types.
3020 std::vector<blink::mojom::EditCommandPtr> edit_commands;
3021 for (std::vector<ui::TextEditCommandAuraLinux>::const_iterator it =
3022 commands.begin(); it != commands.end(); ++it) {
3023 edit_commands.push_back(blink::mojom::EditCommand::New(
3024 it->GetCommandString(), it->argument()));
3027 target_host->ForwardKeyboardEventWithCommands(
3028 event, latency, std::move(edit_commands), update_event);
3033 target_host->ForwardKeyboardEventWithCommands(
3034 event, latency, std::vector<blink::mojom::EditCommandPtr>(),
3038 void RenderWidgetHostViewAura::CreateSelectionController() {
3039 ui::TouchSelectionController::Config tsc_config;
3040 tsc_config.max_tap_duration = base::Milliseconds(
3041 ui::GestureConfiguration::GetInstance()->long_press_time_in_ms());
3042 tsc_config.tap_slop = ui::GestureConfiguration::GetInstance()
3043 ->max_touch_move_in_pixels_for_click();
3044 tsc_config.enable_longpress_drag_selection =
3045 features::IsTouchTextEditingRedesignEnabled();
3046 selection_controller_ = std::make_unique<ui::TouchSelectionController>(
3047 selection_controller_client_.get(), tsc_config);
3050 void RenderWidgetHostViewAura::DidNavigateMainFramePreCommit() {
3051 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
3053 // Invalidate the surface so that we don't attempt to evict it multiple times.
3054 window_->InvalidateLocalSurfaceId();
3055 delegated_frame_host_->DidNavigateMainFramePreCommit();
3056 CancelActiveTouches();
3059 void RenderWidgetHostViewAura::DidEnterBackForwardCache() {
3060 CHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
3062 window_->AllocateLocalSurfaceId();
3063 delegated_frame_host_->DidEnterBackForwardCache();
3064 // If we have the fallback content timer running, force it to stop. Else, when
3065 // the page is restored the timer could also fire, setting whatever
3066 // `DelegatedFrameHost::first_local_surface_id_after_navigation_` as the
3067 // fallback to our Surfacelayer.
3069 // This is safe for BFCache restore because we will supply specific fallback
3070 // surfaces for BFCache.
3072 // We do not want to call this in `RWHImpl::WasHidden()` because in the case
3073 // of `Visibility::OCCLUDED` we still want to keep the timer running.
3075 // Called after to prevent prematurely evict the BFCached surface.
3076 host()->ForceFirstFrameAfterNavigationTimeout();
3079 const viz::FrameSinkId& RenderWidgetHostViewAura::GetFrameSinkId() const {
3080 return frame_sink_id_;
3083 const viz::LocalSurfaceId& RenderWidgetHostViewAura::GetLocalSurfaceId() const {
3084 return window_->GetLocalSurfaceId();
3087 void RenderWidgetHostViewAura::OnUpdateTextInputStateCalled(
3088 TextInputManager* text_input_manager,
3089 RenderWidgetHostViewBase* updated_view,
3090 bool did_update_state) {
3091 DCHECK_EQ(text_input_manager_, text_input_manager);
3093 if (!GetInputMethod())
3096 if (did_update_state)
3097 GetInputMethod()->OnTextInputTypeChanged(this);
3099 const ui::mojom::TextInputState* state =
3100 text_input_manager_->GetTextInputState();
3102 #if BUILDFLAG(IS_CHROMEOS)
3103 if (state && state->type != ui::TEXT_INPUT_TYPE_NONE) {
3104 if (state->last_vk_visibility_request ==
3105 ui::mojom::VirtualKeyboardVisibilityRequest::SHOW) {
3106 GetInputMethod()->SetVirtualKeyboardVisibilityIfEnabled(true);
3107 } else if (state->last_vk_visibility_request ==
3108 ui::mojom::VirtualKeyboardVisibilityRequest::HIDE) {
3109 GetInputMethod()->SetVirtualKeyboardVisibilityIfEnabled(false);
3114 // Show the virtual keyboard if needed.
3115 if (state && state->type != ui::TEXT_INPUT_TYPE_NONE &&
3116 state->mode != ui::TEXT_INPUT_MODE_NONE) {
3117 #if !BUILDFLAG(IS_WIN)
3118 if (state->show_ime_if_needed &&
3119 GetInputMethod()->GetTextInputClient() == this) {
3120 GetInputMethod()->SetVirtualKeyboardVisibilityIfEnabled(true);
3122 // TODO(crbug.com/1031786): Remove this once TSF fix for input pane policy
3124 #elif BUILDFLAG(IS_WIN)
3125 if (GetInputMethod()) {
3126 if (!virtual_keyboard_controller_win_) {
3127 virtual_keyboard_controller_win_ =
3128 std::make_unique<VirtualKeyboardControllerWin>(this,
3131 virtual_keyboard_controller_win_->UpdateTextInputState(state);
3136 // Ensure that selection bounds changes are sent to the IME.
3137 if (state && state->type != ui::TEXT_INPUT_TYPE_NONE) {
3138 text_input_manager->NotifySelectionBoundsChanged(updated_view);
3141 if (auto* render_widget_host = updated_view->host()) {
3142 // Monitor the composition information if there is a focused editable node.
3143 render_widget_host->RequestCompositionUpdates(
3144 false /* immediate_request */,
3146 (state->type != ui::TEXT_INPUT_TYPE_NONE) /* monitor_updates */);
3150 void RenderWidgetHostViewAura::OnImeCancelComposition(
3151 TextInputManager* text_input_manager,
3152 RenderWidgetHostViewBase* view) {
3153 // |view| is not necessarily the one corresponding to
3154 // TextInputManager::GetActiveWidget() as RenderWidgetHostViewAura can call
3155 // this method to finish any ongoing composition in response to a mouse down
3157 if (GetInputMethod())
3158 GetInputMethod()->CancelComposition(this);
3159 has_composition_text_ = false;
3162 void RenderWidgetHostViewAura::OnSelectionBoundsChanged(
3163 TextInputManager* text_input_manager,
3164 RenderWidgetHostViewBase* updated_view) {
3165 // Note: accessibility caret move events are no longer fired directly here,
3166 // because they were redundant with the events fired by the top level window
3167 // by HWNDMessageHandler::OnCaretBoundsChanged().
3168 if (GetInputMethod())
3169 GetInputMethod()->OnCaretBoundsChanged(this);
3172 void RenderWidgetHostViewAura::OnTextSelectionChanged(
3173 TextInputManager* text_input_manager,
3174 RenderWidgetHostViewBase* updated_view) {
3175 if (!GetTextInputManager())
3178 // We obtain the TextSelection from focused RWH which is obtained from the
3180 RenderWidgetHostViewBase* focused_view =
3181 GetFocusedWidget() ? GetFocusedWidget()->GetView() : nullptr;
3186 // IMF relies on the |OnCaretBoundsChanged| for the surrounding text changed
3187 // events to IME. Explicitly call |OnCaretBoundsChanged| here so that IMF can
3188 // know about the surrounding text changes when the caret bounds are not
3189 // changed. e.g. When the rendered text is wider than the input field,
3190 // deleting the last character won't change the caret bounds but will change
3191 // the surrounding text.
3192 if (GetInputMethod())
3193 GetInputMethod()->OnCaretBoundsChanged(this);
3195 if (ui::Clipboard::IsSupportedClipboardBuffer(
3196 ui::ClipboardBuffer::kSelection)) {
3197 const TextInputManager::TextSelection* selection =
3198 GetTextInputManager()->GetTextSelection(focused_view);
3199 if (selection->selected_text().length()) {
3200 // Set the ClipboardBuffer::kSelection to the ui::Clipboard.
3201 ui::ScopedClipboardWriter clipboard_writer(
3202 ui::ClipboardBuffer::kSelection);
3203 clipboard_writer.WriteText(selection->selected_text());
3208 void RenderWidgetHostViewAura::SetPopupChild(
3209 RenderWidgetHostViewAura* popup_child_host_view) {
3210 popup_child_host_view_ = popup_child_host_view;
3211 event_handler_->SetPopupChild(
3212 popup_child_host_view,
3213 popup_child_host_view ? popup_child_host_view->event_handler() : nullptr);
3216 void RenderWidgetHostViewAura::ScrollFocusedEditableNodeIntoView() {
3217 auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
3220 input_handler->ScrollFocusedEditableNodeIntoView();
3223 void RenderWidgetHostViewAura::OnSynchronizedDisplayPropertiesChanged(
3225 SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
3229 viz::ScopedSurfaceIdAllocator
3230 RenderWidgetHostViewAura::DidUpdateVisualProperties(
3231 const cc::RenderFrameMetadata& metadata) {
3232 base::OnceCallback<void()> allocation_task = base::BindOnce(
3233 &RenderWidgetHostViewAura::OnDidUpdateVisualPropertiesComplete,
3234 weak_ptr_factory_.GetWeakPtr(), metadata);
3235 return window_->GetSurfaceIdAllocator(std::move(allocation_task));
3238 void RenderWidgetHostViewAura::DidNavigate() {
3239 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
3242 // Navigating while hidden should not allocate a new LocalSurfaceID. Once
3243 // sizes are ready, or we begin to Show, we can then allocate the new
3245 window_->InvalidateLocalSurfaceId();
3247 if (is_first_navigation_) {
3248 // The first navigation does not need a new LocalSurfaceID. The renderer
3249 // can use the ID that was already provided.
3250 SynchronizeVisualProperties(cc::DeadlinePolicy::UseExistingDeadline(),
3251 window_->GetLocalSurfaceId());
3253 SynchronizeVisualProperties(cc::DeadlinePolicy::UseExistingDeadline(),
3257 delegated_frame_host_->DidNavigate();
3258 is_first_navigation_ = false;
3261 MouseWheelPhaseHandler* RenderWidgetHostViewAura::GetMouseWheelPhaseHandler() {
3262 return &event_handler_->mouse_wheel_phase_handler();
3265 void RenderWidgetHostViewAura::TakeFallbackContentFrom(
3266 RenderWidgetHostView* view) {
3267 DCHECK(!static_cast<RenderWidgetHostViewBase*>(view)
3268 ->IsRenderWidgetHostViewChildFrame());
3269 RenderWidgetHostViewAura* view_aura =
3270 static_cast<RenderWidgetHostViewAura*>(view);
3271 CopyBackgroundColorIfPresentFrom(*view);
3273 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
3274 DCHECK(view_aura->delegated_frame_host_);
3275 delegated_frame_host_->TakeFallbackContentFrom(
3276 view_aura->delegated_frame_host_.get());
3279 bool RenderWidgetHostViewAura::CanSynchronizeVisualProperties() {
3280 return !needs_to_update_display_metrics_;
3283 std::vector<std::unique_ptr<ui::TouchEvent>>
3284 RenderWidgetHostViewAura::ExtractAndCancelActiveTouches() {
3285 aura::Env* env = aura::Env::GetInstance();
3286 std::vector<std::unique_ptr<ui::TouchEvent>> touches =
3287 env->gesture_recognizer()->ExtractTouches(window());
3288 CancelActiveTouches();
3292 void RenderWidgetHostViewAura::TransferTouches(
3293 const std::vector<std::unique_ptr<ui::TouchEvent>>& touches) {
3294 aura::Env* env = aura::Env::GetInstance();
3295 env->gesture_recognizer()->TransferTouches(window(), touches);
3298 void RenderWidgetHostViewAura::SetLastPointerType(
3299 ui::EventPointerType last_pointer_type) {
3300 last_pointer_type_ = last_pointer_type;
3303 void RenderWidgetHostViewAura::InvalidateLocalSurfaceIdAndAllocationGroup() {
3304 window_->InvalidateLocalSurfaceId(/*also_invalidate_allocation_group=*/true);
3307 void RenderWidgetHostViewAura::InvalidateLocalSurfaceIdOnEviction() {
3308 window_->InvalidateLocalSurfaceId();
3311 void RenderWidgetHostViewAura::ProcessDisplayMetricsChanged() {
3312 // TODO(crbug.com/1169291): Unify per-platform DisplayObserver instances.
3313 needs_to_update_display_metrics_ = false;
3315 current_cursor_.SetDisplayInfo(
3316 display::Screen::GetScreen()->GetDisplayNearestWindow(window_));
3317 UpdateCursorIfOverSelf();
3320 void RenderWidgetHostViewAura::CancelActiveTouches() {
3321 aura::Env* env = aura::Env::GetInstance();
3322 env->gesture_recognizer()->CancelActiveTouches(window());
3325 blink::mojom::FrameWidgetInputHandler*
3326 RenderWidgetHostViewAura::GetFrameWidgetInputHandlerForFocusedWidget() {
3327 auto* focused_widget = GetFocusedWidget();
3328 if (!focused_widget)
3330 return focused_widget->GetFrameWidgetInputHandler();
3333 void RenderWidgetHostViewAura::SetTooltipText(
3334 const std::u16string& tooltip_text) {
3335 tooltip_ = tooltip_text;
3336 if (tooltip_observer_for_testing_)
3337 tooltip_observer_for_testing_->OnTooltipTextUpdated(tooltip_text);
3340 ui::Compositor* RenderWidgetHostViewAura::GetCompositor() {
3341 if (!window_ || !window_->GetHost())
3344 return window_->GetHost()->compositor();
3347 } // namespace content