Move Mouse Lock Dispatcher into blink.
This removes the somewhat duplicated mouse lock functionality in content::MouseLockDispatcher and uses the blink::PointerLockController solely. Pepper called directly into the content API previously and input was directed to the MouseLockDispatcher before it was sent into blink. Now Pepper calls an API on the WebPluginContainer to request pointer lock (similar to requesting fullscreen). The pointer locked target becomes the plugin container and input is dispatched to the plugin via normal blink input processing. Tested pepper running out/Release/chrome --register-pepper-plugins="out/Release/libppapi_example_mouse_lock.so;application/x-ppapi-example-mouse-lock" ppapi/examples/mouse_lock/mouse_lock.html BUG=1130991 Change-Id: I6452738f4bae33a0d2ad584ba80705d277b103f7 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2458426 Commit-Queue: Dave Tapuska <dtapuska@chromium.org> Reviewed-by: Mustaq Ahmed <mustaq@chromium.org> Reviewed-by: danakj <danakj@chromium.org> Reviewed-by: James Hollyer <jameshollyer@chromium.org> Cr-Commit-Position: refs/heads/master@{#817263}
This commit is contained in:
content
renderer
BUILD.gnmouse_lock_dispatcher.ccmouse_lock_dispatcher.hmouse_lock_dispatcher_browsertest.cc
pepper
event_conversion.ccevent_conversion.hevent_conversion_unittest.ccpepper_plugin_instance_impl.ccpepper_plugin_instance_impl.hpepper_webplugin_impl.ccpepper_webplugin_impl.h
render_widget.ccrender_widget.hrender_widget_mouse_lock_dispatcher.ccrender_widget_mouse_lock_dispatcher.htest
web_test
renderer
third_party/blink
public
renderer
core
dom
exported
web_page_popup_impl.ccweb_page_popup_impl.hweb_plugin_container_impl.ccweb_plugin_container_impl.hweb_view_impl.cc
frame
page
platform
@ -135,8 +135,6 @@ target(link_target_type, "renderer") {
|
||||
"mhtml_handle_writer.h",
|
||||
"mojo/blink_interface_registry_impl.cc",
|
||||
"mojo/blink_interface_registry_impl.h",
|
||||
"mouse_lock_dispatcher.cc",
|
||||
"mouse_lock_dispatcher.h",
|
||||
"navigation_client.cc",
|
||||
"navigation_client.h",
|
||||
"navigation_state.cc",
|
||||
@ -160,8 +158,6 @@ target(link_target_type, "renderer") {
|
||||
"render_widget.cc",
|
||||
"render_widget.h",
|
||||
"render_widget_delegate.h",
|
||||
"render_widget_mouse_lock_dispatcher.cc",
|
||||
"render_widget_mouse_lock_dispatcher.h",
|
||||
"renderer_blink_platform_impl.cc",
|
||||
"renderer_blink_platform_impl.h",
|
||||
"renderer_main.cc",
|
||||
|
@ -1,147 +0,0 @@
|
||||
// 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 "content/renderer/mouse_lock_dispatcher.h"
|
||||
|
||||
#include "base/check.h"
|
||||
#include "third_party/blink/public/common/input/web_input_event.h"
|
||||
|
||||
namespace content {
|
||||
|
||||
MouseLockDispatcher::MouseLockDispatcher()
|
||||
: pending_lock_request_(false),
|
||||
pending_unlock_request_(false),
|
||||
target_(nullptr) {}
|
||||
|
||||
MouseLockDispatcher::~MouseLockDispatcher() = default;
|
||||
|
||||
bool MouseLockDispatcher::LockMouse(
|
||||
LockTarget* target,
|
||||
blink::WebLocalFrame* requester_frame,
|
||||
blink::WebWidgetClient::PointerLockCallback callback,
|
||||
bool request_unadjusted_movement) {
|
||||
if (MouseLockedOrPendingAction())
|
||||
return false;
|
||||
|
||||
pending_lock_request_ = true;
|
||||
target_ = target;
|
||||
|
||||
lock_mouse_callback_ = std::move(callback);
|
||||
|
||||
SendLockMouseRequest(requester_frame, request_unadjusted_movement);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MouseLockDispatcher::ChangeMouseLock(
|
||||
LockTarget* target,
|
||||
blink::WebLocalFrame* requester_frame,
|
||||
blink::WebWidgetClient::PointerLockCallback callback,
|
||||
bool request_unadjusted_movement) {
|
||||
if (!mouse_lock_context_)
|
||||
return false;
|
||||
|
||||
lock_mouse_callback_ = std::move(callback);
|
||||
// Unretained is safe because |this| owns the mojo::Remote
|
||||
mouse_lock_context_->RequestMouseLockChange(
|
||||
request_unadjusted_movement,
|
||||
base::BindOnce(&MouseLockDispatcher::OnChangeLockAck,
|
||||
base::Unretained(this)));
|
||||
return true;
|
||||
}
|
||||
|
||||
void MouseLockDispatcher::FlushContextPipeForTesting() {
|
||||
if (mouse_lock_context_)
|
||||
mouse_lock_context_.FlushForTesting();
|
||||
}
|
||||
|
||||
void MouseLockDispatcher::UnlockMouse(LockTarget* target) {
|
||||
if (IsMouseLockedTo(target)) {
|
||||
mouse_lock_context_.reset();
|
||||
target->OnMouseLockLost();
|
||||
}
|
||||
}
|
||||
|
||||
void MouseLockDispatcher::OnLockTargetDestroyed(LockTarget* target) {
|
||||
if (target == target_) {
|
||||
UnlockMouse(target);
|
||||
target_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void MouseLockDispatcher::ClearLockTarget() {
|
||||
OnLockTargetDestroyed(target_);
|
||||
}
|
||||
|
||||
bool MouseLockDispatcher::IsMouseLockedTo(LockTarget* target) {
|
||||
return mouse_lock_context_ && target_ == target;
|
||||
}
|
||||
|
||||
bool MouseLockDispatcher::WillHandleMouseEvent(
|
||||
const blink::WebMouseEvent& event) {
|
||||
if (mouse_lock_context_ && target_)
|
||||
return target_->HandleMouseLockedInputEvent(event);
|
||||
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,
|
||||
blink::CrossVariantMojoRemote<blink::mojom::PointerLockContextInterfaceBase>
|
||||
context) {
|
||||
DCHECK(!mouse_lock_context_ && pending_lock_request_);
|
||||
|
||||
pending_lock_request_ = false;
|
||||
if (pending_unlock_request_ && !context) {
|
||||
// We have sent an unlock request after the lock request. However, since
|
||||
// the lock request has failed, the unlock request will be ignored by the
|
||||
// browser side and there won't be any response to it.
|
||||
pending_unlock_request_ = false;
|
||||
}
|
||||
|
||||
if (context) {
|
||||
mouse_lock_context_.Bind(std::move(context));
|
||||
// The browser might unlock the mouse for many reasons including closing
|
||||
// the tab, the user hitting esc, the page losing focus, and more.
|
||||
mouse_lock_context_.set_disconnect_handler(base::BindOnce(
|
||||
&MouseLockDispatcher::OnMouseLockLost, base::Unretained(this)));
|
||||
}
|
||||
|
||||
if (lock_mouse_callback_)
|
||||
std::move(lock_mouse_callback_).Run(result);
|
||||
|
||||
LockTarget* last_target = target_;
|
||||
if (!mouse_lock_context_)
|
||||
target_ = nullptr;
|
||||
|
||||
// Callbacks made after all state modification to prevent reentrant errors
|
||||
// such as OnLockMouseACK() synchronously calling LockMouse().
|
||||
|
||||
if (last_target)
|
||||
last_target->OnLockMouseACK(result ==
|
||||
blink::mojom::PointerLockResult::kSuccess);
|
||||
}
|
||||
|
||||
void MouseLockDispatcher::OnMouseLockLost() {
|
||||
DCHECK(mouse_lock_context_ && !pending_lock_request_);
|
||||
mouse_lock_context_.reset();
|
||||
pending_unlock_request_ = false;
|
||||
|
||||
LockTarget* last_target = target_;
|
||||
target_ = nullptr;
|
||||
|
||||
// Callbacks made after all state modification to prevent reentrant errors
|
||||
// such as OnMouseLockLost() synchronously calling LockMouse().
|
||||
|
||||
if (last_target)
|
||||
last_target->OnMouseLockLost();
|
||||
}
|
||||
|
||||
} // namespace content
|
@ -1,106 +0,0 @@
|
||||
// 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 CONTENT_RENDERER_MOUSE_LOCK_DISPATCHER_H_
|
||||
#define CONTENT_RENDERER_MOUSE_LOCK_DISPATCHER_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "content/common/content_export.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
#include "third_party/blink/public/mojom/input/pointer_lock_context.mojom.h"
|
||||
#include "third_party/blink/public/web/web_widget_client.h"
|
||||
|
||||
namespace blink {
|
||||
class WebMouseEvent;
|
||||
class WebLocalFrame;
|
||||
} // namespace blink
|
||||
|
||||
namespace content {
|
||||
|
||||
class CONTENT_EXPORT MouseLockDispatcher {
|
||||
public:
|
||||
MouseLockDispatcher();
|
||||
virtual ~MouseLockDispatcher();
|
||||
|
||||
class LockTarget {
|
||||
public:
|
||||
virtual ~LockTarget() {}
|
||||
// A mouse lock request was pending and this reports success or failure.
|
||||
virtual void OnLockMouseACK(bool succeeded) = 0;
|
||||
// A mouse lock was in place, but has been lost.
|
||||
virtual void OnMouseLockLost() = 0;
|
||||
// A mouse lock is enabled and mouse events are being delievered.
|
||||
virtual bool HandleMouseLockedInputEvent(
|
||||
const blink::WebMouseEvent& event) = 0;
|
||||
};
|
||||
|
||||
// Locks the mouse to |target| if |requester_frame| has transient user
|
||||
// activation. If true is returned, an asynchronous response to
|
||||
// target->OnLockMouseACK() will follow.
|
||||
bool LockMouse(LockTarget* target,
|
||||
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. This call destroys the |mouse_lock_context_|.
|
||||
// A response to target->OnMouseLockLost() will follow.
|
||||
void UnlockMouse(LockTarget* target);
|
||||
// Clears out the reference to the |target| because it has or is being
|
||||
// destroyed. Unlocks if locked. The pointer will not be accessed.
|
||||
void OnLockTargetDestroyed(LockTarget* target);
|
||||
// Clears out any reference to a lock target. Unlocks if locked.
|
||||
void ClearLockTarget();
|
||||
bool IsMouseLockedTo(LockTarget* target);
|
||||
|
||||
// Allow lock target to consumed a mouse event, if it does return true.
|
||||
bool WillHandleMouseEvent(const blink::WebMouseEvent& event);
|
||||
|
||||
// Subclasses or users have to call these methods to report mouse lock events
|
||||
// from the browser.
|
||||
void OnLockMouseACK(
|
||||
blink::mojom::PointerLockResult result,
|
||||
blink::CrossVariantMojoRemote<
|
||||
blink::mojom::PointerLockContextInterfaceBase> context);
|
||||
void OnChangeLockAck(blink::mojom::PointerLockResult result);
|
||||
|
||||
void FlushContextPipeForTesting();
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
bool MouseLockedOrPendingAction() const {
|
||||
return mouse_lock_context_ || pending_lock_request_ ||
|
||||
pending_unlock_request_;
|
||||
}
|
||||
|
||||
void OnMouseLockLost();
|
||||
|
||||
// If both |pending_lock_request_| and |pending_unlock_request_| are true,
|
||||
// it means a lock request was sent before an unlock request and we haven't
|
||||
// received responses for them. The logic in LockMouse() makes sure that a
|
||||
// lock request won't be sent when there is a pending unlock request.
|
||||
bool pending_lock_request_;
|
||||
bool pending_unlock_request_;
|
||||
mojo::Remote<blink::mojom::PointerLockContext> mouse_lock_context_;
|
||||
|
||||
blink::WebWidgetClient::PointerLockCallback lock_mouse_callback_;
|
||||
|
||||
// |target_| is the pending or current owner of mouse lock. We retain a non
|
||||
// owning reference here that must be cleared by |OnLockTargetDestroyed|
|
||||
// when it is destroyed.
|
||||
LockTarget* target_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MouseLockDispatcher);
|
||||
};
|
||||
|
||||
} // namespace content
|
||||
|
||||
#endif // CONTENT_RENDERER_MOUSE_LOCK_DISPATCHER_H_
|
@ -1,305 +0,0 @@
|
||||
// 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 <string>
|
||||
|
||||
#include "content/common/widget_messages.h"
|
||||
#include "content/public/test/render_view_test.h"
|
||||
#include "content/renderer/mouse_lock_dispatcher.h"
|
||||
#include "content/renderer/render_view_impl.h"
|
||||
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "third_party/blink/public/common/input/web_mouse_event.h"
|
||||
|
||||
using ::testing::_;
|
||||
|
||||
namespace content {
|
||||
namespace {
|
||||
|
||||
class MockLockTarget : public MouseLockDispatcher::LockTarget {
|
||||
public:
|
||||
MOCK_METHOD1(OnLockMouseACK, void(bool));
|
||||
MOCK_METHOD0(OnMouseLockLost, void());
|
||||
MOCK_METHOD1(HandleMouseLockedInputEvent,
|
||||
bool(const blink::WebMouseEvent&));
|
||||
};
|
||||
|
||||
class PointerLockContextImpl : public blink::mojom::PointerLockContext {
|
||||
public:
|
||||
void RequestMouseLockChange(
|
||||
bool unadjusted_movement,
|
||||
PointerLockContext::RequestMouseLockChangeCallback response) override {}
|
||||
};
|
||||
|
||||
// MouseLockDispatcher is a RenderViewObserver, and we test it by creating a
|
||||
// fixture containing a RenderViewImpl view() and interacting to that interface.
|
||||
class MouseLockDispatcherTest : public RenderViewTest {
|
||||
public:
|
||||
void SetUp() override {
|
||||
RenderViewTest::SetUp();
|
||||
route_id_ = widget()->routing_id();
|
||||
target_ = new MockLockTarget();
|
||||
alternate_target_ = new MockLockTarget();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
RenderViewTest::TearDown();
|
||||
delete target_;
|
||||
delete alternate_target_;
|
||||
}
|
||||
|
||||
protected:
|
||||
RenderViewImpl* view() { return static_cast<RenderViewImpl*>(view_); }
|
||||
RenderWidget* widget() {
|
||||
return view()->GetMainRenderFrame()->GetLocalRootRenderWidget();
|
||||
}
|
||||
MouseLockDispatcher* dispatcher() {
|
||||
return widget()->mouse_lock_dispatcher();
|
||||
}
|
||||
int route_id_;
|
||||
MockLockTarget* target_;
|
||||
MockLockTarget* alternate_target_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
// Test simple use of RenderViewImpl interface for pointer lock.
|
||||
TEST_F(MouseLockDispatcherTest, BasicWebWidget) {
|
||||
// Start unlocked.
|
||||
EXPECT_FALSE(widget()->IsPointerLocked());
|
||||
|
||||
// Lock.
|
||||
EXPECT_TRUE(widget()->RequestPointerLock(
|
||||
view()->GetMainRenderFrame()->GetWebFrame(), base::DoNothing(),
|
||||
false /* unadjusted_movement */));
|
||||
|
||||
mojo::PendingRemote<blink::mojom::PointerLockContext> remote_context;
|
||||
auto receiver_context = mojo::MakeSelfOwnedReceiver(
|
||||
std::make_unique<PointerLockContextImpl>(),
|
||||
remote_context.InitWithNewPipeAndPassReceiver());
|
||||
dispatcher()->OnLockMouseACK(blink::mojom::PointerLockResult::kSuccess,
|
||||
std::move(remote_context));
|
||||
EXPECT_TRUE(widget()->IsPointerLocked());
|
||||
|
||||
// Unlock.
|
||||
widget()->RequestPointerUnlock();
|
||||
receiver_context->Close();
|
||||
dispatcher()->FlushContextPipeForTesting();
|
||||
EXPECT_FALSE(widget()->IsPointerLocked());
|
||||
|
||||
// Attempt a lock, and have it fail.
|
||||
EXPECT_TRUE(widget()->RequestPointerLock(
|
||||
view()->GetMainRenderFrame()->GetWebFrame(), base::DoNothing(),
|
||||
false /* unadjusted_movement */));
|
||||
dispatcher()->OnLockMouseACK(blink::mojom::PointerLockResult::kUnknownError,
|
||||
mojo::NullRemote());
|
||||
EXPECT_FALSE(widget()->IsPointerLocked());
|
||||
}
|
||||
|
||||
// Test simple use of MouseLockDispatcher with a mock LockTarget.
|
||||
TEST_F(MouseLockDispatcherTest, BasicMockLockTarget) {
|
||||
::testing::InSequence expect_calls_in_sequence;
|
||||
EXPECT_CALL(*target_, OnLockMouseACK(/*succeeded=*/true));
|
||||
EXPECT_CALL(*target_, HandleMouseLockedInputEvent(_));
|
||||
EXPECT_CALL(*target_, OnMouseLockLost());
|
||||
EXPECT_CALL(*target_, OnLockMouseACK(/*succeeded=*/false));
|
||||
|
||||
// Start unlocked.
|
||||
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(nullptr));
|
||||
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
|
||||
|
||||
// Lock.
|
||||
EXPECT_TRUE(dispatcher()->LockMouse(
|
||||
target_, view()->GetMainRenderFrame()->GetWebFrame(), base::DoNothing(),
|
||||
false /* unadjusted_movement */));
|
||||
mojo::PendingRemote<blink::mojom::PointerLockContext> remote_context;
|
||||
auto receiver_context = mojo::MakeSelfOwnedReceiver(
|
||||
std::make_unique<PointerLockContextImpl>(),
|
||||
remote_context.InitWithNewPipeAndPassReceiver());
|
||||
dispatcher()->OnLockMouseACK(blink::mojom::PointerLockResult::kSuccess,
|
||||
std::move(remote_context));
|
||||
EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
|
||||
|
||||
// Receive mouse event.
|
||||
dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
|
||||
|
||||
// Unlock.
|
||||
receiver_context->Close();
|
||||
dispatcher()->FlushContextPipeForTesting();
|
||||
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
|
||||
|
||||
// Attempt a lock, and have it fail.
|
||||
EXPECT_TRUE(dispatcher()->LockMouse(
|
||||
target_, view()->GetMainRenderFrame()->GetWebFrame(), base::DoNothing(),
|
||||
false /* unadjusted_movement */));
|
||||
dispatcher()->OnLockMouseACK(blink::mojom::PointerLockResult::kUnknownError,
|
||||
mojo::NullRemote());
|
||||
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
|
||||
}
|
||||
|
||||
// Test deleting a target while it is in use by MouseLockDispatcher.
|
||||
TEST_F(MouseLockDispatcherTest, DeleteAndUnlock) {
|
||||
::testing::InSequence expect_calls_in_sequence;
|
||||
EXPECT_CALL(*target_, OnLockMouseACK(/*succeeded=*/true));
|
||||
EXPECT_CALL(*target_, HandleMouseLockedInputEvent(_)).Times(0);
|
||||
EXPECT_CALL(*target_, OnMouseLockLost()).Times(1);
|
||||
|
||||
// Lock.
|
||||
EXPECT_TRUE(dispatcher()->LockMouse(
|
||||
target_, view()->GetMainRenderFrame()->GetWebFrame(), base::DoNothing(),
|
||||
false /* unadjusted_movement */));
|
||||
mojo::PendingRemote<blink::mojom::PointerLockContext> remote_context;
|
||||
auto receiver_context = mojo::MakeSelfOwnedReceiver(
|
||||
std::make_unique<PointerLockContextImpl>(),
|
||||
remote_context.InitWithNewPipeAndPassReceiver());
|
||||
dispatcher()->OnLockMouseACK(blink::mojom::PointerLockResult::kSuccess,
|
||||
std::move(remote_context));
|
||||
EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
|
||||
|
||||
// Unlock, with a deleted target and context destruction.
|
||||
// Don't receive mouse events.
|
||||
dispatcher()->OnLockTargetDestroyed(target_);
|
||||
delete target_;
|
||||
target_ = nullptr;
|
||||
dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
|
||||
receiver_context->Close();
|
||||
dispatcher()->FlushContextPipeForTesting();
|
||||
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
|
||||
}
|
||||
|
||||
// Test deleting a target that is pending a lock request response.
|
||||
TEST_F(MouseLockDispatcherTest, DeleteWithPendingLockSuccess) {
|
||||
::testing::InSequence expect_calls_in_sequence;
|
||||
EXPECT_CALL(*target_, OnLockMouseACK(/*succeeded=*/true)).Times(0);
|
||||
EXPECT_CALL(*target_, OnMouseLockLost()).Times(0);
|
||||
|
||||
// Lock request.
|
||||
EXPECT_TRUE(dispatcher()->LockMouse(
|
||||
target_, view()->GetMainRenderFrame()->GetWebFrame(), base::DoNothing(),
|
||||
false /* unadjusted_movement */));
|
||||
|
||||
// Before receiving response delete the target.
|
||||
dispatcher()->OnLockTargetDestroyed(target_);
|
||||
delete target_;
|
||||
target_ = nullptr;
|
||||
|
||||
// Lock response.
|
||||
mojo::PendingRemote<blink::mojom::PointerLockContext> context;
|
||||
dispatcher()->OnLockMouseACK(blink::mojom::PointerLockResult::kSuccess,
|
||||
std::move(context));
|
||||
}
|
||||
|
||||
// Test deleting a target that is pending a lock request failure response.
|
||||
TEST_F(MouseLockDispatcherTest, DeleteWithPendingLockFail) {
|
||||
::testing::InSequence expect_calls_in_sequence;
|
||||
EXPECT_CALL(*target_, OnLockMouseACK(/*succeeded=*/true)).Times(0);
|
||||
EXPECT_CALL(*target_, OnMouseLockLost()).Times(0);
|
||||
|
||||
// Lock request.
|
||||
EXPECT_TRUE(dispatcher()->LockMouse(
|
||||
target_, view()->GetMainRenderFrame()->GetWebFrame(), base::DoNothing(),
|
||||
false /* unadjusted_movement */));
|
||||
|
||||
// Before receiving response delete the target.
|
||||
dispatcher()->OnLockTargetDestroyed(target_);
|
||||
delete target_;
|
||||
target_ = nullptr;
|
||||
|
||||
// Lock response.
|
||||
dispatcher()->OnLockMouseACK(blink::mojom::PointerLockResult::kUnknownError,
|
||||
mojo::NullRemote());
|
||||
}
|
||||
|
||||
// Test not receiving mouse events when a target is not locked.
|
||||
TEST_F(MouseLockDispatcherTest, MouseEventsNotReceived) {
|
||||
::testing::InSequence expect_calls_in_sequence;
|
||||
EXPECT_CALL(*target_, HandleMouseLockedInputEvent(_)).Times(0);
|
||||
EXPECT_CALL(*target_, OnLockMouseACK(/*succeeded=*/true));
|
||||
EXPECT_CALL(*target_, HandleMouseLockedInputEvent(_));
|
||||
EXPECT_CALL(*target_, OnMouseLockLost());
|
||||
EXPECT_CALL(*target_, HandleMouseLockedInputEvent(_)).Times(0);
|
||||
|
||||
// (Don't) receive mouse event.
|
||||
dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
|
||||
|
||||
// Lock.
|
||||
EXPECT_TRUE(dispatcher()->LockMouse(
|
||||
target_, view()->GetMainRenderFrame()->GetWebFrame(), base::DoNothing(),
|
||||
false /* unadjusted_movement */));
|
||||
mojo::PendingRemote<blink::mojom::PointerLockContext> remote_context;
|
||||
auto receiver_context = mojo::MakeSelfOwnedReceiver(
|
||||
std::make_unique<PointerLockContextImpl>(),
|
||||
remote_context.InitWithNewPipeAndPassReceiver());
|
||||
dispatcher()->OnLockMouseACK(blink::mojom::PointerLockResult::kSuccess,
|
||||
std::move(remote_context));
|
||||
EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
|
||||
|
||||
// Receive mouse event.
|
||||
dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
|
||||
|
||||
// Unlock.
|
||||
receiver_context->Close();
|
||||
dispatcher()->FlushContextPipeForTesting();
|
||||
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
|
||||
|
||||
// (Don't) receive mouse event.
|
||||
dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
|
||||
}
|
||||
|
||||
// Test multiple targets
|
||||
TEST_F(MouseLockDispatcherTest, MultipleTargets) {
|
||||
::testing::InSequence expect_calls_in_sequence;
|
||||
EXPECT_CALL(*target_, OnLockMouseACK(/*succeeded=*/true));
|
||||
EXPECT_CALL(*target_, HandleMouseLockedInputEvent(_));
|
||||
EXPECT_CALL(*alternate_target_, HandleMouseLockedInputEvent(_)).Times(0);
|
||||
EXPECT_CALL(*target_, OnMouseLockLost()).Times(0);
|
||||
EXPECT_CALL(*alternate_target_, OnMouseLockLost()).Times(0);
|
||||
EXPECT_CALL(*target_, OnMouseLockLost());
|
||||
|
||||
// Lock request for target.
|
||||
EXPECT_TRUE(dispatcher()->LockMouse(
|
||||
target_, view()->GetMainRenderFrame()->GetWebFrame(), base::DoNothing(),
|
||||
false /* unadjusted_movement */));
|
||||
|
||||
// Fail attempt to lock alternate.
|
||||
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(alternate_target_));
|
||||
EXPECT_FALSE(dispatcher()->LockMouse(
|
||||
alternate_target_, view()->GetMainRenderFrame()->GetWebFrame(),
|
||||
base::DoNothing(), false /* unadjusted_movement */));
|
||||
|
||||
// Lock completion for target.
|
||||
|
||||
mojo::PendingRemote<blink::mojom::PointerLockContext> remote_context;
|
||||
auto receiver_context = mojo::MakeSelfOwnedReceiver(
|
||||
std::make_unique<PointerLockContextImpl>(),
|
||||
remote_context.InitWithNewPipeAndPassReceiver());
|
||||
|
||||
dispatcher()->OnLockMouseACK(blink::mojom::PointerLockResult::kSuccess,
|
||||
std::move(remote_context));
|
||||
EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
|
||||
|
||||
// Fail attempt to lock alternate.
|
||||
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(alternate_target_));
|
||||
EXPECT_FALSE(dispatcher()->LockMouse(
|
||||
alternate_target_, view()->GetMainRenderFrame()->GetWebFrame(),
|
||||
base::DoNothing(), false /* unadjusted_movement */));
|
||||
|
||||
// Receive mouse event to only one target.
|
||||
dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
|
||||
|
||||
// Unlock alternate target has no effect.
|
||||
dispatcher()->UnlockMouse(alternate_target_);
|
||||
EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
|
||||
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(alternate_target_));
|
||||
|
||||
// Though the call to UnlockMouse should not unlock any target, we will
|
||||
// cause an unlock by disconnecting the pipe (e.g. user escaped
|
||||
// mouse lock) and verify the correct target is unlocked.
|
||||
receiver_context->Close();
|
||||
dispatcher()->FlushContextPipeForTesting();
|
||||
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
|
||||
}
|
||||
|
||||
} // namespace content
|
@ -203,7 +203,6 @@ void AppendCharEvent(const WebInputEvent& event,
|
||||
}
|
||||
|
||||
void AppendMouseEvent(const WebInputEvent& event,
|
||||
std::unique_ptr<gfx::PointF>* in_out_last_mouse_position,
|
||||
std::vector<InputEventData>* result_events) {
|
||||
static_assert(static_cast<int>(WebMouseEvent::Button::kNoButton) ==
|
||||
static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_NONE),
|
||||
@ -240,27 +239,8 @@ void AppendMouseEvent(const WebInputEvent& event,
|
||||
result.mouse_position.y = mouse_event.PositionInWidget().y();
|
||||
result.mouse_click_count = mouse_event.click_count;
|
||||
|
||||
if (base::FeatureList::IsEnabled(features::kConsolidatedMovementXY)) {
|
||||
if (mouse_event.GetType() == WebInputEvent::Type::kMouseMove &&
|
||||
*in_out_last_mouse_position) {
|
||||
result.mouse_movement.x = mouse_event.PositionInScreen().x() -
|
||||
(*in_out_last_mouse_position)->x();
|
||||
result.mouse_movement.y = mouse_event.PositionInScreen().y() -
|
||||
(*in_out_last_mouse_position)->y();
|
||||
}
|
||||
*in_out_last_mouse_position =
|
||||
std::make_unique<gfx::PointF>(mouse_event.PositionInScreen());
|
||||
|
||||
// Filter out event generated by recentering the cursor when mouse locked.
|
||||
// See |RenderWidgetHostViewEventHandler::HandleMouseEventWhileLocked|.
|
||||
if ((mouse_event.GetModifiers() &
|
||||
WebInputEvent::Modifiers::kRelativeMotionEvent)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
result.mouse_movement.x = mouse_event.movement_x;
|
||||
result.mouse_movement.y = mouse_event.movement_y;
|
||||
}
|
||||
result.mouse_movement.x = mouse_event.movement_x;
|
||||
result.mouse_movement.y = mouse_event.movement_y;
|
||||
|
||||
result_events->push_back(result);
|
||||
}
|
||||
@ -626,7 +606,6 @@ void GetKeyCode(const std::string& char_text,
|
||||
|
||||
void CreateInputEventData(
|
||||
const WebInputEvent& event,
|
||||
std::unique_ptr<gfx::PointF>* in_out_last_mouse_position,
|
||||
std::vector<InputEventData>* result) {
|
||||
result->clear();
|
||||
|
||||
@ -637,7 +616,7 @@ void CreateInputEventData(
|
||||
case WebInputEvent::Type::kMouseEnter:
|
||||
case WebInputEvent::Type::kMouseLeave:
|
||||
case WebInputEvent::Type::kContextMenu:
|
||||
AppendMouseEvent(event, in_out_last_mouse_position, result);
|
||||
AppendMouseEvent(event, result);
|
||||
break;
|
||||
case WebInputEvent::Type::kMouseWheel:
|
||||
AppendMouseWheelEvent(event, result);
|
||||
|
@ -29,7 +29,6 @@ namespace content {
|
||||
// events will ge generated and the vector will be empty.
|
||||
CONTENT_EXPORT void CreateInputEventData(
|
||||
const blink::WebInputEvent& event,
|
||||
std::unique_ptr<gfx::PointF>* last_mouse_position,
|
||||
std::vector<ppapi::InputEventData>* pp_events);
|
||||
|
||||
// Creates a WebInputEvent from the given PP_InputEvent. If it fails, returns
|
||||
|
@ -47,7 +47,7 @@ TEST_F(EventConversionTest, TouchStart) {
|
||||
touch.PressPoint(1.f, 2.f);
|
||||
|
||||
std::vector<ppapi::InputEventData> pp_events;
|
||||
CreateInputEventData(touch, nullptr, &pp_events);
|
||||
CreateInputEventData(touch, &pp_events);
|
||||
ASSERT_EQ(1U, pp_events.size());
|
||||
|
||||
const ppapi::InputEventData& pp_event = pp_events[0];
|
||||
@ -75,7 +75,7 @@ TEST_F(EventConversionTest, TouchMove) {
|
||||
touch.MovePoint(1, 5.f, 6.f);
|
||||
|
||||
std::vector<ppapi::InputEventData> pp_events;
|
||||
CreateInputEventData(touch, nullptr, &pp_events);
|
||||
CreateInputEventData(touch, &pp_events);
|
||||
ASSERT_EQ(1U, pp_events.size());
|
||||
|
||||
const ppapi::InputEventData& pp_event = pp_events[0];
|
||||
@ -103,7 +103,7 @@ TEST_F(EventConversionTest, TouchEnd) {
|
||||
touch.ReleasePoint(0);
|
||||
|
||||
std::vector<ppapi::InputEventData> pp_events;
|
||||
CreateInputEventData(touch, nullptr, &pp_events);
|
||||
CreateInputEventData(touch, &pp_events);
|
||||
ASSERT_EQ(1U, pp_events.size());
|
||||
|
||||
const ppapi::InputEventData& pp_event = pp_events[0];
|
||||
@ -132,7 +132,7 @@ TEST_F(EventConversionTest, TouchCancel) {
|
||||
touch.CancelPoint(0);
|
||||
|
||||
std::vector<ppapi::InputEventData> pp_events;
|
||||
CreateInputEventData(touch, nullptr, &pp_events);
|
||||
CreateInputEventData(touch, &pp_events);
|
||||
ASSERT_EQ(1U, pp_events.size());
|
||||
|
||||
const ppapi::InputEventData& pp_event = pp_events[0];
|
||||
@ -152,13 +152,12 @@ TEST_F(EventConversionTest, TouchCancel) {
|
||||
}
|
||||
|
||||
TEST_F(EventConversionTest, MouseMove) {
|
||||
std::unique_ptr<gfx::PointF> last_mouse_position;
|
||||
blink::WebMouseEvent mouse_event =
|
||||
blink::SyntheticWebMouseEventBuilder::Build(
|
||||
blink::WebInputEvent::Type::kMouseMove, 100, 200, 0);
|
||||
|
||||
std::vector<ppapi::InputEventData> pp_events;
|
||||
CreateInputEventData(mouse_event, &last_mouse_position, &pp_events);
|
||||
CreateInputEventData(mouse_event, &pp_events);
|
||||
ASSERT_EQ(1U, pp_events.size());
|
||||
const ppapi::InputEventData& pp_event = pp_events[0];
|
||||
ASSERT_EQ(PP_INPUTEVENT_TYPE_MOUSEMOVE, pp_event.event_type);
|
||||
@ -166,14 +165,12 @@ TEST_F(EventConversionTest, MouseMove) {
|
||||
ASSERT_EQ(pp_event.mouse_position.y, mouse_event.PositionInWidget().y());
|
||||
ASSERT_EQ(pp_event.mouse_movement.x, 0);
|
||||
ASSERT_EQ(pp_event.mouse_movement.y, 0);
|
||||
if (last_mouse_position) {
|
||||
ASSERT_EQ(*last_mouse_position.get(),
|
||||
gfx::PointF(mouse_event.PositionInScreen()));
|
||||
}
|
||||
|
||||
mouse_event = blink::SyntheticWebMouseEventBuilder::Build(
|
||||
blink::WebInputEvent::Type::kMouseMove, 123, 188, 0);
|
||||
CreateInputEventData(mouse_event, &last_mouse_position, &pp_events);
|
||||
mouse_event.movement_x = 23;
|
||||
mouse_event.movement_y = -12;
|
||||
CreateInputEventData(mouse_event, &pp_events);
|
||||
ASSERT_EQ(PP_INPUTEVENT_TYPE_MOUSEMOVE, pp_event.event_type);
|
||||
ASSERT_EQ(pp_event.mouse_position.x, mouse_event.PositionInWidget().x());
|
||||
ASSERT_EQ(pp_event.mouse_position.y, mouse_event.PositionInWidget().y());
|
||||
|
@ -344,26 +344,6 @@ bool IsReservedSystemInputEvent(const blink::WebInputEvent& event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
class PluginInstanceLockTarget : public MouseLockDispatcher::LockTarget {
|
||||
public:
|
||||
explicit PluginInstanceLockTarget(PepperPluginInstanceImpl* plugin)
|
||||
: plugin_(plugin) {}
|
||||
|
||||
void OnLockMouseACK(bool succeeded) override {
|
||||
plugin_->OnLockMouseACK(succeeded);
|
||||
}
|
||||
|
||||
void OnMouseLockLost() override { plugin_->OnMouseLockLost(); }
|
||||
|
||||
bool HandleMouseLockedInputEvent(const blink::WebMouseEvent& event) override {
|
||||
plugin_->HandleMouseLockedInputEvent(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
PepperPluginInstanceImpl* plugin_;
|
||||
};
|
||||
|
||||
void PrintPDFOutput(PP_Resource print_output,
|
||||
printing::MetafileSkia* metafile) {
|
||||
#if BUILDFLAG(ENABLE_PRINTING)
|
||||
@ -617,7 +597,6 @@ PepperPluginInstanceImpl::~PepperPluginInstanceImpl() {
|
||||
browser_connection->DidDeleteInProcessInstance(pp_instance());
|
||||
}
|
||||
|
||||
UnSetAndDeleteLockTargetAdapter();
|
||||
module_->InstanceDeleted(this);
|
||||
// If we switched from the NaCl plugin module, notify it too.
|
||||
if (original_module_.get())
|
||||
@ -816,7 +795,6 @@ void PepperPluginInstanceImpl::InstanceCrashed() {
|
||||
|
||||
if (render_frame_)
|
||||
render_frame_->PluginCrashed(module_->path(), module_->GetPeerProcessId());
|
||||
UnSetAndDeleteLockTargetAdapter();
|
||||
}
|
||||
|
||||
bool PepperPluginInstanceImpl::Initialize(
|
||||
@ -1138,10 +1116,9 @@ bool PepperPluginInstanceImpl::HandleInputEvent(
|
||||
std::unique_ptr<const WebInputEvent> event_in_dip(
|
||||
ui::ScaleWebInputEvent(event, viewport_to_dip_scale_));
|
||||
if (event_in_dip)
|
||||
CreateInputEventData(*event_in_dip.get(), &last_mouse_position_,
|
||||
&events);
|
||||
CreateInputEventData(*event_in_dip.get(), &events);
|
||||
else
|
||||
CreateInputEventData(event, &last_mouse_position_, &events);
|
||||
CreateInputEventData(event, &events);
|
||||
|
||||
// Each input event may generate more than one PP_InputEvent.
|
||||
for (size_t i = 0; i < events.size(); i++) {
|
||||
@ -2692,7 +2669,7 @@ int32_t PepperPluginInstanceImpl::LockMouse(
|
||||
}
|
||||
|
||||
void PepperPluginInstanceImpl::UnlockMouse(PP_Instance instance) {
|
||||
GetMouseLockDispatcher()->UnlockMouse(GetOrCreateLockTargetAdapter());
|
||||
container_->UnlockMouse();
|
||||
}
|
||||
|
||||
void PepperPluginInstanceImpl::SetTextInputType(PP_Instance instance,
|
||||
@ -3092,36 +3069,11 @@ void PepperPluginInstanceImpl::ResetSizeAttributesAfterFullscreen() {
|
||||
}
|
||||
|
||||
bool PepperPluginInstanceImpl::IsMouseLocked() {
|
||||
return GetMouseLockDispatcher()->IsMouseLockedTo(
|
||||
GetOrCreateLockTargetAdapter());
|
||||
return container_->IsMouseLocked();
|
||||
}
|
||||
|
||||
bool PepperPluginInstanceImpl::LockMouse(bool request_unadjusted_movement) {
|
||||
WebLocalFrame* requester_frame = container_->GetDocument().GetFrame();
|
||||
return GetMouseLockDispatcher()->LockMouse(
|
||||
GetOrCreateLockTargetAdapter(), requester_frame,
|
||||
base::OnceCallback<void(blink::mojom::PointerLockResult)>(),
|
||||
request_unadjusted_movement);
|
||||
}
|
||||
|
||||
MouseLockDispatcher::LockTarget*
|
||||
PepperPluginInstanceImpl::GetOrCreateLockTargetAdapter() {
|
||||
if (!lock_target_)
|
||||
lock_target_ = std::make_unique<PluginInstanceLockTarget>(this);
|
||||
return lock_target_.get();
|
||||
}
|
||||
|
||||
MouseLockDispatcher* PepperPluginInstanceImpl::GetMouseLockDispatcher() {
|
||||
if (render_frame_)
|
||||
return render_frame_->GetLocalRootRenderWidget()->mouse_lock_dispatcher();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void PepperPluginInstanceImpl::UnSetAndDeleteLockTargetAdapter() {
|
||||
if (lock_target_) {
|
||||
GetMouseLockDispatcher()->OnLockTargetDestroyed(lock_target_.get());
|
||||
lock_target_.reset();
|
||||
}
|
||||
return container_->LockMouse(request_unadjusted_movement);
|
||||
}
|
||||
|
||||
void PepperPluginInstanceImpl::DidDataFromWebURLResponse(
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include "content/public/renderer/plugin_instance_throttler.h"
|
||||
#include "content/public/renderer/render_frame.h"
|
||||
#include "content/public/renderer/render_frame_observer.h"
|
||||
#include "content/renderer/mouse_lock_dispatcher.h"
|
||||
#include "gin/handle.h"
|
||||
#include "ppapi/c/dev/pp_cursor_type_dev.h"
|
||||
#include "ppapi/c/dev/ppp_printing_dev.h"
|
||||
@ -607,9 +606,6 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
|
||||
|
||||
bool IsMouseLocked();
|
||||
bool LockMouse(bool request_unadjusted_movement);
|
||||
MouseLockDispatcher* GetMouseLockDispatcher();
|
||||
MouseLockDispatcher::LockTarget* GetOrCreateLockTargetAdapter();
|
||||
void UnSetAndDeleteLockTargetAdapter();
|
||||
|
||||
void DidDataFromWebURLResponse(const blink::WebURLResponse& response,
|
||||
int pending_host_id,
|
||||
@ -808,11 +804,6 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
|
||||
|
||||
scoped_refptr<ppapi::TrackedCallback> lock_mouse_callback_;
|
||||
|
||||
// Last mouse position from mouse event, used for calculating movements. Null
|
||||
// means no mouse event received yet. This value is updated by
|
||||
// |CreateInputEventData|.
|
||||
std::unique_ptr<gfx::PointF> last_mouse_position_;
|
||||
|
||||
// We store the arguments so we can re-send them if we are reset to talk to
|
||||
// NaCl via the IPC NaCl proxy.
|
||||
std::vector<std::string> argn_;
|
||||
@ -832,8 +823,6 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
|
||||
// Isolate in which this Instance was created when interacting with v8.
|
||||
v8::Isolate* isolate_;
|
||||
|
||||
std::unique_ptr<MouseLockDispatcher::LockTarget> lock_target_;
|
||||
|
||||
bool is_deleted_;
|
||||
|
||||
// The text that is currently selected in the plugin.
|
||||
|
@ -491,4 +491,14 @@ bool PepperWebPluginImpl::IsPlaceholder() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void PepperWebPluginImpl::DidLoseMouseLock() {
|
||||
if (instance_)
|
||||
instance_->OnMouseLockLost();
|
||||
}
|
||||
|
||||
void PepperWebPluginImpl::DidReceiveMouseLockResult(bool success) {
|
||||
if (instance_)
|
||||
instance_->OnLockMouseACK(success);
|
||||
}
|
||||
|
||||
} // namespace content
|
||||
|
@ -88,6 +88,8 @@ class PepperWebPluginImpl : public blink::WebPlugin {
|
||||
bool CanRotateView() override;
|
||||
void RotateView(RotationType type) override;
|
||||
bool IsPlaceholder() override;
|
||||
void DidLoseMouseLock() override;
|
||||
void DidReceiveMouseLockResult(bool success) override;
|
||||
|
||||
private:
|
||||
friend class base::DeleteHelper<PepperWebPluginImpl>;
|
||||
|
@ -127,32 +127,6 @@ namespace {
|
||||
RenderWidget::CreateRenderWidgetFunction g_create_render_widget_for_frame =
|
||||
nullptr;
|
||||
|
||||
class WebWidgetLockTarget : public content::MouseLockDispatcher::LockTarget {
|
||||
public:
|
||||
explicit WebWidgetLockTarget(RenderWidget* render_widget)
|
||||
: render_widget_(render_widget) {}
|
||||
|
||||
void OnLockMouseACK(bool succeeded) override {
|
||||
if (succeeded)
|
||||
render_widget_->GetWebWidget()->DidAcquirePointerLock();
|
||||
else
|
||||
render_widget_->GetWebWidget()->DidNotAcquirePointerLock();
|
||||
}
|
||||
|
||||
void OnMouseLockLost() override {
|
||||
render_widget_->GetWebWidget()->DidLosePointerLock();
|
||||
}
|
||||
|
||||
bool HandleMouseLockedInputEvent(const blink::WebMouseEvent& event) override {
|
||||
// The WebWidget handles mouse lock in Blink's handleInputEvent().
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
// The RenderWidget owns this instance and is guaranteed to outlive it.
|
||||
RenderWidget* render_widget_;
|
||||
};
|
||||
|
||||
WebDragData DropMetaDataToWebDragData(
|
||||
const std::vector<DropData::Metadata>& drop_meta_data) {
|
||||
std::vector<WebDragData::Item> item_list;
|
||||
@ -294,10 +268,6 @@ void RenderWidget::Initialize(ShowCallback show_callback,
|
||||
|
||||
show_callback_ = std::move(show_callback);
|
||||
|
||||
webwidget_mouse_lock_target_ = std::make_unique<WebWidgetLockTarget>(this);
|
||||
mouse_lock_dispatcher_ =
|
||||
std::make_unique<RenderWidgetMouseLockDispatcher>(this);
|
||||
|
||||
agent_scheduling_group_.AddRoute(routing_id_, this);
|
||||
|
||||
webwidget_ = web_widget;
|
||||
@ -444,10 +414,6 @@ void RenderWidget::UpdateTextInputState() {
|
||||
GetWebWidget()->UpdateTextInputState();
|
||||
}
|
||||
|
||||
bool RenderWidget::WillHandleMouseEvent(const blink::WebMouseEvent& event) {
|
||||
return mouse_lock_dispatcher()->WillHandleMouseEvent(event);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// WebWidgetClient
|
||||
|
||||
@ -661,33 +627,6 @@ viz::FrameSinkId RenderWidget::GetFrameSinkId() {
|
||||
return viz::FrameSinkId(RenderThread::Get()->GetClientId(), routing_id());
|
||||
}
|
||||
|
||||
bool RenderWidget::RequestPointerLock(
|
||||
WebLocalFrame* requester_frame,
|
||||
blink::WebWidgetClient::PointerLockCallback callback,
|
||||
bool request_unadjusted_movement) {
|
||||
return mouse_lock_dispatcher_->LockMouse(webwidget_mouse_lock_target_.get(),
|
||||
requester_frame, std::move(callback),
|
||||
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::RequestPointerUnlock() {
|
||||
mouse_lock_dispatcher_->UnlockMouse(webwidget_mouse_lock_target_.get());
|
||||
}
|
||||
|
||||
bool RenderWidget::IsPointerLocked() {
|
||||
return mouse_lock_dispatcher_->IsMouseLockedTo(
|
||||
webwidget_mouse_lock_target_.get());
|
||||
}
|
||||
|
||||
void RenderWidget::DidNavigate(ukm::SourceId source_id, const GURL& url) {
|
||||
// Update the URL and the document source id used to key UKM metrics in the
|
||||
// compositor. Note that the metrics for all frames are keyed to the main
|
||||
|
@ -33,9 +33,7 @@
|
||||
#include "content/common/content_export.h"
|
||||
#include "content/common/renderer.mojom-forward.h"
|
||||
#include "content/public/common/drop_data.h"
|
||||
#include "content/renderer/mouse_lock_dispatcher.h"
|
||||
#include "content/renderer/render_widget_delegate.h"
|
||||
#include "content/renderer/render_widget_mouse_lock_dispatcher.h"
|
||||
#include "ipc/ipc_listener.h"
|
||||
#include "ipc/ipc_message.h"
|
||||
#include "ipc/ipc_sender.h"
|
||||
@ -63,8 +61,6 @@
|
||||
|
||||
namespace blink {
|
||||
class WebFrameWidget;
|
||||
class WebLocalFrame;
|
||||
class WebMouseEvent;
|
||||
class WebPagePopup;
|
||||
} // namespace blink
|
||||
|
||||
@ -205,19 +201,9 @@ class CONTENT_EXPORT RenderWidget
|
||||
void ClosePopupWidgetSoon() override;
|
||||
void Show(blink::WebNavigationPolicy) override;
|
||||
void SetWindowRect(const gfx::Rect&) override;
|
||||
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 RequestPointerUnlock() override;
|
||||
bool IsPointerLocked() override;
|
||||
viz::FrameSinkId GetFrameSinkId() override;
|
||||
void RecordTimeToFirstActivePaint(base::TimeDelta duration) override;
|
||||
void DidCommitCompositorFrame(base::TimeTicks commit_start_time) override;
|
||||
bool WillHandleMouseEvent(const blink::WebMouseEvent& event) override;
|
||||
bool CanComposeInline() override;
|
||||
bool ShouldDispatchImeEventsToPepper() override;
|
||||
blink::WebTextInputType GetPepperTextInputType() override;
|
||||
@ -245,10 +231,6 @@ class CONTENT_EXPORT RenderWidget
|
||||
// the new value will be sent to the browser process.
|
||||
void UpdateSelectionBounds();
|
||||
|
||||
MouseLockDispatcher* mouse_lock_dispatcher() const {
|
||||
return mouse_lock_dispatcher_.get();
|
||||
}
|
||||
|
||||
void DidNavigate(ukm::SourceId source_id, const GURL& url);
|
||||
|
||||
void SetActive(bool active);
|
||||
@ -373,12 +355,6 @@ class CONTENT_EXPORT RenderWidget
|
||||
// The time spent in input handlers this frame. Used to throttle input acks.
|
||||
base::TimeDelta total_input_handling_time_this_frame_;
|
||||
|
||||
// Mouse Lock dispatcher attached to this view.
|
||||
std::unique_ptr<RenderWidgetMouseLockDispatcher> mouse_lock_dispatcher_;
|
||||
|
||||
// Wraps the |webwidget_| as a MouseLockDispatcher::LockTarget interface.
|
||||
std::unique_ptr<MouseLockDispatcher::LockTarget> webwidget_mouse_lock_target_;
|
||||
|
||||
// Whether this widget is for a child local root frame. This excludes widgets
|
||||
// that are not for a frame (eg popups) and excludes the widget for the main
|
||||
// frame (which is attached to the RenderViewImpl).
|
||||
|
@ -1,51 +0,0 @@
|
||||
// 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 "content/renderer/render_widget_mouse_lock_dispatcher.h"
|
||||
|
||||
#include "content/renderer/render_view_impl.h"
|
||||
#include "third_party/blink/public/mojom/input/pointer_lock_context.mojom.h"
|
||||
#include "third_party/blink/public/web/web_frame.h"
|
||||
#include "third_party/blink/public/web/web_local_frame.h"
|
||||
#include "third_party/blink/public/web/web_view.h"
|
||||
#include "third_party/blink/public/web/web_widget.h"
|
||||
|
||||
namespace content {
|
||||
|
||||
RenderWidgetMouseLockDispatcher::RenderWidgetMouseLockDispatcher(
|
||||
RenderWidget* render_widget)
|
||||
: render_widget_(render_widget) {}
|
||||
|
||||
RenderWidgetMouseLockDispatcher::~RenderWidgetMouseLockDispatcher() {}
|
||||
|
||||
void RenderWidgetMouseLockDispatcher::SendLockMouseRequest(
|
||||
blink::WebLocalFrame* requester_frame,
|
||||
bool request_unadjusted_movement) {
|
||||
bool has_transient_user_activation =
|
||||
requester_frame ? requester_frame->HasTransientUserActivation() : false;
|
||||
render_widget_->GetWebWidget()->RequestMouseLock(
|
||||
has_transient_user_activation, request_unadjusted_movement,
|
||||
base::BindOnce(&RenderWidgetMouseLockDispatcher::OnMouseLocked,
|
||||
weak_ptr_factory_.GetWeakPtr()));
|
||||
}
|
||||
|
||||
void RenderWidgetMouseLockDispatcher::OnMouseLocked(
|
||||
blink::mojom::PointerLockResult result,
|
||||
blink::CrossVariantMojoRemote<blink::mojom::PointerLockContextInterfaceBase>
|
||||
context) {
|
||||
// Notify the base class.
|
||||
MouseLockDispatcher::OnLockMouseACK(result, std::move(context));
|
||||
|
||||
// Mouse Lock removes the system cursor and provides all mouse motion as
|
||||
// .movementX/Y values on events all sent to a fixed target. This requires
|
||||
// content to specifically request the mode to be entered.
|
||||
// Mouse Capture is implicitly given for the duration of a drag event, and
|
||||
// sends all mouse events to the initial target of the drag.
|
||||
// If Lock is entered it supersedes any in progress Capture.
|
||||
if (result == blink::mojom::PointerLockResult::kSuccess &&
|
||||
render_widget_->GetWebWidget())
|
||||
render_widget_->GetWebWidget()->MouseCaptureLost();
|
||||
}
|
||||
|
||||
} // namespace content
|
@ -1,47 +0,0 @@
|
||||
// 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 CONTENT_RENDERER_RENDER_WIDGET_MOUSE_LOCK_DISPATCHER_H_
|
||||
#define CONTENT_RENDERER_RENDER_WIDGET_MOUSE_LOCK_DISPATCHER_H_
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/macros.h"
|
||||
#include "content/renderer/mouse_lock_dispatcher.h"
|
||||
|
||||
namespace IPC {
|
||||
class Message;
|
||||
}
|
||||
|
||||
namespace content {
|
||||
|
||||
class RenderWidget;
|
||||
|
||||
// RenderWidgetMouseLockDispatcher is owned by RenderWidget.
|
||||
class RenderWidgetMouseLockDispatcher : public MouseLockDispatcher {
|
||||
public:
|
||||
explicit RenderWidgetMouseLockDispatcher(RenderWidget* render_widget);
|
||||
~RenderWidgetMouseLockDispatcher() override;
|
||||
|
||||
bool OnMessageReceived(const IPC::Message& message);
|
||||
|
||||
private:
|
||||
// MouseLockDispatcher implementation.
|
||||
void SendLockMouseRequest(blink::WebLocalFrame* requester_frame,
|
||||
bool request_unadjusted_movement) override;
|
||||
|
||||
void OnMouseLocked(
|
||||
blink::mojom::PointerLockResult result,
|
||||
blink::CrossVariantMojoRemote<
|
||||
blink::mojom::PointerLockContextInterfaceBase> context);
|
||||
|
||||
RenderWidget* render_widget_;
|
||||
|
||||
base::WeakPtrFactory<RenderWidgetMouseLockDispatcher> weak_ptr_factory_{this};
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RenderWidgetMouseLockDispatcher);
|
||||
};
|
||||
|
||||
} // namespace content
|
||||
|
||||
#endif // CONTENT_RENDERER_RENDER_WIDGET_MOUSE_LOCK_DISPATCHER_H_
|
@ -1178,7 +1178,6 @@ test("content_browsertests") {
|
||||
"../renderer/blink_platform_audio_hardware_browsertest.cc",
|
||||
"../renderer/gin_browsertest.cc",
|
||||
"../renderer/media/renderer_webmediaplayer_delegate_browsertest.cc",
|
||||
"../renderer/mouse_lock_dispatcher_browsertest.cc",
|
||||
"../renderer/render_frame_impl_browsertest.cc",
|
||||
"../renderer/render_thread_impl_browsertest.cc",
|
||||
"../renderer/render_view_browsertest.cc",
|
||||
|
@ -1266,9 +1266,6 @@ void EventSender::Reset() {
|
||||
current_drag_data_ = base::nullopt;
|
||||
current_drag_effect_ = blink::kDragOperationNone;
|
||||
current_drag_effects_allowed_ = blink::kDragOperationNone;
|
||||
if (widget() && current_pointer_state_[kRawMousePointerId].pressed_button_ !=
|
||||
WebMouseEvent::Button::kNoButton)
|
||||
widget()->MouseCaptureLost();
|
||||
current_pointer_state_.clear();
|
||||
is_drag_mode_ = true;
|
||||
force_layout_on_events_ = true;
|
||||
|
@ -2308,6 +2308,7 @@ void TestRunner::ResetWebWidget(WebWidgetTestProxy* web_widget_test_proxy) {
|
||||
web_widget_test_proxy->GetWebFrameWidget();
|
||||
|
||||
web_widget->SetDeviceScaleFactorForTesting(0);
|
||||
web_widget->ReleaseMouseLockAndPointerCaptureForTesting();
|
||||
|
||||
// These things are only modified/valid for the main frame's widget.
|
||||
if (web_widget_test_proxy->delegate()) {
|
||||
|
@ -206,6 +206,10 @@ class WebFrameWidget : public WebWidget {
|
||||
// See https://github.com/webscreens/window-segments/blob/master/EXPLAINER.md
|
||||
virtual const WebVector<gfx::Rect>& WindowSegments() const = 0;
|
||||
|
||||
// Release any mouse lock or pointer capture held. This is used to reset
|
||||
// state between WebTest runs.
|
||||
virtual void ReleaseMouseLockAndPointerCaptureForTesting() = 0;
|
||||
|
||||
private:
|
||||
// This private constructor and the class/friend declaration ensures that
|
||||
// WebFrameWidgetBase is the only concrete subclass that implements
|
||||
|
7
third_party/blink/public/web/web_plugin.h
vendored
7
third_party/blink/public/web/web_plugin.h
vendored
@ -255,6 +255,13 @@ class WebPlugin {
|
||||
// it loading later.
|
||||
virtual bool IsErrorPlaceholder() { return false; }
|
||||
|
||||
// Indication that a current mouse lock has been lost.
|
||||
virtual void DidLoseMouseLock() {}
|
||||
|
||||
// A response has been received from a previous WebPluginContainer::LockMouse
|
||||
// call.
|
||||
virtual void DidReceiveMouseLockResult(bool success) {}
|
||||
|
||||
protected:
|
||||
virtual ~WebPlugin() = default;
|
||||
};
|
||||
|
@ -157,6 +157,16 @@ class WebPluginContainer {
|
||||
// Returns true if this container was the target for the last mouse event.
|
||||
virtual bool WasTargetForLastMouseEvent() = 0;
|
||||
|
||||
// Whether this plugin current has the mouse lock or not.
|
||||
virtual bool IsMouseLocked() = 0;
|
||||
|
||||
// Request to lock the mouse. A subsequent callback on
|
||||
// WebPlugin::DidReceiveMouseLockResult will be called.
|
||||
virtual bool LockMouse(bool request_unadjusted_movement) = 0;
|
||||
|
||||
// Request to unlock a current mouse lock.
|
||||
virtual void UnlockMouse() = 0;
|
||||
|
||||
protected:
|
||||
~WebPluginContainer() = default;
|
||||
};
|
||||
|
23
third_party/blink/public/web/web_widget.h
vendored
23
third_party/blink/public/web/web_widget.h
vendored
@ -148,9 +148,6 @@ class WebWidget {
|
||||
return WebInputEventResult::kNotHandled;
|
||||
}
|
||||
|
||||
// Called to inform the WebWidget that mouse capture was lost.
|
||||
virtual void MouseCaptureLost() {}
|
||||
|
||||
// Called to inform the WebWidget of the mouse cursor's visibility.
|
||||
virtual void SetCursorVisibilityState(bool is_visible) {}
|
||||
|
||||
@ -160,16 +157,6 @@ class WebWidget {
|
||||
// Returns the state of focus for the WebWidget.
|
||||
virtual bool HasFocus() { return false; }
|
||||
|
||||
// Calling WebWidgetClient::requestPointerLock() will result in one
|
||||
// return call to didAcquirePointerLock() or didNotAcquirePointerLock().
|
||||
virtual void DidAcquirePointerLock() {}
|
||||
virtual void DidNotAcquirePointerLock() {}
|
||||
|
||||
// Pointer lock was held, but has been lost. This may be due to a
|
||||
// request via WebWidgetClient::requestPointerUnlock(), or for other
|
||||
// reasons such as the user exiting lock, window focus changing, etc.
|
||||
virtual void DidLosePointerLock() {}
|
||||
|
||||
// Accessor to the WebWidget scheduing state.
|
||||
virtual scheduler::WebRenderWidgetSchedulingState*
|
||||
RendererWidgetSchedulingState() = 0;
|
||||
@ -207,16 +194,6 @@ class WebWidget {
|
||||
// updated state will be sent to the browser.
|
||||
virtual void UpdateTextInputState() = 0;
|
||||
|
||||
// Request Mouse Lock. This can be removed eventually when the mouse lock
|
||||
// dispatcher is moved into blink.
|
||||
virtual void RequestMouseLock(
|
||||
bool has_transient_user_activation,
|
||||
bool request_unadjusted_movement,
|
||||
base::OnceCallback<
|
||||
void(mojom::PointerLockResult,
|
||||
CrossVariantMojoRemote<mojom::PointerLockContextInterfaceBase>)>
|
||||
callback) = 0;
|
||||
|
||||
// Flush any pending input.
|
||||
virtual void FlushInputProcessedCallback() = 0;
|
||||
|
||||
|
37
third_party/blink/public/web/web_widget_client.h
vendored
37
third_party/blink/public/web/web_widget_client.h
vendored
@ -68,9 +68,6 @@ struct ImeTextSpan;
|
||||
|
||||
namespace blink {
|
||||
class WebDragData;
|
||||
class WebMouseEvent;
|
||||
class WebWidget;
|
||||
class WebLocalFrame;
|
||||
class WebString;
|
||||
|
||||
class WebWidgetClient {
|
||||
@ -113,33 +110,6 @@ class WebWidgetClient {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Requests to lock the mouse cursor for the |requester_frame| in the
|
||||
// widget. If true is returned, the success result will be asynchronously
|
||||
// returned via a single call to WebWidget::didAcquirePointerLock() or
|
||||
// WebWidget::didNotAcquirePointerLock() and a single call to the callback.
|
||||
// If false, the request has been denied synchronously.
|
||||
using PointerLockCallback =
|
||||
base::OnceCallback<void(mojom::PointerLockResult)>;
|
||||
virtual bool RequestPointerLock(WebLocalFrame* requester_frame,
|
||||
PointerLockCallback callback,
|
||||
bool request_unadjusted_movement) {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool RequestPointerLockChange(WebLocalFrame* requester_frame,
|
||||
PointerLockCallback callback,
|
||||
bool request_unadjusted_movement) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cause the pointer lock to be released. This may be called at any time,
|
||||
// including when a lock is pending but not yet acquired.
|
||||
// WebWidget::didLosePointerLock() is called when unlock is complete.
|
||||
virtual void RequestPointerUnlock() {}
|
||||
|
||||
// Returns true iff the pointer is locked to this widget.
|
||||
virtual bool IsPointerLocked() { return false; }
|
||||
|
||||
// Called when a drag-and-drop operation should begin. Returns whether the
|
||||
// call has been handled.
|
||||
virtual bool InterceptStartDragging(const WebDragData&,
|
||||
@ -175,13 +145,6 @@ class WebWidgetClient {
|
||||
// from background inactive to active.
|
||||
virtual void RecordTimeToFirstActivePaint(base::TimeDelta duration) {}
|
||||
|
||||
// Called before mouse events are processed and allows the
|
||||
// client to handle the event itself. Return true if event was handled
|
||||
// and further processing should stop.
|
||||
virtual bool WillHandleMouseEvent(const WebMouseEvent& event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Determines whether composition can happen inline.
|
||||
virtual bool CanComposeInline() { return false; }
|
||||
|
||||
|
@ -7411,7 +7411,7 @@ void Document::exitPointerLock() {
|
||||
if (Element* target = GetPage()->GetPointerLockController().GetElement()) {
|
||||
if (target->GetDocument() != this)
|
||||
return;
|
||||
GetPage()->GetPointerLockController().RequestPointerUnlock();
|
||||
GetPage()->GetPointerLockController().ExitPointerLock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -456,18 +456,6 @@ void WebPagePopupImpl::CancelCompositionForPepper() {
|
||||
widget_base_->CancelCompositionForPepper();
|
||||
}
|
||||
|
||||
void WebPagePopupImpl::RequestMouseLock(
|
||||
bool has_transient_user_activation,
|
||||
bool request_unadjusted_movement,
|
||||
base::OnceCallback<void(
|
||||
mojom::blink::PointerLockResult,
|
||||
CrossVariantMojoRemote<mojom::blink::PointerLockContextInterfaceBase>)>
|
||||
callback) {
|
||||
widget_base_->RequestMouseLock(has_transient_user_activation,
|
||||
request_unadjusted_movement,
|
||||
std::move(callback));
|
||||
}
|
||||
|
||||
void WebPagePopupImpl::ApplyVisualProperties(
|
||||
const VisualProperties& visual_properties) {
|
||||
widget_base_->UpdateVisualProperties(visual_properties);
|
||||
@ -649,9 +637,7 @@ bool WebPagePopupImpl::WillHandleGestureEvent(const WebGestureEvent& event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WebPagePopupImpl::WillHandleMouseEvent(const WebMouseEvent& event) {
|
||||
return WidgetClient()->WillHandleMouseEvent(event);
|
||||
}
|
||||
void WebPagePopupImpl::WillHandleMouseEvent(const WebMouseEvent& event) {}
|
||||
|
||||
void WebPagePopupImpl::ObserveGestureEventAndResult(
|
||||
const WebGestureEvent& gesture_event,
|
||||
|
@ -122,7 +122,7 @@ class CORE_EXPORT WebPagePopupImpl final : public WebPagePopup,
|
||||
void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) final;
|
||||
WebInputEventResult DispatchBufferedTouchEvents() override;
|
||||
bool WillHandleGestureEvent(const WebGestureEvent& event) override;
|
||||
bool WillHandleMouseEvent(const WebMouseEvent& event) override;
|
||||
void WillHandleMouseEvent(const WebMouseEvent& event) override;
|
||||
void ObserveGestureEventAndResult(
|
||||
const WebGestureEvent& gesture_event,
|
||||
const gfx::Vector2dF& unused_delta,
|
||||
@ -176,13 +176,6 @@ class CORE_EXPORT WebPagePopupImpl final : public WebPagePopup,
|
||||
void ShowVirtualKeyboard() override;
|
||||
void FlushInputProcessedCallback() override;
|
||||
void CancelCompositionForPepper() override;
|
||||
void RequestMouseLock(
|
||||
bool has_transient_user_activation,
|
||||
bool request_unadjusted_movement,
|
||||
base::OnceCallback<
|
||||
void(mojom::blink::PointerLockResult,
|
||||
CrossVariantMojoRemote<
|
||||
mojom::blink::PointerLockContextInterfaceBase>)>) override;
|
||||
|
||||
// PageWidgetEventHandler functions
|
||||
WebInputEventResult HandleCharEvent(const WebKeyboardEvent&) override;
|
||||
|
@ -59,6 +59,7 @@
|
||||
#include "third_party/blink/renderer/core/clipboard/data_transfer.h"
|
||||
#include "third_party/blink/renderer/core/clipboard/system_clipboard.h"
|
||||
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
|
||||
#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
|
||||
#include "third_party/blink/renderer/core/events/drag_event.h"
|
||||
#include "third_party/blink/renderer/core/events/gesture_event.h"
|
||||
#include "third_party/blink/renderer/core/events/keyboard_event.h"
|
||||
@ -91,6 +92,7 @@
|
||||
#include "third_party/blink/renderer/core/page/chrome_client.h"
|
||||
#include "third_party/blink/renderer/core/page/focus_controller.h"
|
||||
#include "third_party/blink/renderer/core/page/page.h"
|
||||
#include "third_party/blink/renderer/core/page/pointer_lock_controller.h"
|
||||
#include "third_party/blink/renderer/core/paint/paint_layer.h"
|
||||
#include "third_party/blink/renderer/core/script/classic_script.h"
|
||||
#include "third_party/blink/renderer/core/scroll/scroll_animator_base.h"
|
||||
@ -122,6 +124,29 @@ const WebInputEvent::Modifiers kEditingModifier = WebInputEvent::kControlKey;
|
||||
|
||||
} // namespace
|
||||
|
||||
class WebPluginContainerImpl::MouseLockLostListener final
|
||||
: public NativeEventListener {
|
||||
public:
|
||||
explicit MouseLockLostListener(WebPluginContainerImpl* plugin_container)
|
||||
: plugin_container_(plugin_container) {}
|
||||
|
||||
void Disconnect() { plugin_container_ = nullptr; }
|
||||
|
||||
void Invoke(ExecutionContext*, Event*) override {
|
||||
if (!plugin_container_)
|
||||
return;
|
||||
plugin_container_->MaybeLostMouseLock();
|
||||
}
|
||||
|
||||
void Trace(Visitor* visitor) const override {
|
||||
visitor->Trace(plugin_container_);
|
||||
NativeEventListener::Trace(visitor);
|
||||
}
|
||||
|
||||
private:
|
||||
Member<WebPluginContainerImpl> plugin_container_;
|
||||
};
|
||||
|
||||
// Public methods --------------------------------------------------------------
|
||||
|
||||
void WebPluginContainerImpl::AttachToLayout() {
|
||||
@ -362,6 +387,50 @@ void WebPluginContainerImpl::CancelFullscreen() {
|
||||
Fullscreen::FullyExitFullscreen(element_->GetDocument());
|
||||
}
|
||||
|
||||
bool WebPluginContainerImpl::IsMouseLocked() {
|
||||
return element_->GetDocument().PointerLockElement() == element_;
|
||||
}
|
||||
|
||||
bool WebPluginContainerImpl::LockMouse(bool request_unadjusted_movement) {
|
||||
if (Page* page = element_->GetDocument().GetPage()) {
|
||||
bool res = page->GetPointerLockController().RequestPointerLock(
|
||||
element_, WTF::Bind(&WebPluginContainerImpl::HandleLockMouseResult,
|
||||
WrapWeakPersistent(this)));
|
||||
if (res) {
|
||||
mouse_lock_lost_listener_ =
|
||||
MakeGarbageCollected<MouseLockLostListener>(this);
|
||||
element_->GetDocument().addEventListener(
|
||||
event_type_names::kPointerlockchange, mouse_lock_lost_listener_,
|
||||
false);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void WebPluginContainerImpl::UnlockMouse() {
|
||||
element_->GetDocument().exitPointerLock();
|
||||
}
|
||||
|
||||
void WebPluginContainerImpl::HandleLockMouseResult(
|
||||
mojom::blink::PointerLockResult result) {
|
||||
web_plugin_->DidReceiveMouseLockResult(
|
||||
result == mojom::blink::PointerLockResult::kSuccess);
|
||||
}
|
||||
|
||||
void WebPluginContainerImpl::MaybeLostMouseLock() {
|
||||
if (!IsMouseLocked()) {
|
||||
if (mouse_lock_lost_listener_) {
|
||||
mouse_lock_lost_listener_->Disconnect();
|
||||
element_->GetDocument().removeEventListener(
|
||||
event_type_names::kPointerlockchange, mouse_lock_lost_listener_,
|
||||
false);
|
||||
mouse_lock_lost_listener_ = nullptr;
|
||||
}
|
||||
web_plugin_->DidLoseMouseLock();
|
||||
}
|
||||
}
|
||||
|
||||
bool WebPluginContainerImpl::SupportsPaginatedPrint() const {
|
||||
return web_plugin_->SupportsPaginatedPrint();
|
||||
}
|
||||
@ -805,6 +874,7 @@ void WebPluginContainerImpl::SetFrameRect(const IntRect& rect) {
|
||||
|
||||
void WebPluginContainerImpl::Trace(Visitor* visitor) const {
|
||||
visitor->Trace(element_);
|
||||
visitor->Trace(mouse_lock_lost_listener_);
|
||||
ExecutionContextClient::Trace(visitor);
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "third_party/blink/public/common/input/web_coalesced_input_event.h"
|
||||
#include "third_party/blink/public/common/input/web_touch_event.h"
|
||||
#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
|
||||
#include "third_party/blink/public/mojom/input/pointer_lock_result.mojom-blink-forward.h"
|
||||
#include "third_party/blink/public/web/web_plugin_container.h"
|
||||
#include "third_party/blink/renderer/core/core_export.h"
|
||||
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
|
||||
@ -134,27 +135,25 @@ class CORE_EXPORT WebPluginContainerImpl final
|
||||
gfx::Point RootFrameToLocalPoint(const gfx::Point&) override;
|
||||
gfx::Point LocalToRootFramePoint(const gfx::Point&) override;
|
||||
bool WasTargetForLastMouseEvent() override;
|
||||
|
||||
// Non-Oilpan, this cannot be null. With Oilpan, it will be
|
||||
// null when in a disposed state, pending finalization during the next GC.
|
||||
WebPlugin* Plugin() override { return web_plugin_; }
|
||||
void SetPlugin(WebPlugin*) override;
|
||||
|
||||
void UsePluginAsFindHandler() override;
|
||||
void ReportFindInPageMatchCount(int identifier,
|
||||
int total,
|
||||
bool final_update) override;
|
||||
void ReportFindInPageSelection(int identifier, int index) override;
|
||||
|
||||
float DeviceScaleFactor() override;
|
||||
float PageScaleFactor() override;
|
||||
float PageZoomFactor() override;
|
||||
|
||||
void SetCcLayer(cc::Layer*, bool prevent_contents_opaque_changes) override;
|
||||
|
||||
void RequestFullscreen() override;
|
||||
bool IsFullscreenElement() const override;
|
||||
void CancelFullscreen() override;
|
||||
bool IsMouseLocked() override;
|
||||
bool LockMouse(bool request_unadjusted_movement) override;
|
||||
void UnlockMouse() override;
|
||||
|
||||
// Printing interface. The plugin can support custom printing
|
||||
// (which means it controls the layout, number of pages etc).
|
||||
@ -194,6 +193,8 @@ class CORE_EXPORT WebPluginContainerImpl final
|
||||
void SetFrameRect(const IntRect&) override;
|
||||
void PropagateFrameRects() override { ReportGeometry(); }
|
||||
|
||||
void MaybeLostMouseLock();
|
||||
|
||||
protected:
|
||||
void ParentVisibleChanged() override;
|
||||
|
||||
@ -221,6 +222,8 @@ class CORE_EXPORT WebPluginContainerImpl final
|
||||
void HandleTouchEvent(TouchEvent&);
|
||||
void HandleGestureEvent(GestureEvent&);
|
||||
|
||||
void HandleLockMouseResult(mojom::blink::PointerLockResult result);
|
||||
|
||||
void SynthesizeMouseEventIfPossible(TouchEvent&);
|
||||
|
||||
void FocusPlugin();
|
||||
@ -230,8 +233,10 @@ class CORE_EXPORT WebPluginContainerImpl final
|
||||
IntRect& unobscured_rect);
|
||||
|
||||
friend class WebPluginContainerTest;
|
||||
class MouseLockLostListener;
|
||||
|
||||
Member<HTMLPlugInElement> element_;
|
||||
Member<MouseLockLostListener> mouse_lock_lost_listener_;
|
||||
WebPlugin* web_plugin_;
|
||||
cc::Layer* layer_;
|
||||
TouchEventRequestType touch_event_request_type_;
|
||||
|
@ -2345,11 +2345,7 @@ WebInputEventResult WebViewImpl::HandleInputEvent(
|
||||
&CurrentInputEvent::current_input_event_, &input_event);
|
||||
UIEventWithKeyState::ClearNewTabModifierSetFromIsolatedWorld();
|
||||
|
||||
bool is_pointer_locked = false;
|
||||
if (WebWidgetClient* client = widget->Client())
|
||||
is_pointer_locked = client->IsPointerLocked();
|
||||
|
||||
if (is_pointer_locked &&
|
||||
if (GetPage()->GetPointerLockController().IsPointerLocked() &&
|
||||
WebInputEvent::IsMouseEventType(input_event.GetType())) {
|
||||
widget->PointerLockMouseEvent(coalesced_event);
|
||||
return WebInputEventResult::kHandledSystem;
|
||||
|
@ -596,23 +596,6 @@ WebFrameWidgetBase::GetAssociatedFrameWidgetHost() const {
|
||||
return frame_widget_host_.get();
|
||||
}
|
||||
|
||||
void WebFrameWidgetBase::DidAcquirePointerLock() {
|
||||
GetPage()->GetPointerLockController().DidAcquirePointerLock();
|
||||
|
||||
LocalFrame* focusedFrame = FocusedLocalFrameInWidget();
|
||||
if (focusedFrame) {
|
||||
focusedFrame->GetEventHandler().ReleaseMousePointerCapture();
|
||||
}
|
||||
}
|
||||
|
||||
void WebFrameWidgetBase::DidNotAcquirePointerLock() {
|
||||
GetPage()->GetPointerLockController().DidNotAcquirePointerLock();
|
||||
}
|
||||
|
||||
void WebFrameWidgetBase::DidLosePointerLock() {
|
||||
GetPage()->GetPointerLockController().DidLosePointerLock();
|
||||
}
|
||||
|
||||
void WebFrameWidgetBase::RequestDecode(
|
||||
const PaintImage& image,
|
||||
base::OnceCallback<void(bool)> callback) {
|
||||
@ -972,6 +955,12 @@ void WebFrameWidgetBase::PointerLockMouseEvent(
|
||||
event_type);
|
||||
}
|
||||
}
|
||||
bool WebFrameWidgetBase::IsPointerLocked() {
|
||||
if (GetPage()) {
|
||||
return GetPage()->GetPointerLockController().IsPointerLocked();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void WebFrameWidgetBase::ShowContextMenu(
|
||||
ui::mojom::blink::MenuSourceType source_type,
|
||||
@ -1068,11 +1057,10 @@ bool WebFrameWidgetBase::WillHandleGestureEvent(const WebGestureEvent& event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WebFrameWidgetBase::WillHandleMouseEvent(const WebMouseEvent& event) {
|
||||
void WebFrameWidgetBase::WillHandleMouseEvent(const WebMouseEvent& event) {
|
||||
possible_drag_event_info_.source = ui::mojom::blink::DragEventSource::kMouse;
|
||||
possible_drag_event_info_.location =
|
||||
gfx::Point(event.PositionInScreen().x(), event.PositionInScreen().y());
|
||||
return Client()->WillHandleMouseEvent(event);
|
||||
}
|
||||
|
||||
void WebFrameWidgetBase::ObserveGestureEventAndResult(
|
||||
@ -1179,13 +1167,20 @@ void WebFrameWidgetBase::CancelCompositionForPepper() {
|
||||
void WebFrameWidgetBase::RequestMouseLock(
|
||||
bool has_transient_user_activation,
|
||||
bool request_unadjusted_movement,
|
||||
base::OnceCallback<void(
|
||||
mojom::blink::PointerLockResult,
|
||||
CrossVariantMojoRemote<mojom::blink::PointerLockContextInterfaceBase>)>
|
||||
callback) {
|
||||
widget_base_->RequestMouseLock(has_transient_user_activation,
|
||||
request_unadjusted_movement,
|
||||
std::move(callback));
|
||||
mojom::blink::WidgetInputHandlerHost::RequestMouseLockCallback callback) {
|
||||
mojom::blink::WidgetInputHandlerHost* host =
|
||||
widget_base_->widget_input_handler_manager()->GetWidgetInputHandlerHost();
|
||||
|
||||
// If we don't have a host just leave the callback uncalled. This simulates
|
||||
// the browser indefinitely postponing the mouse request which is valid.
|
||||
// Note that |callback| is not a mojo bound callback (until it is passed
|
||||
// into the mojo interface) and can be destructed without invoking the
|
||||
// callback. It does share the same signature as the mojo definition
|
||||
// for simplicity.
|
||||
if (host) {
|
||||
host->RequestMouseLock(has_transient_user_activation,
|
||||
request_unadjusted_movement, std::move(callback));
|
||||
}
|
||||
}
|
||||
|
||||
void WebFrameWidgetBase::ApplyVisualProperties(
|
||||
@ -2313,4 +2308,9 @@ KURL WebFrameWidgetBase::GetURLForDebugTrace() {
|
||||
return {};
|
||||
}
|
||||
|
||||
void WebFrameWidgetBase::ReleaseMouseLockAndPointerCaptureForTesting() {
|
||||
GetPage()->GetPointerLockController().ExitPointerLock();
|
||||
MouseCaptureLost();
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
|
@ -236,6 +236,11 @@ class CORE_EXPORT WebFrameWidgetBase
|
||||
gfx::PointF DIPsToBlinkSpace(const gfx::PointF& point) override;
|
||||
gfx::Point DIPsToRoundedBlinkSpace(const gfx::Point& point) override;
|
||||
float DIPsToBlinkSpace(float scalar) override;
|
||||
void RequestMouseLock(
|
||||
bool has_transient_user_activation,
|
||||
bool request_unadjusted_movement,
|
||||
mojom::blink::WidgetInputHandlerHost::RequestMouseLockCallback callback)
|
||||
override;
|
||||
|
||||
// WebFrameWidget implementation.
|
||||
WebLocalFrame* LocalRoot() const override;
|
||||
@ -267,6 +272,7 @@ class CORE_EXPORT WebFrameWidgetBase
|
||||
void ClearEditCommands() override;
|
||||
bool IsPasting() override;
|
||||
bool HandlingSelectRange() override;
|
||||
void ReleaseMouseLockAndPointerCaptureForTesting() override;
|
||||
|
||||
// Called when a drag-n-drop operation should begin.
|
||||
void StartDragging(const WebDragData&,
|
||||
@ -288,9 +294,6 @@ class CORE_EXPORT WebFrameWidgetBase
|
||||
const cc::LayerTreeSettings* settings) override;
|
||||
void Close(
|
||||
scoped_refptr<base::SingleThreadTaskRunner> cleanup_runner) override;
|
||||
void DidAcquirePointerLock() override;
|
||||
void DidNotAcquirePointerLock() override;
|
||||
void DidLosePointerLock() override;
|
||||
void SetCompositorVisible(bool visible) override;
|
||||
void SetCursor(const ui::Cursor& cursor) override;
|
||||
bool HandlingInputEvent() override;
|
||||
@ -304,13 +307,6 @@ class CORE_EXPORT WebFrameWidgetBase
|
||||
void SetFocus(bool focus) override;
|
||||
void FlushInputProcessedCallback() override;
|
||||
void CancelCompositionForPepper() override;
|
||||
void RequestMouseLock(
|
||||
bool has_transient_user_activation,
|
||||
bool request_unadjusted_movement,
|
||||
base::OnceCallback<
|
||||
void(mojom::blink::PointerLockResult,
|
||||
CrossVariantMojoRemote<
|
||||
mojom::blink::PointerLockContextInterfaceBase>)>) override;
|
||||
void ApplyVisualProperties(
|
||||
const VisualProperties& visual_properties) override;
|
||||
bool IsFullscreenGranted() override;
|
||||
@ -340,7 +336,7 @@ class CORE_EXPORT WebFrameWidgetBase
|
||||
void WillBeginMainFrame() override;
|
||||
void FocusChangeComplete() override;
|
||||
bool WillHandleGestureEvent(const WebGestureEvent& event) override;
|
||||
bool WillHandleMouseEvent(const WebMouseEvent& event) override;
|
||||
void WillHandleMouseEvent(const WebMouseEvent& event) override;
|
||||
void ObserveGestureEventAndResult(
|
||||
const WebGestureEvent& gesture_event,
|
||||
const gfx::Vector2dF& unused_delta,
|
||||
@ -602,6 +598,7 @@ class CORE_EXPORT WebFrameWidgetBase
|
||||
|
||||
// Helper function to process events while pointer locked.
|
||||
void PointerLockMouseEvent(const WebCoalescedInputEvent&);
|
||||
bool IsPointerLocked();
|
||||
|
||||
virtual PageWidgetEventHandler* GetPageWidgetEventHandler() = 0;
|
||||
|
||||
|
@ -501,8 +501,7 @@ WebInputEventResult WebFrameWidgetImpl::HandleInputEvent(
|
||||
base::AutoReset<const WebInputEvent*> current_event_change(
|
||||
&CurrentInputEvent::current_input_event_, &input_event);
|
||||
|
||||
DCHECK(Client());
|
||||
if (Client()->IsPointerLocked() &&
|
||||
if (IsPointerLocked() &&
|
||||
WebInputEvent::IsMouseEventType(input_event.GetType())) {
|
||||
PointerLockMouseEvent(coalesced_event);
|
||||
return WebInputEventResult::kHandledSystem;
|
||||
|
@ -431,21 +431,6 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
|
||||
|
||||
virtual bool IsSVGImageChromeClient() const { return false; }
|
||||
|
||||
virtual bool RequestPointerLock(LocalFrame*,
|
||||
WebWidgetClient::PointerLockCallback callback,
|
||||
bool request_unadjusted_movement) {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool RequestPointerLockChange(
|
||||
LocalFrame*,
|
||||
WebWidgetClient::PointerLockCallback callback,
|
||||
bool request_unadjusted_movement) {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void RequestPointerUnlock(LocalFrame*) {}
|
||||
|
||||
virtual IntSize MinimumWindowSize() const { return IntSize(100, 100); }
|
||||
|
||||
virtual bool IsChromeClientImpl() const { return false; }
|
||||
|
@ -1031,36 +1031,6 @@ void ChromeClientImpl::SetTouchAction(LocalFrame* frame,
|
||||
widget->ProcessTouchAction(touch_action);
|
||||
}
|
||||
|
||||
bool ChromeClientImpl::RequestPointerLock(
|
||||
LocalFrame* frame,
|
||||
WebWidgetClient::PointerLockCallback callback,
|
||||
bool request_unadjusted_movement) {
|
||||
return WebLocalFrameImpl::FromFrame(frame)
|
||||
->LocalRootFrameWidget()
|
||||
->Client()
|
||||
->RequestPointerLock(WebLocalFrameImpl::FromFrame(frame),
|
||||
std::move(callback), request_unadjusted_movement);
|
||||
}
|
||||
|
||||
bool ChromeClientImpl::RequestPointerLockChange(
|
||||
LocalFrame* frame,
|
||||
WebWidgetClient::PointerLockCallback callback,
|
||||
bool request_unadjusted_movement) {
|
||||
return WebLocalFrameImpl::FromFrame(frame)
|
||||
->LocalRootFrameWidget()
|
||||
->Client()
|
||||
->RequestPointerLockChange(WebLocalFrameImpl::FromFrame(frame),
|
||||
std::move(callback),
|
||||
request_unadjusted_movement);
|
||||
}
|
||||
|
||||
void ChromeClientImpl::RequestPointerUnlock(LocalFrame* frame) {
|
||||
return WebLocalFrameImpl::FromFrame(frame)
|
||||
->LocalRootFrameWidget()
|
||||
->Client()
|
||||
->RequestPointerUnlock();
|
||||
}
|
||||
|
||||
void ChromeClientImpl::DidAssociateFormControlsAfterLoad(LocalFrame* frame) {
|
||||
if (auto* fill_client = AutofillClientFromFrame(frame))
|
||||
fill_client->DidAssociateFormControlsDynamically();
|
||||
|
@ -235,14 +235,6 @@ class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
|
||||
const String& dialog_message,
|
||||
Document::PageDismissalType) const override;
|
||||
|
||||
bool RequestPointerLock(LocalFrame*,
|
||||
WebWidgetClient::PointerLockCallback,
|
||||
bool) override;
|
||||
bool RequestPointerLockChange(LocalFrame*,
|
||||
WebWidgetClient::PointerLockCallback,
|
||||
bool) override;
|
||||
void RequestPointerUnlock(LocalFrame*) override;
|
||||
|
||||
// AutofillClient pass throughs:
|
||||
void DidAssociateFormControlsAfterLoad(LocalFrame*) override;
|
||||
void HandleKeyboardEventOnTextField(HTMLInputElement&,
|
||||
|
@ -33,18 +33,39 @@
|
||||
#include "third_party/blink/renderer/core/dom/dom_exception.h"
|
||||
#include "third_party/blink/renderer/core/dom/element.h"
|
||||
#include "third_party/blink/renderer/core/dom/events/event.h"
|
||||
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
|
||||
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
|
||||
#include "third_party/blink/renderer/core/input/event_handler.h"
|
||||
#include "third_party/blink/renderer/core/inspector/console_message.h"
|
||||
#include "third_party/blink/renderer/core/page/chrome_client.h"
|
||||
#include "third_party/blink/renderer/core/page/focus_controller.h"
|
||||
#include "third_party/blink/renderer/core/page/page.h"
|
||||
#include "third_party/blink/renderer/platform/heap/heap.h"
|
||||
#include "third_party/blink/renderer/platform/widget/frame_widget.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
PointerLockController::PointerLockController(Page* page)
|
||||
: page_(page), lock_pending_(false) {}
|
||||
|
||||
bool PointerLockController::RequestPointerLock(Element* target,
|
||||
ResultCallback callback) {
|
||||
if (!target || !target->isConnected() ||
|
||||
document_of_removed_element_while_waiting_for_unlock_ || element_) {
|
||||
return false;
|
||||
}
|
||||
LocalDOMWindow* window = To<LocalDOMWindow>(target->GetExecutionContext());
|
||||
window->GetFrame()->GetWidgetForLocalRoot()->RequestMouseLock(
|
||||
LocalFrame::HasTransientUserActivation(window->GetFrame()),
|
||||
/*unadjusted_movement_requested=*/false,
|
||||
WTF::Bind(&PointerLockController::LockRequestCallback,
|
||||
WrapWeakPersistent(this), std::move(callback),
|
||||
/*unadjusted_movement_requested=*/false));
|
||||
lock_pending_ = true;
|
||||
element_ = target;
|
||||
return true;
|
||||
}
|
||||
|
||||
ScriptPromise PointerLockController::RequestPointerLock(
|
||||
ScriptPromiseResolver* resolver,
|
||||
Element* target,
|
||||
@ -98,20 +119,23 @@ ScriptPromise PointerLockController::RequestPointerLock(
|
||||
"element that currently holds the lock.");
|
||||
return promise;
|
||||
}
|
||||
|
||||
// Attempt to change options if necessary.
|
||||
if (unadjusted_movement_requested != current_unadjusted_movement_setting_) {
|
||||
if (!page_->GetChromeClient().RequestPointerLockChange(
|
||||
window->GetFrame(),
|
||||
WTF::Bind(&PointerLockController::ChangeLockRequestCallback,
|
||||
WrapWeakPersistent(this), WrapWeakPersistent(target),
|
||||
WrapPersistent(resolver),
|
||||
unadjusted_movement_requested),
|
||||
unadjusted_movement_requested)) {
|
||||
if (!mouse_lock_context_.is_bound() || lock_pending_) {
|
||||
EnqueueEvent(event_type_names::kPointerlockerror, target);
|
||||
exception_state.ThrowDOMException(
|
||||
DOMExceptionCode::kInUseAttributeError, "Pointer lock pending.");
|
||||
return promise;
|
||||
}
|
||||
|
||||
mouse_lock_context_->RequestMouseLockChange(
|
||||
unadjusted_movement_requested,
|
||||
WTF::Bind(
|
||||
&PointerLockController::ChangeLockRequestCallback,
|
||||
WrapWeakPersistent(this), WrapWeakPersistent(target),
|
||||
WTF::Bind(&PointerLockController::ProcessResultScriptPromise,
|
||||
WrapPersistent(resolver)),
|
||||
unadjusted_movement_requested));
|
||||
return promise;
|
||||
}
|
||||
|
||||
@ -120,18 +144,17 @@ ScriptPromise PointerLockController::RequestPointerLock(
|
||||
resolver->Resolve();
|
||||
|
||||
// Subsequent steps are handled in the browser process.
|
||||
} else if (page_->GetChromeClient().RequestPointerLock(
|
||||
window->GetFrame(),
|
||||
WTF::Bind(&PointerLockController::LockRequestCallback,
|
||||
WrapWeakPersistent(this), WrapPersistent(resolver),
|
||||
unadjusted_movement_requested),
|
||||
unadjusted_movement_requested)) {
|
||||
} else {
|
||||
window->GetFrame()->GetWidgetForLocalRoot()->RequestMouseLock(
|
||||
LocalFrame::HasTransientUserActivation(window->GetFrame()),
|
||||
unadjusted_movement_requested,
|
||||
WTF::Bind(&PointerLockController::LockRequestCallback,
|
||||
WrapWeakPersistent(this),
|
||||
WTF::Bind(&PointerLockController::ProcessResultScriptPromise,
|
||||
WrapPersistent(resolver)),
|
||||
unadjusted_movement_requested));
|
||||
lock_pending_ = true;
|
||||
element_ = target;
|
||||
} else {
|
||||
EnqueueEvent(event_type_names::kPointerlockerror, target);
|
||||
exception_state.ThrowDOMException(DOMExceptionCode::kInUseAttributeError,
|
||||
"Pointer lock pending.");
|
||||
}
|
||||
|
||||
return promise;
|
||||
@ -139,21 +162,41 @@ ScriptPromise PointerLockController::RequestPointerLock(
|
||||
|
||||
void PointerLockController::ChangeLockRequestCallback(
|
||||
Element* target,
|
||||
ScriptPromiseResolver* resolver,
|
||||
ResultCallback callback,
|
||||
bool unadjusted_movement_requested,
|
||||
mojom::blink::PointerLockResult result) {
|
||||
if (result == mojom::blink::PointerLockResult::kSuccess)
|
||||
element_ = target;
|
||||
|
||||
LockRequestCallback(resolver, unadjusted_movement_requested, result);
|
||||
ProcessResult(std::move(callback), unadjusted_movement_requested, result);
|
||||
}
|
||||
|
||||
void PointerLockController::LockRequestCallback(
|
||||
ScriptPromiseResolver* resolver,
|
||||
ResultCallback callback,
|
||||
bool unadjusted_movement_requested,
|
||||
mojom::blink::PointerLockResult result,
|
||||
mojo::PendingRemote<blink::mojom::blink::PointerLockContext> context) {
|
||||
if (element_ && context) {
|
||||
mouse_lock_context_.Bind(std::move(context),
|
||||
element_->GetExecutionContext()->GetTaskRunner(
|
||||
TaskType::kUserInteraction));
|
||||
// The browser might unlock the mouse for many reasons including closing
|
||||
// the tab, the user hitting esc, the page losing focus, and more.
|
||||
mouse_lock_context_.set_disconnect_handler(WTF::Bind(
|
||||
&PointerLockController::ExitPointerLock, WrapWeakPersistent(this)));
|
||||
}
|
||||
ProcessResult(std::move(callback), unadjusted_movement_requested, result);
|
||||
if (result == mojom::blink::PointerLockResult::kSuccess) {
|
||||
DidAcquirePointerLock();
|
||||
} else {
|
||||
DidNotAcquirePointerLock();
|
||||
}
|
||||
}
|
||||
|
||||
void PointerLockController::ProcessResultScriptPromise(
|
||||
ScriptPromiseResolver* resolver,
|
||||
mojom::blink::PointerLockResult result) {
|
||||
if (result == mojom::blink::PointerLockResult::kSuccess) {
|
||||
current_unadjusted_movement_setting_ = unadjusted_movement_requested;
|
||||
resolver->Resolve();
|
||||
return;
|
||||
}
|
||||
@ -161,6 +204,15 @@ void PointerLockController::LockRequestCallback(
|
||||
RejectIfPromiseEnabled(resolver, exception);
|
||||
}
|
||||
|
||||
void PointerLockController::ProcessResult(
|
||||
ResultCallback callback,
|
||||
bool unadjusted_movement_requested,
|
||||
mojom::blink::PointerLockResult result) {
|
||||
if (result == mojom::blink::PointerLockResult::kSuccess)
|
||||
current_unadjusted_movement_setting_ = unadjusted_movement_requested;
|
||||
std::move(callback).Run(result);
|
||||
}
|
||||
|
||||
DOMException* PointerLockController::ConvertResultToException(
|
||||
mojom::blink::PointerLockResult result) {
|
||||
switch (result) {
|
||||
@ -210,16 +262,29 @@ void PointerLockController::RejectIfPromiseEnabled(
|
||||
}
|
||||
}
|
||||
|
||||
void PointerLockController::RequestPointerUnlock() {
|
||||
return page_->GetChromeClient().RequestPointerUnlock(
|
||||
element_->GetDocument().GetFrame());
|
||||
void PointerLockController::ExitPointerLock() {
|
||||
Document* pointer_lock_document =
|
||||
element_ ? &element_->GetDocument()
|
||||
: document_of_removed_element_while_waiting_for_unlock_.Get();
|
||||
EnqueueEvent(event_type_names::kPointerlockchange, pointer_lock_document);
|
||||
|
||||
// Set the last mouse position back the locked position.
|
||||
if (pointer_lock_document && pointer_lock_document->GetFrame()) {
|
||||
pointer_lock_document->GetFrame()
|
||||
->GetEventHandler()
|
||||
.ResetMousePositionForPointerUnlock();
|
||||
}
|
||||
|
||||
ClearElement();
|
||||
document_of_removed_element_while_waiting_for_unlock_ = nullptr;
|
||||
mouse_lock_context_.reset();
|
||||
}
|
||||
|
||||
void PointerLockController::ElementRemoved(Element* element) {
|
||||
if (element_ == element) {
|
||||
document_of_removed_element_while_waiting_for_unlock_ =
|
||||
&element_->GetDocument();
|
||||
RequestPointerUnlock();
|
||||
ExitPointerLock();
|
||||
// Set element null immediately to block any future interaction with it
|
||||
// including mouse events received before the unlock completes.
|
||||
ClearElement();
|
||||
@ -228,7 +293,7 @@ void PointerLockController::ElementRemoved(Element* element) {
|
||||
|
||||
void PointerLockController::DocumentDetached(Document* document) {
|
||||
if (element_ && element_->GetDocument() == document) {
|
||||
RequestPointerUnlock();
|
||||
ExitPointerLock();
|
||||
ClearElement();
|
||||
}
|
||||
}
|
||||
@ -237,6 +302,10 @@ bool PointerLockController::LockPending() const {
|
||||
return lock_pending_;
|
||||
}
|
||||
|
||||
bool PointerLockController::IsPointerLocked() const {
|
||||
return mouse_lock_context_.is_bound();
|
||||
}
|
||||
|
||||
Element* PointerLockController::GetElement() const {
|
||||
return element_.Get();
|
||||
}
|
||||
@ -252,6 +321,19 @@ void PointerLockController::DidAcquirePointerLock() {
|
||||
pointer_lock_screen_position_ = frame->LocalFrameRoot()
|
||||
.GetEventHandler()
|
||||
.LastKnownMouseScreenPosition();
|
||||
LocalFrame* focused_frame =
|
||||
frame->GetPage()->GetFocusController().FocusedFrame();
|
||||
if (focused_frame) {
|
||||
focused_frame->GetEventHandler().ReleaseMousePointerCapture();
|
||||
}
|
||||
|
||||
// Mouse Lock removes the system cursor and provides all mouse motion as
|
||||
// .movementX/Y values on events all sent to a fixed target. This requires
|
||||
// content to specifically request the mode to be entered.
|
||||
// Mouse Capture is implicitly given for the duration of a drag event, and
|
||||
// sends all mouse events to the initial target of the drag.
|
||||
// If Lock is entered it supersedes any in progress Capture.
|
||||
frame->GetWidgetForLocalRoot()->MouseCaptureLost();
|
||||
}
|
||||
}
|
||||
|
||||
@ -260,23 +342,6 @@ void PointerLockController::DidNotAcquirePointerLock() {
|
||||
ClearElement();
|
||||
}
|
||||
|
||||
void PointerLockController::DidLosePointerLock() {
|
||||
Document* pointer_lock_document =
|
||||
element_ ? &element_->GetDocument()
|
||||
: document_of_removed_element_while_waiting_for_unlock_.Get();
|
||||
EnqueueEvent(event_type_names::kPointerlockchange, pointer_lock_document);
|
||||
|
||||
// Set the last mouse position back the locked position.
|
||||
if (pointer_lock_document && pointer_lock_document->GetFrame()) {
|
||||
pointer_lock_document->GetFrame()
|
||||
->GetEventHandler()
|
||||
.ResetMousePositionForPointerUnlock();
|
||||
}
|
||||
|
||||
ClearElement();
|
||||
document_of_removed_element_while_waiting_for_unlock_ = nullptr;
|
||||
}
|
||||
|
||||
void PointerLockController::DispatchLockedMouseEvent(
|
||||
const WebMouseEvent& event,
|
||||
const Vector<WebMouseEvent>& coalesced_events,
|
||||
@ -336,6 +401,7 @@ void PointerLockController::Trace(Visitor* visitor) const {
|
||||
visitor->Trace(page_);
|
||||
visitor->Trace(element_);
|
||||
visitor->Trace(document_of_removed_element_while_waiting_for_unlock_);
|
||||
visitor->Trace(mouse_lock_context_);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "third_party/blink/public/mojom/input/pointer_lock_context.mojom-blink.h"
|
||||
#include "third_party/blink/public/mojom/input/pointer_lock_result.mojom-blink-forward.h"
|
||||
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
|
||||
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
|
||||
@ -35,6 +36,7 @@
|
||||
#include "third_party/blink/renderer/platform/bindings/script_state.h"
|
||||
#include "third_party/blink/renderer/platform/geometry/float_point.h"
|
||||
#include "third_party/blink/renderer/platform/heap/handle.h"
|
||||
#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
|
||||
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
|
||||
|
||||
namespace blink {
|
||||
@ -52,19 +54,23 @@ class CORE_EXPORT PointerLockController final
|
||||
public:
|
||||
explicit PointerLockController(Page*);
|
||||
|
||||
using ResultCallback =
|
||||
base::OnceCallback<void(mojom::blink::PointerLockResult)>;
|
||||
bool RequestPointerLock(Element* target, ResultCallback callback);
|
||||
|
||||
ScriptPromise RequestPointerLock(ScriptPromiseResolver* resolver,
|
||||
Element* target,
|
||||
ExceptionState& exception_state,
|
||||
const PointerLockOptions* options = nullptr);
|
||||
void RequestPointerUnlock();
|
||||
void ExitPointerLock();
|
||||
void ElementRemoved(Element*);
|
||||
void DocumentDetached(Document*);
|
||||
bool LockPending() const;
|
||||
bool IsPointerLocked() const;
|
||||
Element* GetElement() const;
|
||||
|
||||
void DidAcquirePointerLock();
|
||||
void DidNotAcquirePointerLock();
|
||||
void DidLosePointerLock();
|
||||
void DispatchLockedMouseEvent(const WebMouseEvent&,
|
||||
const Vector<WebMouseEvent>& coalesced_events,
|
||||
const Vector<WebMouseEvent>& predicted_events,
|
||||
@ -83,22 +89,34 @@ class CORE_EXPORT PointerLockController final
|
||||
void EnqueueEvent(const AtomicString& type, Element*);
|
||||
void EnqueueEvent(const AtomicString& type, Document*);
|
||||
void ChangeLockRequestCallback(Element* target,
|
||||
ScriptPromiseResolver* resolver,
|
||||
ResultCallback callback,
|
||||
bool unadjusted_movement_requested,
|
||||
mojom::blink::PointerLockResult result);
|
||||
void LockRequestCallback(ScriptPromiseResolver* resolver,
|
||||
bool unadjusted_movement_requested,
|
||||
mojom::blink::PointerLockResult result);
|
||||
DOMException* ConvertResultToException(
|
||||
void LockRequestCallback(
|
||||
ResultCallback callback,
|
||||
bool unadjusted_movement_requested,
|
||||
mojom::blink::PointerLockResult result,
|
||||
mojo::PendingRemote<blink::mojom::blink::PointerLockContext> context);
|
||||
|
||||
void ProcessResult(ResultCallback callback,
|
||||
bool unadjusted_movement_requested,
|
||||
mojom::blink::PointerLockResult result);
|
||||
|
||||
static void ProcessResultScriptPromise(
|
||||
ScriptPromiseResolver* resolver,
|
||||
mojom::blink::PointerLockResult result);
|
||||
void RejectIfPromiseEnabled(ScriptPromiseResolver* resolver,
|
||||
DOMException* exception);
|
||||
static DOMException* ConvertResultToException(
|
||||
mojom::blink::PointerLockResult result);
|
||||
static void RejectIfPromiseEnabled(ScriptPromiseResolver* resolver,
|
||||
DOMException* exception);
|
||||
|
||||
Member<Page> page_;
|
||||
bool lock_pending_;
|
||||
Member<Element> element_;
|
||||
Member<Document> document_of_removed_element_while_waiting_for_unlock_;
|
||||
|
||||
HeapMojoRemote<mojom::blink::PointerLockContext> mouse_lock_context_{nullptr};
|
||||
|
||||
// Store the locked position so that the event position keeps unchanged when
|
||||
// in locked states. These values only get set when entering lock states.
|
||||
FloatPoint pointer_lock_position_;
|
||||
|
@ -31,7 +31,7 @@ class StubWidgetBaseClient : public WidgetBaseClient {
|
||||
}
|
||||
bool SupportsBufferedTouchEvents() override { return false; }
|
||||
bool WillHandleGestureEvent(const WebGestureEvent&) override { return false; }
|
||||
bool WillHandleMouseEvent(const WebMouseEvent&) override { return false; }
|
||||
void WillHandleMouseEvent(const WebMouseEvent&) override {}
|
||||
void ObserveGestureEventAndResult(const WebGestureEvent&,
|
||||
const gfx::Vector2dF&,
|
||||
const cc::OverscrollBehavior&,
|
||||
|
@ -202,6 +202,15 @@ class PLATFORM_EXPORT FrameWidget
|
||||
virtual gfx::PointF DIPsToBlinkSpace(const gfx::PointF& point) = 0;
|
||||
virtual gfx::Point DIPsToRoundedBlinkSpace(const gfx::Point& point) = 0;
|
||||
virtual float DIPsToBlinkSpace(float scalar) = 0;
|
||||
|
||||
virtual void RequestMouseLock(
|
||||
bool has_transient_user_activation,
|
||||
bool request_unadjusted_movement,
|
||||
mojom::blink::WidgetInputHandlerHost::RequestMouseLockCallback
|
||||
callback) = 0;
|
||||
|
||||
// Mouse capture has been lost.
|
||||
virtual void MouseCaptureLost() = 0;
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
|
@ -366,7 +366,7 @@ void WidgetBaseInputHandler::HandleInputEvent(
|
||||
mouse_event.PositionInWidget().x(), "y",
|
||||
mouse_event.PositionInWidget().y());
|
||||
|
||||
prevent_default = widget_->client()->WillHandleMouseEvent(mouse_event);
|
||||
widget_->client()->WillHandleMouseEvent(mouse_event);
|
||||
|
||||
// Reset the last known cursor if mouse has left this widget. So next
|
||||
// time that the mouse enters we always set the cursor accordingly.
|
||||
|
@ -1138,7 +1138,10 @@ void WidgetBase::UpdateSelectionBounds() {
|
||||
}
|
||||
|
||||
void WidgetBase::MouseCaptureLost() {
|
||||
client_->MouseCaptureLost();
|
||||
FrameWidget* frame_widget = client_->FrameWidget();
|
||||
if (!frame_widget)
|
||||
return;
|
||||
frame_widget->MouseCaptureLost();
|
||||
}
|
||||
|
||||
void WidgetBase::SetEditCommandsForNextKeyEvent(
|
||||
@ -1313,31 +1316,6 @@ void WidgetBase::OnImeEventGuardFinish(ImeEventGuard* guard) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void WidgetBase::RequestMouseLock(
|
||||
bool has_transient_user_activation,
|
||||
bool request_unadjusted_movement,
|
||||
base::OnceCallback<void(
|
||||
blink::mojom::PointerLockResult,
|
||||
CrossVariantMojoRemote<mojom::blink::PointerLockContextInterfaceBase>)>
|
||||
callback) {
|
||||
if (mojom::blink::WidgetInputHandlerHost* host =
|
||||
widget_input_handler_manager_->GetWidgetInputHandlerHost()) {
|
||||
host->RequestMouseLock(
|
||||
has_transient_user_activation, request_unadjusted_movement,
|
||||
base::BindOnce(
|
||||
[](base::OnceCallback<void(
|
||||
blink::mojom::PointerLockResult,
|
||||
CrossVariantMojoRemote<
|
||||
mojom::blink::PointerLockContextInterfaceBase>)>
|
||||
callback,
|
||||
blink::mojom::PointerLockResult result,
|
||||
mojo::PendingRemote<mojom::blink::PointerLockContext> context) {
|
||||
std::move(callback).Run(result, std::move(context));
|
||||
},
|
||||
std::move(callback)));
|
||||
}
|
||||
}
|
||||
|
||||
void WidgetBase::UpdateSurfaceAndScreenInfo(
|
||||
const viz::LocalSurfaceId& new_local_surface_id,
|
||||
const gfx::Rect& compositor_viewport_pixel_rect,
|
||||
|
@ -219,13 +219,6 @@ class PLATFORM_EXPORT WidgetBase : public mojom::blink::Widget,
|
||||
void set_handling_select_range(bool value) { handling_select_range_ = value; }
|
||||
bool handling_select_range() const { return handling_select_range_; }
|
||||
|
||||
void RequestMouseLock(
|
||||
bool has_transient_user_activation,
|
||||
bool request_unadjusted_movement,
|
||||
base::OnceCallback<
|
||||
void(blink::mojom::PointerLockResult,
|
||||
CrossVariantMojoRemote<
|
||||
mojom::blink::PointerLockContextInterfaceBase>)> callback);
|
||||
bool ComputePreferCompositingToLCDText();
|
||||
|
||||
const viz::LocalSurfaceId& local_surface_id_from_parent() {
|
||||
|
@ -121,7 +121,7 @@ class WidgetBaseClient {
|
||||
|
||||
virtual void DidHandleKeyEvent() {}
|
||||
virtual bool WillHandleGestureEvent(const WebGestureEvent& event) = 0;
|
||||
virtual bool WillHandleMouseEvent(const WebMouseEvent& event) = 0;
|
||||
virtual void WillHandleMouseEvent(const WebMouseEvent& event) = 0;
|
||||
virtual void ObserveGestureEventAndResult(
|
||||
const WebGestureEvent& gesture_event,
|
||||
const gfx::Vector2dF& unused_delta,
|
||||
@ -135,9 +135,6 @@ class WidgetBaseClient {
|
||||
// Called to inform the Widget of the mouse cursor's visibility.
|
||||
virtual void SetCursorVisibilityState(bool is_visible) {}
|
||||
|
||||
// Mouse capture has been lost.
|
||||
virtual void MouseCaptureLost() {}
|
||||
|
||||
// The FrameWidget interface if this is a FrameWidget.
|
||||
virtual blink::FrameWidget* FrameWidget() { return nullptr; }
|
||||
|
||||
|
Reference in New Issue
Block a user