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