Commit 6e8f1f65 authored by Dave Tapuska's avatar Dave Tapuska Committed by Commit Bot

Remove duplicated code around input handling in Frame Widget classes.

Since WebFrameWidgetBase is now a PageWidgetEventhandler we can
deduplicate some of the input handling code. The remaining methods have
a few fundamental differences in them and will need to collapse them.

BUG=1097816

Change-Id: Id5bbeb435b9b0ed698c9644ed5b44e39844ed39a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2523335
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
Reviewed-by: default avatardanakj <danakj@chromium.org>
Cr-Commit-Position: refs/heads/master@{#825378}
parent 3b05543d
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "third_party/blink/renderer/core/frame/visual_viewport.h" #include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h" #include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/html/html_plugin_element.h"
#include "third_party/blink/renderer/core/html/portal/document_portals.h" #include "third_party/blink/renderer/core/html/portal/document_portals.h"
#include "third_party/blink/renderer/core/html/portal/portal_contents.h" #include "third_party/blink/renderer/core/html/portal/portal_contents.h"
#include "third_party/blink/renderer/core/input/context_menu_allowed_scope.h" #include "third_party/blink/renderer/core/input/context_menu_allowed_scope.h"
...@@ -502,6 +503,171 @@ void WebFrameWidgetBase::SetActive(bool active) { ...@@ -502,6 +503,171 @@ void WebFrameWidgetBase::SetActive(bool active) {
View()->SetIsActive(active); View()->SetIsActive(active);
} }
void WebFrameWidgetBase::HandleMouseDown(LocalFrame& main_frame,
const WebMouseEvent& event) {
WebViewImpl* view_impl = View();
// If there is a popup open, close it as the user is clicking on the page
// (outside of the popup). We also save it so we can prevent a click on an
// element from immediately reopening the same popup.
scoped_refptr<WebPagePopupImpl> page_popup;
if (event.button == WebMouseEvent::Button::kLeft) {
page_popup = view_impl->GetPagePopup();
view_impl->CancelPagePopup();
}
// Take capture on a mouse down on a plugin so we can send it mouse events.
// If the hit node is a plugin but a scrollbar is over it don't start mouse
// capture because it will interfere with the scrollbar receiving events.
PhysicalOffset point(LayoutUnit(event.PositionInWidget().x()),
LayoutUnit(event.PositionInWidget().y()));
if (event.button == WebMouseEvent::Button::kLeft) {
HitTestLocation location(
LocalRootImpl()->GetFrameView()->ConvertFromRootFrame(point));
HitTestResult result(
LocalRootImpl()->GetFrame()->GetEventHandler().HitTestResultAtLocation(
location));
result.SetToShadowHostIfInRestrictedShadowRoot();
Node* hit_node = result.InnerNode();
auto* html_element = DynamicTo<HTMLElement>(hit_node);
if (!result.GetScrollbar() && hit_node && hit_node->GetLayoutObject() &&
hit_node->GetLayoutObject()->IsEmbeddedObject() && html_element &&
html_element->IsPluginElement()) {
mouse_capture_element_ = To<HTMLPlugInElement>(hit_node);
TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("input", "capturing mouse",
TRACE_ID_LOCAL(this));
}
}
PageWidgetEventHandler::HandleMouseDown(main_frame, event);
if (view_impl->GetPagePopup() && page_popup &&
view_impl->GetPagePopup()->HasSamePopupClient(page_popup.get())) {
// That click triggered a page popup that is the same as the one we just
// closed. It needs to be closed.
view_impl->CancelPagePopup();
}
// Dispatch the contextmenu event regardless of if the click was swallowed.
if (!GetPage()->GetSettings().GetShowContextMenuOnMouseUp()) {
#if defined(OS_MAC)
if (event.button == WebMouseEvent::Button::kRight ||
(event.button == WebMouseEvent::Button::kLeft &&
event.GetModifiers() & WebMouseEvent::kControlKey))
MouseContextMenu(event);
#else
if (event.button == WebMouseEvent::Button::kRight)
MouseContextMenu(event);
#endif
}
}
void WebFrameWidgetBase::MouseContextMenu(const WebMouseEvent& event) {
GetPage()->GetContextMenuController().ClearContextMenu();
WebMouseEvent transformed_event =
TransformWebMouseEvent(LocalRootImpl()->GetFrameView(), event);
transformed_event.menu_source_type = kMenuSourceMouse;
// Find the right target frame. See issue 1186900.
HitTestResult result = HitTestResultForRootFramePos(
FloatPoint(transformed_event.PositionInRootFrame()));
Frame* target_frame;
if (result.InnerNodeOrImageMapImage())
target_frame = result.InnerNodeOrImageMapImage()->GetDocument().GetFrame();
else
target_frame = GetPage()->GetFocusController().FocusedOrMainFrame();
// This will need to be changed to a nullptr check when focus control
// is refactored, at which point focusedOrMainFrame will never return a
// RemoteFrame.
// See https://crbug.com/341918.
LocalFrame* target_local_frame = DynamicTo<LocalFrame>(target_frame);
if (!target_local_frame)
return;
{
ContextMenuAllowedScope scope;
target_local_frame->GetEventHandler().SendContextMenuEvent(
transformed_event);
}
// Actually showing the context menu is handled by the ContextMenuClient
// implementation...
}
WebInputEventResult WebFrameWidgetBase::HandleMouseUp(
LocalFrame& main_frame,
const WebMouseEvent& event) {
WebInputEventResult result =
PageWidgetEventHandler::HandleMouseUp(main_frame, event);
if (GetPage()->GetSettings().GetShowContextMenuOnMouseUp()) {
// Dispatch the contextmenu event regardless of if the click was swallowed.
// On Mac/Linux, we handle it on mouse down, not up.
if (event.button == WebMouseEvent::Button::kRight)
MouseContextMenu(event);
}
return result;
}
WebInputEventResult WebFrameWidgetBase::HandleMouseWheel(
LocalFrame& frame,
const WebMouseWheelEvent& event) {
View()->CancelPagePopup();
return PageWidgetEventHandler::HandleMouseWheel(frame, event);
}
WebInputEventResult WebFrameWidgetBase::HandleCharEvent(
const WebKeyboardEvent& event) {
DCHECK_EQ(event.GetType(), WebInputEvent::Type::kChar);
// Please refer to the comments explaining the m_suppressNextKeypressEvent
// member. The m_suppressNextKeypressEvent is set if the KeyDown is
// handled by Webkit. A keyDown event is typically associated with a
// keyPress(char) event and a keyUp event. We reset this flag here as it
// only applies to the current keyPress event.
bool suppress = suppress_next_keypress_event_;
suppress_next_keypress_event_ = false;
// If there is a popup open, it should be the one processing the event,
// not the page.
scoped_refptr<WebPagePopupImpl> page_popup = View()->GetPagePopup();
if (page_popup)
return page_popup->HandleKeyEvent(event);
LocalFrame* frame = To<LocalFrame>(FocusedCoreFrame());
if (!frame) {
return suppress ? WebInputEventResult::kHandledSuppressed
: WebInputEventResult::kNotHandled;
}
EventHandler& handler = frame->GetEventHandler();
if (!event.IsCharacterKey())
return WebInputEventResult::kHandledSuppressed;
// Accesskeys are triggered by char events and can't be suppressed.
// It is unclear whether a keypress should be dispatched as well
// crbug.com/563507
if (handler.HandleAccessKey(event))
return WebInputEventResult::kHandledSystem;
// Safari 3.1 does not pass off windows system key messages (WM_SYSCHAR) to
// the eventHandler::keyEvent. We mimic this behavior on all platforms since
// for now we are converting other platform's key events to windows key
// events.
if (event.is_system_key)
return WebInputEventResult::kNotHandled;
if (suppress)
return WebInputEventResult::kHandledSuppressed;
WebInputEventResult result = handler.KeyEvent(event);
if (result != WebInputEventResult::kNotHandled)
return result;
return WebInputEventResult::kNotHandled;
}
void WebFrameWidgetBase::CancelDrag() { void WebFrameWidgetBase::CancelDrag() {
// It's possible for this to be called while we're not doing a drag if // It's possible for this to be called while we're not doing a drag if
// it's from a previous page that got unloaded. // it's from a previous page that got unloaded.
...@@ -633,6 +799,7 @@ void WebFrameWidgetBase::Trace(Visitor* visitor) const { ...@@ -633,6 +799,7 @@ void WebFrameWidgetBase::Trace(Visitor* visitor) const {
visitor->Trace(frame_widget_host_); visitor->Trace(frame_widget_host_);
visitor->Trace(receiver_); visitor->Trace(receiver_);
visitor->Trace(input_target_receiver_); visitor->Trace(input_target_receiver_);
visitor->Trace(mouse_capture_element_);
} }
void WebFrameWidgetBase::SetNeedsRecalculateRasterScales() { void WebFrameWidgetBase::SetNeedsRecalculateRasterScales() {
...@@ -2429,6 +2596,24 @@ void WebFrameWidgetBase::NotifyInputObservers( ...@@ -2429,6 +2596,24 @@ void WebFrameWidgetBase::NotifyInputObservers(
paint_timing_detector.NotifyInputEvent(input_event.GetType()); paint_timing_detector.NotifyInputEvent(input_event.GetType());
} }
Frame* WebFrameWidgetBase::FocusedCoreFrame() const {
return GetPage() ? GetPage()->GetFocusController().FocusedOrMainFrame()
: nullptr;
}
HitTestResult WebFrameWidgetBase::HitTestResultForRootFramePos(
const FloatPoint& pos_in_root_frame) {
FloatPoint doc_point =
LocalRootImpl()->GetFrame()->View()->ConvertFromRootFrame(
pos_in_root_frame);
HitTestLocation location(doc_point);
HitTestResult result =
LocalRootImpl()->GetFrame()->GetEventHandler().HitTestResultAtLocation(
location, HitTestRequest::kReadOnly | HitTestRequest::kActive);
result.SetToShadowHostIfInRestrictedShadowRoot();
return result;
}
KURL WebFrameWidgetBase::GetURLForDebugTrace() { KURL WebFrameWidgetBase::GetURLForDebugTrace() {
WebFrame* main_frame = View()->MainFrame(); WebFrame* main_frame = View()->MainFrame();
if (main_frame->IsWebLocalFrame()) if (main_frame->IsWebLocalFrame())
......
...@@ -46,7 +46,9 @@ class PointF; ...@@ -46,7 +46,9 @@ class PointF;
namespace blink { namespace blink {
class AnimationWorkletMutatorDispatcherImpl; class AnimationWorkletMutatorDispatcherImpl;
class FloatPoint;
class HitTestResult; class HitTestResult;
class HTMLPlugInElement;
class LocalFrameView; class LocalFrameView;
class Page; class Page;
class PageWidgetEventHandler; class PageWidgetEventHandler;
...@@ -658,6 +660,12 @@ class CORE_EXPORT WebFrameWidgetBase ...@@ -658,6 +660,12 @@ class CORE_EXPORT WebFrameWidgetBase
// of WebViewImpl::HandleInputEvent and WebFrameWidgetImpl::HandleInputEvent. // of WebViewImpl::HandleInputEvent and WebFrameWidgetImpl::HandleInputEvent.
void NotifyInputObservers(const WebCoalescedInputEvent& coalesced_event); void NotifyInputObservers(const WebCoalescedInputEvent& coalesced_event);
Frame* FocusedCoreFrame() const;
// Perform a hit test for a point relative to the root frame of the page.
HitTestResult HitTestResultForRootFramePos(
const FloatPoint& pos_in_root_frame);
// A copy of the web drop data object we received from the browser. // A copy of the web drop data object we received from the browser.
Member<DataObject> current_drag_data_; Member<DataObject> current_drag_data_;
...@@ -686,7 +694,26 @@ class CORE_EXPORT WebFrameWidgetBase ...@@ -686,7 +694,26 @@ class CORE_EXPORT WebFrameWidgetBase
float page_scale_factor_in_mainframe_ = 1.f; float page_scale_factor_in_mainframe_ = 1.f;
bool is_pinch_gesture_active_in_mainframe_ = false; bool is_pinch_gesture_active_in_mainframe_ = false;
// If set, the (plugin) element which has mouse capture.
// TODO(dtapuska): Move to private once all input handling is moved to
// base class.
Member<HTMLPlugInElement> mouse_capture_element_;
// keyPress events to be suppressed if the associated keyDown event was
// handled.
// TODO(dtapuska): Move to private once all input handling is moved to
// base class.
bool suppress_next_keypress_event_ = false;
private: private:
// PageWidgetEventHandler methods:
void HandleMouseDown(LocalFrame&, const WebMouseEvent&) override;
WebInputEventResult HandleMouseUp(LocalFrame&, const WebMouseEvent&) override;
WebInputEventResult HandleMouseWheel(LocalFrame&,
const WebMouseWheelEvent&) override;
WebInputEventResult HandleCharEvent(const WebKeyboardEvent&) override;
void MouseContextMenu(const WebMouseEvent&);
void CancelDrag(); void CancelDrag();
void RequestAnimationAfterDelayTimerFired(TimerBase*); void RequestAnimationAfterDelayTimerFired(TimerBase*);
void PresentationCallbackForMeaningfulLayout(blink::WebSwapResult, void PresentationCallbackForMeaningfulLayout(blink::WebSwapResult,
......
...@@ -227,11 +227,6 @@ WebFrameWidgetImpl::WebFrameWidgetImpl( ...@@ -227,11 +227,6 @@ WebFrameWidgetImpl::WebFrameWidgetImpl(
WebFrameWidgetImpl::~WebFrameWidgetImpl() = default; WebFrameWidgetImpl::~WebFrameWidgetImpl() = default;
void WebFrameWidgetImpl::Trace(Visitor* visitor) const {
visitor->Trace(mouse_capture_element_);
WebFrameWidgetBase::Trace(visitor);
}
// WebWidget ------------------------------------------------------------------ // WebWidget ------------------------------------------------------------------
void WebFrameWidgetImpl::Close( void WebFrameWidgetImpl::Close(
...@@ -679,119 +674,6 @@ void WebFrameWidgetImpl::HandleMouseLeave(LocalFrame& main_frame, ...@@ -679,119 +674,6 @@ void WebFrameWidgetImpl::HandleMouseLeave(LocalFrame& main_frame,
PageWidgetEventHandler::HandleMouseLeave(main_frame, event); PageWidgetEventHandler::HandleMouseLeave(main_frame, event);
} }
void WebFrameWidgetImpl::HandleMouseDown(LocalFrame& main_frame,
const WebMouseEvent& event) {
WebViewImpl* view_impl = View();
// If there is a popup open, close it as the user is clicking on the page
// (outside of the popup). We also save it so we can prevent a click on an
// element from immediately reopening the same popup.
scoped_refptr<WebPagePopupImpl> page_popup;
if (event.button == WebMouseEvent::Button::kLeft) {
page_popup = view_impl->GetPagePopup();
view_impl->CancelPagePopup();
}
// Take capture on a mouse down on a plugin so we can send it mouse events.
// If the hit node is a plugin but a scrollbar is over it don't start mouse
// capture because it will interfere with the scrollbar receiving events.
PhysicalOffset point(LayoutUnit(event.PositionInWidget().x()),
LayoutUnit(event.PositionInWidget().y()));
if (event.button == WebMouseEvent::Button::kLeft) {
HitTestLocation location(
LocalRootImpl()->GetFrameView()->ConvertFromRootFrame(point));
HitTestResult result(
LocalRootImpl()->GetFrame()->GetEventHandler().HitTestResultAtLocation(
location));
result.SetToShadowHostIfInRestrictedShadowRoot();
Node* hit_node = result.InnerNode();
auto* html_element = DynamicTo<HTMLElement>(hit_node);
if (!result.GetScrollbar() && hit_node && hit_node->GetLayoutObject() &&
hit_node->GetLayoutObject()->IsEmbeddedObject() && html_element &&
html_element->IsPluginElement()) {
mouse_capture_element_ = To<HTMLPlugInElement>(hit_node);
TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("input", "capturing mouse",
TRACE_ID_LOCAL(this));
}
}
PageWidgetEventHandler::HandleMouseDown(main_frame, event);
if (view_impl->GetPagePopup() && page_popup &&
view_impl->GetPagePopup()->HasSamePopupClient(page_popup.get())) {
// That click triggered a page popup that is the same as the one we just
// closed. It needs to be closed.
view_impl->CancelPagePopup();
}
// Dispatch the contextmenu event regardless of if the click was swallowed.
if (!GetPage()->GetSettings().GetShowContextMenuOnMouseUp()) {
#if defined(OS_MAC)
if (event.button == WebMouseEvent::Button::kRight ||
(event.button == WebMouseEvent::Button::kLeft &&
event.GetModifiers() & WebMouseEvent::kControlKey))
MouseContextMenu(event);
#else
if (event.button == WebMouseEvent::Button::kRight)
MouseContextMenu(event);
#endif
}
}
void WebFrameWidgetImpl::MouseContextMenu(const WebMouseEvent& event) {
GetPage()->GetContextMenuController().ClearContextMenu();
WebMouseEvent transformed_event =
TransformWebMouseEvent(LocalRootImpl()->GetFrameView(), event);
transformed_event.menu_source_type = kMenuSourceMouse;
// Find the right target frame. See issue 1186900.
HitTestResult result = HitTestResultForRootFramePos(
FloatPoint(transformed_event.PositionInRootFrame()));
Frame* target_frame;
if (result.InnerNodeOrImageMapImage())
target_frame = result.InnerNodeOrImageMapImage()->GetDocument().GetFrame();
else
target_frame = GetPage()->GetFocusController().FocusedOrMainFrame();
// This will need to be changed to a nullptr check when focus control
// is refactored, at which point focusedOrMainFrame will never return a
// RemoteFrame.
// See https://crbug.com/341918.
LocalFrame* target_local_frame = DynamicTo<LocalFrame>(target_frame);
if (!target_local_frame)
return;
{
ContextMenuAllowedScope scope;
target_local_frame->GetEventHandler().SendContextMenuEvent(
transformed_event);
}
// Actually showing the context menu is handled by the ContextMenuClient
// implementation...
}
WebInputEventResult WebFrameWidgetImpl::HandleMouseUp(
LocalFrame& main_frame,
const WebMouseEvent& event) {
WebInputEventResult result =
PageWidgetEventHandler::HandleMouseUp(main_frame, event);
if (GetPage()->GetSettings().GetShowContextMenuOnMouseUp()) {
// Dispatch the contextmenu event regardless of if the click was swallowed.
// On Mac/Linux, we handle it on mouse down, not up.
if (event.button == WebMouseEvent::Button::kRight)
MouseContextMenu(event);
}
return result;
}
WebInputEventResult WebFrameWidgetImpl::HandleMouseWheel(
LocalFrame& frame,
const WebMouseWheelEvent& event) {
View()->CancelPagePopup();
return PageWidgetEventHandler::HandleMouseWheel(frame, event);
}
WebInputEventResult WebFrameWidgetImpl::HandleGestureEvent( WebInputEventResult WebFrameWidgetImpl::HandleGestureEvent(
const WebGestureEvent& event) { const WebGestureEvent& event) {
DCHECK(Client()); DCHECK(Client());
...@@ -931,63 +813,6 @@ WebInputEventResult WebFrameWidgetImpl::HandleKeyEvent( ...@@ -931,63 +813,6 @@ WebInputEventResult WebFrameWidgetImpl::HandleKeyEvent(
return WebInputEventResult::kNotHandled; return WebInputEventResult::kNotHandled;
} }
WebInputEventResult WebFrameWidgetImpl::HandleCharEvent(
const WebKeyboardEvent& event) {
DCHECK_EQ(event.GetType(), WebInputEvent::Type::kChar);
// Please refer to the comments explaining the m_suppressNextKeypressEvent
// member. The m_suppressNextKeypressEvent is set if the KeyDown is
// handled by Webkit. A keyDown event is typically associated with a
// keyPress(char) event and a keyUp event. We reset this flag here as it
// only applies to the current keyPress event.
bool suppress = suppress_next_keypress_event_;
suppress_next_keypress_event_ = false;
// If there is a popup open, it should be the one processing the event,
// not the page.
scoped_refptr<WebPagePopupImpl> page_popup = View()->GetPagePopup();
if (page_popup)
return page_popup->HandleKeyEvent(event);
LocalFrame* frame = To<LocalFrame>(FocusedCoreFrame());
if (!frame) {
return suppress ? WebInputEventResult::kHandledSuppressed
: WebInputEventResult::kNotHandled;
}
EventHandler& handler = frame->GetEventHandler();
if (!event.IsCharacterKey())
return WebInputEventResult::kHandledSuppressed;
// Accesskeys are triggered by char events and can't be suppressed.
// It is unclear whether a keypress should be dispatched as well
// crbug.com/563507
if (handler.HandleAccessKey(event))
return WebInputEventResult::kHandledSystem;
// Safari 3.1 does not pass off windows system key messages (WM_SYSCHAR) to
// the eventHandler::keyEvent. We mimic this behavior on all platforms since
// for now we are converting other platform's key events to windows key
// events.
if (event.is_system_key)
return WebInputEventResult::kNotHandled;
if (suppress)
return WebInputEventResult::kHandledSuppressed;
WebInputEventResult result = handler.KeyEvent(event);
if (result != WebInputEventResult::kNotHandled)
return result;
return WebInputEventResult::kNotHandled;
}
Frame* WebFrameWidgetImpl::FocusedCoreFrame() const {
return GetPage() ? GetPage()->GetFocusController().FocusedOrMainFrame()
: nullptr;
}
Element* WebFrameWidgetImpl::FocusedElement() const { Element* WebFrameWidgetImpl::FocusedElement() const {
LocalFrame* frame = GetPage()->GetFocusController().FocusedFrame(); LocalFrame* frame = GetPage()->GetFocusController().FocusedFrame();
if (!frame) if (!frame)
...@@ -1048,19 +873,6 @@ void WebFrameWidgetImpl::SetAutoResizeMode(bool auto_resize, ...@@ -1048,19 +873,6 @@ void WebFrameWidgetImpl::SetAutoResizeMode(bool auto_resize,
// Auto resize mode only exists on the top level widget. // Auto resize mode only exists on the top level widget.
} }
HitTestResult WebFrameWidgetImpl::HitTestResultForRootFramePos(
const FloatPoint& pos_in_root_frame) {
FloatPoint doc_point =
LocalRootImpl()->GetFrame()->View()->ConvertFromRootFrame(
pos_in_root_frame);
HitTestLocation location(doc_point);
HitTestResult result =
LocalRootImpl()->GetFrame()->GetEventHandler().HitTestResultAtLocation(
location, HitTestRequest::kReadOnly | HitTestRequest::kActive);
result.SetToShadowHostIfInRestrictedShadowRoot();
return result;
}
LocalFrame* WebFrameWidgetImpl::FocusedLocalFrameAvailableForIme() const { LocalFrame* WebFrameWidgetImpl::FocusedLocalFrameAvailableForIme() const {
if (!ime_accept_events_) if (!ime_accept_events_)
return nullptr; return nullptr;
......
...@@ -55,14 +55,11 @@ class Layer; ...@@ -55,14 +55,11 @@ class Layer;
} }
namespace blink { namespace blink {
class Frame;
class Element; class Element;
class HTMLPlugInElement;
class LocalFrame; class LocalFrame;
class PaintLayerCompositor; class PaintLayerCompositor;
class WebFrameWidget; class WebFrameWidget;
class WebMouseEvent; class WebMouseEvent;
class WebMouseWheelEvent;
class WebFrameWidgetImpl; class WebFrameWidgetImpl;
// Implements WebFrameWidget for a child local root frame (OOPIF). This object // Implements WebFrameWidget for a child local root frame (OOPIF). This object
...@@ -119,8 +116,6 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase { ...@@ -119,8 +116,6 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase {
void ResetZoomLevelForTesting() override; void ResetZoomLevelForTesting() override;
void SetDeviceScaleFactorForTesting(float factor) override; void SetDeviceScaleFactorForTesting(float factor) override;
Frame* FocusedCoreFrame() const;
// Returns the currently focused Element or null if no element has focus. // Returns the currently focused Element or null if no element has focus.
Element* FocusedElement() const; Element* FocusedElement() const;
...@@ -161,29 +156,15 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase { ...@@ -161,29 +156,15 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase {
void UpdateMainFrameLayoutSize(); void UpdateMainFrameLayoutSize();
// Event related methods:
void MouseContextMenu(const WebMouseEvent&);
void Trace(Visitor*) const override;
private: private:
friend class WebFrameWidget; // For WebFrameWidget::create. friend class WebFrameWidget; // For WebFrameWidget::create.
// Perform a hit test for a point relative to the root frame of the page.
HitTestResult HitTestResultForRootFramePos(
const FloatPoint& pos_in_root_frame);
void UpdateLayerTreeViewport(); void UpdateLayerTreeViewport();
// PageWidgetEventHandler functions // PageWidgetEventHandler functions
void HandleMouseLeave(LocalFrame&, const WebMouseEvent&) override; void HandleMouseLeave(LocalFrame&, const WebMouseEvent&) override;
void HandleMouseDown(LocalFrame&, const WebMouseEvent&) override;
WebInputEventResult HandleMouseUp(LocalFrame&, const WebMouseEvent&) override;
WebInputEventResult HandleMouseWheel(LocalFrame&,
const WebMouseWheelEvent&) override;
WebInputEventResult HandleGestureEvent(const WebGestureEvent&) override; WebInputEventResult HandleGestureEvent(const WebGestureEvent&) override;
WebInputEventResult HandleKeyEvent(const WebKeyboardEvent&) override; WebInputEventResult HandleKeyEvent(const WebKeyboardEvent&) override;
WebInputEventResult HandleCharEvent(const WebKeyboardEvent&) override;
LocalFrameView* GetLocalFrameViewForAnimationScrolling() override; LocalFrameView* GetLocalFrameViewForAnimationScrolling() override;
...@@ -200,15 +181,10 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase { ...@@ -200,15 +181,10 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase {
base::Optional<gfx::Size> size_; base::Optional<gfx::Size> size_;
// If set, the (plugin) element which has mouse capture.
Member<HTMLPlugInElement> mouse_capture_element_;
// Metrics gathering timing information // Metrics gathering timing information
base::Optional<base::TimeTicks> update_layers_start_time_; base::Optional<base::TimeTicks> update_layers_start_time_;
base::Optional<base::TimeTicks> commit_compositor_frame_start_time_; base::Optional<base::TimeTicks> commit_compositor_frame_start_time_;
bool suppress_next_keypress_event_ = false;
bool did_suspend_parsing_ = false; bool did_suspend_parsing_ = false;
// TODO(ekaramad): Can we remove this and make sure IME events are not called // TODO(ekaramad): Can we remove this and make sure IME events are not called
......
...@@ -405,7 +405,6 @@ void WebViewFrameWidget::ZoomToFindInPageRect( ...@@ -405,7 +405,6 @@ void WebViewFrameWidget::ZoomToFindInPageRect(
void WebViewFrameWidget::Trace(Visitor* visitor) const { void WebViewFrameWidget::Trace(Visitor* visitor) const {
WebFrameWidgetBase::Trace(visitor); WebFrameWidgetBase::Trace(visitor);
visitor->Trace(device_emulator_); visitor->Trace(device_emulator_);
visitor->Trace(mouse_capture_element_);
} }
WebInputEventResult WebViewFrameWidget::HandleKeyEvent( WebInputEventResult WebViewFrameWidget::HandleKeyEvent(
...@@ -494,181 +493,12 @@ WebInputEventResult WebViewFrameWidget::HandleKeyEvent( ...@@ -494,181 +493,12 @@ WebInputEventResult WebViewFrameWidget::HandleKeyEvent(
return WebInputEventResult::kNotHandled; return WebInputEventResult::kNotHandled;
} }
WebInputEventResult WebViewFrameWidget::HandleCharEvent(
const WebKeyboardEvent& event) {
DCHECK_EQ(event.GetType(), WebInputEvent::Type::kChar);
TRACE_EVENT1("input", "WebViewFrameWidget::HandleCharEvent", "text",
String(event.text).Utf8());
// Please refer to the comments explaining |suppress_next_keypress_event_|
// |suppress_next_keypress_event_| is set if the KeyDown is
// handled by Webkit. A keyDown event is typically associated with a
// keyPress(char) event and a keyUp event. We reset this flag here as it
// only applies to the current keyPress event.
bool suppress = suppress_next_keypress_event_;
suppress_next_keypress_event_ = false;
// If there is a popup, it should be the one processing the event, not the
// page.
scoped_refptr<WebPagePopupImpl> page_popup = View()->GetPagePopup();
if (page_popup)
return page_popup->HandleKeyEvent(event);
auto* frame = To<LocalFrame>(web_view_->FocusedCoreFrame());
if (!frame) {
return suppress ? WebInputEventResult::kHandledSuppressed
: WebInputEventResult::kNotHandled;
}
EventHandler& handler = frame->GetEventHandler();
if (!event.IsCharacterKey())
return WebInputEventResult::kHandledSuppressed;
// Accesskeys are triggered by char events and can't be suppressed.
if (handler.HandleAccessKey(event))
return WebInputEventResult::kHandledSystem;
// Safari 3.1 does not pass off windows system key messages (WM_SYSCHAR) to
// the eventHandler::keyEvent. We mimic this behavior on all platforms since
// for now we are converting other platform's key events to windows key
// events.
if (event.is_system_key)
return WebInputEventResult::kNotHandled;
if (suppress)
return WebInputEventResult::kHandledSuppressed;
WebInputEventResult result = handler.KeyEvent(event);
if (result != WebInputEventResult::kNotHandled)
return result;
return WebInputEventResult::kNotHandled;
}
void WebViewFrameWidget::HandleMouseLeave(LocalFrame& main_frame, void WebViewFrameWidget::HandleMouseLeave(LocalFrame& main_frame,
const WebMouseEvent& event) { const WebMouseEvent& event) {
web_view_->SetMouseOverURL(WebURL()); web_view_->SetMouseOverURL(WebURL());
PageWidgetEventHandler::HandleMouseLeave(main_frame, event); PageWidgetEventHandler::HandleMouseLeave(main_frame, event);
} }
void WebViewFrameWidget::HandleMouseDown(LocalFrame& main_frame,
const WebMouseEvent& event) {
// If there is a popup open, close it as the user is clicking on the page
// (outside of the popup). We also save it so we can prevent a click on an
// element from immediately reopening the same popup.
//
// The popup would not be destroyed in this stack normally as it is owned by
// closership from the RenderWidget, which is owned by the browser via the
// Close IPC. However if a nested message loop were to happen then the browser
// close of the RenderWidget and WebPagePopupImpl could feasibly occur inside
// this method, so holding a reference here ensures we can use the
// |page_popup| even if it is closed.
scoped_refptr<WebPagePopupImpl> page_popup;
if (event.button == WebMouseEvent::Button::kLeft) {
page_popup = web_view_->GetPagePopup();
web_view_->CancelPagePopup();
}
// Take capture on a mouse down on a plugin so we can send it mouse events.
// If the hit node is a plugin but a scrollbar is over it don't start mouse
// capture because it will interfere with the scrollbar receiving events.
if (event.button == WebMouseEvent::Button::kLeft) {
HitTestLocation location(main_frame.View()->ConvertFromRootFrame(
FloatPoint(event.PositionInWidget())));
HitTestResult result(
main_frame.GetEventHandler().HitTestResultAtLocation(location));
result.SetToShadowHostIfInRestrictedShadowRoot();
Node* hit_node = result.InnerNodeOrImageMapImage();
auto* html_element = DynamicTo<HTMLElement>(hit_node);
if (!result.GetScrollbar() && hit_node && hit_node->GetLayoutObject() &&
hit_node->GetLayoutObject()->IsEmbeddedObject() && html_element &&
html_element->IsPluginElement()) {
mouse_capture_element_ = To<HTMLPlugInElement>(hit_node);
main_frame.Client()->SetMouseCapture(true);
TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("input", "capturing mouse",
TRACE_ID_LOCAL(this));
}
}
PageWidgetEventHandler::HandleMouseDown(main_frame, event);
if (web_view_->GetPagePopup() && page_popup &&
web_view_->GetPagePopup()->HasSamePopupClient(page_popup.get())) {
// That click triggered a page popup that is the same as the one we just
// closed. It needs to be closed.
web_view_->CancelPagePopup();
}
// Dispatch the contextmenu event regardless of if the click was swallowed.
if (!GetPage()->GetSettings().GetShowContextMenuOnMouseUp()) {
#if defined(OS_MAC)
if (event.button == WebMouseEvent::Button::kRight ||
(event.button == WebMouseEvent::Button::kLeft &&
event.GetModifiers() & WebMouseEvent::kControlKey))
MouseContextMenu(event);
#else
if (event.button == WebMouseEvent::Button::kRight)
MouseContextMenu(event);
#endif
}
}
void WebViewFrameWidget::MouseContextMenu(const WebMouseEvent& event) {
if (!web_view_->MainFrameImpl() ||
!web_view_->MainFrameImpl()->GetFrameView())
return;
GetPage()->GetContextMenuController().ClearContextMenu();
WebMouseEvent transformed_event =
TransformWebMouseEvent(web_view_->MainFrameImpl()->GetFrameView(), event);
transformed_event.menu_source_type = kMenuSourceMouse;
// Find the right target frame. See issue 1186900.
HitTestResult result = web_view_->HitTestResultForRootFramePos(
FloatPoint(transformed_event.PositionInRootFrame()));
Frame* target_frame;
if (result.InnerNodeOrImageMapImage())
target_frame = result.InnerNodeOrImageMapImage()->GetDocument().GetFrame();
else
target_frame = GetPage()->GetFocusController().FocusedOrMainFrame();
auto* target_local_frame = DynamicTo<LocalFrame>(target_frame);
if (!target_local_frame)
return;
{
ContextMenuAllowedScope scope;
target_local_frame->GetEventHandler().SendContextMenuEvent(
transformed_event);
}
// Actually showing the context menu is handled by the ContextMenuController
// implementation...
}
WebInputEventResult WebViewFrameWidget::HandleMouseUp(
LocalFrame& main_frame,
const WebMouseEvent& event) {
WebInputEventResult result =
PageWidgetEventHandler::HandleMouseUp(main_frame, event);
if (GetPage()->GetSettings().GetShowContextMenuOnMouseUp()) {
// Dispatch the contextmenu event regardless of if the click was swallowed.
// On Mac/Linux, we handle it on mouse down, not up.
if (event.button == WebMouseEvent::Button::kRight)
MouseContextMenu(event);
}
return result;
}
WebInputEventResult WebViewFrameWidget::HandleMouseWheel(
LocalFrame& main_frame,
const WebMouseWheelEvent& event) {
web_view_->CancelPagePopup();
return PageWidgetEventHandler::HandleMouseWheel(main_frame, event);
}
WebInputEventResult WebViewFrameWidget::HandleGestureEvent( WebInputEventResult WebViewFrameWidget::HandleGestureEvent(
const WebGestureEvent& event) { const WebGestureEvent& event) {
if (!web_view_->Client() || !web_view_->Client()->CanHandleGestureEvent()) { if (!web_view_->Client() || !web_view_->Client()->CanHandleGestureEvent()) {
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
namespace blink { namespace blink {
class HTMLPlugInElement;
class WebFrameWidget; class WebFrameWidget;
class WebViewImpl; class WebViewImpl;
class WebWidgetClient; class WebWidgetClient;
...@@ -148,17 +147,10 @@ class CORE_EXPORT WebViewFrameWidget : public WebFrameWidgetBase { ...@@ -148,17 +147,10 @@ class CORE_EXPORT WebViewFrameWidget : public WebFrameWidgetBase {
private: private:
// PageWidgetEventHandler overrides: // PageWidgetEventHandler overrides:
void HandleMouseLeave(LocalFrame&, const WebMouseEvent&) override; void HandleMouseLeave(LocalFrame&, const WebMouseEvent&) override;
void HandleMouseDown(LocalFrame&, const WebMouseEvent&) override;
WebInputEventResult HandleMouseUp(LocalFrame&, const WebMouseEvent&) override;
WebInputEventResult HandleMouseWheel(LocalFrame&,
const WebMouseWheelEvent&) override;
WebInputEventResult HandleGestureEvent(const WebGestureEvent&) override; WebInputEventResult HandleGestureEvent(const WebGestureEvent&) override;
WebInputEventResult HandleKeyEvent(const WebKeyboardEvent&) override; WebInputEventResult HandleKeyEvent(const WebKeyboardEvent&) override;
WebInputEventResult HandleCharEvent(const WebKeyboardEvent&) override;
WebInputEventResult HandleCapturedMouseEvent(const WebCoalescedInputEvent&); WebInputEventResult HandleCapturedMouseEvent(const WebCoalescedInputEvent&);
void MouseContextMenu(const WebMouseEvent&);
void MouseDoubleClick(const WebMouseEvent&);
LocalFrameView* GetLocalFrameViewForAnimationScrolling() override; LocalFrameView* GetLocalFrameViewForAnimationScrolling() override;
void SetWindowRectSynchronously(const gfx::Rect& new_window_rect); void SetWindowRectSynchronously(const gfx::Rect& new_window_rect);
...@@ -204,13 +196,6 @@ class CORE_EXPORT WebViewFrameWidget : public WebFrameWidgetBase { ...@@ -204,13 +196,6 @@ class CORE_EXPORT WebViewFrameWidget : public WebFrameWidgetBase {
// than the WebViewImpl::size_ since isn't set in auto resize mode. // than the WebViewImpl::size_ since isn't set in auto resize mode.
gfx::Size size_; gfx::Size size_;
// keyPress events to be suppressed if the associated keyDown event was
// handled.
bool suppress_next_keypress_event_ = false;
// If set, the (plugin) element which has mouse capture.
Member<HTMLPlugInElement> mouse_capture_element_;
// This stores the last hidden page popup. If a GestureTap attempts to open // This stores the last hidden page popup. If a GestureTap attempts to open
// the popup that is closed by its previous GestureTapDown, the popup remains // the popup that is closed by its previous GestureTapDown, the popup remains
// closed. // closed.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment