mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Add multi-touch support for OSR (issue #1059)
This commit is contained in:
committed by
Marshall Greenblatt
parent
9ba28dd730
commit
5f615a95bc
@@ -3697,3 +3697,21 @@ bool CefBrowserHostImpl::Send(IPC::Message* message) {
|
||||
delete message;
|
||||
return false;
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::SendTouchEvent(const CefTouchEvent& event) {
|
||||
if (!IsWindowless()) {
|
||||
NOTREACHED() << "Window rendering is not disabled";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefBrowserHostImpl::SendTouchEvent, this, event));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!web_contents() || !platform_delegate_)
|
||||
return;
|
||||
|
||||
platform_delegate_->SendTouchEvent(event);
|
||||
}
|
||||
|
@@ -222,6 +222,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
void SendMouseWheelEvent(const CefMouseEvent& event,
|
||||
int deltaX,
|
||||
int deltaY) override;
|
||||
void SendTouchEvent(const CefTouchEvent& event) override;
|
||||
void SendFocusEvent(bool setFocus) override;
|
||||
void SendCaptureLostEvent() override;
|
||||
void NotifyMoveOrResizeStarted() override;
|
||||
|
@@ -22,6 +22,7 @@ namespace blink {
|
||||
class WebMouseEvent;
|
||||
class WebMouseWheelEvent;
|
||||
class WebInputEvent;
|
||||
class WebTouchEvent;
|
||||
} // namespace blink
|
||||
|
||||
namespace content {
|
||||
@@ -150,6 +151,9 @@ class CefBrowserPlatformDelegate {
|
||||
virtual void SendMouseEvent(const blink::WebMouseEvent& event) = 0;
|
||||
virtual void SendMouseWheelEvent(const blink::WebMouseWheelEvent& event) = 0;
|
||||
|
||||
// Send touch events.
|
||||
virtual void SendTouchEvent(const CefTouchEvent& event) = 0;
|
||||
|
||||
// Send focus event. The browser's WebContents may be NULL when this method is
|
||||
// called.
|
||||
virtual void SendFocusEvent(bool setFocus) = 0;
|
||||
|
@@ -66,6 +66,11 @@ void CefBrowserPlatformDelegateBackground::SendMouseWheelEvent(
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateBackground::SendTouchEvent(
|
||||
const CefTouchEvent& event) {
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateBackground::SendFocusEvent(bool setFocus) {
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
@@ -28,6 +28,7 @@ class CefBrowserPlatformDelegateBackground
|
||||
void SendKeyEvent(const content::NativeWebKeyboardEvent& event) override;
|
||||
void SendMouseEvent(const blink::WebMouseEvent& event) override;
|
||||
void SendMouseWheelEvent(const blink::WebMouseWheelEvent& event) override;
|
||||
void SendTouchEvent(const CefTouchEvent& event) override;
|
||||
void SendFocusEvent(bool setFocus) override;
|
||||
gfx::Point GetScreenPoint(const gfx::Point& view) const override;
|
||||
void ViewText(const std::string& text) override;
|
||||
|
@@ -59,6 +59,9 @@ void CefBrowserPlatformDelegateNative::SendMouseWheelEvent(
|
||||
host->GetWidget()->ForwardWheelEvent(event);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateNative::SendTouchEvent(
|
||||
const CefTouchEvent& event) {}
|
||||
|
||||
bool CefBrowserPlatformDelegateNative::IsWindowless() const {
|
||||
return false;
|
||||
}
|
||||
|
@@ -32,6 +32,7 @@ class CefBrowserPlatformDelegateNative : public CefBrowserPlatformDelegate {
|
||||
void SendKeyEvent(const content::NativeWebKeyboardEvent& event) override;
|
||||
void SendMouseEvent(const blink::WebMouseEvent& event) override;
|
||||
void SendMouseWheelEvent(const blink::WebMouseWheelEvent& event) override;
|
||||
void SendTouchEvent(const CefTouchEvent& event) override;
|
||||
bool IsWindowless() const override;
|
||||
bool IsViewsHosted() const override;
|
||||
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
|
||||
#include "content/browser/web_contents/web_contents_impl.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "ui/events/base_event_utils.h"
|
||||
|
||||
CefBrowserPlatformDelegateOsr::CefBrowserPlatformDelegateOsr(
|
||||
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate)
|
||||
@@ -109,6 +110,12 @@ void CefBrowserPlatformDelegateOsr::SendMouseWheelEvent(
|
||||
view->SendMouseWheelEvent(event);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateOsr::SendTouchEvent(const CefTouchEvent& event) {
|
||||
CefRenderWidgetHostViewOSR* view = GetOSRHostView();
|
||||
if (view)
|
||||
view->SendTouchEvent(event);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateOsr::SendFocusEvent(bool setFocus) {
|
||||
CefRenderWidgetHostViewOSR* view = GetOSRHostView();
|
||||
if (view)
|
||||
|
@@ -35,6 +35,7 @@ class CefBrowserPlatformDelegateOsr
|
||||
void SendKeyEvent(const content::NativeWebKeyboardEvent& event) override;
|
||||
void SendMouseEvent(const blink::WebMouseEvent& event) override;
|
||||
void SendMouseWheelEvent(const blink::WebMouseWheelEvent& event) override;
|
||||
void SendTouchEvent(const CefTouchEvent& event) override;
|
||||
void SendFocusEvent(bool setFocus) override;
|
||||
gfx::Point GetScreenPoint(const gfx::Point& view) const override;
|
||||
void ViewText(const std::string& text) override;
|
||||
|
218
libcef/browser/osr/motion_event_osr.cc
Normal file
218
libcef/browser/osr/motion_event_osr.cc
Normal file
@@ -0,0 +1,218 @@
|
||||
// Copyright (c) 2017 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "libcef/browser/osr/motion_event_osr.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "ui/events/base_event_utils.h"
|
||||
#include "ui/events/gesture_detection/gesture_configuration.h"
|
||||
|
||||
CefMotionEventOSR::CefMotionEventOSR() {
|
||||
std::fill(id_map_, id_map_ + blink::WebTouchEvent::kTouchesLengthCap, -1);
|
||||
}
|
||||
|
||||
CefMotionEventOSR::~CefMotionEventOSR() {}
|
||||
|
||||
int CefMotionEventOSR::GetSourceDeviceId(size_t pointer_index) const {
|
||||
if (IsValidIndex(pointer_index))
|
||||
return pointer(pointer_index).source_device_id;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Returns true if the touch was valid.
|
||||
bool CefMotionEventOSR::OnTouch(const CefTouchEvent& touch) {
|
||||
int id = LookupId(touch.id);
|
||||
bool pointer_id_is_active = id != -1;
|
||||
|
||||
if (touch.type == CEF_TET_PRESSED && pointer_id_is_active) {
|
||||
// Ignore pressed events for already active touches.
|
||||
return false;
|
||||
} else if (touch.type != CEF_TET_PRESSED && !pointer_id_is_active) {
|
||||
// When a window begins capturing touch events, we could have an active
|
||||
// touch stream transfered to us, resulting in touch move or touch up
|
||||
// events without associated touch down events. Ignore them.
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (touch.type) {
|
||||
case CEF_TET_PRESSED:
|
||||
id = AddId(touch.id);
|
||||
if (id == -1)
|
||||
return false;
|
||||
if (!AddTouch(touch, id))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case CEF_TET_MOVED: {
|
||||
// Discard if touch is stationary.
|
||||
int index = FindPointerIndexOfId(id);
|
||||
if (IsValidIndex(index) &&
|
||||
(touch.x == GetX(index) && touch.y == GetY(index))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
[[fallthrough]];
|
||||
// No break.
|
||||
case CEF_TET_RELEASED:
|
||||
case CEF_TET_CANCELLED:
|
||||
// Removing these touch points needs to be postponed until after the
|
||||
// MotionEvent has been dispatched. This cleanup occurs in
|
||||
// CleanupRemovedTouchPoints.
|
||||
UpdateTouch(touch, id);
|
||||
break;
|
||||
}
|
||||
|
||||
UpdateCachedAction(touch, id);
|
||||
set_unique_event_id(ui::GetNextTouchEventId());
|
||||
set_flags(touch.modifiers);
|
||||
set_event_time(base::TimeTicks::Now());
|
||||
return true;
|
||||
}
|
||||
|
||||
// We can't cleanup removed touch points immediately upon receipt of a
|
||||
// TouchCancel or TouchRelease, as the MotionEvent needs to be able to report
|
||||
// information about those touch events. Once the MotionEvent has been
|
||||
// processed, we call CleanupRemovedTouchPoints to do the required
|
||||
// book-keeping.
|
||||
void CefMotionEventOSR::CleanupRemovedTouchPoints(const CefTouchEvent& event) {
|
||||
if (event.type != CEF_TET_RELEASED && event.type != CEF_TET_CANCELLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
DCHECK(GetPointerCount());
|
||||
|
||||
int id = LookupId(event.id);
|
||||
int index_to_delete = FindPointerIndexOfId(id);
|
||||
set_action_index(-1);
|
||||
set_action(ui::MotionEvent::Action::NONE);
|
||||
if (IsValidIndex(index_to_delete)) {
|
||||
pointer(index_to_delete) = pointer(GetPointerCount() - 1);
|
||||
PopPointer();
|
||||
RemoveId(event.id);
|
||||
}
|
||||
}
|
||||
|
||||
// Reset unchanged touch point to StateStationary for touchmove and touchcancel.
|
||||
void CefMotionEventOSR::MarkUnchangedTouchPointsAsStationary(
|
||||
blink::WebTouchEvent* event,
|
||||
const CefTouchEvent& cef_event) {
|
||||
int id = LookupId(cef_event.id);
|
||||
if (event->GetType() == blink::WebInputEvent::kTouchMove ||
|
||||
event->GetType() == blink::WebInputEvent::kTouchCancel) {
|
||||
for (size_t i = 0; i < event->touches_length; ++i) {
|
||||
if (event->touches[i].id != id)
|
||||
event->touches[i].state = blink::WebTouchPoint::kStateStationary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CefMotionEventOSR::LookupId(int id) {
|
||||
if (id == -1)
|
||||
return -1;
|
||||
|
||||
for (int i = 0; i < blink::WebTouchEvent::kTouchesLengthCap; i++) {
|
||||
if (id_map_[i] == id) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CefMotionEventOSR::AddId(int id) {
|
||||
if (id == -1 || LookupId(id) >= 0)
|
||||
return -1;
|
||||
|
||||
for (int i = 0; i < blink::WebTouchEvent::kTouchesLengthCap; i++) {
|
||||
if (id_map_[i] == -1) {
|
||||
id_map_[i] = id;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CefMotionEventOSR::RemoveId(int id) {
|
||||
for (int i = 0; i < blink::WebTouchEvent::kTouchesLengthCap; i++) {
|
||||
if (id_map_[i] == id) {
|
||||
id_map_[i] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CefMotionEventOSR::AddTouch(const CefTouchEvent& touch, int id) {
|
||||
if (GetPointerCount() == MotionEvent::MAX_TOUCH_POINT_COUNT)
|
||||
return false;
|
||||
|
||||
PushPointer(GetPointerPropertiesFromTouchEvent(touch, id));
|
||||
return true;
|
||||
}
|
||||
|
||||
void CefMotionEventOSR::UpdateTouch(const CefTouchEvent& touch, int id) {
|
||||
int index_to_update = FindPointerIndexOfId(id);
|
||||
if (IsValidIndex(index_to_update))
|
||||
pointer(index_to_update) = GetPointerPropertiesFromTouchEvent(touch, id);
|
||||
}
|
||||
|
||||
void CefMotionEventOSR::UpdateCachedAction(const CefTouchEvent& touch, int id) {
|
||||
DCHECK(GetPointerCount());
|
||||
switch (touch.type) {
|
||||
case CEF_TET_PRESSED:
|
||||
if (GetPointerCount() == 1) {
|
||||
set_action(ui::MotionEvent::Action::DOWN);
|
||||
} else {
|
||||
set_action(ui::MotionEvent::Action::POINTER_DOWN);
|
||||
set_action_index(FindPointerIndexOfId(id));
|
||||
}
|
||||
break;
|
||||
case CEF_TET_RELEASED:
|
||||
if (GetPointerCount() == 1) {
|
||||
set_action(ui::MotionEvent::Action::UP);
|
||||
} else {
|
||||
set_action(ui::MotionEvent::Action::POINTER_UP);
|
||||
set_action_index(FindPointerIndexOfId(id));
|
||||
}
|
||||
break;
|
||||
case CEF_TET_CANCELLED:
|
||||
set_action(ui::MotionEvent::Action::CANCEL);
|
||||
break;
|
||||
case CEF_TET_MOVED:
|
||||
set_action(ui::MotionEvent::Action::MOVE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool CefMotionEventOSR::IsValidIndex(int index) const {
|
||||
return (index >= 0) && (index < static_cast<int>(GetPointerCount()));
|
||||
}
|
||||
|
||||
ui::PointerProperties CefMotionEventOSR::GetPointerPropertiesFromTouchEvent(
|
||||
const CefTouchEvent& touch,
|
||||
int id) {
|
||||
ui::PointerProperties pointer_properties;
|
||||
pointer_properties.x = touch.x;
|
||||
pointer_properties.y = touch.y;
|
||||
pointer_properties.raw_x = touch.x;
|
||||
pointer_properties.raw_y = touch.y;
|
||||
pointer_properties.id = id;
|
||||
pointer_properties.pressure = touch.pressure;
|
||||
pointer_properties.source_device_id = 0;
|
||||
|
||||
pointer_properties.SetAxesAndOrientation(touch.radius_x, touch.radius_y,
|
||||
touch.rotation_angle);
|
||||
if (!pointer_properties.touch_major) {
|
||||
pointer_properties.touch_major =
|
||||
2.f * ui::GestureConfiguration::GetInstance()->default_radius();
|
||||
pointer_properties.touch_minor =
|
||||
2.f * ui::GestureConfiguration::GetInstance()->default_radius();
|
||||
pointer_properties.orientation = 0;
|
||||
}
|
||||
|
||||
pointer_properties.tool_type = ui::MotionEvent::ToolType::FINGER;
|
||||
|
||||
return pointer_properties;
|
||||
}
|
59
libcef/browser/osr/motion_event_osr.h
Normal file
59
libcef/browser/osr/motion_event_osr.h
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright (c) 2017 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_LIBCEF_BROWSER_OSR_MOTION_EVENT_OSR_H_
|
||||
#define CEF_LIBCEF_BROWSER_OSR_MOTION_EVENT_OSR_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/cef_base.h"
|
||||
|
||||
#include "third_party/blink/public/platform/web_touch_event.h"
|
||||
#include "ui/events/gesture_detection/motion_event_generic.h"
|
||||
|
||||
// Implementation of MotionEvent which takes a stream of CefTouchEvents.
|
||||
// This class is based on ui::MotionEventAura.
|
||||
class CefMotionEventOSR : public ui::MotionEventGeneric {
|
||||
public:
|
||||
CefMotionEventOSR();
|
||||
~CefMotionEventOSR() override;
|
||||
|
||||
int GetSourceDeviceId(size_t pointer_index) const override;
|
||||
|
||||
// Returns true if the touch was valid.
|
||||
bool OnTouch(const CefTouchEvent& touch);
|
||||
|
||||
// We can't cleanup removed touch points immediately upon receipt of a
|
||||
// TouchCancel or TouchRelease, as the MotionEvent needs to be able to report
|
||||
// information about those touch events. Once the MotionEvent has been
|
||||
// processed, we call CleanupRemovedTouchPoints to do the required
|
||||
// book-keeping.
|
||||
void CleanupRemovedTouchPoints(const CefTouchEvent& event);
|
||||
|
||||
// Reset unchanged touch point to StateStationary for touchmove and
|
||||
// touchcancel to make sure only send one ack per WebTouchEvent.
|
||||
void MarkUnchangedTouchPointsAsStationary(blink::WebTouchEvent* event,
|
||||
const CefTouchEvent& cef_event);
|
||||
|
||||
private:
|
||||
// Chromium can't cope with touch ids >31, so let's map the incoming
|
||||
// ids to a safe range.
|
||||
int id_map_[blink::WebTouchEvent::kTouchesLengthCap];
|
||||
|
||||
int LookupId(int id);
|
||||
int AddId(int id);
|
||||
void RemoveId(int id);
|
||||
|
||||
bool AddTouch(const CefTouchEvent& touch, int id);
|
||||
void UpdateTouch(const CefTouchEvent& touch, int id);
|
||||
void UpdateCachedAction(const CefTouchEvent& touch, int id);
|
||||
bool IsValidIndex(int index) const;
|
||||
ui::PointerProperties GetPointerPropertiesFromTouchEvent(
|
||||
const CefTouchEvent& touch,
|
||||
int id);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefMotionEventOSR);
|
||||
};
|
||||
|
||||
#endif
|
@@ -31,9 +31,12 @@
|
||||
#include "content/browser/renderer_host/cursor_manager.h"
|
||||
#include "content/browser/renderer_host/delegated_frame_host.h"
|
||||
#include "content/browser/renderer_host/dip_util.h"
|
||||
#include "content/browser/renderer_host/input/motion_event_web.h"
|
||||
#include "content/browser/renderer_host/input/synthetic_gesture_target_base.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_delegate.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
|
||||
#include "content/common/content_switches_internal.h"
|
||||
#include "content/common/input_messages.h"
|
||||
#include "content/common/view_messages.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
@@ -44,6 +47,9 @@
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "media/base/video_frame.h"
|
||||
#include "ui/compositor/compositor_vsync_manager.h"
|
||||
#include "ui/events/blink/blink_event_util.h"
|
||||
#include "ui/events/gesture_detection/gesture_provider_config_helper.h"
|
||||
#include "ui/events/gesture_detection/motion_event.h"
|
||||
#include "ui/gfx/geometry/dip_util.h"
|
||||
#include "ui/gfx/geometry/size_conversions.h"
|
||||
|
||||
@@ -165,6 +171,23 @@ class CefDelegatedFrameHostClient : public content::DelegatedFrameHostClient {
|
||||
|
||||
#endif // !defined(OS_MACOSX)
|
||||
|
||||
ui::GestureProvider::Config CreateGestureProviderConfig() {
|
||||
ui::GestureProvider::Config config = ui::GetGestureProviderConfig(
|
||||
ui::GestureProviderConfigType::CURRENT_PLATFORM);
|
||||
return config;
|
||||
}
|
||||
|
||||
ui::LatencyInfo CreateLatencyInfo(const blink::WebInputEvent& event) {
|
||||
ui::LatencyInfo latency_info;
|
||||
// The latency number should only be added if the timestamp is valid.
|
||||
base::TimeTicks time = event.TimeStamp();
|
||||
if (!time.is_null()) {
|
||||
latency_info.AddLatencyNumberWithTimestamp(
|
||||
ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, time, 1);
|
||||
}
|
||||
return latency_info;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Used for managing copy requests when GPU compositing is enabled. Based on
|
||||
@@ -327,8 +350,11 @@ CefRenderWidgetHostViewOSR::CefRenderWidgetHostViewOSR(
|
||||
child_host_view_(NULL),
|
||||
is_showing_(!render_widget_host_->is_hidden()),
|
||||
is_destroyed_(false),
|
||||
pinch_zoom_enabled_(content::IsPinchToZoomEnabled()),
|
||||
is_scroll_offset_changed_pending_(false),
|
||||
mouse_wheel_phase_handler_(this),
|
||||
gesture_provider_(CreateGestureProviderConfig(), this),
|
||||
forward_touch_to_popup_(false),
|
||||
weak_ptr_factory_(this) {
|
||||
DCHECK(render_widget_host_);
|
||||
DCHECK(!render_widget_host_->GetView());
|
||||
@@ -399,6 +425,12 @@ CefRenderWidgetHostViewOSR::CefRenderWidgetHostViewOSR(
|
||||
|
||||
if (GetTextInputManager())
|
||||
GetTextInputManager()->AddObserver(this);
|
||||
|
||||
if (render_widget_host_->delegate() &&
|
||||
render_widget_host_->delegate()->GetInputEventRouter()) {
|
||||
render_widget_host_->delegate()->GetInputEventRouter()->AddFrameSinkIdOwner(
|
||||
GetFrameSinkId(), this);
|
||||
}
|
||||
}
|
||||
|
||||
CefRenderWidgetHostViewOSR::~CefRenderWidgetHostViewOSR() {
|
||||
@@ -855,7 +887,13 @@ content::CursorManager* CefRenderWidgetHostViewOSR::GetCursorManager() {
|
||||
return cursor_manager_.get();
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::SetIsLoading(bool is_loading) {}
|
||||
void CefRenderWidgetHostViewOSR::SetIsLoading(bool is_loading) {
|
||||
if (!is_loading)
|
||||
return;
|
||||
// Make sure gesture detection is fresh.
|
||||
gesture_provider_.ResetDetection();
|
||||
forward_touch_to_popup_ = false;
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::RenderProcessGone(
|
||||
base::TerminationStatus status,
|
||||
@@ -1085,6 +1123,14 @@ const viz::FrameSinkId& CefRenderWidgetHostViewOSR::GetFrameSinkId() const {
|
||||
return GetDelegatedFrameHost()->frame_sink_id();
|
||||
}
|
||||
|
||||
viz::FrameSinkId CefRenderWidgetHostViewOSR::GetRootFrameSinkId() {
|
||||
#if defined(OS_MACOSX)
|
||||
return browser_compositor_->GetRootFrameSinkId();
|
||||
#else
|
||||
return compositor_->frame_sink_id();
|
||||
#endif
|
||||
}
|
||||
|
||||
std::unique_ptr<content::SyntheticGestureTarget>
|
||||
CefRenderWidgetHostViewOSR::CreateSyntheticGestureTarget() {
|
||||
// TODO(cef): This is likely incorrect for OOPIF.
|
||||
@@ -1412,6 +1458,78 @@ void CefRenderWidgetHostViewOSR::SendMouseWheelEvent(
|
||||
}
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::SendTouchEvent(const CefTouchEvent& event) {
|
||||
TRACE_EVENT0("cef", "CefRenderWidgetHostViewOSR::SendTouchEvent");
|
||||
|
||||
if (!IsPopupWidget() && popup_host_view_) {
|
||||
if (!forward_touch_to_popup_ && event.type == CEF_TET_PRESSED &&
|
||||
pointer_state_.GetPointerCount() == 0) {
|
||||
forward_touch_to_popup_ =
|
||||
popup_host_view_->popup_position_.Contains(event.x, event.y);
|
||||
}
|
||||
|
||||
if (forward_touch_to_popup_) {
|
||||
CefTouchEvent popup_event(event);
|
||||
popup_event.x -= popup_host_view_->popup_position_.x();
|
||||
popup_event.y -= popup_host_view_->popup_position_.y();
|
||||
popup_host_view_->SendTouchEvent(popup_event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the touch event first.
|
||||
if (!pointer_state_.OnTouch(event))
|
||||
return;
|
||||
|
||||
ui::FilteredGestureProvider::TouchHandlingResult result =
|
||||
gesture_provider_.OnTouchEvent(pointer_state_);
|
||||
|
||||
blink::WebTouchEvent touch_event = ui::CreateWebTouchEventFromMotionEvent(
|
||||
pointer_state_, result.moved_beyond_slop_region, false);
|
||||
|
||||
pointer_state_.CleanupRemovedTouchPoints(event);
|
||||
|
||||
// Set unchanged touch point to StateStationary for touchmove and
|
||||
// touchcancel to make sure only send one ack per WebTouchEvent.
|
||||
if (!result.succeeded)
|
||||
pointer_state_.MarkUnchangedTouchPointsAsStationary(&touch_event, event);
|
||||
|
||||
if (!render_widget_host_)
|
||||
return;
|
||||
|
||||
ui::LatencyInfo latency_info = CreateLatencyInfo(touch_event);
|
||||
if (ShouldRouteEvents()) {
|
||||
render_widget_host_->delegate()->GetInputEventRouter()->RouteTouchEvent(
|
||||
this, &touch_event, latency_info);
|
||||
} else {
|
||||
render_widget_host_->ForwardTouchEventWithLatencyInfo(touch_event,
|
||||
latency_info);
|
||||
}
|
||||
|
||||
bool touch_end = touch_event.GetType() == blink::WebInputEvent::kTouchEnd ||
|
||||
touch_event.GetType() == blink::WebInputEvent::kTouchCancel;
|
||||
|
||||
if (touch_end && IsPopupWidget() && parent_host_view_ &&
|
||||
parent_host_view_->popup_host_view_ == this) {
|
||||
parent_host_view_->forward_touch_to_popup_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CefRenderWidgetHostViewOSR::ShouldRouteEvents() const {
|
||||
if (!render_widget_host_->delegate())
|
||||
return false;
|
||||
|
||||
// Do not route events that are currently targeted to page popups such as
|
||||
// <select> element drop-downs, since these cannot contain cross-process
|
||||
// frames.
|
||||
if (!render_widget_host_->delegate()->IsWidgetForMainFrame(
|
||||
render_widget_host_)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !!render_widget_host_->delegate()->GetInputEventRouter();
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::SendFocusEvent(bool focus) {
|
||||
if (!render_widget_host_)
|
||||
return;
|
||||
@@ -1455,6 +1573,41 @@ void CefRenderWidgetHostViewOSR::OnUpdateTextInputStateCalled(
|
||||
handler->OnVirtualKeyboardRequested(browser_impl_->GetBrowser(), mode);
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::ProcessAckedTouchEvent(
|
||||
const content::TouchEventWithLatencyInfo& touch,
|
||||
content::InputEventAckState ack_result) {
|
||||
const bool event_consumed =
|
||||
ack_result == content::INPUT_EVENT_ACK_STATE_CONSUMED;
|
||||
gesture_provider_.OnTouchEventAck(touch.event.unique_touch_event_id,
|
||||
event_consumed, false);
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::OnGestureEvent(
|
||||
const ui::GestureEventData& gesture) {
|
||||
if ((gesture.type() == ui::ET_GESTURE_PINCH_BEGIN ||
|
||||
gesture.type() == ui::ET_GESTURE_PINCH_UPDATE ||
|
||||
gesture.type() == ui::ET_GESTURE_PINCH_END) &&
|
||||
!pinch_zoom_enabled_) {
|
||||
return;
|
||||
}
|
||||
|
||||
blink::WebGestureEvent web_event =
|
||||
ui::CreateWebGestureEventFromGestureEventData(gesture);
|
||||
|
||||
// without this check, forwarding gestures does not work!
|
||||
if (web_event.GetType() == blink::WebInputEvent::kUndefined)
|
||||
return;
|
||||
|
||||
ui::LatencyInfo latency_info = CreateLatencyInfo(web_event);
|
||||
if (ShouldRouteEvents()) {
|
||||
render_widget_host_->delegate()->GetInputEventRouter()->RouteGestureEvent(
|
||||
this, &web_event, latency_info);
|
||||
} else {
|
||||
render_widget_host_->ForwardGestureEventWithLatencyInfo(web_event,
|
||||
latency_info);
|
||||
}
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::UpdateFrameRate() {
|
||||
frame_rate_threshold_us_ = 0;
|
||||
SetFrameRate();
|
||||
@@ -1684,6 +1837,9 @@ void CefRenderWidgetHostViewOSR::SendBeginFrame(base::TimeTicks frame_time,
|
||||
DCHECK(begin_frame_args.IsValid());
|
||||
begin_frame_number_++;
|
||||
|
||||
if (render_widget_host_)
|
||||
render_widget_host_->ProgressFlingIfNeeded(frame_time);
|
||||
|
||||
if (renderer_compositor_frame_sink_) {
|
||||
renderer_compositor_frame_sink_->OnBeginFrame(begin_frame_args, {});
|
||||
}
|
||||
|
@@ -14,6 +14,8 @@
|
||||
#include "include/cef_base.h"
|
||||
#include "include/cef_browser.h"
|
||||
|
||||
#include "libcef/browser/osr/motion_event_osr.h"
|
||||
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "build/build_config.h"
|
||||
#include "components/viz/common/frame_sinks/begin_frame_source.h"
|
||||
@@ -24,6 +26,10 @@
|
||||
#include "content/public/common/widget_type.h"
|
||||
#include "ui/compositor/compositor.h"
|
||||
#include "ui/compositor/external_begin_frame_client.h"
|
||||
#include "ui/events/base_event_utils.h"
|
||||
#include "ui/events/gesture_detection/filtered_gesture_provider.h"
|
||||
#include "ui/events/gesture_detection/gesture_configuration.h"
|
||||
#include "ui/events/gesture_detection/motion_event_generic.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
@@ -98,7 +104,8 @@ class MacHelper;
|
||||
class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
|
||||
public ui::ExternalBeginFrameClient,
|
||||
public ui::CompositorDelegate,
|
||||
public content::TextInputManager::Observer {
|
||||
public content::TextInputManager::Observer,
|
||||
public ui::GestureProviderClient {
|
||||
public:
|
||||
CefRenderWidgetHostViewOSR(SkColor background_color,
|
||||
bool use_shared_texture,
|
||||
@@ -198,6 +205,7 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
|
||||
const viz::LocalSurfaceIdAllocation& GetLocalSurfaceIdAllocation()
|
||||
const override;
|
||||
const viz::FrameSinkId& GetFrameSinkId() const override;
|
||||
viz::FrameSinkId GetRootFrameSinkId() override;
|
||||
|
||||
// ui::ExternalBeginFrameClient implementation:
|
||||
void OnDisplayDidFinishFrame(const viz::BeginFrameAck& ack) override;
|
||||
@@ -213,6 +221,11 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
|
||||
RenderWidgetHostViewBase* updated_view,
|
||||
bool did_update_state) override;
|
||||
|
||||
// ui::GestureProviderClient implementation.
|
||||
void ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo& touch,
|
||||
content::InputEventAckState ack_result) override;
|
||||
void OnGestureEvent(const ui::GestureEventData& gesture) override;
|
||||
|
||||
bool InstallTransparency();
|
||||
|
||||
void SynchronizeVisualProperties();
|
||||
@@ -222,6 +235,8 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
|
||||
void SendKeyEvent(const content::NativeWebKeyboardEvent& event);
|
||||
void SendMouseEvent(const blink::WebMouseEvent& event);
|
||||
void SendMouseWheelEvent(const blink::WebMouseWheelEvent& event);
|
||||
void SendTouchEvent(const CefTouchEvent& event);
|
||||
bool ShouldRouteEvents() const;
|
||||
void SendFocusEvent(bool focus);
|
||||
void UpdateFrameRate();
|
||||
|
||||
@@ -253,6 +268,8 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
|
||||
}
|
||||
|
||||
void set_popup_host_view(CefRenderWidgetHostViewOSR* popup_view) {
|
||||
if (popup_view != popup_host_view_)
|
||||
forward_touch_to_popup_ = false;
|
||||
popup_host_view_ = popup_view;
|
||||
}
|
||||
void set_child_host_view(CefRenderWidgetHostViewOSR* popup_view) {
|
||||
@@ -354,8 +371,8 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
|
||||
std::unique_ptr<content::BrowserCompositorMac> browser_compositor_;
|
||||
MacHelper* mac_helper_;
|
||||
#elif defined(USE_X11)
|
||||
CefWindowX11* window_;
|
||||
std::unique_ptr<ui::XScopedCursor> invisible_cursor_;
|
||||
CefWindowX11* window_;
|
||||
std::unique_ptr<ui::XScopedCursor> invisible_cursor_;
|
||||
#endif
|
||||
|
||||
std::unique_ptr<content::CursorManager> cursor_manager_;
|
||||
@@ -401,6 +418,10 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
|
||||
base::Lock damage_rect_lock_;
|
||||
std::map<uint32_t, gfx::Rect> damage_rects_;
|
||||
|
||||
// Whether pinch-to-zoom should be enabled and pinch events forwarded to the
|
||||
// renderer.
|
||||
bool pinch_zoom_enabled_;
|
||||
|
||||
// The last scroll offset of the view.
|
||||
gfx::Vector2dF last_scroll_offset_;
|
||||
bool is_scroll_offset_changed_pending_;
|
||||
@@ -415,6 +436,12 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
|
||||
// EnsureSurfaceSynchronizedForLayoutTest().
|
||||
uint32_t latest_capture_sequence_number_ = 0u;
|
||||
|
||||
// ui::GestureProviderClient implementation.
|
||||
ui::FilteredGestureProvider gesture_provider_;
|
||||
|
||||
CefMotionEventOSR pointer_state_;
|
||||
bool forward_touch_to_popup_;
|
||||
|
||||
base::WeakPtrFactory<CefRenderWidgetHostViewOSR> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefRenderWidgetHostViewOSR);
|
||||
|
@@ -204,6 +204,9 @@ void CefBrowserPlatformDelegateViews::SendMouseWheelEvent(
|
||||
host->GetWidget()->ForwardWheelEvent(event);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::SendTouchEvent(
|
||||
const CefTouchEvent& event) {}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::SendFocusEvent(bool setFocus) {
|
||||
// Will result in a call to WebContents::Focus().
|
||||
if (setFocus && browser_view_->root_view())
|
||||
|
@@ -48,6 +48,7 @@ class CefBrowserPlatformDelegateViews
|
||||
void SendKeyEvent(const content::NativeWebKeyboardEvent& event) override;
|
||||
void SendMouseEvent(const blink::WebMouseEvent& event) override;
|
||||
void SendMouseWheelEvent(const blink::WebMouseWheelEvent& event) override;
|
||||
void SendTouchEvent(const CefTouchEvent& event) override;
|
||||
void SendFocusEvent(bool setFocus) override;
|
||||
gfx::Point GetScreenPoint(const gfx::Point& view) const override;
|
||||
void ViewText(const std::string& text) override;
|
||||
|
Reference in New Issue
Block a user