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 using gfx::RectToSkIRect;
149 using gfx::SkIRectToRect;
151 using blink::WebInputEvent;
152 using blink::WebGestureEvent;
153 using blink::WebTouchEvent;
157 // We need to watch for mouse events outside a Web Popup or its parent
158 // and dismiss the popup for certain events.
159 class RenderWidgetHostViewAura::EventObserverForPopupExit
160 : public ui::EventObserver {
162 explicit EventObserverForPopupExit(RenderWidgetHostViewAura* rwhva)
164 aura::Env* env = aura::Env::GetInstance();
165 env->AddEventObserver(this, env,
166 {ui::ET_MOUSE_PRESSED, ui::ET_TOUCH_PRESSED});
169 EventObserverForPopupExit(const EventObserverForPopupExit&) = delete;
170 EventObserverForPopupExit& operator=(const EventObserverForPopupExit&) =
173 ~EventObserverForPopupExit() override {
174 aura::Env::GetInstance()->RemoveEventObserver(this);
177 // ui::EventObserver:
178 void OnEvent(const ui::Event& event) override {
179 rwhva_->ApplyEventObserverForPopupExit(*event.AsLocatedEvent());
183 raw_ptr<RenderWidgetHostViewAura> rwhva_;
186 void RenderWidgetHostViewAura::ApplyEventObserverForPopupExit(
187 const ui::LocatedEvent& event) {
188 DCHECK(event.type() == ui::ET_MOUSE_PRESSED ||
189 event.type() == ui::ET_TOUCH_PRESSED);
194 // |target| may be null.
195 aura::Window* target = static_cast<aura::Window*>(event.target());
196 if (target != window_ &&
197 (!popup_parent_host_view_ ||
198 target != popup_parent_host_view_->window_)) {
199 // If we enter this code path it means that we did not receive any focus
200 // lost notifications for the popup window. Ensure that blink is aware
201 // of the fact that focus was lost for the host window by sending a Blur
202 // notification. We also set a flag in the view indicating that we need
203 // to force a Focus notification on the next mouse down.
204 if (popup_parent_host_view_ && popup_parent_host_view_->host()) {
205 popup_parent_host_view_->event_handler()
206 ->set_focus_on_mouse_down_or_key_event(true);
207 popup_parent_host_view_->host()->Blur();
209 // Note: popup_parent_host_view_ may be NULL when there are multiple
210 // popup children per view. See: RenderWidgetHostViewAura::InitAsPopup().
215 // We have to implement the WindowObserver interface on a separate object
216 // because clang doesn't like implementing multiple interfaces that have
217 // methods with the same name. This object is owned by the
218 // RenderWidgetHostViewAura.
219 class RenderWidgetHostViewAura::WindowObserver : public aura::WindowObserver {
221 explicit WindowObserver(RenderWidgetHostViewAura* view)
223 view_->window_->AddObserver(this);
226 WindowObserver(const WindowObserver&) = delete;
227 WindowObserver& operator=(const WindowObserver&) = delete;
229 ~WindowObserver() override { view_->window_->RemoveObserver(this); }
231 // Overridden from aura::WindowObserver:
232 void OnWindowAddedToRootWindow(aura::Window* window) override {
233 if (window == view_->window_)
234 view_->AddedToRootWindow();
237 void OnWindowRemovingFromRootWindow(aura::Window* window,
238 aura::Window* new_root) override {
239 if (window == view_->window_)
240 view_->RemovingFromRootWindow();
243 void OnWindowHierarchyChanged(const HierarchyChangeParams& params) override {
244 view_->ParentHierarchyChanged();
247 void OnWindowTitleChanged(aura::Window* window) override {
248 if (window == view_->window_)
249 view_->WindowTitleChanged();
253 raw_ptr<RenderWidgetHostViewAura> view_;
256 ////////////////////////////////////////////////////////////////////////////////
257 // RenderWidgetHostViewAura, public:
259 RenderWidgetHostViewAura::RenderWidgetHostViewAura(
260 RenderWidgetHost* widget_host,
261 WebContents& web_contents)
262 : RenderWidgetHostViewBase(widget_host),
265 in_bounds_changed_(false),
266 popup_parent_host_view_(nullptr),
267 popup_child_host_view_(nullptr),
269 has_composition_text_(false),
270 added_frame_observer_(false),
271 cursor_visibility_state_in_renderer_(UNKNOWN),
272 #if BUILDFLAG(IS_WIN)
273 legacy_render_widget_host_HWND_(nullptr),
274 legacy_window_destroyed_(false),
276 device_scale_factor_(0.0f),
277 event_handler_(new RenderWidgetHostViewEventHandler(host(), this, this)),
278 frame_sink_id_(host()->GetFrameSinkId()),
279 visibility_(host()->is_hidden() ? Visibility::HIDDEN
280 : Visibility::VISIBLE) {
281 // CreateDelegatedFrameHostClient() and CreateAuraWindow() assume that the
282 // FrameSinkId is valid. RenderWidgetHostImpl::GetFrameSinkId() always returns
283 // a valid FrameSinkId.
284 DCHECK(frame_sink_id_.is_valid());
286 CreateDelegatedFrameHostClient();
288 host()->SetView(this);
290 // We should start observing the TextInputManager for IME-related events as
291 // well as monitoring its lifetime.
292 if (GetTextInputManager())
293 GetTextInputManager()->AddObserver(this);
295 cursor_manager_ = std::make_unique<CursorManager>(this);
297 selection_controller_client_ =
298 std::make_unique<TouchSelectionControllerClientAura>(this);
299 CreateSelectionController();
301 RenderWidgetHostOwnerDelegate* owner_delegate = host()->owner_delegate();
302 if (owner_delegate) {
303 // NOTE: This will not be run for child frame widgets, which do not have
304 // an owner delegate and won't get a RenderViewHost here.
305 double_tap_to_zoom_enabled_ =
306 owner_delegate->GetWebkitPreferencesForWidget()
307 .double_tap_to_zoom_enabled;
310 host()->render_frame_metadata_provider()->AddObserver(this);
312 #if BUILDFLAG(IS_EFL)
314 base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableOffscreenRendering)
315 ? std::make_unique<RWHVAuraOffscreenHelperEfl>(this, &web_contents)
316 : std::make_unique<RWHVAuraCommonHelperEfl>(this, &web_contents);
320 ////////////////////////////////////////////////////////////////////////////////
321 // RenderWidgetHostViewAura, RenderWidgetHostView implementation:
323 void RenderWidgetHostViewAura::InitAsChild(gfx::NativeView parent_view) {
324 DCHECK_EQ(widget_type_, WidgetType::kFrame);
325 CreateAuraWindow(aura::client::WINDOW_TYPE_CONTROL);
328 parent_view->AddChild(GetNativeView());
330 #if BUILDFLAG(IS_EFL)
331 efl_helper_->SetAuraParentWindow(parent_view);
334 device_scale_factor_ = GetDeviceScaleFactor();
336 aura::Window* root = window_->GetRootWindow();
338 auto* cursor_client = aura::client::GetCursorClient(root);
340 UpdateSystemCursorSize(cursor_client->GetSystemCursorSize());
343 #if BUILDFLAG(IS_WIN)
344 // This will fetch and set the display features.
345 EnsureDevicePostureServiceConnection();
349 void RenderWidgetHostViewAura::InitAsPopup(
350 RenderWidgetHostView* parent_host_view,
351 const gfx::Rect& bounds_in_screen,
352 const gfx::Rect& anchor_rect) {
353 DCHECK_EQ(widget_type_, WidgetType::kPopup);
354 DCHECK(!static_cast<RenderWidgetHostViewBase*>(parent_host_view)
355 ->IsRenderWidgetHostViewChildFrame());
357 popup_parent_host_view_ =
358 static_cast<RenderWidgetHostViewAura*>(parent_host_view);
360 // TransientWindowClient may be NULL during tests.
361 aura::client::TransientWindowClient* transient_window_client =
362 aura::client::GetTransientWindowClient();
363 RenderWidgetHostViewAura* old_child =
364 popup_parent_host_view_->popup_child_host_view_;
366 // TODO(jhorwich): Allow multiple popup_child_host_view_ per view, or
367 // similar mechanism to ensure a second popup doesn't cause the first one
368 // to never get a chance to filter events. See crbug.com/160589.
369 DCHECK(old_child->popup_parent_host_view_ == popup_parent_host_view_);
370 if (transient_window_client) {
371 transient_window_client->RemoveTransientChild(
372 popup_parent_host_view_->window_, old_child->window_);
374 old_child->popup_parent_host_view_ = nullptr;
376 popup_parent_host_view_->SetPopupChild(this);
377 CreateAuraWindow(aura::client::WINDOW_TYPE_MENU);
378 // Use transparent background color for the popup in order to avoid flashing
379 // the white background on popup open when dark color-scheme is used.
380 SetContentBackgroundColor(SK_ColorTRANSPARENT);
382 // Setting the transient child allows for the popup to get mouse events when
383 // in a system modal dialog. Do this before calling ParentWindowWithContext
384 // below so that the transient parent is visible to WindowTreeClient.
385 // This fixes crbug.com/328593.
386 if (transient_window_client) {
387 transient_window_client->AddTransientChild(
388 popup_parent_host_view_->window_, window_);
391 ui::OwnedWindowAnchor owned_window_anchor = {
392 anchor_rect, ui::OwnedWindowAnchorPosition::kBottomLeft,
393 ui::OwnedWindowAnchorGravity::kBottomRight,
394 ui::OwnedWindowConstraintAdjustment::kAdjustmentFlipY};
395 window_->SetProperty(aura::client::kOwnedWindowAnchor, owned_window_anchor);
397 aura::Window* root = popup_parent_host_view_->window_->GetRootWindow();
398 aura::client::ParentWindowWithContext(window_, root, bounds_in_screen,
399 display::kInvalidDisplayId);
401 SetBounds(bounds_in_screen);
403 if (NeedsMouseCapture())
404 window_->SetCapture();
406 event_observer_for_popup_exit_ =
407 std::make_unique<EventObserverForPopupExit>(this);
409 device_scale_factor_ = GetDeviceScaleFactor();
411 // If HiDPI capture mode is active for the parent, propagate the scale
412 // override to the popup window also. Its content was created assuming
413 // that the new window will share the parent window's scale. See
414 // https://crbug.com/1354703 .
415 SetScaleOverrideForCapture(
416 popup_parent_host_view_->GetScaleOverrideForCapture());
418 auto* cursor_client = aura::client::GetCursorClient(root);
420 UpdateSystemCursorSize(cursor_client->GetSystemCursorSize());
422 #if BUILDFLAG(IS_WIN)
423 // This will fetch and set the display features.
424 EnsureDevicePostureServiceConnection();
428 void RenderWidgetHostViewAura::Hide() {
430 visibility_ = Visibility::HIDDEN;
434 void RenderWidgetHostViewAura::SetSize(const gfx::Size& size) {
435 // For a SetSize operation, we don't care what coordinate system the origin
436 // of the window is in, it's only important to make sure that the origin
437 // remains constant after the operation.
438 InternalSetBounds(gfx::Rect(window_->bounds().origin(), size));
441 void RenderWidgetHostViewAura::SetBounds(const gfx::Rect& rect) {
442 gfx::Point relative_origin(rect.origin());
444 // RenderWidgetHostViewAura::SetBounds() takes screen coordinates, but
445 // Window::SetBounds() takes parent coordinates, so do the conversion here.
446 aura::Window* root = window_->GetRootWindow();
448 aura::client::ScreenPositionClient* screen_position_client =
449 aura::client::GetScreenPositionClient(root);
450 if (screen_position_client) {
451 screen_position_client->ConvertPointFromScreen(window_->parent(),
456 InternalSetBounds(gfx::Rect(relative_origin, rect.size()));
459 gfx::NativeView RenderWidgetHostViewAura::GetNativeView() {
463 #if BUILDFLAG(IS_WIN)
464 HWND RenderWidgetHostViewAura::GetHostWindowHWND() const {
465 aura::WindowTreeHost* host = window_->GetHost();
466 return host ? host->GetAcceleratedWidget() : nullptr;
470 gfx::NativeViewAccessible RenderWidgetHostViewAura::GetNativeViewAccessible() {
471 #if BUILDFLAG(IS_WIN)
472 aura::WindowTreeHost* window_host = window_->GetHost();
474 return static_cast<gfx::NativeViewAccessible>(NULL);
476 BrowserAccessibilityManager* manager =
477 host()->GetOrCreateRootBrowserAccessibilityManager();
479 return ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot())
482 #elif BUILDFLAG(IS_LINUX)
483 BrowserAccessibilityManager* manager =
484 host()->GetOrCreateRootBrowserAccessibilityManager();
485 if (manager && manager->GetBrowserAccessibilityRoot())
486 return manager->GetBrowserAccessibilityRoot()->GetNativeViewAccessible();
489 NOTIMPLEMENTED_LOG_ONCE();
490 return static_cast<gfx::NativeViewAccessible>(nullptr);
493 ui::TextInputClient* RenderWidgetHostViewAura::GetTextInputClient() {
497 RenderFrameHostImpl* RenderWidgetHostViewAura::GetFocusedFrame() const {
498 FrameTreeNode* focused_frame = host()->frame_tree()->GetFocusedFrame();
501 return focused_frame->current_frame_host();
504 void RenderWidgetHostViewAura::HandleBoundsInRootChanged() {
505 #if BUILDFLAG(IS_WIN)
506 if (legacy_render_widget_host_HWND_) {
507 legacy_render_widget_host_HWND_->SetBounds(
508 window_->GetBoundsInRootWindow());
512 // Send screen rects through the delegate if there is one. Not every
513 // RenderWidgetHost has a delegate (for example, drop-down widgets).
514 if (host_->delegate())
515 host_->delegate()->SendScreenRects();
517 host_->SendScreenRects();
520 UpdateInsetsWithVirtualKeyboardEnabled();
523 void RenderWidgetHostViewAura::ParentHierarchyChanged() {
524 if (window_->parent()) {
525 // Track changes of the window relative to the root. This is done to snap
526 // `window_` to a pixel boundary, which could change when the bounds
527 // relative to the root changes. An example where this happens:
528 // The fast resize code path for bookmarks where in the parent of RWHVA
529 // which is WCV has its bounds changed before the bookmark is hidden. This
530 // results in the traditional bounds change notification for the WCV
531 // reporting the old bounds as the bookmark is still around. Observing all
532 // the ancestors of the RWHVA window enables us to know when the bounds of
533 // the window relative to root changes and allows us to snap accordingly.
534 position_in_root_observer_ =
535 std::make_unique<aura_extra::WindowPositionInRootMonitor>(
538 &RenderWidgetHostViewAura::HandleBoundsInRootChanged,
539 base::Unretained(this)));
541 position_in_root_observer_.reset();
543 // Snap when we receive a hierarchy changed. http://crbug.com/388908.
544 HandleBoundsInRootChanged();
547 void RenderWidgetHostViewAura::Focus() {
548 // Make sure we have a FocusClient before attempting to Focus(). In some
549 // situations we may not yet be in a valid Window hierarchy (such as reloading
550 // after out of memory discarded the tab).
551 aura::client::FocusClient* client = aura::client::GetFocusClient(window_);
555 #if BUILDFLAG(IS_EFL)
556 if (!efl_helper_->HasFocus())
557 efl_helper_->Focus(true);
561 bool RenderWidgetHostViewAura::HasFocus() {
562 return window_->HasFocus();
565 bool RenderWidgetHostViewAura::IsSurfaceAvailableForCopy() {
566 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
567 return delegated_frame_host_->CanCopyFromCompositingSurface();
570 #if BUILDFLAG(IS_EFL)
571 void RenderWidgetHostViewAura::BackgroundColorReceived(int callback_id,
573 efl_helper_->BackgroundColorReceived(callback_id, bg_color);
576 void RenderWidgetHostViewAura::DidGetContentSnapshot(const SkBitmap& bitmap,
578 efl_helper_->DidGetContentSnapshot(bitmap, request_id);
581 void RenderWidgetHostViewAura::DidHandleKeyEvent(
582 blink::WebInputEvent::Type input_event_type,
584 efl_helper_->DidHandleKeyEvent(input_event_type, processed);
587 void RenderWidgetHostViewAura::SelectionChanged(const std::u16string& text,
589 const gfx::Range& range) {
590 RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
591 efl_helper_->SelectionChanged(text, offset, range);
594 void RenderWidgetHostViewAura::TextInputStateChanged(
595 const ui::mojom::TextInputState& params) {
596 RenderWidgetHostViewBase::TextInputStateChanged(params);
597 efl_helper_->TextInputStateChanged(params);
601 void RenderWidgetHostViewAura::EnsureSurfaceSynchronizedForWebTest() {
602 ++latest_capture_sequence_number_;
603 SynchronizeVisualProperties(cc::DeadlinePolicy::UseInfiniteDeadline(),
607 bool RenderWidgetHostViewAura::IsShowing() {
608 return window_->IsVisible();
611 void RenderWidgetHostViewAura::WasUnOccluded() {
612 ShowImpl(PageVisibilityState::kVisible);
615 void RenderWidgetHostViewAura::ShowImpl(PageVisibilityState page_visibility) {
616 // OnShowWithPageVisibility will not call NotifyHostAndDelegateOnWasShown,
617 // which updates `visibility_`, unless the host is hidden. Make sure no update
619 DCHECK(host_->is_hidden() || visibility_ == Visibility::VISIBLE);
620 OnShowWithPageVisibility(page_visibility);
623 void RenderWidgetHostViewAura::NotifyHostAndDelegateOnWasShown(
624 blink::mojom::RecordContentToVisibleTimeRequestPtr tab_switch_start_state) {
625 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
626 DCHECK(host_->is_hidden());
627 DCHECK_NE(visibility_, Visibility::VISIBLE);
629 auto* wth = window()->GetHost();
630 if (wth && allocate_local_surface_id_on_next_show_) {
631 wth->window()->AllocateLocalSurfaceId();
632 wth->compositor()->SetLocalSurfaceIdFromParent(
633 wth->window()->GetLocalSurfaceId());
635 allocate_local_surface_id_on_next_show_ = false;
637 visibility_ = Visibility::VISIBLE;
639 bool has_saved_frame = delegated_frame_host_->HasSavedFrame();
641 bool show_reason_bfcache_restore =
642 tab_switch_start_state
643 ? tab_switch_start_state->show_reason_bfcache_restore
646 // No need to check for saved frames for the case of bfcache restore.
647 if (show_reason_bfcache_restore) {
648 host()->WasShown(tab_switch_start_state.Clone());
650 host()->WasShown(has_saved_frame
651 ? blink::mojom::RecordContentToVisibleTimeRequestPtr()
652 : tab_switch_start_state.Clone());
654 aura::Window* root = window_->GetRootWindow();
656 aura::client::CursorClient* cursor_client =
657 aura::client::GetCursorClient(root);
659 NotifyRendererOfCursorVisibilityState(cursor_client->IsCursorVisible());
663 // If the frame for the renderer is already available, then the
664 // tab-switching time is the presentation time for the browser-compositor.
665 delegated_frame_host_->WasShown(
666 GetLocalSurfaceId(), window_->bounds().size(),
667 has_saved_frame ? std::move(tab_switch_start_state)
668 : blink::mojom::RecordContentToVisibleTimeRequestPtr());
670 #if BUILDFLAG(IS_WIN)
675 void RenderWidgetHostViewAura::HideImpl() {
676 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
677 DCHECK(visibility_ == Visibility::HIDDEN ||
678 visibility_ == Visibility::OCCLUDED);
680 #if BUILDFLAG(IS_EFL)
684 if (!host()->is_hidden()) {
686 aura::WindowTreeHost* host = window_->GetHost();
687 aura::Window* parent = window_->parent();
688 aura::Window::OcclusionState parent_occl_state =
689 parent ? parent->GetOcclusionState()
690 : aura::Window::OcclusionState::UNKNOWN;
691 aura::Window::OcclusionState native_win_occlusion_state =
692 host ? host->GetNativeWindowOcclusionState()
693 : aura::Window::OcclusionState::UNKNOWN;
694 DelegatedFrameHost::HiddenCause cause;
695 if (parent_occl_state == aura::Window::OcclusionState::OCCLUDED &&
696 native_win_occlusion_state ==
697 aura::Window::OcclusionState::OCCLUDED) {
698 cause = DelegatedFrameHost::HiddenCause::kOccluded;
700 cause = DelegatedFrameHost::HiddenCause::kOther;
702 delegated_frame_host_->WasHidden(cause);
703 #if BUILDFLAG(IS_WIN)
705 // We reparent the legacy Chrome_RenderWidgetHostHWND window to the
706 // global hidden window on the same lines as Windowed plugin windows.
707 if (legacy_render_widget_host_HWND_)
708 legacy_render_widget_host_HWND_->UpdateParent(ui::GetHiddenWindow());
713 #if BUILDFLAG(IS_WIN)
714 if (legacy_render_widget_host_HWND_)
715 legacy_render_widget_host_HWND_->Hide();
719 void RenderWidgetHostViewAura::WasOccluded() {
720 visibility_ = Visibility::OCCLUDED;
724 void RenderWidgetHostViewAura::
725 RequestSuccessfulPresentationTimeFromHostOrDelegate(
726 blink::mojom::RecordContentToVisibleTimeRequestPtr
727 visible_time_request) {
728 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
729 DCHECK(!host_->is_hidden());
730 DCHECK_EQ(visibility_, Visibility::VISIBLE);
731 DCHECK(visible_time_request);
733 bool has_saved_frame = delegated_frame_host_->HasSavedFrame();
735 // No need to check for saved frames for the case of bfcache restore.
736 if (visible_time_request->show_reason_bfcache_restore || !has_saved_frame) {
737 host()->RequestSuccessfulPresentationTimeForNextFrame(
738 visible_time_request.Clone());
741 // If the frame for the renderer is already available, then the
742 // tab-switching time is the presentation time for the browser-compositor.
743 if (has_saved_frame) {
744 delegated_frame_host_->RequestSuccessfulPresentationTimeForNextFrame(
745 std::move(visible_time_request));
749 void RenderWidgetHostViewAura::
750 CancelSuccessfulPresentationTimeRequestForHostAndDelegate() {
751 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
752 DCHECK(!host_->is_hidden());
753 DCHECK_EQ(visibility_, Visibility::VISIBLE);
755 host()->CancelSuccessfulPresentationTimeRequest();
756 delegated_frame_host_->CancelSuccessfulPresentationTimeRequest();
759 bool RenderWidgetHostViewAura::ShouldSkipCursorUpdate() const {
760 aura::Window* root_window = window_->GetRootWindow();
762 display::Screen* screen = display::Screen::GetScreen();
765 // Ignore cursor update messages if the window under the cursor is not us.
766 #if BUILDFLAG(IS_WIN)
767 gfx::Point cursor_screen_point = screen->GetCursorScreenPoint();
768 aura::Window* window_at_screen_point =
769 screen->GetWindowAtScreenPoint(cursor_screen_point);
770 // On Windows we may fail to retrieve the aura Window at the current cursor
771 // position. This is because the WindowFromPoint API may return the legacy
772 // window which is not associated with an aura Window. In this case we need
773 // to get the aura window for the parent of the legacy window.
774 if (!window_at_screen_point && legacy_render_widget_host_HWND_) {
775 HWND hwnd_at_point = ::WindowFromPoint(cursor_screen_point.ToPOINT());
777 if (hwnd_at_point == legacy_render_widget_host_HWND_->hwnd())
778 hwnd_at_point = legacy_render_widget_host_HWND_->GetParent();
780 display::win::ScreenWin* screen_win =
781 static_cast<display::win::ScreenWin*>(screen);
782 window_at_screen_point = screen_win->GetNativeWindowFromHWND(hwnd_at_point);
784 if (!window_at_screen_point ||
785 (window_at_screen_point->GetRootWindow() != root_window)) {
788 #elif !BUILDFLAG(IS_CHROMEOS_ASH)
789 if (!screen->IsWindowUnderCursor(root_window))
791 #endif // !BUILDFLAG(IS_CHROMEOS_ASH)
795 bool RenderWidgetHostViewAura::ShouldShowStaleContentOnEviction() {
796 return host() && host()->ShouldShowStaleContentOnEviction();
799 gfx::Rect RenderWidgetHostViewAura::GetViewBounds() {
800 #if BUILDFLAG(IS_EFL)
801 if (offscreen_helper())
802 return offscreen_helper()->GetViewBounds();
804 return window_->GetBoundsInScreen();
807 void RenderWidgetHostViewAura::UpdateBackgroundColor() {
808 DCHECK(GetBackgroundColor());
810 SkColor color = *GetBackgroundColor();
811 // Set transparent bg for Browser process
812 if (color == SK_ColorTRANSPARENT && GetCompositor()) {
813 GetCompositor()->SetBackgroundColor(SK_ColorTRANSPARENT);
816 bool opaque = SkColorGetA(color) == SK_AlphaOPAQUE;
817 window_->layer()->SetFillsBoundsOpaquely(opaque);
818 window_->layer()->SetColor(color);
821 #if BUILDFLAG(IS_WIN)
822 void RenderWidgetHostViewAura::EnsureDevicePostureServiceConnection() {
823 if (device_posture_provider_.is_bound() &&
824 device_posture_provider_.is_connected()) {
827 GetDeviceService().BindDevicePostureProvider(
828 device_posture_provider_.BindNewPipeAndPassReceiver());
829 device_posture_provider_->AddListenerAndGetCurrentViewportSegments(
830 device_posture_receiver_.BindNewPipeAndPassRemote(),
831 base::BindOnce(&RenderWidgetHostViewAura::OnViewportSegmentsChanged,
832 base::Unretained(this)));
836 void RenderWidgetHostViewAura::OnViewportSegmentsChanged(
837 const std::vector<gfx::Rect>& segments) {
838 display_feature_ = absl::nullopt;
839 viewport_segments_.clear();
840 if (segments.empty()) {
841 SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
842 window_->GetLocalSurfaceId());
846 if (segments.size() >= 2) {
847 viewport_segments_ = std::move(segments);
848 ComputeDisplayFeature();
850 SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
851 window_->GetLocalSurfaceId());
854 void RenderWidgetHostViewAura::ComputeDisplayFeature() {
855 if (viewport_segments_.size() < 2) {
859 display_feature_ = absl::nullopt;
860 if (!window_->GetRootWindow()) {
864 const display::Display display =
865 display::Screen::GetScreen()->GetDisplayNearestWindow(window_);
866 // Set the display feature only if the browser window is maximized or
868 if (window_->GetRootWindow()->GetBoundsInScreen() != display.work_area() &&
869 window_->GetRootWindow()->GetBoundsInScreen() != display.bounds()) {
873 float dip_scale = 1 / device_scale_factor_;
874 // Segments coming from the platform are in native resolution.
875 gfx::Rect transformed_display_feature =
876 gfx::ScaleToRoundedRect(viewport_segments_[1], dip_scale);
877 transformed_display_feature.Offset(-GetViewBounds().x(),
878 -GetViewBounds().y());
879 transformed_display_feature.Intersect(gfx::Rect(GetVisibleViewportSize()));
880 if (transformed_display_feature.x() == 0) {
881 display_feature_ = {DisplayFeature::Orientation::kHorizontal,
882 transformed_display_feature.y(),
883 transformed_display_feature.height()};
884 } else if (transformed_display_feature.y() == 0) {
885 display_feature_ = {DisplayFeature::Orientation::kVertical,
886 transformed_display_feature.x(),
887 transformed_display_feature.width()};
891 absl::optional<DisplayFeature> RenderWidgetHostViewAura::GetDisplayFeature() {
892 return display_feature_;
895 void RenderWidgetHostViewAura::SetDisplayFeatureForTesting(
896 const DisplayFeature* display_feature) {
898 display_feature_ = *display_feature;
900 display_feature_ = absl::nullopt;
903 void RenderWidgetHostViewAura::WindowTitleChanged() {
904 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
905 delegated_frame_host_->WindowTitleChanged(
906 base::UTF16ToUTF8(window_->GetTitle()));
909 bool RenderWidgetHostViewAura::IsMouseLocked() {
910 return event_handler_->mouse_locked();
913 gfx::Size RenderWidgetHostViewAura::GetVisibleViewportSize() {
914 #if BUILDFLAG(IS_EFL)
915 if (efl_helper_->IsOffscreenMode())
916 return efl_helper_->GetVisibleViewportSize();
918 gfx::Rect requested_rect(GetRequestedRendererSize());
919 requested_rect.Inset(insets_);
920 return requested_rect.size();
923 void RenderWidgetHostViewAura::SetInsets(const gfx::Insets& insets) {
924 TRACE_EVENT0("vk", "RenderWidgetHostViewAura::SetInsets");
925 if (insets != insets_) {
927 window_->AllocateLocalSurfaceId();
928 if (!insets.IsEmpty()) {
929 inset_surface_id_ = window_->GetLocalSurfaceId();
931 inset_surface_id_ = viz::LocalSurfaceId();
933 SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
934 window_->GetLocalSurfaceId());
938 void RenderWidgetHostViewAura::UpdateCursor(const ui::Cursor& cursor) {
939 GetCursorManager()->UpdateCursor(this, cursor);
942 void RenderWidgetHostViewAura::DisplayCursor(const ui::Cursor& cursor) {
943 current_cursor_ = WebCursor(cursor);
944 const display::Display display =
945 display::Screen::GetScreen()->GetDisplayNearestWindow(window_);
946 current_cursor_.SetDisplayInfo(display);
947 UpdateCursorIfOverSelf();
950 CursorManager* RenderWidgetHostViewAura::GetCursorManager() {
951 return cursor_manager_.get();
954 void RenderWidgetHostViewAura::SetIsLoading(bool is_loading) {
955 is_loading_ = is_loading;
956 UpdateCursorIfOverSelf();
959 void RenderWidgetHostViewAura::RenderProcessGone() {
960 UpdateCursorIfOverSelf();
964 void RenderWidgetHostViewAura::ShowWithVisibility(
965 PageVisibilityState page_visibility) {
966 // Make sure we grab updated ScreenInfos before synchronizing visual
967 // properties, in case they have changed or this is the initial show.
970 #if BUILDFLAG(IS_EFL)
974 // If the viz::LocalSurfaceId is invalid, we may have been evicted,
975 // and no other visual properties have since been changed. Allocate a new id
976 // and start synchronizing.
977 if (!window_->GetLocalSurfaceId().is_valid()) {
978 window_->AllocateLocalSurfaceId();
979 SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
980 window_->GetLocalSurfaceId());
984 ShowImpl(page_visibility);
985 #if BUILDFLAG(IS_WIN)
986 if (page_visibility != PageVisibilityState::kVisible &&
987 legacy_render_widget_host_HWND_) {
988 legacy_render_widget_host_HWND_->Hide();
990 #endif // BUILDFLAG(IS_WIN)
993 void RenderWidgetHostViewAura::Destroy() {
994 // Beware, this function is not called on all destruction paths. If |window_|
995 // has been created, then it will implicitly end up calling
996 // ~RenderWidgetHostViewAura when |window_| is destroyed. Otherwise, The
997 // destructor is invoked directly from here. So all destruction/cleanup code
998 // should happen there, not here.
1000 // Call this here in case any observers need access to `this` before we
1001 // destruct the derived class.
1002 NotifyObserversAboutShutdown();
1010 void RenderWidgetHostViewAura::UpdateTooltipUnderCursor(
1011 const std::u16string& tooltip_text) {
1012 if (GetCursorManager()->IsViewUnderCursor(this))
1013 UpdateTooltip(tooltip_text);
1016 void RenderWidgetHostViewAura::UpdateTooltip(
1017 const std::u16string& tooltip_text) {
1018 SetTooltipText(tooltip_text);
1020 wm::TooltipClient* tooltip_client =
1021 wm::GetTooltipClient(window_->GetRootWindow());
1022 if (tooltip_client) {
1023 // Content tooltips should be visible indefinitely.
1024 tooltip_client->SetHideTooltipTimeout(window_, {});
1025 tooltip_client->UpdateTooltip(window_);
1029 void RenderWidgetHostViewAura::UpdateTooltipFromKeyboard(
1030 const std::u16string& tooltip_text,
1031 const gfx::Rect& bounds) {
1032 SetTooltipText(tooltip_text);
1034 wm::TooltipClient* tooltip_client =
1035 wm::GetTooltipClient(window_->GetRootWindow());
1036 if (tooltip_client) {
1037 // Content tooltips should be visible indefinitely.
1038 tooltip_client->SetHideTooltipTimeout(window_, {});
1039 tooltip_client->UpdateTooltipFromKeyboard(bounds, window_);
1043 void RenderWidgetHostViewAura::ClearKeyboardTriggeredTooltip() {
1044 if (!window_ || !window_->GetHost())
1047 wm::TooltipClient* tooltip_client =
1048 wm::GetTooltipClient(window_->GetRootWindow());
1049 if (!tooltip_client || !tooltip_client->IsTooltipSetFromKeyboard(window_))
1052 SetTooltipText(std::u16string());
1053 tooltip_client->UpdateTooltipFromKeyboard(gfx::Rect(), window_);
1056 uint32_t RenderWidgetHostViewAura::GetCaptureSequenceNumber() const {
1057 return latest_capture_sequence_number_;
1060 void RenderWidgetHostViewAura::CopyFromSurface(
1061 const gfx::Rect& src_subrect,
1062 const gfx::Size& dst_size,
1063 base::OnceCallback<void(const SkBitmap&)> callback) {
1064 base::WeakPtr<RenderWidgetHostImpl> popup_host;
1065 base::WeakPtr<DelegatedFrameHost> popup_frame_host;
1066 if (popup_child_host_view_) {
1067 popup_host = popup_child_host_view_->host()->GetWeakPtr();
1069 popup_child_host_view_->GetDelegatedFrameHost()->GetWeakPtr();
1071 RenderWidgetHostViewBase::CopyMainAndPopupFromSurface(
1072 host()->GetWeakPtr(), delegated_frame_host_->GetWeakPtr(), popup_host,
1073 popup_frame_host, src_subrect, dst_size, device_scale_factor_,
1074 std::move(callback));
1077 #if BUILDFLAG(IS_WIN)
1078 bool RenderWidgetHostViewAura::UsesNativeWindowFrame() const {
1079 return (legacy_render_widget_host_HWND_ != nullptr);
1082 void RenderWidgetHostViewAura::UpdateMouseLockRegion() {
1084 display::Screen::GetScreen()
1085 ->DIPToScreenRectInWindow(window_, window_->GetBoundsInScreen())
1087 ::ClipCursor(&window_rect);
1090 void RenderWidgetHostViewAura::OnLegacyWindowDestroyed() {
1091 legacy_render_widget_host_HWND_ = nullptr;
1092 legacy_window_destroyed_ = true;
1096 gfx::NativeViewAccessible
1097 RenderWidgetHostViewAura::GetParentNativeViewAccessible() {
1098 // If a popup_parent_host_view_ exists, that means we are in a popup (such as
1099 // datetime) and our accessible parent window is popup_parent_host_view_
1100 if (popup_parent_host_view_) {
1101 DCHECK_EQ(widget_type_, WidgetType::kPopup);
1102 return popup_parent_host_view_->GetParentNativeViewAccessible();
1105 if (window_->parent()) {
1106 return window_->parent()->GetProperty(
1107 aura::client::kParentNativeViewAccessibleKey);
1113 void RenderWidgetHostViewAura::ClearFallbackSurfaceForCommitPending() {
1114 delegated_frame_host_->ClearFallbackSurfaceForCommitPending();
1115 window_->InvalidateLocalSurfaceId();
1118 void RenderWidgetHostViewAura::ResetFallbackToFirstNavigationSurface() {
1119 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
1120 delegated_frame_host_->ResetFallbackToFirstNavigationSurface();
1123 bool RenderWidgetHostViewAura::RequestRepaintForTesting() {
1124 return SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
1128 void RenderWidgetHostViewAura::DidStopFlinging() {
1129 selection_controller_client_->OnScrollCompleted();
1132 void RenderWidgetHostViewAura::TransformPointToRootSurface(gfx::PointF* point) {
1133 aura::Window* root = window_->GetRootWindow();
1134 aura::Window::ConvertPointToTarget(window_, root, point);
1135 *point = root->GetRootWindow()->transform().MapPoint(*point);
1138 gfx::Rect RenderWidgetHostViewAura::GetBoundsInRootWindow() {
1139 aura::Window* top_level = window_->GetToplevelWindow();
1140 gfx::Rect bounds(top_level->GetBoundsInScreen());
1142 #if BUILDFLAG(IS_WIN)
1143 // TODO(zturner,iyengar): This will break when we remove support for NPAPI and
1144 // remove the legacy hwnd, so a better fix will need to be decided when that
1146 if (UsesNativeWindowFrame()) {
1147 // aura::Window doesn't take into account non-client area of native windows
1148 // (e.g. HWNDs), so for that case ask Windows directly what the bounds are.
1149 aura::WindowTreeHost* host = top_level->GetHost();
1151 return top_level->GetBoundsInScreen();
1153 // If this is a headless window return the headless window bounds stored in
1154 // Aura window properties instead of the actual platform window bounds which
1155 // may be different.
1156 if (gfx::Rect* headless_bounds =
1157 host->window()->GetProperty(aura::client::kHeadlessBoundsKey)) {
1158 return *headless_bounds;
1161 RECT window_rect = {0};
1162 HWND hwnd = host->GetAcceleratedWidget();
1163 ::GetWindowRect(hwnd, &window_rect);
1164 bounds = gfx::Rect(window_rect);
1166 // Maximized windows are outdented from the work area by the frame thickness
1167 // even though this "frame" is not painted. This confuses code (and people)
1168 // that think of a maximized window as corresponding exactly to the work
1169 // area. Correct for this by subtracting the frame thickness back off.
1170 if (::IsZoomed(hwnd)) {
1171 bounds.Inset(gfx::Insets::VH(GetSystemMetrics(SM_CYSIZEFRAME),
1172 GetSystemMetrics(SM_CXSIZEFRAME)));
1173 bounds.Inset(GetSystemMetrics(SM_CXPADDEDBORDER));
1176 // Pixels come back from GetWindowHost, so we need to convert those back to
1178 bounds = display::Screen::GetScreen()->ScreenToDIPRectInWindow(top_level,
1187 void RenderWidgetHostViewAura::WheelEventAck(
1188 const blink::WebMouseWheelEvent& event,
1189 blink::mojom::InputEventResultState ack_result) {
1190 if (overscroll_controller_) {
1191 overscroll_controller_->ReceivedEventACK(
1192 event, (blink::mojom::InputEventResultState::kConsumed == ack_result));
1196 void RenderWidgetHostViewAura::DidOverscroll(
1197 const ui::DidOverscrollParams& params) {
1198 if (overscroll_controller_)
1199 overscroll_controller_->OnDidOverscroll(params);
1200 #if BUILDFLAG(IS_EFL)
1201 efl_helper_->DidOverscroll(params);
1205 void RenderWidgetHostViewAura::GestureEventAck(
1206 const blink::WebGestureEvent& event,
1207 blink::mojom::InputEventResultState ack_result,
1208 blink::mojom::ScrollResultDataPtr scroll_result_data) {
1209 const blink::WebInputEvent::Type event_type = event.GetType();
1210 if (event_type == blink::WebGestureEvent::Type::kGestureScrollBegin ||
1211 event_type == blink::WebGestureEvent::Type::kGestureScrollEnd) {
1212 if (host()->delegate()) {
1213 host()->delegate()->SetTopControlsGestureScrollInProgress(
1214 event_type == blink::WebGestureEvent::Type::kGestureScrollBegin);
1218 if (overscroll_controller_) {
1219 overscroll_controller_->ReceivedEventACK(
1220 event, (blink::mojom::InputEventResultState::kConsumed == ack_result));
1221 // Terminate an active fling when the ACK for a GSU generated from the fling
1222 // progress (GSU with inertial state) is consumed and the overscrolling mode
1223 // is not |OVERSCROLL_NONE|. The early fling termination generates a GSE
1224 // which completes the overscroll action. Without this change the overscroll
1225 // action would complete at the end of the active fling progress which
1226 // causes noticeable delay in cases that the fling velocity is large.
1227 // https://crbug.com/797855
1228 if (event_type == blink::WebInputEvent::Type::kGestureScrollUpdate &&
1229 event.data.scroll_update.inertial_phase ==
1230 blink::WebGestureEvent::InertialPhaseState::kMomentum &&
1231 overscroll_controller_->overscroll_mode() != OVERSCROLL_NONE) {
1236 // Stop flinging if a GSU event with momentum phase is sent to the renderer
1237 // but not consumed.
1238 StopFlingingIfNecessary(event, ack_result);
1240 event_handler_->GestureEventAck(event, ack_result);
1242 ForwardTouchpadZoomEventIfNecessary(event, ack_result);
1245 void RenderWidgetHostViewAura::ProcessAckedTouchEvent(
1246 const TouchEventWithLatencyInfo& touch,
1247 blink::mojom::InputEventResultState ack_result) {
1248 aura::WindowTreeHost* window_host = window_->GetHost();
1249 // |host| is NULL during tests.
1253 // The TouchScrollStarted event is generated & consumed downstream from the
1254 // TouchEventQueue. So we don't expect an ACK up here.
1255 DCHECK(touch.event.GetType() !=
1256 blink::WebInputEvent::Type::kTouchScrollStarted);
1258 ui::EventResult result =
1259 (ack_result == blink::mojom::InputEventResultState::kConsumed)
1263 blink::WebTouchPoint::State required_state;
1264 switch (touch.event.GetType()) {
1265 case blink::WebInputEvent::Type::kTouchStart:
1266 required_state = blink::WebTouchPoint::State::kStatePressed;
1268 case blink::WebInputEvent::Type::kTouchEnd:
1269 required_state = blink::WebTouchPoint::State::kStateReleased;
1271 case blink::WebInputEvent::Type::kTouchMove:
1272 required_state = blink::WebTouchPoint::State::kStateMoved;
1274 case blink::WebInputEvent::Type::kTouchCancel:
1275 required_state = blink::WebTouchPoint::State::kStateCancelled;
1278 required_state = blink::WebTouchPoint::State::kStateUndefined;
1283 #if BUILDFLAG(IS_EFL)
1284 if (touch.event.GetType() == blink::WebInputEvent::Type::kTouchStart)
1285 efl_helper_->SetTouchStartConsumed(result == ui::ER_HANDLED);
1287 if (touch.event.GetType() == blink::WebInputEvent::Type::kTouchEnd)
1288 efl_helper_->SetTouchEndConsumed(result == ui::ER_HANDLED);
1291 // Only send acks for one changed touch point.
1292 bool sent_ack = false;
1293 for (size_t i = 0; i < touch.event.touches_length; ++i) {
1294 if (touch.event.touches[i].state == required_state) {
1296 window_host->dispatcher()->ProcessedTouchEvent(
1297 touch.event.unique_touch_event_id, window_, result,
1298 InputEventResultStateIsSetBlocking(ack_result));
1299 if (touch.event.touch_start_or_first_touch_move &&
1300 result == ui::ER_HANDLED && host()->delegate() &&
1301 host()->delegate()->GetInputEventRouter()) {
1304 ->GetInputEventRouter()
1305 ->OnHandledTouchStartOrFirstTouchMove(
1306 touch.event.unique_touch_event_id);
1313 std::unique_ptr<SyntheticGestureTarget>
1314 RenderWidgetHostViewAura::CreateSyntheticGestureTarget() {
1315 return std::unique_ptr<SyntheticGestureTarget>(
1316 new SyntheticGestureTargetAura(host()));
1319 blink::mojom::InputEventResultState RenderWidgetHostViewAura::FilterInputEvent(
1320 const blink::WebInputEvent& input_event) {
1321 bool consumed = false;
1322 if (input_event.GetType() == WebInputEvent::Type::kGestureFlingStart) {
1323 const WebGestureEvent& gesture_event =
1324 static_cast<const WebGestureEvent&>(input_event);
1325 // Zero-velocity touchpad flings are an Aura-specific signal that the
1326 // touchpad scroll has ended, and should not be forwarded to the renderer.
1327 if (gesture_event.SourceDevice() == blink::WebGestureDevice::kTouchpad &&
1328 !gesture_event.data.fling_start.velocity_x &&
1329 !gesture_event.data.fling_start.velocity_y) {
1334 if (overscroll_controller_)
1335 consumed |= overscroll_controller_->WillHandleEvent(input_event);
1337 // Touch events should always propagate to the renderer.
1338 if (WebTouchEvent::IsTouchEventType(input_event.GetType()))
1339 return blink::mojom::InputEventResultState::kNotConsumed;
1342 input_event.GetType() == blink::WebInputEvent::Type::kGestureFlingStart) {
1343 // Here we indicate that there was no consumer for this event, as
1344 // otherwise the fling animation system will try to run an animation
1345 // and will also expect a notification when the fling ends. Since
1346 // CrOS just uses the GestureFlingStart with zero-velocity as a means
1347 // of indicating that touchpad scroll has ended, we don't actually want
1348 // a fling animation. Note: Similar code exists in
1349 // RenderWidgetHostViewChildFrame::FilterInputEvent()
1350 return blink::mojom::InputEventResultState::kNoConsumerExists;
1353 return consumed ? blink::mojom::InputEventResultState::kConsumed
1354 : blink::mojom::InputEventResultState::kNotConsumed;
1357 gfx::AcceleratedWidget
1358 RenderWidgetHostViewAura::AccessibilityGetAcceleratedWidget() {
1359 #if BUILDFLAG(IS_WIN)
1360 if (legacy_render_widget_host_HWND_)
1361 return legacy_render_widget_host_HWND_->hwnd();
1363 return gfx::kNullAcceleratedWidget;
1366 gfx::NativeViewAccessible
1367 RenderWidgetHostViewAura::AccessibilityGetNativeViewAccessible() {
1368 #if BUILDFLAG(IS_WIN)
1369 if (legacy_render_widget_host_HWND_) {
1370 return legacy_render_widget_host_HWND_->window_accessible();
1374 if (window_->parent()) {
1375 return window_->parent()->GetProperty(
1376 aura::client::kParentNativeViewAccessibleKey);
1382 void RenderWidgetHostViewAura::SetMainFrameAXTreeID(ui::AXTreeID id) {
1383 window_->SetProperty(ui::kChildAXTreeID, id.ToString());
1386 blink::mojom::PointerLockResult RenderWidgetHostViewAura::LockMouse(
1387 bool request_unadjusted_movement) {
1388 return event_handler_->LockMouse(request_unadjusted_movement);
1391 blink::mojom::PointerLockResult RenderWidgetHostViewAura::ChangeMouseLock(
1392 bool request_unadjusted_movement) {
1393 return event_handler_->ChangeMouseLock(request_unadjusted_movement);
1396 void RenderWidgetHostViewAura::UnlockMouse() {
1397 event_handler_->UnlockMouse();
1400 bool RenderWidgetHostViewAura::GetIsMouseLockedUnadjustedMovementForTesting() {
1401 return event_handler_->mouse_locked_unadjusted_movement();
1404 bool RenderWidgetHostViewAura::LockKeyboard(
1405 absl::optional<base::flat_set<ui::DomCode>> codes) {
1406 return event_handler_->LockKeyboard(std::move(codes));
1409 void RenderWidgetHostViewAura::UnlockKeyboard() {
1410 event_handler_->UnlockKeyboard();
1413 bool RenderWidgetHostViewAura::IsKeyboardLocked() {
1414 return event_handler_->IsKeyboardLocked();
1417 base::flat_map<std::string, std::string>
1418 RenderWidgetHostViewAura::GetKeyboardLayoutMap() {
1419 aura::WindowTreeHost* host = window_->GetHost();
1421 return host->GetKeyboardLayoutMap();
1425 ////////////////////////////////////////////////////////////////////////////////
1426 // RenderWidgetHostViewAura, ui::TextInputClient implementation:
1427 void RenderWidgetHostViewAura::SetCompositionText(
1428 const ui::CompositionText& composition) {
1429 if (!text_input_manager_ || !text_input_manager_->GetActiveWidget())
1432 // TODO(suzhe): due to a bug of webkit, we can't use selection range with
1433 // composition string. See: https://bugs.webkit.org/show_bug.cgi?id=37788
1434 text_input_manager_->GetActiveWidget()->ImeSetComposition(
1435 composition.text, composition.ime_text_spans, gfx::Range::InvalidRange(),
1436 composition.selection.end(), composition.selection.end());
1438 has_composition_text_ = !composition.text.empty();
1441 size_t RenderWidgetHostViewAura::ConfirmCompositionText(bool keep_selection) {
1442 if (text_input_manager_ && text_input_manager_->GetActiveWidget() &&
1443 has_composition_text_) {
1444 text_input_manager_->GetActiveWidget()->ImeFinishComposingText(
1447 has_composition_text_ = false;
1448 // TODO(crbug/1109604): Return the number of characters committed by this
1450 return std::numeric_limits<size_t>::max();
1453 void RenderWidgetHostViewAura::ClearCompositionText() {
1454 if (text_input_manager_ && text_input_manager_->GetActiveWidget() &&
1455 has_composition_text_)
1456 text_input_manager_->GetActiveWidget()->ImeCancelComposition();
1457 has_composition_text_ = false;
1460 void RenderWidgetHostViewAura::InsertText(
1461 const std::u16string& text,
1462 InsertTextCursorBehavior cursor_behavior) {
1463 DCHECK_NE(GetTextInputType(), ui::TEXT_INPUT_TYPE_NONE);
1465 if (text_input_manager_ && text_input_manager_->GetActiveWidget()) {
1466 const int relative_cursor_position =
1467 cursor_behavior == InsertTextCursorBehavior::kMoveCursorBeforeText
1470 text_input_manager_->GetActiveWidget()->ImeCommitText(
1471 text, std::vector<ui::ImeTextSpan>(), gfx::Range::InvalidRange(),
1472 relative_cursor_position);
1474 has_composition_text_ = false;
1477 void RenderWidgetHostViewAura::InsertChar(const ui::KeyEvent& event) {
1478 if (popup_child_host_view_ && popup_child_host_view_->NeedsInputGrab()) {
1479 popup_child_host_view_->InsertChar(event);
1483 // Ignore character messages for VKEY_RETURN sent on CTRL+M. crbug.com/315547
1484 if (event_handler_->accept_return_character() ||
1485 event.GetCharacter() != ui::VKEY_RETURN) {
1486 // Send a blink::WebInputEvent::Char event to |host_|.
1487 ForwardKeyboardEventWithLatencyInfo(
1488 NativeWebKeyboardEvent(event, event.GetCharacter()), *event.latency(),
1493 bool RenderWidgetHostViewAura::CanInsertImage() {
1494 RenderFrameHostImpl* render_frame_host = GetFocusedFrame();
1496 if (!render_frame_host) {
1500 return render_frame_host->has_focused_richly_editable_element();
1503 void RenderWidgetHostViewAura::InsertImage(const GURL& src) {
1504 auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1506 if (!input_handler) {
1510 input_handler->ExecuteEditCommand("PasteFromImageURL",
1511 base::UTF8ToUTF16(src.spec()));
1514 ui::TextInputType RenderWidgetHostViewAura::GetTextInputType() const {
1515 if (text_input_manager_ && text_input_manager_->GetTextInputState())
1516 return text_input_manager_->GetTextInputState()->type;
1517 return ui::TEXT_INPUT_TYPE_NONE;
1520 ui::TextInputMode RenderWidgetHostViewAura::GetTextInputMode() const {
1521 if (text_input_manager_ && text_input_manager_->GetTextInputState())
1522 return text_input_manager_->GetTextInputState()->mode;
1523 return ui::TEXT_INPUT_MODE_DEFAULT;
1526 base::i18n::TextDirection RenderWidgetHostViewAura::GetTextDirection() const {
1527 NOTIMPLEMENTED_LOG_ONCE();
1528 return base::i18n::UNKNOWN_DIRECTION;
1531 int RenderWidgetHostViewAura::GetTextInputFlags() const {
1532 if (text_input_manager_ && text_input_manager_->GetTextInputState())
1533 return text_input_manager_->GetTextInputState()->flags;
1537 bool RenderWidgetHostViewAura::CanComposeInline() const {
1538 if (text_input_manager_ && text_input_manager_->GetTextInputState())
1539 return text_input_manager_->GetTextInputState()->can_compose_inline;
1543 gfx::Rect RenderWidgetHostViewAura::ConvertRectToScreen(
1544 const gfx::Rect& rect) const {
1545 gfx::Point origin = rect.origin();
1546 gfx::Point end = gfx::Point(rect.right(), rect.bottom());
1548 aura::Window* root_window = window_->GetRootWindow();
1551 aura::client::ScreenPositionClient* screen_position_client =
1552 aura::client::GetScreenPositionClient(root_window);
1553 if (!screen_position_client)
1555 screen_position_client->ConvertPointToScreen(window_, &origin);
1556 screen_position_client->ConvertPointToScreen(window_, &end);
1557 return gfx::Rect(origin.x(), origin.y(), base::ClampSub(end.x(), origin.x()),
1558 base::ClampSub(end.y(), origin.y()));
1561 gfx::Rect RenderWidgetHostViewAura::ConvertRectFromScreen(
1562 const gfx::Rect& rect) const {
1563 gfx::Rect result = rect;
1564 if (window_->GetRootWindow() &&
1565 aura::client::GetScreenPositionClient(window_->GetRootWindow()))
1566 wm::ConvertRectFromScreen(window_, &result);
1570 gfx::Rect RenderWidgetHostViewAura::GetCaretBounds() const {
1571 if (!text_input_manager_ || !text_input_manager_->GetActiveWidget())
1574 // Check selection bound first (currently populated only for EditContext)
1575 const absl::optional<gfx::Rect> text_selection_bound =
1576 text_input_manager_->GetTextSelectionBounds();
1577 if (text_selection_bound)
1578 return ConvertRectToScreen(text_selection_bound.value());
1580 // If no selection bound, we fall back to use selection region.
1581 const TextInputManager::SelectionRegion* region =
1582 text_input_manager_->GetSelectionRegion();
1583 gfx::Rect caret_rect = ConvertRectToScreen(
1584 gfx::RectBetweenSelectionBounds(region->anchor, region->focus));
1585 TRACE_EVENT1("ime", "RenderWidgetHostViewAura::GetCaretBounds", "caret_rect",
1586 caret_rect.ToString());
1590 gfx::Rect RenderWidgetHostViewAura::GetSelectionBoundingBox() const {
1591 auto* focused_view = GetFocusedViewForTextSelection();
1595 const gfx::Rect bounding_box =
1596 text_input_manager_->GetSelectionRegion(focused_view)->bounding_box;
1597 if (bounding_box.IsEmpty())
1600 return ConvertRectToScreen(bounding_box);
1603 bool RenderWidgetHostViewAura::GetCompositionCharacterBounds(
1605 gfx::Rect* rect) const {
1608 if (!text_input_manager_ || !text_input_manager_->GetActiveWidget())
1611 const TextInputManager::CompositionRangeInfo* composition_range_info =
1612 text_input_manager_->GetCompositionRangeInfo();
1614 if (index >= composition_range_info->character_bounds.size())
1616 *rect = ConvertRectToScreen(composition_range_info->character_bounds[index]);
1617 TRACE_EVENT1("ime", "RenderWidgetHostViewAura::GetCompositionCharacterBounds",
1618 "comp_char_rect", rect->ToString());
1622 bool RenderWidgetHostViewAura::HasCompositionText() const {
1623 return has_composition_text_;
1626 ui::TextInputClient::FocusReason RenderWidgetHostViewAura::GetFocusReason()
1628 if (!window_->HasFocus())
1629 return ui::TextInputClient::FOCUS_REASON_NONE;
1631 switch (last_pointer_type_before_focus_) {
1632 case ui::EventPointerType::kMouse:
1633 return ui::TextInputClient::FOCUS_REASON_MOUSE;
1634 case ui::EventPointerType::kPen:
1635 return ui::TextInputClient::FOCUS_REASON_PEN;
1636 case ui::EventPointerType::kTouch:
1637 return ui::TextInputClient::FOCUS_REASON_TOUCH;
1639 return ui::TextInputClient::FOCUS_REASON_OTHER;
1643 bool RenderWidgetHostViewAura::GetTextRange(gfx::Range* range) const {
1644 if (!text_input_manager_ || !GetFocusedWidget())
1647 const ui::mojom::TextInputState* state =
1648 text_input_manager_->GetTextInputState();
1652 range->set_start(0);
1653 range->set_end(state->value ? state->value->length() : 0);
1657 bool RenderWidgetHostViewAura::GetCompositionTextRange(
1658 gfx::Range* range) const {
1659 if (!text_input_manager_ || !GetFocusedWidget())
1662 const ui::mojom::TextInputState* state =
1663 text_input_manager_->GetTextInputState();
1664 // Return false when there is no composition.
1665 if (!state || !state->composition)
1668 *range = state->composition.value();
1672 bool RenderWidgetHostViewAura::GetEditableSelectionRange(
1673 gfx::Range* range) const {
1674 if (!text_input_manager_ || !GetFocusedWidget())
1677 const ui::mojom::TextInputState* state =
1678 text_input_manager_->GetTextInputState();
1682 *range = state->selection;
1686 bool RenderWidgetHostViewAura::SetEditableSelectionRange(
1687 const gfx::Range& range) {
1688 // TODO(crbug.com/915630): Write an unit test for this method.
1689 auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1692 input_handler->SetEditableSelectionOffsets(range.start(), range.end());
1696 bool RenderWidgetHostViewAura::GetTextFromRange(const gfx::Range& range,
1697 std::u16string* text) const {
1698 if (!text_input_manager_ || !GetFocusedWidget())
1701 const ui::mojom::TextInputState* state =
1702 text_input_manager_->GetTextInputState();
1706 gfx::Range text_range;
1707 GetTextRange(&text_range);
1709 if (!text_range.Contains(range)) {
1713 if (!state->value) {
1717 if (text_range.EqualsIgnoringDirection(range)) {
1718 // Avoid calling substr whose performance is low.
1719 *text = *state->value;
1721 *text = state->value->substr(range.GetMin(), range.length());
1726 void RenderWidgetHostViewAura::OnInputMethodChanged() {
1727 // TODO(suzhe): implement the newly added "locale" property of HTML DOM
1731 bool RenderWidgetHostViewAura::ChangeTextDirectionAndLayoutAlignment(
1732 base::i18n::TextDirection direction) {
1733 if (!GetTextInputManager() && !GetTextInputManager()->GetActiveWidget())
1736 GetTextInputManager()->GetActiveWidget()->UpdateTextDirection(direction);
1737 GetTextInputManager()->GetActiveWidget()->NotifyTextDirection();
1741 void RenderWidgetHostViewAura::ExtendSelectionAndDelete(
1742 size_t before, size_t after) {
1743 auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1746 input_handler->ExtendSelectionAndDelete(before, after);
1749 #if BUILDFLAG(IS_CHROMEOS)
1750 void RenderWidgetHostViewAura::ExtendSelectionAndReplace(
1753 const base::StringPiece16 replacement_text) {
1754 auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1755 if (!input_handler) {
1758 input_handler->ExtendSelectionAndReplace(before, after,
1759 std::u16string(replacement_text));
1763 void RenderWidgetHostViewAura::EnsureCaretNotInRect(
1764 const gfx::Rect& rect_in_screen) {
1765 keyboard_occluded_bounds_ = rect_in_screen;
1767 // If keyboard is disabled, reset the insets_.
1768 if (keyboard_occluded_bounds_.IsEmpty()) {
1769 SetInsets(gfx::Insets());
1771 UpdateInsetsWithVirtualKeyboardEnabled();
1774 aura::Window* top_level_window = window_->GetToplevelWindow();
1775 #if BUILDFLAG(IS_CHROMEOS_ASH)
1776 wm::EnsureWindowNotInRect(top_level_window, keyboard_occluded_bounds_);
1779 // Perform overscroll if the caret is still hidden by the keyboard.
1780 const gfx::Rect hidden_window_bounds_in_screen = gfx::IntersectRects(
1781 keyboard_occluded_bounds_, top_level_window->GetBoundsInScreen());
1783 if (hidden_window_bounds_in_screen.IsEmpty())
1786 ScrollFocusedEditableNodeIntoView();
1789 bool RenderWidgetHostViewAura::IsTextEditCommandEnabled(
1790 ui::TextEditCommand command) const {
1794 void RenderWidgetHostViewAura::SetTextEditCommandForNextKeyEvent(
1795 ui::TextEditCommand command) {}
1797 ukm::SourceId RenderWidgetHostViewAura::GetClientSourceForMetrics() const {
1798 RenderFrameHostImpl* frame = GetFocusedFrame();
1799 // ukm::SourceId is not available while prerendering.
1800 if (frame && !frame->IsInLifecycleState(
1801 RenderFrameHost::LifecycleState::kPrerendering)) {
1802 return frame->GetPageUkmSourceId();
1804 return ukm::SourceId();
1807 bool RenderWidgetHostViewAura::ShouldDoLearning() {
1808 return GetTextInputManager() && GetTextInputManager()->should_do_learning();
1811 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
1812 bool RenderWidgetHostViewAura::SetCompositionFromExistingText(
1813 const gfx::Range& range,
1814 const std::vector<ui::ImeTextSpan>& ui_ime_text_spans) {
1815 auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1818 input_handler->SetCompositionFromExistingText(range.start(), range.end(),
1820 has_composition_text_ = true;
1826 #if BUILDFLAG(IS_CHROMEOS)
1827 gfx::Range RenderWidgetHostViewAura::GetAutocorrectRange() const {
1828 if (!text_input_manager_ || !text_input_manager_->GetActiveWidget())
1829 return gfx::Range();
1830 return text_input_manager_->GetAutocorrectRange();
1833 gfx::Rect RenderWidgetHostViewAura::GetAutocorrectCharacterBounds() const {
1834 if (!text_input_manager_ || !text_input_manager_->GetActiveWidget())
1837 const std::vector<ui::mojom::ImeTextSpanInfoPtr>& ime_text_spans_info =
1838 text_input_manager_->GetTextInputState()->ime_text_spans_info;
1840 unsigned autocorrect_span_found = 0;
1842 for (const auto& ime_text_span_info : ime_text_spans_info) {
1843 if (ime_text_span_info->span.type == ui::ImeTextSpan::Type::kAutocorrect) {
1844 bounds = ConvertRectToScreen(ime_text_span_info->bounds);
1845 autocorrect_span_found++;
1848 // Assuming there is only one autocorrect span at any point in time.
1849 DCHECK_LE(autocorrect_span_found, 1u);
1853 bool RenderWidgetHostViewAura::SetAutocorrectRange(
1854 const gfx::Range& range) {
1855 if (!range.is_empty()) {
1856 base::UmaHistogramEnumeration(
1857 "InputMethod.Assistive.Autocorrect.Count",
1858 TextInputClient::SubClass::kRenderWidgetHostViewAura);
1860 #if BUILDFLAG(IS_CHROMEOS_ASH)
1861 auto* input_method_manager = ash::input_method::InputMethodManager::Get();
1862 if (input_method_manager &&
1863 ash::extension_ime_util::IsExperimentalMultilingual(
1864 input_method_manager->GetActiveIMEState()
1865 ->GetCurrentInputMethod()
1867 base::UmaHistogramEnumeration(
1868 "InputMethod.MultilingualExperiment.Autocorrect.Count",
1869 TextInputClient::SubClass::kRenderWidgetHostViewAura);
1874 auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1878 input_handler->ClearImeTextSpansByType(0,
1879 std::numeric_limits<uint32_t>::max(),
1880 ui::ImeTextSpan::Type::kAutocorrect);
1882 if (range.is_empty())
1885 ui::ImeTextSpan ui_ime_text_span;
1886 ui_ime_text_span.type = ui::ImeTextSpan::Type::kAutocorrect;
1887 ui_ime_text_span.start_offset = 0;
1888 ui_ime_text_span.end_offset = range.length();
1889 ui_ime_text_span.underline_style = ui::ImeTextSpan::UnderlineStyle::kDot;
1890 ui_ime_text_span.underline_color =
1891 SkColorSetA(gfx::kGoogleGrey700, SK_AlphaOPAQUE * 0.7);
1892 ui_ime_text_span.thickness = ui::ImeTextSpan::Thickness::kThick;
1894 input_handler->AddImeTextSpansToExistingText(range.start(), range.end(),
1895 {ui_ime_text_span});
1899 absl::optional<ui::GrammarFragment>
1900 RenderWidgetHostViewAura::GetGrammarFragmentAtCursor() const {
1901 if (!text_input_manager_ || !text_input_manager_->GetActiveWidget())
1902 return absl::nullopt;
1903 gfx::Range selection_range;
1904 if (GetEditableSelectionRange(&selection_range)) {
1905 return text_input_manager_->GetGrammarFragment(selection_range);
1907 return absl::nullopt;
1911 bool RenderWidgetHostViewAura::ClearGrammarFragments(const gfx::Range& range) {
1912 auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1916 input_handler->ClearImeTextSpansByType(
1917 range.start(), range.end(), ui::ImeTextSpan::Type::kGrammarSuggestion);
1921 bool RenderWidgetHostViewAura::AddGrammarFragments(
1922 const std::vector<ui::GrammarFragment>& fragments) {
1923 if (!fragments.empty()) {
1924 base::UmaHistogramEnumeration(
1925 "InputMethod.Assistive.Grammar.Count",
1926 TextInputClient::SubClass::kRenderWidgetHostViewAura);
1929 auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
1930 if (!input_handler || fragments.empty())
1933 unsigned max_fragment_end = 0;
1934 std::vector<::ui::ImeTextSpan> ime_text_spans;
1935 ime_text_spans.reserve(fragments.size());
1936 for (auto& fragment : fragments) {
1937 ui::ImeTextSpan ui_ime_text_span;
1938 ui_ime_text_span.type = ui::ImeTextSpan::Type::kGrammarSuggestion;
1939 ui_ime_text_span.start_offset = fragment.range.start();
1940 ui_ime_text_span.end_offset = fragment.range.end();
1941 ui_ime_text_span.thickness = ui::ImeTextSpan::Thickness::kThick;
1942 ui_ime_text_span.underline_style = ui::ImeTextSpan::UnderlineStyle::kDot;
1943 ui_ime_text_span.underline_color = gfx::kGoogleBlue400;
1944 ui_ime_text_span.suggestions = {fragment.suggestion};
1946 ime_text_spans.push_back(ui_ime_text_span);
1947 if (fragment.range.end() > max_fragment_end) {
1948 max_fragment_end = fragment.range.end();
1951 input_handler->AddImeTextSpansToExistingText(0, max_fragment_end,
1959 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS)
1960 void RenderWidgetHostViewAura::GetActiveTextInputControlLayoutBounds(
1961 absl::optional<gfx::Rect>* control_bounds,
1962 absl::optional<gfx::Rect>* selection_bounds) {
1963 if (text_input_manager_) {
1964 const absl::optional<gfx::Rect> text_control_bounds =
1965 text_input_manager_->GetTextControlBounds();
1966 if (text_control_bounds) {
1967 *control_bounds = ConvertRectToScreen(text_control_bounds.value());
1970 "RenderWidgetHostViewAura::GetActiveTextInputControlLayoutBounds",
1971 "control_bounds_rect", control_bounds->value().ToString());
1973 // Selection bounds are currently populated only for EditContext.
1974 // For editable elements we use GetCompositionCharacterBounds.
1975 const absl::optional<gfx::Rect> text_selection_bounds =
1976 text_input_manager_->GetTextSelectionBounds();
1977 if (text_selection_bounds) {
1978 *selection_bounds = ConvertRectToScreen(text_selection_bounds.value());
1984 #if BUILDFLAG(IS_WIN)
1985 void RenderWidgetHostViewAura::SetActiveCompositionForAccessibility(
1986 const gfx::Range& range,
1987 const std::u16string& active_composition_text,
1988 bool is_composition_committed) {
1989 BrowserAccessibilityManager* manager =
1990 host()->GetRootBrowserAccessibilityManager();
1992 ui::AXPlatformNodeWin* focus_node = static_cast<ui::AXPlatformNodeWin*>(
1993 ui::AXPlatformNode::FromNativeViewAccessible(
1994 manager->GetFocus()->GetNativeViewAccessible()));
1996 // Notify accessibility object about this composition
1997 focus_node->OnActiveComposition(range, active_composition_text,
1998 is_composition_committed);
2004 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH)
2005 ui::TextInputClient::EditingContext
2006 RenderWidgetHostViewAura::GetTextEditingContext() {
2007 ui::TextInputClient::EditingContext editing_context;
2008 // We use the focused frame's URL here and not the main frame because
2009 // TSF(Windows Text Service Framework) works on the active editable element
2010 // context and it uses this information to assist the UIA(Microsoft UI
2011 // Automation) service to determine the character that is being typed by the
2012 // user via IME composition, the URL of the site that the user is typing on
2013 // and other text related services that are used by the UIA clients to power
2014 // accessibility features on Windows. We want to expose the focused frame's
2015 // URL to TSF that notifies the UIA service which uses this info and the
2016 // focused element's data to provide better screen reading capabilities.
2017 RenderFrameHostImpl* frame = GetFocusedFrame();
2019 editing_context.page_url = frame->GetLastCommittedURL();
2020 return editing_context;
2024 #if BUILDFLAG(IS_WIN)
2025 void RenderWidgetHostViewAura::NotifyOnFrameFocusChanged() {
2026 if (GetInputMethod()) {
2027 GetInputMethod()->OnUrlChanged();
2032 ////////////////////////////////////////////////////////////////////////////////
2033 // RenderWidgetHostViewAura, display::DisplayObserver implementation:
2035 void RenderWidgetHostViewAura::OnDisplayMetricsChanged(
2036 const display::Display& display,
2038 display::Screen* screen = display::Screen::GetScreen();
2039 if (display.id() != screen->GetDisplayNearestWindow(window_).id())
2042 if (window_->GetHost() && window_->GetHost()->device_scale_factor() !=
2043 display.device_scale_factor()) {
2044 // The DisplayMetrics changed, but the Compositor hasn't been updated yet.
2045 // Delay updating until the Compositor is updated as well, otherwise we
2046 // are likely to hit surface invariants (LocalSurfaceId generated with a
2047 // size/scale-factor that differs from scale-factor used by Compositor).
2048 needs_to_update_display_metrics_ = true;
2051 ProcessDisplayMetricsChanged();
2054 ////////////////////////////////////////////////////////////////////////////////
2055 // RenderWidgetHostViewAura, aura::WindowDelegate implementation:
2057 gfx::Size RenderWidgetHostViewAura::GetMinimumSize() const {
2061 gfx::Size RenderWidgetHostViewAura::GetMaximumSize() const {
2065 void RenderWidgetHostViewAura::OnBoundsChanged(const gfx::Rect& old_bounds,
2066 const gfx::Rect& new_bounds) {
2067 base::AutoReset<bool> in_bounds_changed(&in_bounds_changed_, true);
2068 // We care about this whenever RenderWidgetHostViewAura is not owned by a
2069 // WebContentsViewAura since changes to the Window's bounds need to be
2070 // messaged to the renderer. WebContentsViewAura invokes SetSize() or
2071 // SetBounds() itself. No matter how we got here, any redundant calls are
2073 SetSize(new_bounds.size());
2075 if (GetInputMethod()) {
2076 GetInputMethod()->OnCaretBoundsChanged(this);
2077 UpdateInsetsWithVirtualKeyboardEnabled();
2081 gfx::NativeCursor RenderWidgetHostViewAura::GetCursor(const gfx::Point& point) {
2082 if (IsMouseLocked())
2083 return ui::mojom::CursorType::kNone;
2084 return current_cursor_.GetNativeCursor();
2087 int RenderWidgetHostViewAura::GetNonClientComponent(
2088 const gfx::Point& point) const {
2092 bool RenderWidgetHostViewAura::ShouldDescendIntoChildForEventHandling(
2093 aura::Window* child,
2094 const gfx::Point& location) {
2098 bool RenderWidgetHostViewAura::CanFocus() {
2099 return widget_type_ == WidgetType::kFrame;
2102 void RenderWidgetHostViewAura::OnCaptureLost() {
2103 host()->LostCapture();
2106 void RenderWidgetHostViewAura::OnPaint(const ui::PaintContext& context) {
2110 void RenderWidgetHostViewAura::OnDeviceScaleFactorChanged(
2111 float old_device_scale_factor,
2112 float new_device_scale_factor) {
2113 if (!window_->GetRootWindow())
2116 // TODO(crbug.com/1446142): Add unittest for lacros.
2117 if (needs_to_update_display_metrics_ ||
2118 old_device_scale_factor != new_device_scale_factor) {
2119 ProcessDisplayMetricsChanged();
2122 SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
2123 window_->GetLocalSurfaceId());
2125 device_scale_factor_ = new_device_scale_factor;
2126 const display::Display display =
2127 display::Screen::GetScreen()->GetDisplayNearestWindow(window_);
2128 // Sometimes GetDisplayNearestWindow returns the default monitor. We don't
2129 // want to use that here.
2130 if (display.is_valid()) {
2131 DCHECK_EQ(new_device_scale_factor, display.device_scale_factor());
2132 current_cursor_.SetDisplayInfo(display);
2136 void RenderWidgetHostViewAura::OnWindowDestroying(aura::Window* window) {
2137 #if BUILDFLAG(IS_WIN)
2138 // The LegacyRenderWidgetHostHWND instance is destroyed when its window is
2139 // destroyed. Normally we control when that happens via the Destroy call
2140 // in the dtor. However there may be cases where the window is destroyed
2141 // by Windows, i.e. the parent window is destroyed before the
2142 // RenderWidgetHostViewAura instance goes away etc. To avoid that we
2143 // destroy the LegacyRenderWidgetHostHWND instance here.
2144 if (legacy_render_widget_host_HWND_) {
2145 // The Destroy call below will delete the LegacyRenderWidgetHostHWND
2147 legacy_render_widget_host_HWND_.ExtractAsDangling()->Destroy();
2151 // Make sure that the input method no longer references to this object before
2152 // this object is removed from the root window (i.e. this object loses access
2153 // to the input method).
2154 DetachFromInputMethod(true);
2156 if (overscroll_controller_)
2157 overscroll_controller_->Reset();
2160 void RenderWidgetHostViewAura::OnWindowDestroyed(aura::Window* window) {
2161 // This is not called on all destruction paths (e.g. if this view was never
2162 // inialized properly to create the window). So the destruction/cleanup code
2163 // that do not depend on |window_| should happen in the destructor, not here.
2167 void RenderWidgetHostViewAura::OnWindowTargetVisibilityChanged(bool visible) {
2170 bool RenderWidgetHostViewAura::HasHitTestMask() const {
2174 void RenderWidgetHostViewAura::GetHitTestMask(SkPath* mask) const {}
2176 bool RenderWidgetHostViewAura::RequiresDoubleTapGestureEvents() const {
2177 RenderWidgetHostOwnerDelegate* owner_delegate = host()->owner_delegate();
2178 // TODO(crbug.com/916715): Child local roots do not work here?
2179 if (!owner_delegate)
2181 return double_tap_to_zoom_enabled_;
2184 ////////////////////////////////////////////////////////////////////////////////
2185 // RenderWidgetHostViewAura, ui::EventHandler implementation:
2187 void RenderWidgetHostViewAura::OnKeyEvent(ui::KeyEvent* event) {
2188 last_pointer_type_ = ui::EventPointerType::kUnknown;
2189 event_handler_->OnKeyEvent(event);
2192 void RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent* event) {
2193 #if BUILDFLAG(IS_WIN)
2194 if (event->type() == ui::ET_MOUSE_MOVED) {
2195 if (event->location() == last_mouse_move_location_ &&
2196 event->movement().IsZero()) {
2197 event->SetHandled();
2200 last_mouse_move_location_ = event->location();
2203 #if BUILDFLAG(IS_EFL)
2205 efl_helper_->OnMouseOrTouchEvent(event);
2207 last_pointer_type_ = ui::EventPointerType::kMouse;
2208 event_handler_->OnMouseEvent(event);
2211 bool RenderWidgetHostViewAura::HasFallbackSurface() const {
2212 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2213 return delegated_frame_host_->HasFallbackSurface();
2216 bool RenderWidgetHostViewAura::TransformPointToCoordSpaceForView(
2217 const gfx::PointF& point,
2218 RenderWidgetHostViewBase* target_view,
2219 gfx::PointF* transformed_point) {
2220 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2222 if (target_view == this) {
2223 *transformed_point = point;
2227 // In TransformPointToLocalCoordSpace() there is a Point-to-Pixel conversion,
2228 // but it is not necessary here because the final target view is responsible
2229 // for converting before computing the final transform.
2230 return target_view->TransformPointToLocalCoordSpace(
2231 point, GetCurrentSurfaceId(), transformed_point);
2234 viz::FrameSinkId RenderWidgetHostViewAura::GetRootFrameSinkId() {
2235 if (!GetCompositor())
2236 return viz::FrameSinkId();
2238 return GetCompositor()->frame_sink_id();
2241 viz::SurfaceId RenderWidgetHostViewAura::GetCurrentSurfaceId() const {
2242 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2243 return delegated_frame_host_->GetCurrentSurfaceId();
2246 void RenderWidgetHostViewAura::FocusedNodeChanged(
2248 const gfx::Rect& node_bounds_in_screen
2249 #if BUILDFLAG(IS_TIZEN_TV)
2251 bool is_radio_or_checkbox,
2252 int password_input_minlength,
2255 #if BUILDFLAG(IS_EFL)
2257 bool is_content_editable
2260 // The last gesture most likely caused the focus change. The focus reason will
2261 // be incorrect if the focus was triggered without a user gesture.
2262 // TODO(https://crbug.com/824604): Get the focus reason from the renderer
2263 // process instead to get the true focus reason.
2264 last_pointer_type_before_focus_ = last_pointer_type_;
2266 auto* input_method = GetInputMethod();
2268 input_method->CancelComposition(this);
2269 has_composition_text_ = false;
2271 #if defined(USE_EFL)
2272 efl_helper_->FocusedNodeChanged(
2274 #if BUILDFLAG(IS_TIZEN_TV)
2276 is_radio_or_checkbox, password_input_minlength, input_maxlength
2279 is_content_editable);
2282 #if BUILDFLAG(IS_WIN)
2283 if (window_ && virtual_keyboard_controller_win_) {
2284 virtual_keyboard_controller_win_->FocusedNodeChanged(editable);
2289 #if defined(TIZEN_VIDEO_HOLE)
2290 void RenderWidgetHostViewAura::DidMoveWebView() {
2291 if (!on_webview_moved_callback_.is_null())
2292 on_webview_moved_callback_.Run();
2295 void RenderWidgetHostViewAura::SetWebViewMovedCallback(
2296 const base::RepeatingClosure on_webview_moved) {
2297 on_webview_moved_callback_ = std::move(on_webview_moved);
2301 #if BUILDFLAG(IS_TIZEN_TV)
2302 void RenderWidgetHostViewAura::DidEdgeScrollBy(const gfx::Point& offset,
2304 efl_helper_->DidEdgeScrollBy(offset, handled);
2308 void RenderWidgetHostViewAura::OnScrollEvent(ui::ScrollEvent* event) {
2309 event_handler_->OnScrollEvent(event);
2312 void RenderWidgetHostViewAura::OnTouchEvent(ui::TouchEvent* event) {
2313 #if BUILDFLAG(IS_EFL)
2315 efl_helper_->OnMouseOrTouchEvent(event);
2317 last_pointer_type_ = event->pointer_details().pointer_type;
2318 ui::InputMethod* input_method = GetInputMethod();
2319 if (window_ && window_->HasFocus() && input_method) {
2320 input_method->OnTouch(event->pointer_details().pointer_type);
2322 event_handler_->OnTouchEvent(event);
2325 void RenderWidgetHostViewAura::OnGestureEvent(ui::GestureEvent* event) {
2326 last_pointer_type_ = event->details().primary_pointer_type();
2327 #if BUILDFLAG(IS_EFL)
2328 // Gesture event will be processed and forwarded via efl helper.
2329 efl_helper_->OnGestureEvent(event);
2332 event_handler_->OnGestureEvent(event);
2335 base::StringPiece RenderWidgetHostViewAura::GetLogContext() const {
2336 return "RenderWidgetHostViewAura";
2339 ////////////////////////////////////////////////////////////////////////////////
2340 // RenderWidgetHostViewAura, wm::ActivationDelegate implementation:
2342 bool RenderWidgetHostViewAura::ShouldActivate() const {
2343 aura::WindowTreeHost* host = window_->GetHost();
2346 const ui::Event* event = host->dispatcher()->current_event();
2350 ////////////////////////////////////////////////////////////////////////////////
2351 // RenderWidgetHostViewAura, aura::client::CursorClientObserver implementation:
2353 void RenderWidgetHostViewAura::OnCursorVisibilityChanged(bool is_visible) {
2354 NotifyRendererOfCursorVisibilityState(is_visible);
2357 void RenderWidgetHostViewAura::OnSystemCursorSizeChanged(
2358 const gfx::Size& system_cursor_size) {
2359 UpdateSystemCursorSize(system_cursor_size);
2362 ////////////////////////////////////////////////////////////////////////////////
2363 // RenderWidgetHostViewAura, aura::client::FocusChangeObserver implementation:
2365 void RenderWidgetHostViewAura::OnWindowFocused(aura::Window* gained_focus,
2366 aura::Window* lost_focus) {
2367 LOG(INFO) << "OnWindowFocused, Gained : " << gained_focus
2368 << ", Lost : " << lost_focus;
2369 if (window_ == gained_focus) {
2370 #if !BUILDFLAG(IS_TIZEN_TV)
2371 // We need to honor input bypass if the associated tab does not want input.
2372 // This gives the current focused window a chance to be the text input
2373 // client and handle events.
2374 if (host()->IsIgnoringInputEvents())
2379 UpdateActiveState(true);
2381 ui::InputMethod* input_method = GetInputMethod();
2383 // Ask the system-wide IME to send all TextInputClient messages to |this|
2385 input_method->SetFocusedTextInputClient(this);
2388 BrowserAccessibilityManager* manager =
2389 host()->GetRootBrowserAccessibilityManager();
2391 manager->OnWindowFocused();
2395 if (window_ != lost_focus) {
2400 UpdateActiveState(false);
2401 host()->LostFocus();
2403 DetachFromInputMethod(false);
2405 // TODO(wjmaclean): Do we need to let TouchSelectionControllerClientAura
2406 // handle this, just in case it stomps on a new highlight in another view
2407 // that has just become focused? So far it doesn't appear to be a problem,
2408 // but we should keep an eye on it.
2409 selection_controller_->HideAndDisallowShowingAutomatically();
2411 if (overscroll_controller_)
2412 overscroll_controller_->Cancel();
2414 BrowserAccessibilityManager* manager =
2415 host()->GetRootBrowserAccessibilityManager();
2417 manager->OnWindowBlurred();
2419 // Close the child popup window if we lose focus (e.g. due to a JS alert or
2420 // system modal dialog). This is particularly important if
2421 // |popup_child_host_view_| has mouse capture.
2422 if (popup_child_host_view_)
2423 popup_child_host_view_->Shutdown();
2426 ////////////////////////////////////////////////////////////////////////////////
2427 // RenderWidgetHostViewAura, aura::WindowTreeHostObserver implementation:
2429 void RenderWidgetHostViewAura::OnHostMovedInPixels(aura::WindowTreeHost* host) {
2430 TRACE_EVENT0("ui", "RenderWidgetHostViewAura::OnHostMovedInPixels");
2435 ////////////////////////////////////////////////////////////////////////////////
2436 // RenderWidgetHostViewAura, RenderFrameMetadataProvider::Observer
2438 void RenderWidgetHostViewAura::OnRenderFrameMetadataChangedAfterActivation(
2439 base::TimeTicks activation_time) {
2440 const cc::RenderFrameMetadata& metadata =
2441 host()->render_frame_metadata_provider()->LastRenderFrameMetadata();
2443 // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
2444 SetContentBackgroundColor(metadata.root_background_color.toSkColor());
2445 if (inset_surface_id_.is_valid() && metadata.local_surface_id &&
2446 metadata.local_surface_id.value().is_valid() &&
2447 metadata.local_surface_id.value().IsSameOrNewerThan(inset_surface_id_)) {
2448 inset_surface_id_ = viz::LocalSurfaceId();
2449 ScrollFocusedEditableNodeIntoView();
2452 if (metadata.selection.start != selection_start_ ||
2453 metadata.selection.end != selection_end_) {
2454 selection_start_ = metadata.selection.start;
2455 selection_end_ = metadata.selection.end;
2456 selection_controller_client_->UpdateClientSelectionBounds(selection_start_,
2461 #if BUILDFLAG(IS_EFL)
2462 RWHVAuraOffscreenHelperEfl* RenderWidgetHostViewAura::offscreen_helper() {
2463 if (!efl_helper_->IsOffscreenMode()) {
2464 DLOG(INFO) << "Onscreen rendering mode is set";
2468 return static_cast<RWHVAuraOffscreenHelperEfl*>(efl_helper_.get());
2471 void RenderWidgetHostViewAura::DidChangeInputType(bool is_password_field) {
2472 efl_helper_->DidChangeInputType(is_password_field);
2475 void RenderWidgetHostViewAura::OnGetFocusedNodeBounds(const gfx::RectF& rect) {
2476 efl_helper_->OnGetFocusedNodeBounds(rect);
2479 void RenderWidgetHostViewAura::OnGetMainFrameScrollbarVisible(int callback_id,
2481 efl_helper_->OnGetMainFrameScrollbarVisible(callback_id, visible);
2485 ////////////////////////////////////////////////////////////////////////////////
2486 // RenderWidgetHostViewAura, private:
2488 RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
2489 host()->render_frame_metadata_provider()->RemoveObserver(this);
2491 // Ask the RWH to drop reference to us.
2492 host()->ViewDestroyed();
2494 // Dismiss any visible touch selection handles or touch selection menu.
2495 selection_controller_->HideAndDisallowShowingAutomatically();
2496 selection_controller_.reset();
2497 selection_controller_client_.reset();
2499 GetCursorManager()->ViewBeingDestroyed(this);
2501 delegated_frame_host_.reset();
2502 window_observer_.reset();
2504 if (window_->GetHost())
2505 window_->GetHost()->RemoveObserver(this);
2507 wm::SetTooltipText(window_, nullptr);
2509 // This call is usually no-op since |this| object is already removed from
2510 // the Aura root window and we don't have a way to get an input method
2511 // object associated with the window, but just in case.
2512 DetachFromInputMethod(true);
2514 if (popup_parent_host_view_) {
2515 DCHECK(!popup_parent_host_view_->popup_child_host_view_ ||
2516 popup_parent_host_view_->popup_child_host_view_ == this);
2517 popup_parent_host_view_->SetPopupChild(nullptr);
2519 if (popup_child_host_view_) {
2520 DCHECK(!popup_child_host_view_->popup_parent_host_view_ ||
2521 popup_child_host_view_->popup_parent_host_view_ == this);
2522 popup_child_host_view_->popup_parent_host_view_ = nullptr;
2524 event_observer_for_popup_exit_.reset();
2526 #if BUILDFLAG(IS_WIN)
2527 // The LegacyRenderWidgetHostHWND window should have been destroyed in
2528 // RenderWidgetHostViewAura::OnWindowDestroying and the pointer should
2530 DCHECK(!legacy_render_widget_host_HWND_);
2533 if (text_input_manager_)
2534 text_input_manager_->RemoveObserver(this);
2537 void RenderWidgetHostViewAura::CreateAuraWindow(aura::client::WindowType type) {
2539 window_ = new aura::Window(this);
2540 window_->SetName("RenderWidgetHostViewAura");
2541 event_handler_->set_window(window_);
2542 window_observer_ = std::make_unique<WindowObserver>(this);
2544 wm::SetTooltipText(window_, &tooltip_);
2545 wm::SetActivationDelegate(window_, this);
2546 aura::client::SetFocusChangeObserver(window_, this);
2547 display_observer_.emplace(this);
2549 window_->SetType(type);
2550 window_->Init(ui::LAYER_SOLID_COLOR);
2551 window_->layer()->SetColor(GetBackgroundColor() ? *GetBackgroundColor()
2553 // This needs to happen only after |window_| has been initialized using
2554 // Init(), because it needs to have the layer.
2555 window_->SetEmbedFrameSinkId(frame_sink_id_);
2558 void RenderWidgetHostViewAura::CreateDelegatedFrameHostClient() {
2559 delegated_frame_host_client_ =
2560 std::make_unique<DelegatedFrameHostClientAura>(this);
2561 delegated_frame_host_ = std::make_unique<DelegatedFrameHost>(
2562 frame_sink_id_, delegated_frame_host_client_.get(),
2563 false /* should_register_frame_sink_id */);
2566 void RenderWidgetHostViewAura::UpdateCursorIfOverSelf() {
2567 if (host()->GetProcess()->FastShutdownStarted())
2570 aura::Window* root_window = window_->GetRootWindow();
2574 if (ShouldSkipCursorUpdate())
2577 display::Screen* screen = display::Screen::GetScreen();
2579 gfx::Point root_window_point = screen->GetCursorScreenPoint();
2580 aura::client::ScreenPositionClient* screen_position_client =
2581 aura::client::GetScreenPositionClient(root_window);
2582 if (screen_position_client) {
2583 screen_position_client->ConvertPointFromScreen(
2584 root_window, &root_window_point);
2587 if (root_window->GetEventHandlerForPoint(root_window_point) != window_)
2590 gfx::NativeCursor cursor = current_cursor_.GetNativeCursor();
2591 // Do not show loading cursor when the cursor is currently hidden.
2592 if (is_loading_ && cursor != ui::mojom::CursorType::kNone)
2593 cursor = ui::Cursor(ui::mojom::CursorType::kPointer);
2595 aura::client::CursorClient* cursor_client =
2596 aura::client::GetCursorClient(root_window);
2597 if (cursor_client) {
2598 cursor_client->SetCursor(cursor);
2602 bool RenderWidgetHostViewAura::SynchronizeVisualProperties(
2603 const cc::DeadlinePolicy& deadline_policy,
2604 const absl::optional<viz::LocalSurfaceId>& child_local_surface_id) {
2606 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2608 window_->UpdateLocalSurfaceIdFromEmbeddedClient(child_local_surface_id);
2609 // If the viz::LocalSurfaceId is invalid, we may have been evicted,
2610 // allocate a new one to establish bounds.
2611 if (!GetLocalSurfaceId().is_valid())
2612 window_->AllocateLocalSurfaceId();
2614 delegated_frame_host_->EmbedSurface(
2615 GetLocalSurfaceId(), window_->bounds().size(), deadline_policy);
2617 return host()->SynchronizeVisualProperties();
2620 void RenderWidgetHostViewAura::OnDidUpdateVisualPropertiesComplete(
2621 const cc::RenderFrameMetadata& metadata) {
2624 if (host()->delegate()) {
2625 host()->delegate()->SetTopControlsShownRatio(
2626 host(), metadata.top_controls_shown_ratio);
2629 if (host()->is_hidden()) {
2630 // When an embedded child responds, we want to accept its changes to the
2631 // viz::LocalSurfaceId. However we do not want to embed surfaces while
2632 // hidden. Nor do we want to embed invalid ids when we are evicted. Becoming
2633 // visible will generate a new id, if necessary, and begin embedding.
2634 window_->UpdateLocalSurfaceIdFromEmbeddedClient(metadata.local_surface_id);
2636 SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
2637 metadata.local_surface_id);
2641 ui::InputMethod* RenderWidgetHostViewAura::GetInputMethod() const {
2644 aura::Window* root_window = window_->GetRootWindow();
2647 return root_window->GetHost()->GetInputMethod();
2650 RenderWidgetHostViewBase*
2651 RenderWidgetHostViewAura::GetFocusedViewForTextSelection() const {
2652 // We obtain the TextSelection from focused RWH which is obtained from the
2654 return GetFocusedWidget() ? GetFocusedWidget()->GetView() : nullptr;
2657 void RenderWidgetHostViewAura::Shutdown() {
2658 if (!in_shutdown_) {
2659 in_shutdown_ = true;
2660 host()->ShutdownAndDestroyWidget(true);
2664 ui::mojom::VirtualKeyboardMode
2665 RenderWidgetHostViewAura::GetVirtualKeyboardMode() {
2666 // overlaycontent flag can only be set from main frame.
2667 RenderFrameHostImpl* frame = host()->frame_tree()->GetMainFrame();
2669 return ui::mojom::VirtualKeyboardMode::kUnset;
2671 return frame->GetPage().virtual_keyboard_mode();
2674 void RenderWidgetHostViewAura::NotifyVirtualKeyboardOverlayRect(
2675 const gfx::Rect& keyboard_rect) {
2676 // geometrychange event can only be fired on main frame and not focused frame
2677 // which could be an iframe.
2678 RenderFrameHostImpl* frame = host()->frame_tree()->GetMainFrame();
2682 if (GetVirtualKeyboardMode() !=
2683 ui::mojom::VirtualKeyboardMode::kOverlaysContent) {
2686 gfx::Rect keyboard_root_relative_rect = keyboard_rect;
2687 if (!keyboard_root_relative_rect.IsEmpty()) {
2688 // If the rect is non-empty, we need to transform it to be widget-relative
2689 // window (DIP coordinates). The input is client coordinates for the root
2691 // Transform the widget rect origin to root relative coords.
2692 gfx::PointF root_widget_origin(0.f, 0.f);
2693 TransformPointToRootSurface(&root_widget_origin);
2694 gfx::Rect root_widget_rect =
2695 gfx::Rect(root_widget_origin.x(), root_widget_origin.y(),
2696 GetViewBounds().width(), GetViewBounds().height());
2697 // Intersect the keyboard rect with the root widget bounds and transform
2698 // back to widget-relative coordinates, which will be sent to the renderer.
2699 keyboard_root_relative_rect.Intersect(root_widget_rect);
2700 keyboard_root_relative_rect.Offset(-root_widget_origin.x(),
2701 -root_widget_origin.y());
2703 frame->GetPage().NotifyVirtualKeyboardOverlayRect(
2704 keyboard_root_relative_rect);
2707 bool RenderWidgetHostViewAura::IsHTMLFormPopup() const {
2708 return !!popup_parent_host_view_;
2711 bool RenderWidgetHostViewAura::FocusedFrameHasStickyActivation() const {
2712 // Unless user has interacted with the iframe, we shouldn't be displaying VK
2713 // or fire geometrychange event.
2714 RenderFrameHostImpl* frame = GetFocusedFrame();
2718 return frame->frame_tree_node()->HasStickyUserActivation();
2721 TouchSelectionControllerClientManager*
2722 RenderWidgetHostViewAura::GetTouchSelectionControllerClientManager() {
2723 return selection_controller_client_.get();
2726 bool RenderWidgetHostViewAura::NeedsInputGrab() {
2727 return widget_type_ == WidgetType::kPopup;
2730 bool RenderWidgetHostViewAura::NeedsMouseCapture() {
2731 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
2732 return NeedsInputGrab();
2738 void RenderWidgetHostViewAura::SetTooltipsEnabled(bool enable) {
2740 tooltip_disabler_.reset();
2743 std::make_unique<wm::ScopedTooltipDisabler>(window_->GetRootWindow());
2747 void RenderWidgetHostViewAura::NotifyRendererOfCursorVisibilityState(
2749 if (host()->is_hidden() ||
2750 (cursor_visibility_state_in_renderer_ == VISIBLE && is_visible) ||
2751 (cursor_visibility_state_in_renderer_ == NOT_VISIBLE && !is_visible))
2754 cursor_visibility_state_in_renderer_ = is_visible ? VISIBLE : NOT_VISIBLE;
2755 host()->OnCursorVisibilityStateChanged(is_visible);
2758 void RenderWidgetHostViewAura::SetOverscrollControllerEnabled(bool enabled) {
2760 overscroll_controller_.reset();
2761 else if (!overscroll_controller_)
2762 overscroll_controller_ = std::make_unique<OverscrollController>();
2765 void RenderWidgetHostViewAura::SetSelectionControllerClientForTest(
2766 std::unique_ptr<TouchSelectionControllerClientAura> client) {
2767 selection_controller_client_.swap(client);
2768 CreateSelectionController();
2771 void RenderWidgetHostViewAura::InternalSetBounds(const gfx::Rect& rect) {
2772 // Don't recursively call SetBounds if this bounds update is the result of
2773 // a Window::SetBoundsInternal call.
2774 if (!in_bounds_changed_)
2775 window_->SetBounds(rect);
2777 if (!viewport_segments_.empty()) {
2778 // The view bounds have changed so if we have viewport segments from the
2779 // platform we need to make sure display_feature_ is updated considering the
2781 ComputeDisplayFeature();
2784 // Even if not showing yet, we need to synchronize on size. As the renderer
2785 // needs to begin layout. Waiting until we show to start layout leads to
2786 // significant delays in embedding the first shown surface (500+ ms.)
2787 SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
2788 window_->GetLocalSurfaceId());
2790 #if BUILDFLAG(IS_WIN)
2793 if (IsMouseLocked())
2794 UpdateMouseLockRegion();
2798 void RenderWidgetHostViewAura::UpdateInsetsWithVirtualKeyboardEnabled() {
2799 // Update insets if the keyboard is shown.
2800 if (!keyboard_occluded_bounds_.IsEmpty()) {
2801 SetInsets(gfx::Insets::TLBR(
2803 gfx::IntersectRects(GetViewBounds(), keyboard_occluded_bounds_)
2809 #if BUILDFLAG(IS_WIN)
2810 void RenderWidgetHostViewAura::UpdateLegacyWin() {
2811 if (legacy_window_destroyed_ || !GetHostWindowHWND())
2814 if (!legacy_render_widget_host_HWND_) {
2815 legacy_render_widget_host_HWND_ =
2816 LegacyRenderWidgetHostHWND::Create(GetHostWindowHWND(), this);
2819 if (legacy_render_widget_host_HWND_) {
2820 legacy_render_widget_host_HWND_->UpdateParent(GetHostWindowHWND());
2821 legacy_render_widget_host_HWND_->SetBounds(
2822 window_->GetBoundsInRootWindow());
2823 // There are cases where the parent window is created, made visible and
2824 // the associated RenderWidget is also visible before the
2825 // LegacyRenderWidgetHostHWND instace is created. Ensure that it is shown
2827 if (!host()->is_hidden())
2828 legacy_render_widget_host_HWND_->Show();
2833 void RenderWidgetHostViewAura::AddedToRootWindow() {
2834 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2836 #if BUILDFLAG(IS_EFL)
2837 efl_helper_->AuraChildWindowAdded();
2840 window_->GetHost()->AddObserver(this);
2843 aura::client::CursorClient* cursor_client =
2844 aura::client::GetCursorClient(window_->GetRootWindow());
2845 if (cursor_client) {
2846 cursor_client->AddObserver(this);
2847 NotifyRendererOfCursorVisibilityState(cursor_client->IsCursorVisible());
2850 ui::InputMethod* input_method = GetInputMethod();
2852 input_method->SetFocusedTextInputClient(this);
2855 #if BUILDFLAG(IS_WIN)
2859 delegated_frame_host_->AttachToCompositor(GetCompositor());
2862 void RenderWidgetHostViewAura::RemovingFromRootWindow() {
2863 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2865 aura::client::CursorClient* cursor_client =
2866 aura::client::GetCursorClient(window_->GetRootWindow());
2868 cursor_client->RemoveObserver(this);
2870 DetachFromInputMethod(true);
2872 window_->GetHost()->RemoveObserver(this);
2873 delegated_frame_host_->DetachFromCompositor();
2875 #if BUILDFLAG(IS_WIN)
2876 // Update the legacy window's parent temporarily to the hidden window. It
2877 // will eventually get reparented to the right root.
2878 if (legacy_render_widget_host_HWND_)
2879 legacy_render_widget_host_HWND_->UpdateParent(ui::GetHiddenWindow());
2883 void RenderWidgetHostViewAura::DetachFromInputMethod(bool is_removed) {
2884 ui::InputMethod* input_method = GetInputMethod();
2886 input_method->DetachTextInputClient(this);
2887 #if BUILDFLAG(IS_CHROMEOS_ASH)
2888 wm::RestoreWindowBoundsOnClientFocusLost(window_->GetToplevelWindow());
2889 #endif // BUILDFLAG(IS_CHROMEOS_ASH)
2892 #if BUILDFLAG(IS_WIN)
2893 // If window is getting destroyed, then reset the VK controller, else,
2894 // dismiss the VK and notify about the keyboard inset since window has lost
2896 if (virtual_keyboard_controller_win_) {
2898 virtual_keyboard_controller_win_.reset();
2900 virtual_keyboard_controller_win_->HideAndNotifyKeyboardInset();
2902 #endif // BUILDFLAG(IS_WIN)
2905 void RenderWidgetHostViewAura::ForwardKeyboardEventWithLatencyInfo(
2906 const NativeWebKeyboardEvent& event,
2907 const ui::LatencyInfo& latency,
2908 bool* update_event) {
2909 RenderWidgetHostImpl* target_host = host();
2911 // If there are multiple widgets on the page (such as when there are
2912 // out-of-process iframes), pick the one that should process this event.
2913 if (host()->delegate())
2914 target_host = host()->delegate()->GetFocusedRenderWidgetHost(host());
2918 #if BUILDFLAG(IS_LINUX)
2919 auto* linux_ui = ui::LinuxUi::instance();
2920 std::vector<ui::TextEditCommandAuraLinux> commands;
2921 if (!event.skip_if_unhandled && linux_ui && event.os_event &&
2922 linux_ui->GetTextEditCommandsForEvent(
2924 base::FeatureList::IsEnabled(
2925 blink::features::kArrowKeysInVerticalWritingModes)
2926 ? GetTextInputFlags()
2927 : ui::TEXT_INPUT_FLAG_NONE,
2929 // Transform from ui/ types to content/ types.
2930 std::vector<blink::mojom::EditCommandPtr> edit_commands;
2931 for (std::vector<ui::TextEditCommandAuraLinux>::const_iterator it =
2932 commands.begin(); it != commands.end(); ++it) {
2933 edit_commands.push_back(blink::mojom::EditCommand::New(
2934 it->GetCommandString(), it->argument()));
2937 target_host->ForwardKeyboardEventWithCommands(
2938 event, latency, std::move(edit_commands), update_event);
2943 target_host->ForwardKeyboardEventWithCommands(
2944 event, latency, std::vector<blink::mojom::EditCommandPtr>(),
2948 void RenderWidgetHostViewAura::CreateSelectionController() {
2949 ui::TouchSelectionController::Config tsc_config;
2950 tsc_config.max_tap_duration = base::Milliseconds(
2951 ui::GestureConfiguration::GetInstance()->long_press_time_in_ms());
2952 tsc_config.tap_slop = ui::GestureConfiguration::GetInstance()
2953 ->max_touch_move_in_pixels_for_click();
2954 tsc_config.enable_longpress_drag_selection =
2955 features::IsTouchTextEditingRedesignEnabled();
2956 selection_controller_ = std::make_unique<ui::TouchSelectionController>(
2957 selection_controller_client_.get(), tsc_config);
2960 void RenderWidgetHostViewAura::DidNavigateMainFramePreCommit() {
2961 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2963 // Invalidate the surface so that we don't attempt to evict it multiple times.
2964 window_->InvalidateLocalSurfaceId();
2965 delegated_frame_host_->DidNavigateMainFramePreCommit();
2966 CancelActiveTouches();
2969 void RenderWidgetHostViewAura::DidEnterBackForwardCache() {
2970 CHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
2972 window_->AllocateLocalSurfaceId();
2973 delegated_frame_host_->DidEnterBackForwardCache();
2974 // If we have the fallback content timer running, force it to stop. Else, when
2975 // the page is restored the timer could also fire, setting whatever
2976 // `DelegatedFrameHost::first_local_surface_id_after_navigation_` as the
2977 // fallback to our Surfacelayer.
2979 // This is safe for BFCache restore because we will supply specific fallback
2980 // surfaces for BFCache.
2982 // We do not want to call this in `RWHImpl::WasHidden()` because in the case
2983 // of `Visibility::OCCLUDED` we still want to keep the timer running.
2985 // Called after to prevent prematurely evict the BFCached surface.
2986 host()->ForceFirstFrameAfterNavigationTimeout();
2989 const viz::FrameSinkId& RenderWidgetHostViewAura::GetFrameSinkId() const {
2990 return frame_sink_id_;
2993 const viz::LocalSurfaceId& RenderWidgetHostViewAura::GetLocalSurfaceId() const {
2994 return window_->GetLocalSurfaceId();
2997 void RenderWidgetHostViewAura::OnUpdateTextInputStateCalled(
2998 TextInputManager* text_input_manager,
2999 RenderWidgetHostViewBase* updated_view,
3000 bool did_update_state) {
3001 DCHECK_EQ(text_input_manager_, text_input_manager);
3003 if (!GetInputMethod())
3006 if (did_update_state)
3007 GetInputMethod()->OnTextInputTypeChanged(this);
3009 const ui::mojom::TextInputState* state =
3010 text_input_manager_->GetTextInputState();
3012 #if BUILDFLAG(IS_CHROMEOS)
3013 if (state && state->type != ui::TEXT_INPUT_TYPE_NONE) {
3014 if (state->last_vk_visibility_request ==
3015 ui::mojom::VirtualKeyboardVisibilityRequest::SHOW) {
3016 GetInputMethod()->SetVirtualKeyboardVisibilityIfEnabled(true);
3017 } else if (state->last_vk_visibility_request ==
3018 ui::mojom::VirtualKeyboardVisibilityRequest::HIDE) {
3019 GetInputMethod()->SetVirtualKeyboardVisibilityIfEnabled(false);
3024 // Show the virtual keyboard if needed.
3025 if (state && state->type != ui::TEXT_INPUT_TYPE_NONE &&
3026 state->mode != ui::TEXT_INPUT_MODE_NONE) {
3027 #if !BUILDFLAG(IS_WIN)
3028 if (state->show_ime_if_needed &&
3029 GetInputMethod()->GetTextInputClient() == this) {
3030 GetInputMethod()->SetVirtualKeyboardVisibilityIfEnabled(true);
3032 // TODO(crbug.com/1031786): Remove this once TSF fix for input pane policy
3034 #elif BUILDFLAG(IS_WIN)
3035 if (GetInputMethod()) {
3036 if (!virtual_keyboard_controller_win_) {
3037 virtual_keyboard_controller_win_ =
3038 std::make_unique<VirtualKeyboardControllerWin>(this,
3041 virtual_keyboard_controller_win_->UpdateTextInputState(state);
3046 // Ensure that selection bounds changes are sent to the IME.
3047 if (state && state->type != ui::TEXT_INPUT_TYPE_NONE) {
3048 text_input_manager->NotifySelectionBoundsChanged(updated_view);
3051 if (auto* render_widget_host = updated_view->host()) {
3052 // Monitor the composition information if there is a focused editable node.
3053 render_widget_host->RequestCompositionUpdates(
3054 false /* immediate_request */,
3056 (state->type != ui::TEXT_INPUT_TYPE_NONE) /* monitor_updates */);
3060 void RenderWidgetHostViewAura::OnImeCancelComposition(
3061 TextInputManager* text_input_manager,
3062 RenderWidgetHostViewBase* view) {
3063 // |view| is not necessarily the one corresponding to
3064 // TextInputManager::GetActiveWidget() as RenderWidgetHostViewAura can call
3065 // this method to finish any ongoing composition in response to a mouse down
3067 if (GetInputMethod())
3068 GetInputMethod()->CancelComposition(this);
3069 has_composition_text_ = false;
3072 void RenderWidgetHostViewAura::OnSelectionBoundsChanged(
3073 TextInputManager* text_input_manager,
3074 RenderWidgetHostViewBase* updated_view) {
3075 // Note: accessibility caret move events are no longer fired directly here,
3076 // because they were redundant with the events fired by the top level window
3077 // by HWNDMessageHandler::OnCaretBoundsChanged().
3078 if (GetInputMethod())
3079 GetInputMethod()->OnCaretBoundsChanged(this);
3082 void RenderWidgetHostViewAura::OnTextSelectionChanged(
3083 TextInputManager* text_input_manager,
3084 RenderWidgetHostViewBase* updated_view) {
3085 if (!GetTextInputManager())
3088 // We obtain the TextSelection from focused RWH which is obtained from the
3090 RenderWidgetHostViewBase* focused_view =
3091 GetFocusedWidget() ? GetFocusedWidget()->GetView() : nullptr;
3096 // IMF relies on the |OnCaretBoundsChanged| for the surrounding text changed
3097 // events to IME. Explicitly call |OnCaretBoundsChanged| here so that IMF can
3098 // know about the surrounding text changes when the caret bounds are not
3099 // changed. e.g. When the rendered text is wider than the input field,
3100 // deleting the last character won't change the caret bounds but will change
3101 // the surrounding text.
3102 if (GetInputMethod())
3103 GetInputMethod()->OnCaretBoundsChanged(this);
3105 if (ui::Clipboard::IsSupportedClipboardBuffer(
3106 ui::ClipboardBuffer::kSelection)) {
3107 const TextInputManager::TextSelection* selection =
3108 GetTextInputManager()->GetTextSelection(focused_view);
3109 if (selection->selected_text().length()) {
3110 // Set the ClipboardBuffer::kSelection to the ui::Clipboard.
3111 ui::ScopedClipboardWriter clipboard_writer(
3112 ui::ClipboardBuffer::kSelection);
3113 clipboard_writer.WriteText(selection->selected_text());
3118 void RenderWidgetHostViewAura::SetPopupChild(
3119 RenderWidgetHostViewAura* popup_child_host_view) {
3120 popup_child_host_view_ = popup_child_host_view;
3121 event_handler_->SetPopupChild(
3122 popup_child_host_view,
3123 popup_child_host_view ? popup_child_host_view->event_handler() : nullptr);
3126 void RenderWidgetHostViewAura::ScrollFocusedEditableNodeIntoView() {
3127 auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
3130 input_handler->ScrollFocusedEditableNodeIntoView();
3133 void RenderWidgetHostViewAura::OnSynchronizedDisplayPropertiesChanged(
3135 SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
3139 viz::ScopedSurfaceIdAllocator
3140 RenderWidgetHostViewAura::DidUpdateVisualProperties(
3141 const cc::RenderFrameMetadata& metadata) {
3142 base::OnceCallback<void()> allocation_task = base::BindOnce(
3143 &RenderWidgetHostViewAura::OnDidUpdateVisualPropertiesComplete,
3144 weak_ptr_factory_.GetWeakPtr(), metadata);
3145 return window_->GetSurfaceIdAllocator(std::move(allocation_task));
3148 void RenderWidgetHostViewAura::DidNavigate() {
3149 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
3152 // Navigating while hidden should not allocate a new LocalSurfaceID. Once
3153 // sizes are ready, or we begin to Show, we can then allocate the new
3155 window_->InvalidateLocalSurfaceId();
3157 if (is_first_navigation_) {
3158 // The first navigation does not need a new LocalSurfaceID. The renderer
3159 // can use the ID that was already provided.
3160 SynchronizeVisualProperties(cc::DeadlinePolicy::UseExistingDeadline(),
3161 window_->GetLocalSurfaceId());
3163 SynchronizeVisualProperties(cc::DeadlinePolicy::UseExistingDeadline(),
3167 delegated_frame_host_->DidNavigate();
3168 is_first_navigation_ = false;
3171 MouseWheelPhaseHandler* RenderWidgetHostViewAura::GetMouseWheelPhaseHandler() {
3172 return &event_handler_->mouse_wheel_phase_handler();
3175 void RenderWidgetHostViewAura::TakeFallbackContentFrom(
3176 RenderWidgetHostView* view) {
3177 DCHECK(!static_cast<RenderWidgetHostViewBase*>(view)
3178 ->IsRenderWidgetHostViewChildFrame());
3179 RenderWidgetHostViewAura* view_aura =
3180 static_cast<RenderWidgetHostViewAura*>(view);
3181 CopyBackgroundColorIfPresentFrom(*view);
3183 DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
3184 DCHECK(view_aura->delegated_frame_host_);
3185 delegated_frame_host_->TakeFallbackContentFrom(
3186 view_aura->delegated_frame_host_.get());
3189 bool RenderWidgetHostViewAura::CanSynchronizeVisualProperties() {
3190 return !needs_to_update_display_metrics_;
3193 std::vector<std::unique_ptr<ui::TouchEvent>>
3194 RenderWidgetHostViewAura::ExtractAndCancelActiveTouches() {
3195 aura::Env* env = aura::Env::GetInstance();
3196 std::vector<std::unique_ptr<ui::TouchEvent>> touches =
3197 env->gesture_recognizer()->ExtractTouches(window());
3198 CancelActiveTouches();
3202 void RenderWidgetHostViewAura::TransferTouches(
3203 const std::vector<std::unique_ptr<ui::TouchEvent>>& touches) {
3204 aura::Env* env = aura::Env::GetInstance();
3205 env->gesture_recognizer()->TransferTouches(window(), touches);
3208 void RenderWidgetHostViewAura::SetLastPointerType(
3209 ui::EventPointerType last_pointer_type) {
3210 last_pointer_type_ = last_pointer_type;
3213 void RenderWidgetHostViewAura::InvalidateLocalSurfaceIdAndAllocationGroup() {
3214 window_->InvalidateLocalSurfaceId(/*also_invalidate_allocation_group=*/true);
3217 void RenderWidgetHostViewAura::InvalidateLocalSurfaceIdOnEviction() {
3218 window_->InvalidateLocalSurfaceId();
3221 void RenderWidgetHostViewAura::ProcessDisplayMetricsChanged() {
3222 // TODO(crbug.com/1169291): Unify per-platform DisplayObserver instances.
3223 needs_to_update_display_metrics_ = false;
3225 current_cursor_.SetDisplayInfo(
3226 display::Screen::GetScreen()->GetDisplayNearestWindow(window_));
3227 UpdateCursorIfOverSelf();
3230 void RenderWidgetHostViewAura::CancelActiveTouches() {
3231 aura::Env* env = aura::Env::GetInstance();
3232 env->gesture_recognizer()->CancelActiveTouches(window());
3235 blink::mojom::FrameWidgetInputHandler*
3236 RenderWidgetHostViewAura::GetFrameWidgetInputHandlerForFocusedWidget() {
3237 auto* focused_widget = GetFocusedWidget();
3238 if (!focused_widget)
3240 return focused_widget->GetFrameWidgetInputHandler();
3243 void RenderWidgetHostViewAura::SetTooltipText(
3244 const std::u16string& tooltip_text) {
3245 tooltip_ = tooltip_text;
3246 if (tooltip_observer_for_testing_)
3247 tooltip_observer_for_testing_->OnTooltipTextUpdated(tooltip_text);
3250 ui::Compositor* RenderWidgetHostViewAura::GetCompositor() {
3251 if (!window_ || !window_->GetHost())
3254 return window_->GetHost()->compositor();
3257 } // namespace content