Skip to content

Commit

Permalink
Check PointerLock requests for new options and update accordingly
Browse files Browse the repository at this point in the history
Previously if a pointer lock request was made while the pointer was
already locked it would update to the new element in the new request.
However, now that we have options we must also allow the subsequent
requests to change which options they are requesting for.

Relevant Spec change: w3c/pointerlock#49

Bug: 1043640
Change-Id: I777f6de156554254c7a5ffbefcbe32e9d0af504e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2071788
Commit-Queue: James Hollyer <[email protected]>
Reviewed-by: Dave Tapuska <[email protected]>
Reviewed-by: Kinuko Yasuda <[email protected]>
Reviewed-by: Ken Buchanan <[email protected]>
Cr-Commit-Position: refs/heads/master@{#750032}
  • Loading branch information
James Hollyer authored and Commit Bot committed Mar 13, 2020
1 parent bc052c9 commit d6cc9b8
Show file tree
Hide file tree
Showing 36 changed files with 268 additions and 3 deletions.
5 changes: 5 additions & 0 deletions content/browser/renderer_host/frame_connector_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ blink::mojom::PointerLockResult FrameConnectorDelegate::LockMouse(
return blink::mojom::PointerLockResult::kUnknownError;
}

blink::mojom::PointerLockResult FrameConnectorDelegate::ChangeMouseLock(
bool request_unadjusted_movement) {
return blink::mojom::PointerLockResult::kUnknownError;
}

void FrameConnectorDelegate::EnableAutoResize(const gfx::Size& min_size,
const gfx::Size& max_size) {}

Expand Down
5 changes: 5 additions & 0 deletions content/browser/renderer_host/frame_connector_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ class CONTENT_EXPORT FrameConnectorDelegate {
virtual blink::mojom::PointerLockResult LockMouse(
bool request_unadjusted_movement);

// Change the current mouse lock to match the unadjusted movement option
// given.
virtual blink::mojom::PointerLockResult ChangeMouseLock(
bool request_unadjusted_movement);

// Unlocks the mouse if the mouse is locked.
virtual void UnlockMouse() {}

Expand Down
4 changes: 4 additions & 0 deletions content/browser/renderer_host/input/input_router_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ class CONTENT_EXPORT InputRouterClient {
bool unadjusted_movement,
mojom::WidgetInputHandlerHost::RequestMouseLockCallback response) = 0;

virtual void RequestMouseLockChange(
bool unadjusted_movement,
mojom::WidgetInputHandlerHost::RequestMouseLockCallback response) = 0;

virtual void UnlockMouse() = 0;

virtual void FallbackCursorModeLockCursor(bool left,
Expand Down
6 changes: 6 additions & 0 deletions content/browser/renderer_host/input/input_router_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,12 @@ void InputRouterImpl::RequestMouseLock(bool from_user_gesture,
std::move(response));
}

void InputRouterImpl::RequestMouseLockChange(
bool unadjusted_movement,
RequestMouseLockCallback response) {
client_->RequestMouseLockChange(unadjusted_movement, std::move(response));
}

void InputRouterImpl::UnlockMouse() {
client_->UnlockMouse();
}
Expand Down
2 changes: 2 additions & 0 deletions content/browser/renderer_host/input/input_router_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ class CONTENT_EXPORT InputRouterImpl : public InputRouter,
bool privileged,
bool unadjusted_movement,
RequestMouseLockCallback response) override;
void RequestMouseLockChange(bool unadjusted_movement,
RequestMouseLockCallback response) override;
void UnlockMouse() override;
void OnHasTouchEventHandlers(bool has_handlers) override;
void WaitForInputProcessed(base::OnceClosure callback) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ class MockInputRouterImplClient : public InputRouterImplClient {
mojom::WidgetInputHandlerHost::RequestMouseLockCallback
response) override {}

void RequestMouseLockChange(
bool unadjusted_movement,
mojom::WidgetInputHandlerHost::RequestMouseLockCallback response)
override {}

void UnlockMouse() override {}

void FallbackCursorModeLockCursor(bool left,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ class MockInputRouterClient : public InputRouterClient,
bool unadjusted_movement,
mojom::WidgetInputHandlerHost::RequestMouseLockCallback
response) override {}
void RequestMouseLockChange(
bool unadjusted_movement,
mojom::WidgetInputHandlerHost::RequestMouseLockCallback response)
override {}
void UnlockMouse() override {}
void FallbackCursorModeLockCursor(bool left,
bool right,
Expand Down
16 changes: 16 additions & 0 deletions content/browser/renderer_host/render_widget_host_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2500,6 +2500,22 @@ void RenderWidgetHostImpl::RequestMouseLock(
blink::mojom::PointerLockResult::kPermissionDenied);
}

void RenderWidgetHostImpl::RequestMouseLockChange(
bool unadjusted_movement,
InputRouterImpl::RequestMouseLockCallback response) {
if (pending_mouse_lock_request_) {
std::move(response).Run(blink::mojom::PointerLockResult::kAlreadyLocked);
return;
}

if (!view_ || !view_->HasFocus()) {
std::move(response).Run(blink::mojom::PointerLockResult::kWrongDocument);
return;
}

std::move(response).Run(view_->ChangeMouseLock(unadjusted_movement));
}

void RenderWidgetHostImpl::UnlockMouse() {
// Got unlock request from renderer. Will update |is_last_unlocked_by_target_|
// for silent re-lock.
Expand Down
3 changes: 3 additions & 0 deletions content/browser/renderer_host/render_widget_host_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,9 @@ class CONTENT_EXPORT RenderWidgetHostImpl
bool privileged,
bool unadjusted_movement,
InputRouterImpl::RequestMouseLockCallback response) override;
void RequestMouseLockChange(
bool unadjusted_movement,
InputRouterImpl::RequestMouseLockCallback response) override;
void UnlockMouse() override;
void FallbackCursorModeLockCursor(bool left,
bool right,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1660,6 +1660,12 @@ blink::mojom::PointerLockResult RenderWidgetHostViewAndroid::LockMouse(
return blink::mojom::PointerLockResult::kUnsupportedOptions;
}

blink::mojom::PointerLockResult RenderWidgetHostViewAndroid::ChangeMouseLock(
bool request_unadjusted_movement) {
NOTIMPLEMENTED();
return blink::mojom::PointerLockResult::kUnsupportedOptions;
}

void RenderWidgetHostViewAndroid::UnlockMouse() {
NOTIMPLEMENTED();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
bool for_root_frame) override;
blink::mojom::PointerLockResult LockMouse(
bool request_unadjusted_movement) override;
blink::mojom::PointerLockResult ChangeMouseLock(
bool request_unadjusted_movement) override;
void UnlockMouse() override;
void ResetFallbackToFirstNavigationSurface() override;
bool RequestRepaintForTesting() override;
Expand Down
5 changes: 5 additions & 0 deletions content/browser/renderer_host/render_widget_host_view_aura.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1162,6 +1162,11 @@ blink::mojom::PointerLockResult RenderWidgetHostViewAura::LockMouse(
return event_handler_->LockMouse(request_unadjusted_movement);
}

blink::mojom::PointerLockResult RenderWidgetHostViewAura::ChangeMouseLock(
bool request_unadjusted_movement) {
return event_handler_->ChangeMouseLock(request_unadjusted_movement);
}

void RenderWidgetHostViewAura::UnlockMouse() {
event_handler_->UnlockMouse();
}
Expand Down
2 changes: 2 additions & 0 deletions content/browser/renderer_host/render_widget_host_view_aura.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
void SetMainFrameAXTreeID(ui::AXTreeID id) override;
blink::mojom::PointerLockResult LockMouse(
bool request_unadjusted_movement) override;
blink::mojom::PointerLockResult ChangeMouseLock(
bool request_unadjusted_movement) override;
void UnlockMouse() override;
bool GetIsMouseLockedUnadjustedMovementForTesting() override;
bool LockKeyboard(base::Optional<base::flat_set<ui::DomCode>> codes) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,13 @@ blink::mojom::PointerLockResult RenderWidgetHostViewChildFrame::LockMouse(
return blink::mojom::PointerLockResult::kWrongDocument;
}

blink::mojom::PointerLockResult RenderWidgetHostViewChildFrame::ChangeMouseLock(
bool request_unadjusted_movement) {
if (frame_connector_)
return frame_connector_->ChangeMouseLock(request_unadjusted_movement);
return blink::mojom::PointerLockResult::kWrongDocument;
}

void RenderWidgetHostViewChildFrame::UnlockMouse() {
if (host()->delegate() && host()->delegate()->HasMouseLock(host()) &&
frame_connector_)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
void DidStopFlinging() override;
blink::mojom::PointerLockResult LockMouse(
bool request_unadjusted_movement) override;
blink::mojom::PointerLockResult ChangeMouseLock(
bool request_unadjusted_movement) override;
void UnlockMouse() override;
const viz::FrameSinkId& GetFrameSinkId() const override;
const viz::LocalSurfaceIdAllocation& GetLocalSurfaceIdAllocation()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,38 @@ blink::mojom::PointerLockResult RenderWidgetHostViewEventHandler::LockMouse(
return blink::mojom::PointerLockResult::kSuccess;
}

blink::mojom::PointerLockResult
RenderWidgetHostViewEventHandler::ChangeMouseLock(
bool request_unadjusted_movement) {
aura::Window* root_window = window_->GetRootWindow();
if (!root_window || !window_->GetHost())
return blink::mojom::PointerLockResult::kWrongDocument;

// If lock was lost before completing this change request
// it was because the user hit escape or navigated away
// from the page.
if (!mouse_locked_)
return blink::mojom::PointerLockResult::kUserRejected;

if (!request_unadjusted_movement) {
mouse_locked_unadjusted_movement_.reset();
return blink::mojom::PointerLockResult::kSuccess;
}

if (mouse_locked_unadjusted_movement_) {
// Desired state already acquired.
return blink::mojom::PointerLockResult::kSuccess;
}

mouse_locked_unadjusted_movement_ =
window_->GetHost()->RequestUnadjustedMovement();

if (!mouse_locked_unadjusted_movement_)
return blink::mojom::PointerLockResult::kUnsupportedOptions;

return blink::mojom::PointerLockResult::kSuccess;
}

void RenderWidgetHostViewEventHandler::UnlockMouse() {
delegate_->SetTooltipsEnabled(true);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ class CONTENT_EXPORT RenderWidgetHostViewEventHandler

// Lock/Unlock processing of future mouse events.
blink::mojom::PointerLockResult LockMouse(bool request_unadjusted_movement);
// Change the current lock to have the given unadjusted_movement.
blink::mojom::PointerLockResult ChangeMouseLock(
bool request_unadjusted_movement);
void UnlockMouse();

// Start/Stop processing of future system keyboard events.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
void DidNavigate() override;

blink::mojom::PointerLockResult LockMouse(bool) override;
blink::mojom::PointerLockResult ChangeMouseLock(bool) override;
void UnlockMouse() override;
bool LockKeyboard(base::Optional<base::flat_set<ui::DomCode>> codes) override;
void UnlockKeyboard() override;
Expand Down
10 changes: 10 additions & 0 deletions content/browser/renderer_host/render_widget_host_view_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1093,6 +1093,16 @@ void CombineTextNodesAndMakeCallback(SpeechCallback callback,
return blink::mojom::PointerLockResult::kSuccess;
}

blink::mojom::PointerLockResult RenderWidgetHostViewMac::ChangeMouseLock(
bool request_unadjusted_movement) {
// Unadjusted movement is not supported on Mac. Which means that
// |mouse_locked_unadjusted_movement_| must not be set. Therefore,
// |request_unadjusted_movement| must be true so this request will always
// fail with kUnsupportedOptions.
NOTIMPLEMENTED();
return blink::mojom::PointerLockResult::kUnsupportedOptions;
}

void RenderWidgetHostViewMac::UnlockMouse() {
if (!mouse_locked_)
return;
Expand Down
5 changes: 5 additions & 0 deletions content/common/input/input_handler.mojom
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ interface WidgetInputHandlerHost {
bool unadjusted_movement)
=> (blink.mojom.PointerLockResult result);

// A request to change the current mouse lock to have the given unadjusted
// movement.
RequestMouseLockChange(bool unadjusted_movement)
=> (blink.mojom.PointerLockResult result);

// Unlocks the mouse back to its default behavior. This will also returns
// mouse movement back to the platform's adjusted movement if unadjusted
// movement was true while locking.
Expand Down
7 changes: 6 additions & 1 deletion content/public/browser/render_widget_host_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,14 @@ class CONTENT_EXPORT RenderWidgetHostView {
// GetBackgroundColor returns the current background color of the view.
virtual base::Optional<SkColor> GetBackgroundColor() = 0;

// Return value indicates whether the mouse is locked successfully or not.
// Return value indicates whether the mouse is locked successfully or a
// reason why it failed.
virtual blink::mojom::PointerLockResult LockMouse(
bool request_unadjusted_movement) = 0;
// Return value indicates whether the MouseLock was changed successfully
// or a reason why the change failed.
virtual blink::mojom::PointerLockResult ChangeMouseLock(
bool request_unadjusted_movement) = 0;
virtual void UnlockMouse() = 0;
// Returns true if the mouse pointer is currently locked.
virtual bool IsMouseLocked() = 0;
Expand Down
25 changes: 25 additions & 0 deletions content/renderer/mouse_lock_dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,23 @@ bool MouseLockDispatcher::LockMouse(
return true;
}

bool MouseLockDispatcher::ChangeMouseLock(
LockTarget* target,
blink::WebLocalFrame* requester_frame,
blink::WebWidgetClient::PointerLockCallback callback,
bool request_unadjusted_movement) {
if (pending_lock_request_ || pending_unlock_request_)
return false;

pending_lock_request_ = true;
target_ = target;

lock_mouse_callback_ = std::move(callback);

SendChangeLockRequest(requester_frame, request_unadjusted_movement);
return true;
}

void MouseLockDispatcher::UnlockMouse(LockTarget* target) {
if (target && target == target_ && !pending_unlock_request_) {
pending_unlock_request_ = true;
Expand Down Expand Up @@ -64,6 +81,14 @@ bool MouseLockDispatcher::WillHandleMouseEvent(
return false;
}

void MouseLockDispatcher::OnChangeLockAck(
blink::mojom::PointerLockResult result) {
pending_lock_request_ = false;
if (lock_mouse_callback_) {
std::move(lock_mouse_callback_).Run(result);
}
}

void MouseLockDispatcher::OnLockMouseACK(
blink::mojom::PointerLockResult result) {
DCHECK(!mouse_locked_ && pending_lock_request_);
Expand Down
7 changes: 7 additions & 0 deletions content/renderer/mouse_lock_dispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ class CONTENT_EXPORT MouseLockDispatcher {
blink::WebLocalFrame* requester_frame,
blink::WebWidgetClient::PointerLockCallback callback,
bool request_unadjusted_movement);
bool ChangeMouseLock(LockTarget* target,
blink::WebLocalFrame* requester_frame,
blink::WebWidgetClient::PointerLockCallback callback,
bool request_unadjusted_movement);
// Request to unlock the mouse. An asynchronous response to
// target->OnMouseLockLost() will follow.
void UnlockMouse(LockTarget* target);
Expand All @@ -57,13 +61,16 @@ class CONTENT_EXPORT MouseLockDispatcher {
// Subclasses or users have to call these methods to report mouse lock events
// from the browser.
void OnLockMouseACK(blink::mojom::PointerLockResult result);
void OnChangeLockAck(blink::mojom::PointerLockResult result);
void OnMouseLockLost();

protected:
// Subclasses must implement these methods to send mouse lock requests to the
// browser.
virtual void SendLockMouseRequest(blink::WebLocalFrame* requester_frame,
bool request_unadjusted_movement) = 0;
virtual void SendChangeLockRequest(blink::WebLocalFrame* requester_frame,
bool request_unadjusted_movement) {}
virtual void SendUnlockMouseRequest() = 0;

base::WeakPtr<MouseLockDispatcher> AsWeakPtr() {
Expand Down
9 changes: 9 additions & 0 deletions content/renderer/render_widget.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3497,6 +3497,15 @@ bool RenderWidget::RequestPointerLock(
request_unadjusted_movement);
}

bool RenderWidget::RequestPointerLockChange(
blink::WebLocalFrame* requester_frame,
blink::WebWidgetClient::PointerLockCallback callback,
bool request_unadjusted_movement) {
return mouse_lock_dispatcher_->ChangeMouseLock(
webwidget_mouse_lock_target_.get(), requester_frame, std::move(callback),
request_unadjusted_movement);
}

void RenderWidget::PointerLockLost() {
mouse_lock_dispatcher_->OnMouseLockLost();
}
Expand Down
4 changes: 4 additions & 0 deletions content/renderer/render_widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,10 @@ class CONTENT_EXPORT RenderWidget
bool RequestPointerLock(blink::WebLocalFrame* requester_frame,
blink::WebWidgetClient::PointerLockCallback callback,
bool request_unadjusted_movement) override;
bool RequestPointerLockChange(
blink::WebLocalFrame* requester_frame,
blink::WebWidgetClient::PointerLockCallback callback,
bool request_unadjusted_movement) override;
void PointerLockLost();
void RequestPointerUnlock() override;
bool IsPointerLocked() override;
Expand Down
14 changes: 13 additions & 1 deletion content/renderer/render_widget_mouse_lock_dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,19 @@ void RenderWidgetMouseLockDispatcher::SendLockMouseRequest(
host->RequestMouseLock(has_transient_user_activation, /*privileged=*/false,
request_unadjusted_movement,
base::BindOnce(&MouseLockDispatcher::OnLockMouseACK,
weak_ptr_factory_.GetWeakPtr()));
this->AsWeakPtr()));
}
}

void RenderWidgetMouseLockDispatcher::SendChangeLockRequest(
blink::WebLocalFrame* requester_frame,
bool request_unadjusted_movement) {
auto* host = render_widget_->GetInputHandlerHost();
if (host) {
host->RequestMouseLockChange(
request_unadjusted_movement,
base::BindOnce(&MouseLockDispatcher::OnChangeLockAck,
this->AsWeakPtr()));
}
}

Expand Down
Loading

0 comments on commit d6cc9b8

Please sign in to comment.