Verified Commit 0405b9bc authored by Edgar Chen's avatar Edgar Chen Committed by ma1
Browse files

Bug 1743329 - Release pointer lock when xul popup is open; r=smaug,pbz

parent cf5b43c4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -558,5 +558,7 @@ add_task(async function test_notificationDuringFullScreenTransition() {
    info("Wait for full screen transition end.");
    await promiseFullScreenTransitionEnd;
    info("Full screen transition end");

    await SpecialPowers.popPrefEnv();
  });
});
+46 −3
Original line number Diff line number Diff line
@@ -17,8 +17,10 @@
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/PointerEventHandler.h"
#include "mozilla/dom/WindowContext.h"
#include "nsCOMPtr.h"
#include "nsMenuPopupFrame.h"
#include "nsSandboxFlags.h"

namespace mozilla {
@@ -86,6 +88,25 @@ static void DispatchPointerLockError(Document* aTarget, const char* aMessage) {
                                  aMessage);
}

static bool IsPopupOpened() {
  // Check if any popup is open.
  nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
  if (!pm) {
    return false;
  }

  nsTArray<nsMenuPopupFrame*> popups;
  pm->GetVisiblePopups(popups, true);

  for (nsMenuPopupFrame* popup : popups) {
    if (popup->GetPopupType() != widget::PopupType::Tooltip) {
      return true;
    }
  }

  return false;
}

static const char* GetPointerLockError(Element* aElement, Element* aCurrentLock,
                                       bool aNoFocusCheck = false) {
  // Check if pointer lock pref is enabled
@@ -136,6 +157,10 @@ static const char* GetPointerLockError(Element* aElement, Element* aCurrentLock,
    }
  }

  if (IsPopupOpened()) {
    return "PointerLockDeniedFailedToLock";
  }

  return nullptr;
}

@@ -167,6 +192,14 @@ void PointerLockManager::RequestLock(Element* aElement,

/* static */
void PointerLockManager::Unlock(Document* aDoc) {
  if (sLockedRemoteTarget) {
    MOZ_ASSERT(XRE_IsParentProcess());
    MOZ_ASSERT(!sIsLocked);
    Unused << sLockedRemoteTarget->SendReleasePointerLock();
    sLockedRemoteTarget = nullptr;
    return;
  }

  if (!sIsLocked) {
    return;
  }
@@ -311,14 +344,24 @@ bool PointerLockManager::IsInLockContext(BrowsingContext* aContext) {
}

/* static */
bool PointerLockManager::SetLockedRemoteTarget(BrowserParent* aBrowserParent) {
void PointerLockManager::SetLockedRemoteTarget(BrowserParent* aBrowserParent,
                                               nsACString& aError) {
  MOZ_ASSERT(XRE_IsParentProcess());
  if (sLockedRemoteTarget) {
    return sLockedRemoteTarget == aBrowserParent;
    if (sLockedRemoteTarget != aBrowserParent) {
      aError = "PointerLockDeniedInUse"_ns;
    }
    return;
  }

  // Check if any popup is open.
  if (IsPopupOpened()) {
    aError = "PointerLockDeniedFailedToLock"_ns;
    return;
  }

  sLockedRemoteTarget = aBrowserParent;
  return true;
  PointerEventHandler::ReleaseAllPointerCaptureRemoteTarget();
}

/* static */
+2 −1
Original line number Diff line number Diff line
@@ -47,7 +47,8 @@ class PointerLockManager final {

  // Set/release pointer lock remote target. Should only be called in parent
  // process.
  static bool SetLockedRemoteTarget(dom::BrowserParent* aBrowserParent);
  static void SetLockedRemoteTarget(dom::BrowserParent* aBrowserParent,
                                    nsACString& aError);
  static void ReleaseLockedRemoteTarget(dom::BrowserParent* aBrowserParent);

 private:
+6 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#include "mozilla/MouseEvents.h"
#include "mozilla/NativeKeyBindingsType.h"
#include "mozilla/NullPrincipal.h"
#include "mozilla/PointerLockManager.h"
#include "mozilla/Preferences.h"
#include "mozilla/PresShell.h"
#include "mozilla/ProcessHangMonitor.h"
@@ -3184,6 +3185,11 @@ mozilla::ipc::IPCResult BrowserChild::RecvReleaseAllPointerCapture() {
  return IPC_OK();
}

mozilla::ipc::IPCResult BrowserChild::RecvReleasePointerLock() {
  PointerLockManager::Unlock();
  return IPC_OK();
}

PPaymentRequestChild* BrowserChild::AllocPPaymentRequestChild() {
  MOZ_CRASH(
      "We should never be manually allocating PPaymentRequestChild actors");
+2 −0
Original line number Diff line number Diff line
@@ -696,6 +696,8 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,

  mozilla::ipc::IPCResult RecvReleaseAllPointerCapture();

  mozilla::ipc::IPCResult RecvReleasePointerLock();

 private:
  void HandleDoubleTap(const CSSPoint& aPoint, const Modifiers& aModifiers,
                       const ScrollableLayerGuid& aGuid);
Loading