diff options
Diffstat (limited to 'src/core/render_widget_host_view_qt.cpp')
-rw-r--r-- | src/core/render_widget_host_view_qt.cpp | 783 |
1 files changed, 434 insertions, 349 deletions
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 27229df81..888043fda 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -1,47 +1,8 @@ - -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "render_widget_host_view_qt.h" -#include "browser_accessibility_manager_qt.h" -#include "common/qt_messages.h" #include "qtwebenginecoreglobal_p.h" #include "render_widget_host_view_qt_delegate.h" #include "render_widget_host_view_qt_delegate_client.h" @@ -51,26 +12,33 @@ #include "web_contents_adapter_client.h" #include "web_event_factory.h" -#include "base/threading/thread_task_runner_handle.h" #include "components/viz/common/features.h" #include "components/viz/common/frame_sinks/begin_frame_source.h" #include "components/viz/common/surfaces/frame_sink_id_allocator.h" #include "components/viz/host/host_frame_sink_manager.h" -#include "content/browser/frame_host/frame_tree.h" -#include "content/browser/frame_host/render_frame_host_impl.h" +#include "content/browser/compositor/image_transport_factory.h" +#include "content/browser/renderer_host/render_frame_host_impl.h" +#include "content/browser/renderer_host/frame_tree.h" +#include "content/browser/renderer_host/frame_tree_node.h" +#include "content/browser/renderer_host/cursor_manager.h" #include "content/browser/renderer_host/input/synthetic_gesture_target.h" +#include "content/browser/renderer_host/render_frame_host_impl.h" #include "content/browser/renderer_host/render_view_host_delegate.h" #include "content/browser/renderer_host/render_view_host_impl.h" -#include "content/common/content_switches_internal.h" #include "content/browser/renderer_host/render_widget_host_input_event_router.h" +#include "content/browser/renderer_host/ui_events_helper.h" +#include "content/common/content_switches_internal.h" #include "content/common/cursors/webcursor.h" -#include "content/common/input_messages.h" +#include "content/public/browser/web_contents.h" #include "third_party/skia/include/core/SkColor.h" -#include "third_party/blink/public/platform/web_cursor_info.h" +#include "ui/base/cursor/cursor.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/display/display_util.h" #include "ui/events/blink/blink_event_util.h" #include "ui/events/event.h" #include "ui/events/gesture_detection/gesture_configuration.h" #include "ui/events/gesture_detection/gesture_provider_config_helper.h" +#include "ui/events/keycodes/dom/dom_keyboard_layout_map.h" #include "ui/gfx/image/image_skia.h" #if defined(USE_OZONE) @@ -78,13 +46,17 @@ #endif #if defined(USE_AURA) -#include "ui/base/cursor/cursor.h" -#include "ui/base/cursor/cursors_aura.h" -#include "ui/base/resource/resource_bundle.h" +#include "ui/wm/core/cursor_util.h" +#include "ui/base/cursor/cursor_size.h" +#endif + +#if defined(Q_OS_MACOS) +#include "ui/resources/grit/ui_resources.h" #endif #include <QGuiApplication> #include <QPixmap> +#include <QScopeGuard> #include <QScreen> #include <QWindow> @@ -118,9 +90,61 @@ static inline ui::GestureProvider::Config QtGestureProviderConfig() { return config; } +extern display::Display toDisplayDisplay(int id, const QScreen *screen); + +static display::ScreenInfos screenInfosFromQtForUpdate(QScreen *currentScreen) +{ + display::ScreenInfo screenInfo; + const auto &screens = qApp->screens(); + if (screens.isEmpty()) { + screenInfo.device_scale_factor = qGuiApp->devicePixelRatio(); + return display::ScreenInfos(screenInfo); + } + + Q_ASSERT(qApp->primaryScreen() == screens.first()); + display::ScreenInfos result; + for (int i = 0; i < screens.length(); ++i) { + display::DisplayUtil::DisplayToScreenInfo(&screenInfo, toDisplayDisplay(i, screens.at(i))); + result.screen_infos.push_back(screenInfo); + if (currentScreen == screens.at(i)) + result.current_display_id = i; + } + + Q_ASSERT(result.current_display_id != display::kInvalidDisplayId); + + return result; +} + +// An minimal override to support progressing flings +class FlingingCompositor : public ui::Compositor +{ + RenderWidgetHostViewQt *m_rwhv; +public: + FlingingCompositor(RenderWidgetHostViewQt *rwhv, + const viz::FrameSinkId &frame_sink_id, + ui::ContextFactory *context_factory, + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + bool enable_pixel_canvas, + bool use_external_begin_frame_control = false, + bool force_software_compositor = false) + : ui::Compositor(frame_sink_id, context_factory, + task_runner, enable_pixel_canvas, + use_external_begin_frame_control, + force_software_compositor) + , m_rwhv(rwhv) + {} + + void BeginMainFrame(const viz::BeginFrameArgs &args) override + { + if (args.type != viz::BeginFrameArgs::MISSED && !m_rwhv->is_currently_scrolling_viewport()) + m_rwhv->host()->ProgressFlingIfNeeded(args.frame_time); + ui::Compositor::BeginMainFrame(args); + } +}; + RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget) : content::RenderWidgetHostViewBase::RenderWidgetHostViewBase(widget) - , m_taskRunner(base::ThreadTaskRunnerHandle::Get()) + , m_taskRunner(base::SingleThreadTaskRunner::GetCurrentDefault()) , m_gestureProvider(QtGestureProviderConfig(), this) , m_frameSinkId(host()->GetFrameSinkId()) , m_delegateClient(new RenderWidgetHostViewQtDelegateClient(this)) @@ -138,29 +162,24 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget content::ImageTransportFactory *imageTransportFactory = content::ImageTransportFactory::GetInstance(); ui::ContextFactory *contextFactory = imageTransportFactory->GetContextFactory(); - ui::ContextFactoryPrivate *contextFactoryPrivate = imageTransportFactory->GetContextFactoryPrivate(); - m_uiCompositor.reset(new ui::Compositor( - contextFactoryPrivate->AllocateFrameSinkId(), + m_uiCompositor.reset(new FlingingCompositor( + this, + contextFactory->AllocateFrameSinkId(), contextFactory, - contextFactoryPrivate, m_taskRunner, false /* enable_pixel_canvas */)); m_uiCompositor->SetAcceleratedWidget(gfx::kNullAcceleratedWidget); // null means offscreen m_uiCompositor->SetRootLayer(m_rootLayer.get()); - m_displayFrameSink = DisplayFrameSink::findOrCreate(m_uiCompositor->frame_sink_id()); - m_displayFrameSink->connect(this); - if (host()->delegate() && host()->delegate()->GetInputEventRouter()) host()->delegate()->GetInputEventRouter()->AddFrameSinkIdOwner(GetFrameSinkId(), this); + m_cursorManager.reset(new content::CursorManager(this)); + m_touchSelectionControllerClient.reset(new TouchSelectionControllerClientQt(this)); - ui::TouchSelectionController::Config config; - config.max_tap_duration = base::TimeDelta::FromMilliseconds(ui::GestureConfiguration::GetInstance()->long_press_time_in_ms()); - config.tap_slop = ui::GestureConfiguration::GetInstance()->max_touch_move_in_pixels_for_click(); - config.enable_longpress_drag_selection = false; - m_touchSelectionController.reset(new ui::TouchSelectionController(m_touchSelectionControllerClient.get(), config)); + resetTouchSelectionController(); + host()->render_frame_metadata_provider()->AddObserver(this); host()->render_frame_metadata_provider()->ReportAllFrameSubmissionsForTesting(true); host()->SetView(this); @@ -172,13 +191,17 @@ RenderWidgetHostViewQt::~RenderWidgetHostViewQt() QObject::disconnect(m_adapterClientDestroyedConnection); - m_displayFrameSink->disconnect(this); - if (text_input_manager_) text_input_manager_->RemoveObserver(this); + if (host()->delegate()) + m_touchSelectionControllerClient->resetControls(); + m_touchSelectionController.reset(); m_touchSelectionControllerClient.reset(); + + host()->render_frame_metadata_provider()->RemoveObserver(this); + host()->ViewDestroyed(); } void RenderWidgetHostViewQt::setDelegate(RenderWidgetHostViewQtDelegate* delegate) @@ -202,21 +225,51 @@ void RenderWidgetHostViewQt::setAdapterClient(WebContentsAdapterClient *adapterC m_adapterClient = nullptr; }); } -void RenderWidgetHostViewQt::InitAsChild(gfx::NativeView) +void RenderWidgetHostViewQt::OnInputEventAck(blink::mojom::InputEventResultSource, + blink::mojom::InputEventResultState state, + const blink::WebInputEvent &event) { + if (event.GetType() == blink::WebInputEvent::Type::kMouseWheel) + WheelEventAck(static_cast<const blink::WebMouseWheelEvent &>(event), state); } -void RenderWidgetHostViewQt::InitAsPopup(content::RenderWidgetHostView*, const gfx::Rect& rect) +// static +// Called when new child/guest renderframes created. +void RenderWidgetHostViewQt::registerInputEventObserver(content::WebContents *webContents, + content::RenderFrameHost *rfh) +{ + if (static_cast<content::RenderFrameHostImpl *>(rfh)->is_local_root_subframe()) { + content::WebContents *parent = webContents->GetOutermostWebContents(); + QtWebEngineCore::RenderWidgetHostViewQt *mainRwhv = + static_cast<QtWebEngineCore::RenderWidgetHostViewQt *>( + parent->GetRenderWidgetHostView()); + // Child (originAgentCluster) or guest (pdf) frame that is embedded into the main frame + content::RenderWidgetHost *childFrame = rfh->GetRenderWidgetHost(); + childFrame->AddInputEventObserver(mainRwhv); + + if (webContents->IsInnerWebContentsForGuest()) { + // The frame which holds the actual PDF content inside the guest + content::RenderWidgetHost *guestFrame = webContents->GetRenderViewHost()->GetWidget(); + guestFrame->AddInputEventObserver(mainRwhv); + } + } +} + +void RenderWidgetHostViewQt::InitAsChild(gfx::NativeView) { - m_delegate->initAsPopup(toQt(rect)); } -void RenderWidgetHostViewQt::InitAsFullscreen(content::RenderWidgetHostView*) +void RenderWidgetHostViewQt::InitAsPopup(content::RenderWidgetHostView*, const gfx::Rect& rect, const gfx::Rect& anchorRect) { + Q_UNUSED(anchorRect); + m_delegate->initAsPopup(toQt(rect)); } void RenderWidgetHostViewQt::SetSize(const gfx::Size &sizeInDips) { + if (!m_delegate) + return; + m_delegate->resize(sizeInDips.width(), sizeInDips.height()); } @@ -238,22 +291,16 @@ gfx::NativeView RenderWidgetHostViewQt::GetNativeView() return gfx::NativeView(); } -gfx::NativeViewAccessible RenderWidgetHostViewQt::GetNativeViewAccessible() +content::WebContentsAccessibility *RenderWidgetHostViewQt::GetWebContentsAccessibility() { - return 0; + if (!m_webContentsAccessibility) + m_webContentsAccessibility.reset(new WebContentsAccessibilityQt(this)); + return m_webContentsAccessibility.get(); } -content::BrowserAccessibilityManager* RenderWidgetHostViewQt::CreateBrowserAccessibilityManager(content::BrowserAccessibilityDelegate* delegate, bool for_root_frame) +QObject *WebContentsAccessibilityQt::accessibilityParentObject() const { - Q_UNUSED(for_root_frame); // FIXME -#if QT_CONFIG(accessibility) - return new content::BrowserAccessibilityManagerQt( - m_adapterClient->accessibilityParentObject(), - content::BrowserAccessibilityManagerQt::GetEmptyDocument(), - delegate); -#else - return 0; -#endif // QT_CONFIG(accessibility) + return m_rwhv->m_adapterClient->accessibilityParentObject(); } // Set focus to the associated View component. @@ -274,6 +321,11 @@ bool RenderWidgetHostViewQt::IsMouseLocked() return m_isMouseLocked; } +viz::FrameSinkId RenderWidgetHostViewQt::GetRootFrameSinkId() +{ + return m_uiCompositor->frame_sink_id(); +} + bool RenderWidgetHostViewQt::IsSurfaceAvailableForCopy() { return m_delegatedFrameHost->CanCopyFromCompositingSurface(); @@ -286,8 +338,9 @@ void RenderWidgetHostViewQt::CopyFromSurface(const gfx::Rect &src_rect, m_delegatedFrameHost->CopyFromCompositingSurface(src_rect, output_size, std::move(callback)); } -void RenderWidgetHostViewQt::Show() +void RenderWidgetHostViewQt::ShowWithVisibility(content::PageVisibilityState page_visibility) { + Q_ASSERT(page_visibility != content::PageVisibilityState::kHidden); if (m_delegate) m_delegate->show(); else @@ -314,6 +367,9 @@ gfx::Rect RenderWidgetHostViewQt::GetViewBounds() void RenderWidgetHostViewQt::UpdateBackgroundColor() { + if (!m_delegate) + return; + DCHECK(GetBackgroundColor()); SkColor color = *GetBackgroundColor(); @@ -324,18 +380,28 @@ void RenderWidgetHostViewQt::UpdateBackgroundColor() m_rootLayer->SetColor(color); m_uiCompositor->SetBackgroundColor(color); - content::RenderViewHost *rvh = content::RenderViewHost::From(host()); - host()->Send(new RenderViewObserverQt_SetBackgroundColor(rvh->GetRoutingID(), color)); + if (color == SK_ColorTRANSPARENT) + host()->owner_delegate()->SetBackgroundOpaque(false); } // Return value indicates whether the mouse is locked successfully or not. -bool RenderWidgetHostViewQt::LockMouse(bool) +blink::mojom::PointerLockResult RenderWidgetHostViewQt::LockMouse(bool request_unadjusted_movement) { + if (request_unadjusted_movement) + return blink::mojom::PointerLockResult::kUnsupportedOptions; + delegateClient()->resetPreviousMousePosition(); m_delegate->lockMouse(); m_isMouseLocked = true; qApp->setOverrideCursor(Qt::BlankCursor); - return true; + return blink::mojom::PointerLockResult::kSuccess; +} + +blink::mojom::PointerLockResult RenderWidgetHostViewQt::ChangeMouseLock(bool request_unadjusted_movement) +{ + if (request_unadjusted_movement) + return blink::mojom::PointerLockResult::kUnsupportedOptions; + return blink::mojom::PointerLockResult::kSuccess; } void RenderWidgetHostViewQt::UnlockMouse() @@ -346,169 +412,199 @@ void RenderWidgetHostViewQt::UnlockMouse() host()->LostMouseLock(); } -void RenderWidgetHostViewQt::UpdateCursor(const content::WebCursor &webCursor) +bool RenderWidgetHostViewQt::updateCursorFromResource(ui::mojom::CursorType type) +{ + int resourceId; + // GetCursorDataFor only knows hotspots for 1x and 2x cursor images, in physical pixels. + qreal hotspotDpr = GetScreenInfo().device_scale_factor <= 1.0f ? 1.0f : 2.0f; + qreal hotX; + qreal hotY; + +#if defined(USE_AURA) + gfx::Point hotspot; + if (!wm::GetCursorDataFor(ui::CursorSize::kNormal, type, hotspotDpr, &resourceId, &hotspot)) + return false; + hotX = hotspot.x(); + hotY = hotspot.y(); +#elif defined(Q_OS_MACOS) + // See chromium/content/common/cursors/webcursor_mac.mm + switch (type) { + case ui::mojom::CursorType::kVerticalText: + // TODO: [NSCursor IBeamCursorForVerticalLayout] + return false; + case ui::mojom::CursorType::kCell: + resourceId = IDR_CELL_CURSOR; + hotX = 7; + hotY = 7; + break; + case ui::mojom::CursorType::kContextMenu: + // TODO: [NSCursor contextualMenuCursor] + return false; + case ui::mojom::CursorType::kZoomIn: + resourceId = IDR_ZOOMIN_CURSOR; + hotX = 7; + hotY = 7; + break; + case ui::mojom::CursorType::kZoomOut: + resourceId = IDR_ZOOMOUT_CURSOR; + hotX = 7; + hotY = 7; + break; + default: + Q_UNREACHABLE(); + return false; + } +#else + Q_UNREACHABLE(); + return false; +#endif + + const gfx::ImageSkia *imageSkia = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resourceId); + if (!imageSkia) + return false; + + QImage imageQt = toQImage(imageSkia->GetRepresentation(GetScreenInfo().device_scale_factor)); + + // Convert hotspot coordinates into device-independent pixels. + hotX /= hotspotDpr; + hotY /= hotspotDpr; + +#if defined(Q_OS_LINUX) + // QTBUG-68571: On Linux (xcb, wayland, eglfs), hotspot coordinates must be in physical pixels. + qreal imageDpr = imageQt.devicePixelRatio(); + hotX *= imageDpr; + hotY *= imageDpr; +#endif + + m_delegate->updateCursor(QCursor(QPixmap::fromImage(std::move(imageQt)), qRound(hotX), qRound(hotY))); + return true; +} + +void RenderWidgetHostViewQt::UpdateCursor(const ui::Cursor &webCursor) { DisplayCursor(webCursor); } -void RenderWidgetHostViewQt::DisplayCursor(const content::WebCursor &webCursor) +void RenderWidgetHostViewQt::DisplayCursor(const ui::Cursor &cursorInfo) { - const content::CursorInfo &cursorInfo = webCursor.info(); Qt::CursorShape shape = Qt::ArrowCursor; -#if defined(USE_AURA) - ui::CursorType auraType = ui::CursorType::kNull; -#endif - switch (cursorInfo.type) { - case ui::CursorType::kNull: - case ui::CursorType::kPointer: + switch (cursorInfo.type()) { + case ui::mojom::CursorType::kNull: + case ui::mojom::CursorType::kPointer: shape = Qt::ArrowCursor; break; - case ui::CursorType::kCross: + case ui::mojom::CursorType::kCross: shape = Qt::CrossCursor; break; - case ui::CursorType::kHand: + case ui::mojom::CursorType::kHand: shape = Qt::PointingHandCursor; break; - case ui::CursorType::kIBeam: + case ui::mojom::CursorType::kIBeam: shape = Qt::IBeamCursor; break; - case ui::CursorType::kWait: + case ui::mojom::CursorType::kWait: shape = Qt::WaitCursor; break; - case ui::CursorType::kHelp: + case ui::mojom::CursorType::kHelp: shape = Qt::WhatsThisCursor; break; - case ui::CursorType::kEastResize: - case ui::CursorType::kWestResize: - case ui::CursorType::kEastWestResize: - case ui::CursorType::kEastPanning: - case ui::CursorType::kWestPanning: - case ui::CursorType::kMiddlePanningHorizontal: + case ui::mojom::CursorType::kEastResize: + case ui::mojom::CursorType::kWestResize: + case ui::mojom::CursorType::kEastWestResize: + case ui::mojom::CursorType::kEastPanning: + case ui::mojom::CursorType::kWestPanning: + case ui::mojom::CursorType::kMiddlePanningHorizontal: shape = Qt::SizeHorCursor; break; - case ui::CursorType::kNorthResize: - case ui::CursorType::kSouthResize: - case ui::CursorType::kNorthSouthResize: - case ui::CursorType::kNorthPanning: - case ui::CursorType::kSouthPanning: - case ui::CursorType::kMiddlePanningVertical: + case ui::mojom::CursorType::kNorthResize: + case ui::mojom::CursorType::kSouthResize: + case ui::mojom::CursorType::kNorthSouthResize: + case ui::mojom::CursorType::kNorthPanning: + case ui::mojom::CursorType::kSouthPanning: + case ui::mojom::CursorType::kMiddlePanningVertical: shape = Qt::SizeVerCursor; break; - case ui::CursorType::kNorthEastResize: - case ui::CursorType::kSouthWestResize: - case ui::CursorType::kNorthEastSouthWestResize: - case ui::CursorType::kNorthEastPanning: - case ui::CursorType::kSouthWestPanning: + case ui::mojom::CursorType::kNorthEastResize: + case ui::mojom::CursorType::kSouthWestResize: + case ui::mojom::CursorType::kNorthEastSouthWestResize: + case ui::mojom::CursorType::kNorthEastPanning: + case ui::mojom::CursorType::kSouthWestPanning: shape = Qt::SizeBDiagCursor; break; - case ui::CursorType::kNorthWestResize: - case ui::CursorType::kSouthEastResize: - case ui::CursorType::kNorthWestSouthEastResize: - case ui::CursorType::kNorthWestPanning: - case ui::CursorType::kSouthEastPanning: + case ui::mojom::CursorType::kNorthWestResize: + case ui::mojom::CursorType::kSouthEastResize: + case ui::mojom::CursorType::kNorthWestSouthEastResize: + case ui::mojom::CursorType::kNorthWestPanning: + case ui::mojom::CursorType::kSouthEastPanning: shape = Qt::SizeFDiagCursor; break; - case ui::CursorType::kColumnResize: + case ui::mojom::CursorType::kColumnResize: shape = Qt::SplitHCursor; break; - case ui::CursorType::kRowResize: + case ui::mojom::CursorType::kRowResize: shape = Qt::SplitVCursor; break; - case ui::CursorType::kMiddlePanning: - case ui::CursorType::kMove: + case ui::mojom::CursorType::kMiddlePanning: + case ui::mojom::CursorType::kMove: shape = Qt::SizeAllCursor; break; - case ui::CursorType::kProgress: + case ui::mojom::CursorType::kProgress: shape = Qt::BusyCursor; break; - case ui::CursorType::kDndNone: - case ui::CursorType::kDndMove: + case ui::mojom::CursorType::kDndNone: + case ui::mojom::CursorType::kDndMove: shape = Qt::DragMoveCursor; break; - case ui::CursorType::kDndCopy: - case ui::CursorType::kCopy: + case ui::mojom::CursorType::kDndCopy: + case ui::mojom::CursorType::kCopy: shape = Qt::DragCopyCursor; break; - case ui::CursorType::kDndLink: - case ui::CursorType::kAlias: + case ui::mojom::CursorType::kDndLink: + case ui::mojom::CursorType::kAlias: shape = Qt::DragLinkCursor; break; -#if defined(USE_AURA) - case ui::CursorType::kVerticalText: - auraType = ui::CursorType::kVerticalText; - break; - case ui::CursorType::kCell: - auraType = ui::CursorType::kCell; - break; - case ui::CursorType::kContextMenu: - auraType = ui::CursorType::kContextMenu; - break; - case ui::CursorType::kZoomIn: - auraType = ui::CursorType::kZoomIn; - break; - case ui::CursorType::kZoomOut: - auraType = ui::CursorType::kZoomOut; - break; -#else - case ui::CursorType::kVerticalText: - case ui::CursorType::kCell: - case ui::CursorType::kContextMenu: - case ui::CursorType::kZoomIn: - case ui::CursorType::kZoomOut: - // FIXME: Support on OS X + case ui::mojom::CursorType::kVerticalText: + case ui::mojom::CursorType::kCell: + case ui::mojom::CursorType::kContextMenu: + case ui::mojom::CursorType::kZoomIn: + case ui::mojom::CursorType::kZoomOut: + if (updateCursorFromResource(cursorInfo.type())) + return; break; -#endif - case ui::CursorType::kNoDrop: - case ui::CursorType::kNotAllowed: + case ui::mojom::CursorType::kEastWestNoResize: + case ui::mojom::CursorType::kNorthEastSouthWestNoResize: + case ui::mojom::CursorType::kNorthSouthNoResize: + case ui::mojom::CursorType::kNorthWestSouthEastNoResize: + // Use forbidden cursor matching webcursor_mac.mm and win_cursor_factory.cc + case ui::mojom::CursorType::kNoDrop: + case ui::mojom::CursorType::kNotAllowed: shape = Qt::ForbiddenCursor; break; - case ui::CursorType::kNone: + case ui::mojom::CursorType::kNone: shape = Qt::BlankCursor; break; - case ui::CursorType::kGrab: + case ui::mojom::CursorType::kGrab: shape = Qt::OpenHandCursor; break; - case ui::CursorType::kGrabbing: + case ui::mojom::CursorType::kGrabbing: shape = Qt::ClosedHandCursor; break; - case ui::CursorType::kCustom: - if (cursorInfo.custom_image.colorType() == SkColorType::kN32_SkColorType) { - QImage cursor = toQImage(cursorInfo.custom_image, QImage::Format_ARGB32); - m_delegate->updateCursor(QCursor(QPixmap::fromImage(cursor), cursorInfo.hotspot.x(), cursorInfo.hotspot.y())); + case ui::mojom::CursorType::kCustom: + if (cursorInfo.custom_bitmap().colorType() == SkColorType::kN32_SkColorType) { + QImage cursor = toQImage(cursorInfo.custom_bitmap(), QImage::Format_ARGB32); + m_delegate->updateCursor(QCursor(QPixmap::fromImage(cursor), cursorInfo.custom_hotspot().x(), cursorInfo.custom_hotspot().y())); return; } break; } -#if defined(USE_AURA) - if (auraType != ui::CursorType::kNull) { - int resourceId; - gfx::Point hotspot; - // GetCursorDataFor only knows hotspots for 1x and 2x cursor images, in physical pixels. - qreal hotspotDpr = m_screenInfo.device_scale_factor <= 1.0f ? 1.0f : 2.0f; - if (ui::GetCursorDataFor(ui::CursorSize::kNormal, auraType, hotspotDpr, &resourceId, &hotspot)) { - if (const gfx::ImageSkia *imageSkia = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resourceId)) { - QImage imageQt = toQImage(imageSkia->GetRepresentation(m_screenInfo.device_scale_factor)); - - // Convert hotspot coordinates into device-independent pixels. - qreal hotX = hotspot.x() / hotspotDpr; - qreal hotY = hotspot.y() / hotspotDpr; - -#if defined(Q_OS_LINUX) - // QTBUG-68571: On Linux (xcb, wayland, eglfs), hotspot coordinates must be in physical pixels. - qreal imageDpr = imageQt.devicePixelRatio(); - hotX *= imageDpr; - hotY *= imageDpr; -#endif - - m_delegate->updateCursor(QCursor(QPixmap::fromImage(std::move(imageQt)), qRound(hotX), qRound(hotY))); - return; - } - } - } -#endif m_delegate->updateCursor(QCursor(shape)); } +content::CursorManager *RenderWidgetHostViewQt::GetCursorManager() +{ + return m_cursorManager.get(); +} + void RenderWidgetHostViewQt::SetIsLoading(bool) { // We use WebContentsDelegateQt::LoadingStateChanged to notify about loading state. @@ -519,7 +615,9 @@ void RenderWidgetHostViewQt::ImeCancelComposition() qApp->inputMethod()->reset(); } -void RenderWidgetHostViewQt::ImeCompositionRangeChanged(const gfx::Range&, const std::vector<gfx::Rect>&) +void RenderWidgetHostViewQt::ImeCompositionRangeChanged(const gfx::Range &, + const absl::optional<std::vector<gfx::Rect>> &, + const absl::optional<std::vector<gfx::Rect>> &) { // FIXME: not implemented? QT_NOT_YET_IMPLEMENTED @@ -530,37 +628,32 @@ void RenderWidgetHostViewQt::RenderProcessGone() Destroy(); } -void RenderWidgetHostViewQt::Destroy() -{ - delete this; -} - -void RenderWidgetHostViewQt::SetTooltipText(const base::string16 &tooltip_text) +bool RenderWidgetHostViewQt::TransformPointToCoordSpaceForView(const gfx::PointF &point, + content::RenderWidgetHostViewBase *target_view, + gfx::PointF *transformed_point) { - DisplayTooltipText(tooltip_text); -} + if (target_view == this) { + *transformed_point = point; + return true; + } -void RenderWidgetHostViewQt::DisplayTooltipText(const base::string16 &tooltip_text) -{ - if (m_adapterClient) - m_adapterClient->setToolTip(toQt(tooltip_text)); + return target_view->TransformPointToLocalCoordSpace(point, GetCurrentSurfaceId(), transformed_point); } -void RenderWidgetHostViewQt::DidCreateNewRendererCompositorFrameSink(viz::mojom::CompositorFrameSinkClient *frameSinkClient) +void RenderWidgetHostViewQt::Destroy() { - // Not used with viz - NOTREACHED(); + delete this; } -void RenderWidgetHostViewQt::SubmitCompositorFrame(const viz::LocalSurfaceId &local_surface_id, viz::CompositorFrame frame, base::Optional<viz::HitTestRegionList> hit_test_region_list) +void RenderWidgetHostViewQt::UpdateTooltipUnderCursor(const std::u16string &tooltip_text) { - // Not used with viz - NOTREACHED(); + UpdateTooltip(tooltip_text); } -void RenderWidgetHostViewQt::GetScreenInfo(content::ScreenInfo *results) +void RenderWidgetHostViewQt::UpdateTooltip(const std::u16string &tooltip_text) { - *results = m_screenInfo; + if (host()->delegate() && m_adapterClient) + m_adapterClient->setToolTip(toQt(tooltip_text)); } gfx::Rect RenderWidgetHostViewQt::GetBoundsInRootWindow() @@ -574,31 +667,29 @@ void RenderWidgetHostViewQt::OnUpdateTextInputStateCalled(content::TextInputMana Q_UNUSED(updated_view); Q_UNUSED(did_update_state); - const content::TextInputState *state = text_input_manager_->GetTextInputState(); + const ui::mojom::TextInputState *state = text_input_manager_->GetTextInputState(); if (!state) { - m_delegate->inputMethodStateChanged(false /*editorVisible*/, false /*passwordInput*/); - m_delegate->setInputMethodHints(Qt::ImhNone); + // Do not reset input method state here because an editable node might be still focused and + // this would hide the virtual keyboard if a child of the focused node is removed. return; } ui::TextInputType type = getTextInputType(); -#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0) m_delegate->setInputMethodHints(toQtInputMethodHints(getTextInputType()) | Qt::ImhNoPredictiveText | Qt::ImhNoTextHandles | Qt::ImhNoEditMenu); -#else - m_delegate->setInputMethodHints(toQtInputMethodHints(getTextInputType()) | Qt::ImhNoPredictiveText); -#endif QString surroundingText = toQt(state->value); // Remove IME composition text from the surrounding text - if (state->composition_start != -1 && state->composition_end != -1) - surroundingText.remove(state->composition_start, - state->composition_end - state->composition_start); + if (state->composition.has_value()) + surroundingText.remove(state->composition->start(), + state->composition->end() - state->composition->start()); delegateClient()->setSurroundingText(surroundingText); // In case of text selection, the update is expected in RenderWidgetHostViewQt::selectionChanged(). if (GetSelectedText().empty()) { - // At this point it is unknown whether the text input state has been updated due to a text selection. - // Keep the cursor position updated for cursor movements too. - delegateClient()->setCursorPosition(state->selection_start); + if (state->composition.has_value()) { + delegateClient()->setCursorPosition(state->composition->start()); + } else { + delegateClient()->setCursorPosition(state->selection.start()); + } m_delegate->inputMethodStateChanged(type != ui::TEXT_INPUT_TYPE_NONE, type == ui::TEXT_INPUT_TYPE_PASSWORD); } @@ -608,7 +699,7 @@ void RenderWidgetHostViewQt::OnUpdateTextInputStateCalled(content::TextInputMana } // Ignore selection change triggered by ime composition unless it clears an actual text selection - if (state->composition_start != -1 && delegateClient()->isPreviousSelectionEmpty()) { + if (state->composition.has_value() && delegateClient()->isPreviousSelectionEmpty()) { m_imState = 0; return; } @@ -635,15 +726,22 @@ void RenderWidgetHostViewQt::OnTextSelectionChanged(content::TextInputManager *t Q_UNUSED(text_input_manager); Q_UNUSED(updated_view); - const content::TextInputManager::TextSelection *selection = GetTextInputManager()->GetTextSelection(updated_view); - if (!selection) - return; + // We obtain the TextSelection from focused RWH which is obtained from the + // frame tree. + content::RenderWidgetHostViewBase *focused_view = + GetFocusedWidget() ? GetFocusedWidget()->GetView() : nullptr; + + if (!focused_view) + return; #if defined(USE_OZONE) - if (!selection->selected_text().empty() && selection->user_initiated()) { - // Set the CLIPBOARD_TYPE_SELECTION to the ui::Clipboard. - ui::ScopedClipboardWriter clipboard_writer(ui::ClipboardBuffer::kSelection); - clipboard_writer.WriteText(selection->selected_text()); + if (ui::Clipboard::IsSupportedClipboardBuffer(ui::ClipboardBuffer::kSelection)) { + const content::TextInputManager::TextSelection *selection = GetTextInputManager()->GetTextSelection(focused_view); + if (selection->selected_text().length() && selection->user_initiated()) { + // Set the ClipboardBuffer::kSelection to the ui::Clipboard. + ui::ScopedClipboardWriter clipboard_writer(ui::ClipboardBuffer::kSelection); + clipboard_writer.WriteText(selection->selected_text()); + } } #endif // defined(USE_OZONE) @@ -667,16 +765,16 @@ void RenderWidgetHostViewQt::OnGestureEvent(const ui::GestureEventData& gesture) if (m_touchSelectionController && m_touchSelectionControllerClient) { switch (event.GetType()) { - case blink::WebInputEvent::kGestureLongPress: + case blink::WebInputEvent::Type::kGestureLongPress: m_touchSelectionController->HandleLongPressEvent(event.TimeStamp(), event.PositionInWidget()); break; - case blink::WebInputEvent::kGestureTap: + case blink::WebInputEvent::Type::kGestureTap: m_touchSelectionController->HandleTapEvent(event.PositionInWidget(), event.data.tap.tap_count); break; - case blink::WebInputEvent::kGestureScrollBegin: + case blink::WebInputEvent::Type::kGestureScrollBegin: m_touchSelectionControllerClient->onScrollBegin(); break; - case blink::WebInputEvent::kGestureScrollEnd: + case blink::WebInputEvent::Type::kGestureScrollEnd: m_touchSelectionControllerClient->onScrollEnd(); break; default: @@ -684,7 +782,8 @@ void RenderWidgetHostViewQt::OnGestureEvent(const ui::GestureEventData& gesture) } } - host()->ForwardGestureEvent(event); + if (host()->delegate() && host()->delegate()->GetInputEventRouter()) + host()->delegate()->GetInputEventRouter()->RouteGestureEvent(this, &event, ui::LatencyInfo()); } void RenderWidgetHostViewQt::DidStopFlinging() @@ -702,57 +801,29 @@ viz::ScopedSurfaceIdAllocator RenderWidgetHostViewQt::DidUpdateVisualProperties( void RenderWidgetHostViewQt::OnDidUpdateVisualPropertiesComplete(const cc::RenderFrameMetadata &metadata) { - synchronizeVisualProperties(metadata.local_surface_id_allocation); -} - -void RenderWidgetHostViewQt::OnDidFirstVisuallyNonEmptyPaint() -{ - if (m_loadVisuallyCommittedState == NotCommitted) { - m_loadVisuallyCommittedState = DidFirstVisuallyNonEmptyPaint; - } else if (m_loadVisuallyCommittedState == DidFirstCompositorFrameSwap) { - m_adapterClient->loadVisuallyCommitted(); - m_loadVisuallyCommittedState = NotCommitted; - } -} - -void RenderWidgetHostViewQt::scheduleUpdate() -{ - m_taskRunner->PostTask( - FROM_HERE, - base::BindOnce(&RenderWidgetHostViewQt::callUpdate, m_weakPtrFactory.GetWeakPtr())); -} - -void RenderWidgetHostViewQt::callUpdate() -{ - m_delegate->update(); - - if (m_loadVisuallyCommittedState == NotCommitted) { - m_loadVisuallyCommittedState = DidFirstCompositorFrameSwap; - } else if (m_loadVisuallyCommittedState == DidFirstVisuallyNonEmptyPaint) { - m_adapterClient->loadVisuallyCommitted(); - m_loadVisuallyCommittedState = NotCommitted; - } + synchronizeVisualProperties(metadata.local_surface_id); } -QSGNode *RenderWidgetHostViewQt::updatePaintNode(QSGNode *oldNode) +Compositor::Id RenderWidgetHostViewQt::compositorId() { - return m_displayFrameSink->updatePaintNode(oldNode, m_delegate.get()); + return m_uiCompositor->frame_sink_id(); } void RenderWidgetHostViewQt::notifyShown() { // Handle possible frame eviction: - if (!m_dfhLocalSurfaceIdAllocator.HasValidLocalSurfaceIdAllocation()) + if (!m_dfhLocalSurfaceIdAllocator.HasValidLocalSurfaceId()) m_dfhLocalSurfaceIdAllocator.GenerateId(); if (m_visible) return; m_visible = true; - host()->WasShown(base::nullopt); + host()->WasShown(nullptr); m_delegatedFrameHost->AttachToCompositor(m_uiCompositor.get()); - m_delegatedFrameHost->WasShown(GetLocalSurfaceIdAllocation().local_surface_id(), - toGfx(delegateClient()->viewRectInDips().size()), base::nullopt); + m_delegatedFrameHost->WasShown(GetLocalSurfaceId(), + toGfx(delegateClient()->viewRectInDips().size()), + nullptr); } void RenderWidgetHostViewQt::notifyHidden() @@ -765,10 +836,11 @@ void RenderWidgetHostViewQt::notifyHidden() m_delegatedFrameHost->DetachFromCompositor(); } -void RenderWidgetHostViewQt::ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, content::InputEventAckState ack_result) { - Q_UNUSED(touch); - const bool eventConsumed = ack_result == content::INPUT_EVENT_ACK_STATE_CONSUMED; - m_gestureProvider.OnTouchEventAck(touch.event.unique_touch_event_id, eventConsumed, /*fixme: ?? */false); +void RenderWidgetHostViewQt::ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, blink::mojom::InputEventResultState ack_result) +{ + const bool eventConsumed = (ack_result == blink::mojom::InputEventResultState::kConsumed); + const bool isSetBlocking = content::InputEventResultStateIsSetBlocking(ack_result); + m_gestureProvider.OnTouchEventAck(touch.event.unique_touch_event_id, eventConsumed, isSetBlocking); } void RenderWidgetHostViewQt::processMotionEvent(const ui::MotionEvent &motionEvent) @@ -776,11 +848,11 @@ void RenderWidgetHostViewQt::processMotionEvent(const ui::MotionEvent &motionEve auto result = m_gestureProvider.OnTouchEvent(motionEvent); if (!result.succeeded) return; - blink::WebTouchEvent touchEvent = ui::CreateWebTouchEventFromMotionEvent(motionEvent, result.moved_beyond_slop_region, false /*hovering, FIXME ?*/); - host()->ForwardTouchEventWithLatencyInfo(touchEvent, CreateLatencyInfo(touchEvent)); + if (host()->delegate() && host()->delegate()->GetInputEventRouter()) + host()->delegate()->GetInputEventRouter()->RouteTouchEvent(this, &touchEvent, CreateLatencyInfo(touchEvent)); } bool RenderWidgetHostViewQt::isPopup() const @@ -790,21 +862,17 @@ bool RenderWidgetHostViewQt::isPopup() const bool RenderWidgetHostViewQt::updateScreenInfo() { - content::ScreenInfo oldScreenInfo = m_screenInfo; - QScreen *screen = m_delegate->window() ? m_delegate->window()->screen() : nullptr; - - if (screen) { - m_screenInfo.device_scale_factor = screen->devicePixelRatio(); - m_screenInfo.depth_per_component = 8; - m_screenInfo.depth = screen->depth(); - m_screenInfo.is_monochrome = (m_screenInfo.depth == 1); - m_screenInfo.rect = toGfx(screen->geometry()); - m_screenInfo.available_rect = toGfx(screen->availableGeometry()); - } else { - m_screenInfo.device_scale_factor = qGuiApp->devicePixelRatio(); - } - return (m_screenInfo != oldScreenInfo); + QWindow *window = m_delegate->Window(); + if (!window) + return false; + + display::ScreenInfos newScreenInfos = screenInfosFromQtForUpdate(window->screen()); + if (screen_infos_ == newScreenInfos) + return false; + + screen_infos_ = std::move(newScreenInfos); + return true; } void RenderWidgetHostViewQt::handleWheelEvent(QWheelEvent *event) @@ -813,8 +881,9 @@ void RenderWidgetHostViewQt::handleWheelEvent(QWheelEvent *event) Q_ASSERT(m_pendingWheelEvents.isEmpty()); blink::WebMouseWheelEvent webEvent = WebEventFactory::toWebWheelEvent(event); m_wheelAckPending = (webEvent.phase != blink::WebMouseWheelEvent::kPhaseEnded); - GetMouseWheelPhaseHandler()->AddPhaseIfNeededAndScheduleEndEvent(webEvent, false); - host()->ForwardWheelEvent(webEvent); + GetMouseWheelPhaseHandler()->AddPhaseIfNeededAndScheduleEndEvent(webEvent, true); + if (host()->delegate() && host()->delegate()->GetInputEventRouter()) + host()->delegate()->GetInputEventRouter()->RouteMouseWheelEvent(this, &webEvent, ui::LatencyInfo()); return; } if (!m_pendingWheelEvents.isEmpty()) { @@ -825,7 +894,7 @@ void RenderWidgetHostViewQt::handleWheelEvent(QWheelEvent *event) m_pendingWheelEvents.append(WebEventFactory::toWebWheelEvent(event)); } -void RenderWidgetHostViewQt::WheelEventAck(const blink::WebMouseWheelEvent &event, content::InputEventAckState /*ack_result*/) +void RenderWidgetHostViewQt::WheelEventAck(const blink::WebMouseWheelEvent &event, blink::mojom::InputEventResultState /*ack_result*/) { if (event.phase == blink::WebMouseWheelEvent::kPhaseEnded) return; @@ -834,19 +903,22 @@ void RenderWidgetHostViewQt::WheelEventAck(const blink::WebMouseWheelEvent &even while (!m_pendingWheelEvents.isEmpty() && !m_wheelAckPending) { blink::WebMouseWheelEvent webEvent = m_pendingWheelEvents.takeFirst(); m_wheelAckPending = (webEvent.phase != blink::WebMouseWheelEvent::kPhaseEnded); - m_mouseWheelPhaseHandler.AddPhaseIfNeededAndScheduleEndEvent(webEvent, false); - host()->ForwardWheelEvent(webEvent); + m_mouseWheelPhaseHandler.AddPhaseIfNeededAndScheduleEndEvent(webEvent, true); + if (host()->delegate() && host()->delegate()->GetInputEventRouter()) + host()->delegate()->GetInputEventRouter()->RouteMouseWheelEvent(this, &webEvent, ui::LatencyInfo()); } } -void RenderWidgetHostViewQt::GestureEventAck(const blink::WebGestureEvent &event, content::InputEventAckState ack_result) +void RenderWidgetHostViewQt::GestureEventAck(const blink::WebGestureEvent &event, + blink::mojom::InputEventResultState ack_result, + blink::mojom::ScrollResultDataPtr scroll_result_data) { // Forward unhandled scroll events back as wheel events - if (event.GetType() != blink::WebInputEvent::kGestureScrollUpdate) + if (event.GetType() != blink::WebInputEvent::Type::kGestureScrollUpdate) return; switch (ack_result) { - case content::INPUT_EVENT_ACK_STATE_NOT_CONSUMED: - case content::INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: + case blink::mojom::InputEventResultState::kNotConsumed: + case blink::mojom::InputEventResultState::kNoConsumerExists: WebEventFactory::sendUnhandledWheelEvent(event, delegate()); break; default: @@ -859,32 +931,13 @@ content::MouseWheelPhaseHandler *RenderWidgetHostViewQt::GetMouseWheelPhaseHandl return &m_mouseWheelPhaseHandler; } -void RenderWidgetHostViewQt::SetNeedsBeginFrames(bool needs_begin_frames) -{ - // Not used with viz - NOTREACHED(); -} - -content::RenderFrameHost *RenderWidgetHostViewQt::getFocusedFrameHost() -{ - content::RenderViewHostImpl *viewHost = content::RenderViewHostImpl::From(host()); - if (!viewHost) - return nullptr; - - content::FrameTreeNode *focusedFrame = viewHost->GetDelegate()->GetFrameTree()->GetFocusedFrame(); - if (!focusedFrame) - return nullptr; - - return focusedFrame->current_frame_host(); -} - -content::mojom::FrameInputHandler *RenderWidgetHostViewQt::getFrameInputHandler() +blink::mojom::FrameWidgetInputHandler *RenderWidgetHostViewQt::getFrameWidgetInputHandler() { - content::RenderFrameHostImpl *frameHost = static_cast<content::RenderFrameHostImpl *>(getFocusedFrameHost()); - if (!frameHost) + auto *focused_widget = GetFocusedWidget(); + if (!focused_widget) return nullptr; - return frameHost->GetFrameInputHandler(); + return focused_widget->GetFrameWidgetInputHandler(); } ui::TextInputType RenderWidgetHostViewQt::getTextInputType() const @@ -895,11 +948,6 @@ ui::TextInputType RenderWidgetHostViewQt::getTextInputType() const return ui::TEXT_INPUT_TYPE_NONE; } -void RenderWidgetHostViewQt::SetWantsAnimateOnlyBeginFrames() -{ - m_delegatedFrameHost->SetWantsAnimateOnlyBeginFrames(); -} - viz::SurfaceId RenderWidgetHostViewQt::GetCurrentSurfaceId() const { return m_delegatedFrameHost->GetCurrentSurfaceId(); @@ -910,20 +958,32 @@ const viz::FrameSinkId &RenderWidgetHostViewQt::GetFrameSinkId() const return m_delegatedFrameHost->frame_sink_id(); } -const viz::LocalSurfaceIdAllocation &RenderWidgetHostViewQt::GetLocalSurfaceIdAllocation() const +const viz::LocalSurfaceId &RenderWidgetHostViewQt::GetLocalSurfaceId() const { - return m_dfhLocalSurfaceIdAllocator.GetCurrentLocalSurfaceIdAllocation(); + return m_dfhLocalSurfaceIdAllocator.GetCurrentLocalSurfaceId(); +} + +void RenderWidgetHostViewQt::FocusedNodeChanged(bool is_editable_node, const gfx::Rect& node_bounds_in_screen) +{ + Q_UNUSED(node_bounds_in_screen); + if (!is_editable_node) { + m_delegate->inputMethodStateChanged(false /*editorVisible*/, false /*passwordInput*/); + m_delegate->setInputMethodHints(Qt::ImhNone); + } +} + +base::flat_map<std::string, std::string> RenderWidgetHostViewQt::GetKeyboardLayoutMap() +{ + return ui::GenerateDomKeyboardLayoutMap(); } void RenderWidgetHostViewQt::TakeFallbackContentFrom(content::RenderWidgetHostView *view) { DCHECK(!static_cast<RenderWidgetHostViewBase*>(view)->IsRenderWidgetHostViewChildFrame()); RenderWidgetHostViewQt *viewQt = static_cast<RenderWidgetHostViewQt *>(view); - base::Optional<SkColor> color = viewQt->GetBackgroundColor(); - if (color) - SetBackgroundColor(*color); + CopyBackgroundColorIfPresentFrom(*viewQt); + m_delegatedFrameHost->TakeFallbackContentFrom(viewQt->m_delegatedFrameHost.get()); - host()->GetContentRenderingTimeoutFrom(viewQt->host()); } void RenderWidgetHostViewQt::EnsureSurfaceSynchronizedForWebTest() @@ -940,10 +1000,9 @@ void RenderWidgetHostViewQt::ResetFallbackToFirstNavigationSurface() { } -void RenderWidgetHostViewQt::OnRenderFrameMetadataChangedAfterActivation() +void RenderWidgetHostViewQt::OnRenderFrameMetadataChangedAfterActivation(base::TimeTicks activation_time) { - content::RenderWidgetHostViewBase::OnRenderFrameMetadataChangedAfterActivation(); - + Q_UNUSED(activation_time); const cc::RenderFrameMetadata &metadata = host()->render_frame_metadata_provider()->LastRenderFrameMetadata(); if (metadata.selection.start != m_selectionStart || metadata.selection.end != m_selectionEnd) { m_selectionStart = metadata.selection.start; @@ -951,17 +1010,22 @@ void RenderWidgetHostViewQt::OnRenderFrameMetadataChangedAfterActivation() m_touchSelectionControllerClient->UpdateClientSelectionBounds(m_selectionStart, m_selectionEnd); } - gfx::Vector2dF scrollOffset = metadata.root_scroll_offset.value_or(gfx::Vector2dF()); - gfx::SizeF contentsSize = metadata.root_layer_size; + gfx::PointF scrollOffset = gfx::PointF(); + if (metadata.root_scroll_offset.has_value()) + scrollOffset = gfx::ScalePoint(metadata.root_scroll_offset.value(), + 1 / metadata.device_scale_factor); std::swap(m_lastScrollOffset, scrollOffset); - std::swap(m_lastContentsSize, contentsSize); if (m_adapterClient && scrollOffset != m_lastScrollOffset) m_adapterClient->updateScrollPosition(toQt(m_lastScrollOffset)); + + gfx::SizeF contentsSize = + gfx::ScaleSize(metadata.root_layer_size, 1 / metadata.device_scale_factor); + std::swap(m_lastContentsSize, contentsSize); if (m_adapterClient && contentsSize != m_lastContentsSize) m_adapterClient->updateContentsSize(toQt(m_lastContentsSize)); } -void RenderWidgetHostViewQt::synchronizeVisualProperties(const base::Optional<viz::LocalSurfaceIdAllocation> &childSurfaceId) +void RenderWidgetHostViewQt::synchronizeVisualProperties(const absl::optional<viz::LocalSurfaceId> &childSurfaceId) { if (childSurfaceId) m_dfhLocalSurfaceIdAllocator.UpdateFromChild(*childSurfaceId); @@ -973,17 +1037,28 @@ void RenderWidgetHostViewQt::synchronizeVisualProperties(const base::Optional<vi m_rootLayer->SetBounds(gfx::Rect(gfx::Point(), viewSizeInPixels)); m_uiCompositorLocalSurfaceIdAllocator.GenerateId(); m_uiCompositor->SetScaleAndSize( - m_screenInfo.device_scale_factor, + GetScreenInfo().device_scale_factor, viewSizeInPixels, - m_uiCompositorLocalSurfaceIdAllocator.GetCurrentLocalSurfaceIdAllocation()); + m_uiCompositorLocalSurfaceIdAllocator.GetCurrentLocalSurfaceId()); m_delegatedFrameHost->EmbedSurface( - m_dfhLocalSurfaceIdAllocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id(), + m_dfhLocalSurfaceIdAllocator.GetCurrentLocalSurfaceId(), viewSizeInDips, cc::DeadlinePolicy::UseDefaultDeadline()); host()->SynchronizeVisualProperties(); } +void RenderWidgetHostViewQt::resetTouchSelectionController() +{ + Q_ASSERT(m_touchSelectionControllerClient); + m_touchSelectionControllerClient->resetControls(); + ui::TouchSelectionController::Config config; + config.max_tap_duration = base::Milliseconds(ui::GestureConfiguration::GetInstance()->long_press_time_in_ms()); + config.tap_slop = ui::GestureConfiguration::GetInstance()->max_touch_move_in_pixels_for_click(); + config.enable_longpress_drag_selection = false; + m_touchSelectionController.reset(new ui::TouchSelectionController(m_touchSelectionControllerClient.get(), config)); +} + std::unique_ptr<content::SyntheticGestureTarget> RenderWidgetHostViewQt::CreateSyntheticGestureTarget() { return nullptr; @@ -994,4 +1069,14 @@ ui::Compositor *RenderWidgetHostViewQt::GetCompositor() return m_uiCompositor.get(); } +absl::optional<content::DisplayFeature> RenderWidgetHostViewQt::GetDisplayFeature() +{ + return absl::nullopt; +} + +void RenderWidgetHostViewQt::SetDisplayFeatureForTesting(const content::DisplayFeature *) +{ + NOTIMPLEMENTED(); +} + } // namespace QtWebEngineCore |