This is gated behind a new pref: dom.pointer-lock.reset-to-center-from-parent.enabled. The patch preserves the original behavior as much as possible when the pref is off. There are some changes that affect both code paths, but they are minor and should not affect the main logic. Here are some major change when the pref is enabled: - Pointer recentering and computation of the center point are now handled in the parent process. - Locking native pointer is initiated from parent process as well. - When a remote target requests pointer lock, the parent process captures the mouse on the top-level browser element. This is necessary because the center of the chrome window may not correspond to the web page (for example, when a DevTools panel is open and resized to be very large). - This patch introduces an optimization that recenters the pointer only when it moves within a 25% boundary buffer near the edge of the window, reducing the number of recentering operations. Since each platform now uses a native API to "lock" the pointer, we do not need to worry as much about the pointer escaping pointer lock by moving outside the browser window at high speed. Differential Revision: https://phabricator.services.mozilla.com/D296321
104 lines
3.6 KiB
C++
104 lines
3.6 KiB
C++
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef mozilla_PointerLockManager_h
|
|
#define mozilla_PointerLockManager_h
|
|
|
|
#include "mozilla/AlreadyAddRefed.h"
|
|
#include "mozilla/RefPtr.h"
|
|
#include "nsIWeakReferenceUtils.h"
|
|
#include "nsThreadUtils.h"
|
|
|
|
namespace mozilla {
|
|
enum class StyleCursorKind : uint8_t;
|
|
|
|
namespace dom {
|
|
class BrowsingContext;
|
|
class BrowserParent;
|
|
enum class CallerType : uint32_t;
|
|
class Document;
|
|
class Element;
|
|
class Promise;
|
|
struct PointerLockOptions;
|
|
} // namespace dom
|
|
|
|
class PointerLockManager final {
|
|
public:
|
|
// https://w3c.github.io/pointerlock/#dom-element-requestpointerlock
|
|
// |aPromise| is the Promise returned to script; it is resolved when the
|
|
// lock is acquired and rejected with a DOMException matching the spec
|
|
// when any check fails.
|
|
static void RequestLock(dom::Element* aElement,
|
|
const dom::PointerLockOptions& aOptions,
|
|
dom::CallerType aCallerType, dom::Promise* aPromise);
|
|
|
|
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
|
static void Unlock(const char* aReason, dom::Document* aDoc = nullptr);
|
|
|
|
static bool IsLocked() { return sIsLocked; }
|
|
|
|
static already_AddRefed<dom::Element> GetLockedElement();
|
|
|
|
static already_AddRefed<dom::Document> GetLockedDocument();
|
|
|
|
static dom::BrowserParent* GetLockedRemoteTarget();
|
|
|
|
/**
|
|
* Returns true if aContext and the current pointer locked document
|
|
* have common top BrowsingContext.
|
|
* Note that this method returns true only if caller is in the same process
|
|
* as pointer locked document.
|
|
*/
|
|
static bool IsInLockContext(mozilla::dom::BrowsingContext* aContext);
|
|
|
|
// Set/release pointer lock remote target. Should only be called in parent
|
|
// process.
|
|
static void SetLockedRemoteTarget(dom::BrowserParent* aBrowserParent,
|
|
const bool& aUnadjustedMovement,
|
|
nsACString& aError);
|
|
static void ReleaseLockedRemoteTarget(dom::BrowserParent* aBrowserParent);
|
|
|
|
// Returns true if the pointer position should be reset for pointer lock in
|
|
// this process.
|
|
static bool ShouldResetPointer();
|
|
|
|
private:
|
|
class PointerLockRequest final : public Runnable {
|
|
public:
|
|
PointerLockRequest(dom::Element* aElement, bool aUserInputOrChromeCaller,
|
|
bool aUnadjustedMovement, dom::Promise* aPromise);
|
|
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD Run() final;
|
|
|
|
private:
|
|
nsWeakPtr mElement;
|
|
nsWeakPtr mDocument;
|
|
bool mUserInputOrChromeCaller;
|
|
bool mUnadjustedMovement;
|
|
// Strong reference: the script-side lifetime of the returned Promise is
|
|
// independent of the requested element's lifetime, so we keep it alive
|
|
// until we resolve or reject it.
|
|
RefPtr<dom::Promise> mPromise;
|
|
};
|
|
|
|
static void ChangePointerLockedElement(dom::Element* aElement,
|
|
dom::Document* aDocument,
|
|
dom::Element* aPointerLockedElement);
|
|
|
|
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
|
static bool StartSetPointerLock(dom::Element* aElement,
|
|
dom::Document* aDocument,
|
|
bool aUnadjustedMovement);
|
|
|
|
MOZ_CAN_RUN_SCRIPT
|
|
static bool SetPointerLock(dom::Element* aElement, dom::Document* aDocument,
|
|
StyleCursorKind, bool aUnadjustedMovement);
|
|
|
|
static bool sIsLocked;
|
|
static bool sIsLockUnadjustedMovement;
|
|
};
|
|
|
|
} // namespace mozilla
|
|
|
|
#endif // mozilla_PointerLockManager_h
|