Commit c18ebe7a authored by Ella Ge's avatar Ella Ge Committed by Commit Bot

Locked mouse event check ShouldGenerateAppCommand

When pointer is locked, we still need to check ShouldGenerateAppCommand
and set event handled so that won't generate unnecessary navigate
appcommand when kExtendedMouseButtons is enabled. This causes unable
to preventDefault on mouse back/forward buttons to prevent navigation
while pointer is locked.

Bug: 852709
Change-Id: I5f75a68e36037210c38310f8d83825c5efdf311e
Reviewed-on: https://chromium-review.googlesource.com/1148886
Commit-Queue: Ella Ge <eirage@chromium.org>
Reviewed-by: default avatarDave Tapuska <dtapuska@chromium.org>
Reviewed-by: default avatarTimothy Dresser <tdresser@chromium.org>
Cr-Commit-Position: refs/heads/master@{#577889}
parent 95bf7a9e
...@@ -751,73 +751,75 @@ void RenderWidgetHostViewEventHandler::HandleMouseEventWhileLocked( ...@@ -751,73 +751,75 @@ void RenderWidgetHostViewEventHandler::HandleMouseEventWhileLocked(
ProcessMouseWheelEvent(mouse_wheel_event, *event->latency()); ProcessMouseWheelEvent(mouse_wheel_event, *event->latency());
} }
} }
return; } else {
} gfx::Point center(gfx::Rect(window_->bounds().size()).CenterPoint());
gfx::Point center(gfx::Rect(window_->bounds().size()).CenterPoint()); // If we receive non client mouse messages while we are in the locked state
// it probably means that the mouse left the borders of our window and
// If we receive non client mouse messages while we are in the locked state // needs to be moved back to the center.
// it probably means that the mouse left the borders of our window and if (event->flags() & ui::EF_IS_NON_CLIENT) {
// needs to be moved back to the center. // TODO(jonross): ideally this would not be done for mus
if (event->flags() & ui::EF_IS_NON_CLIENT) { // (crbug.com/621412)
// TODO(jonross): ideally this would not be done for mus (crbug.com/621412) MoveCursorToCenter();
MoveCursorToCenter(); return;
return; }
}
blink::WebMouseEvent mouse_event = blink::WebMouseEvent mouse_event =
ui::MakeWebMouseEvent(*event, base::Bind(&GetScreenLocationFromEvent)); ui::MakeWebMouseEvent(*event, base::Bind(&GetScreenLocationFromEvent));
bool is_move_to_center_event = bool is_move_to_center_event =
(event->type() == ui::ET_MOUSE_MOVED || (event->type() == ui::ET_MOUSE_MOVED ||
event->type() == ui::ET_MOUSE_DRAGGED) && event->type() == ui::ET_MOUSE_DRAGGED) &&
mouse_event.PositionInWidget().x == center.x() && mouse_event.PositionInWidget().x == center.x() &&
mouse_event.PositionInWidget().y == center.y(); mouse_event.PositionInWidget().y == center.y();
// For fractional scale factors, the conversion from pixels to dip and // For fractional scale factors, the conversion from pixels to dip and
// vice versa could result in off by 1 or 2 errors which hurts us because // vice versa could result in off by 1 or 2 errors which hurts us because
// we want to avoid sending the artificial move to center event to the // we want to avoid sending the artificial move to center event to the
// renderer. Sending the move to center to the renderer cause the cursor // renderer. Sending the move to center to the renderer cause the cursor
// to bounce around the center of the screen leading to the lock operation // to bounce around the center of the screen leading to the lock operation
// not working correctly. // not working correctly.
// Workaround is to treat a mouse move or drag event off by at most 2 px // Workaround is to treat a mouse move or drag event off by at most 2 px
// from the center as a move to center event. // from the center as a move to center event.
if (synthetic_move_sent_ && if (synthetic_move_sent_ &&
IsFractionalScaleFactor(host_view_->current_device_scale_factor())) { IsFractionalScaleFactor(host_view_->current_device_scale_factor())) {
if (event->type() == ui::ET_MOUSE_MOVED || if (event->type() == ui::ET_MOUSE_MOVED ||
event->type() == ui::ET_MOUSE_DRAGGED) { event->type() == ui::ET_MOUSE_DRAGGED) {
if ((std::abs(mouse_event.PositionInWidget().x - center.x()) <= 2) && if ((std::abs(mouse_event.PositionInWidget().x - center.x()) <= 2) &&
(std::abs(mouse_event.PositionInWidget().y - center.y()) <= 2)) { (std::abs(mouse_event.PositionInWidget().y - center.y()) <= 2)) {
is_move_to_center_event = true; is_move_to_center_event = true;
}
} }
} }
}
ModifyEventMovementAndCoords(*event, &mouse_event); ModifyEventMovementAndCoords(*event, &mouse_event);
bool should_not_forward = is_move_to_center_event && synthetic_move_sent_; bool should_not_forward = is_move_to_center_event && synthetic_move_sent_;
if (should_not_forward) { if (should_not_forward) {
synthetic_move_sent_ = false; synthetic_move_sent_ = false;
} else { } else {
// Check if the mouse has reached the border and needs to be centered. // Check if the mouse has reached the border and needs to be centered.
if (ShouldMoveToCenter()) if (ShouldMoveToCenter())
MoveCursorToCenter(); MoveCursorToCenter();
bool is_selection_popup = NeedsInputGrab(popup_child_host_view_); bool is_selection_popup = NeedsInputGrab(popup_child_host_view_);
// Forward event to renderer. // Forward event to renderer.
if (CanRendererHandleEvent(event, mouse_locked_, is_selection_popup) && if (CanRendererHandleEvent(event, mouse_locked_, is_selection_popup) &&
!(event->flags() & ui::EF_FROM_TOUCH)) { !(event->flags() & ui::EF_FROM_TOUCH)) {
if (ShouldRouteEvent(event)) { if (ShouldRouteEvent(event)) {
host_->delegate()->GetInputEventRouter()->RouteMouseEvent( host_->delegate()->GetInputEventRouter()->RouteMouseEvent(
host_view_, &mouse_event, *event->latency()); host_view_, &mouse_event, *event->latency());
} else { } else {
ProcessMouseEvent(mouse_event, *event->latency()); ProcessMouseEvent(mouse_event, *event->latency());
}
// Ensure that we get keyboard focus on mouse down as a plugin window
// may have grabbed keyboard focus.
if (event->type() == ui::ET_MOUSE_PRESSED)
SetKeyboardFocus();
} }
// Ensure that we get keyboard focus on mouse down as a plugin window
// may have grabbed keyboard focus.
if (event->type() == ui::ET_MOUSE_PRESSED)
SetKeyboardFocus();
} }
} }
if (!ShouldGenerateAppCommand(event))
event->SetHandled();
} }
void RenderWidgetHostViewEventHandler::ModifyEventMovementAndCoords( void RenderWidgetHostViewEventHandler::ModifyEventMovementAndCoords(
......
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Mouse Button Back/Forward</title>
<link rel="author" title="Google" href="http://www.google.com/" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
var testMouseUp = async_test('Tests that when pointer is locked, the mouseup is preventable.');
var received_back = false;
var received_forward = false;
window.addEventListener('mouseup', function(e) {
if (e.button == 0) {
document.body.requestPointerLock();
} else if (e.button == 3) {
received_back = true;
e.preventDefault();
} else if (e.button == 4) {
received_forward = true;
e.preventDefault();
}
if (document.pointerLockElement && received_back && received_forward) {
testMouseUp.done();
document.exitPointerLock();
}
});
</script>
</head>
<body id="target">
<h4>Test Description: Tests that the mouseup event is prevented.
<ol>
<li>Click the left mouse button to lock pointer</li>
<li>Click the back mouse button</li>
<li>Click the back mouse forward</li>
</ol>
</h4>
</body>
</html>
importAutomationScript('/pointerevents/pointerevent_common_input.js');
function inject_input() {
return mouseClickInTarget('#target', undefined, "left").then(function() {
return mouseClickInTarget('#target', undefined, "back").then(function() {
return mouseClickInTarget('#target', undefined, "forward");
});
});
}
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