Bug 2064287 - Harden drag handling; r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D321984
This commit is contained in:
committed by
echen@mozilla.com
parent
a48a2abebd
commit
5197db7444
@@ -510,6 +510,12 @@ void PointerLockManager::SetLockedRemoteTarget(BrowserParent* aBrowserParent,
|
||||
return;
|
||||
}
|
||||
|
||||
if (nsCOMPtr<nsIDragService> dragService =
|
||||
do_GetService("@mozilla.org/widget/dragservice;1")) {
|
||||
dragService->Suppress();
|
||||
}
|
||||
presContext->EventStateManager()->StopTrackingDragGesture(true);
|
||||
|
||||
MOZ_POINTERLOCK_LOG("Set locked remote target to 0x%p", aBrowserParent);
|
||||
sLockedRemoteTarget = aBrowserParent;
|
||||
PointerEventHandler::ReleaseAllPointerCaptureRemoteTarget();
|
||||
@@ -539,6 +545,11 @@ void PointerLockManager::ReleaseLockedRemoteTarget(
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = aBrowserParent->GetTopLevelWidget();
|
||||
EventStateManager::ReleaseLockedPointer(widget);
|
||||
|
||||
if (nsCOMPtr<nsIDragService> dragService =
|
||||
do_GetService("@mozilla.org/widget/dragservice;1")) {
|
||||
dragService->Unsuppress();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ class PointerLockManager final {
|
||||
|
||||
// Set/release pointer lock remote target. Should only be called in parent
|
||||
// process.
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void SetLockedRemoteTarget(dom::BrowserParent* aBrowserParent,
|
||||
const bool& aUnadjustedMovement,
|
||||
nsACString& aError);
|
||||
|
||||
@@ -2636,6 +2636,8 @@ void EventStateManager::BeginTrackingDragGesture(
|
||||
if (!mGestureDownFrameOwner) {
|
||||
mGestureDownFrameOwner = mGestureDownContent;
|
||||
}
|
||||
mGestureDownTopLevelRemoteTarget =
|
||||
BrowserParent::GetFrom(mGestureDownContent);
|
||||
}
|
||||
mGestureModifiers = aMouseDownOrTouchDragEvent.mModifiers;
|
||||
mGestureDownButtons = aMouseDownOrTouchDragEvent.mButtons;
|
||||
@@ -2687,6 +2689,8 @@ void EventStateManager::StopTrackingDragGesture(bool aClearInChildProcesses) {
|
||||
return;
|
||||
}
|
||||
|
||||
mGestureDownTopLevelRemoteTarget = nullptr;
|
||||
|
||||
// Only notify if there is NOT a drag session active in the parent.
|
||||
RefPtr<nsIDragSession> dragSession =
|
||||
nsContentUtils::GetDragSession(mPresContext);
|
||||
@@ -7990,6 +7994,7 @@ bool EventStateManager::WheelPrefs::IsOverOnePageScrollAllowedY(
|
||||
void EventStateManager::UpdateGestureContent(nsIContent* aContent) {
|
||||
mGestureDownContent = aContent;
|
||||
mGestureDownFrameOwner = aContent;
|
||||
mGestureDownTopLevelRemoteTarget = BrowserParent::GetFrom(aContent);
|
||||
}
|
||||
|
||||
void EventStateManager::NotifyContentWillBeRemovedForGesture(
|
||||
|
||||
@@ -561,6 +561,10 @@ class EventStateManager : public nsSupportsWeakReference, public nsIObserver {
|
||||
return mGestureDownContent;
|
||||
}
|
||||
|
||||
dom::BrowserParent* GetTrackingDragGestureTopLevelRemoteTarget() const {
|
||||
return mGestureDownTopLevelRemoteTarget;
|
||||
}
|
||||
|
||||
// Update the tracked gesture content to the parent of its frame when it's
|
||||
// removed, so that the gesture can be continued.
|
||||
void NotifyContentWillBeRemovedForGesture(nsIContent& aContent);
|
||||
@@ -1446,6 +1450,7 @@ class EventStateManager : public nsSupportsWeakReference, public nsIObserver {
|
||||
// as the target in most cases but not always - for example when dragging
|
||||
// an <area> of an image map this is the image. (bug 289667)
|
||||
nsCOMPtr<nsIContent> mGestureDownFrameOwner;
|
||||
RefPtr<dom::BrowserParent> mGestureDownTopLevelRemoteTarget;
|
||||
// Data associated with a drag started in a content process.
|
||||
RefPtr<dom::RemoteDragStartData> mGestureDownDragStartData;
|
||||
// State of keys when the original gesture-down happened
|
||||
|
||||
+40
-10
@@ -1060,6 +1060,20 @@ mozilla::ipc::IPCResult BrowserParent::RecvSetDimensions(
|
||||
nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = do_QueryInterface(treeOwner);
|
||||
NS_ENSURE_TRUE(treeOwnerAsWin, IPC_OK());
|
||||
|
||||
if (nsCOMPtr<nsIDragService> dragService =
|
||||
do_GetService("@mozilla.org/widget/dragservice;1")) {
|
||||
RefPtr<nsIWidget> widget = GetTopLevelWidget();
|
||||
if (RefPtr<nsIDragSession> session =
|
||||
dragService->GetCurrentSession(widget)) {
|
||||
session->EndDragSession(false, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (nsPresContext* presContext =
|
||||
mFrameElement->OwnerDoc()->GetPresContext()) {
|
||||
presContext->EventStateManager()->StopTrackingDragGesture(true);
|
||||
}
|
||||
|
||||
// `BrowserChild` only sends the values to actually be changed, see more
|
||||
// details in `BrowserChild::SetDimensions()`.
|
||||
// Note that `BrowserChild::SetDimensions()` may be called before receiving
|
||||
@@ -3883,8 +3897,29 @@ mozilla::ipc::IPCResult BrowserParent::RecvInvokeDragSession(
|
||||
const CookieJarSettingsArgs& aCookieJarSettingsArgs,
|
||||
const MaybeDiscarded<WindowContext>& aSourceWindowContext,
|
||||
const MaybeDiscarded<WindowContext>& aSourceTopWindowContext) {
|
||||
PresShell* presShell = mFrameElement->OwnerDoc()->GetPresShell();
|
||||
if (!presShell) {
|
||||
nsCOMPtr<nsIDragService> dragService =
|
||||
do_GetService("@mozilla.org/widget/dragservice;1");
|
||||
nsPresContext* presContext = mFrameElement->OwnerDoc()->GetPresContext();
|
||||
const bool isValidRemoteDrag = [&]() {
|
||||
if (!dragService || !presContext) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dragService->GetIsSuppressed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BrowserParent* dragTopLevelRemoteTarget =
|
||||
presContext->EventStateManager()
|
||||
->GetTrackingDragGestureTopLevelRemoteTarget();
|
||||
if (NS_WARN_IF(dragTopLevelRemoteTarget != TopLevelBrowserParent())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}();
|
||||
|
||||
if (!isValidRemoteDrag) {
|
||||
(void)SendEndDragSession(true, true, LayoutDeviceIntPoint(), 0,
|
||||
nsIDragService::DRAGDROP_ACTION_NONE);
|
||||
// Continue sending input events with input priority when stopping the dnd
|
||||
@@ -3922,15 +3957,10 @@ mozilla::ipc::IPCResult BrowserParent::RecvInvokeDragSession(
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDragService> dragService =
|
||||
do_GetService("@mozilla.org/widget/dragservice;1");
|
||||
if (dragService) {
|
||||
dragService->MaybeAddBrowser(this);
|
||||
}
|
||||
dragService->MaybeAddBrowser(this);
|
||||
|
||||
presShell->GetPresContext()
|
||||
->EventStateManager()
|
||||
->BeginTrackingRemoteDragGesture(mFrameElement, dragStartData);
|
||||
presContext->EventStateManager()->BeginTrackingRemoteDragGesture(
|
||||
mFrameElement, dragStartData);
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||
os->NotifyObservers(nullptr, "content-invoked-drag", nullptr);
|
||||
|
||||
@@ -739,6 +739,7 @@ class BrowserParent final : public PBrowserParent,
|
||||
|
||||
mozilla::ipc::IPCResult RecvRemoteIsReadyToHandleInputEvents();
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
mozilla::ipc::IPCResult RecvSetDimensions(mozilla::DimensionRequest aRequest,
|
||||
const double& aScale);
|
||||
|
||||
@@ -758,6 +759,7 @@ class BrowserParent final : public PBrowserParent,
|
||||
mozilla::ipc::IPCResult RecvMaybeFireEmbedderLoadEvents(
|
||||
EmbedderElementEventType aFireEventAtEmbeddingElement);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
mozilla::ipc::IPCResult RecvRequestPointerLock(
|
||||
const bool& aUnadjustedMovement, RequestPointerLockResolver&& aResolve);
|
||||
mozilla::ipc::IPCResult RecvReleasePointerLock();
|
||||
|
||||
@@ -1169,6 +1169,8 @@ nsBaseDragService::Unsuppress() {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool nsBaseDragService::GetIsSuppressed() { return mSuppressLevel > 0; }
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBaseDragSession::UserCancelled() {
|
||||
mUserCancelled = true;
|
||||
|
||||
@@ -172,6 +172,11 @@ interface nsIDragService : nsISupports
|
||||
void suppress();
|
||||
void unsuppress();
|
||||
|
||||
/**
|
||||
* True if the dragging is disabled.
|
||||
*/
|
||||
[notxpcom, nostdcall] readonly attribute boolean isSuppressed;
|
||||
|
||||
[notxpcom, nostdcall] boolean maybeAddBrowser(in BrowserParentPtr aBP);
|
||||
[notxpcom, nostdcall] boolean removeAllBrowsers();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user