Skip to content

Commit

Permalink
Bug 1767165 - Fix dragend coordinates in child processes after bug 17…
Browse files Browse the repository at this point in the history
…56241. r=tnikkel

Bug 1756241 changed nsDragService::mDragEndPoint to be relative to the
window. I didn't realize, but that point is passed as-is to child
widgets. Changing the widget event to actually have a widget made the
point be interpreted as widget-relative (which is correct in the parent
process, but not in the child process). Account for this and fix the
mDragEndPoint documentation while at it.

Differential Revision: https://phabricator.services.mozilla.com/D145182
  • Loading branch information
emilio committed May 2, 2022
1 parent 24905d6 commit d28e76a
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 12 deletions.
4 changes: 3 additions & 1 deletion dom/events/test/mochitest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,12 @@ skip-if = toolkit == 'android' # wheel scroll isn't supported
skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
[test_dragstart.html]
skip-if = toolkit == 'android' # not supported
[test_drag_coords.html]
skip-if = toolkit == 'android' # not supported
[test_error_events.html]
skip-if = toolkit == 'android' #TIMED_OUT
[test_event_handler_cc.html]
skip-if =
skip-if =
os == "linux" && bits == 64 && !debug # Bug 1564622
win10_2004 && bits == 64 && !debug # Bug 1564622
[test_eventctors.html]
Expand Down
50 changes: 50 additions & 0 deletions dom/events/test/test_drag_coords.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<!doctype html>
<title>Test for drag event coordinates</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
<style>
#draggable {
display: inline-block;
border: 1px solid;
}
</style>
<div draggable="true" id="draggable">Drag me</div>
<script>
add_task(async function test_drag_coords() {
let target = document.getElementById("draggable");
let coords = {};
let promises = [];
for (let type of ["dragstart", "dragend"]) {
promises.push(new Promise(function(resolve) {
target.addEventListener(type, function(e) {
info("Got " + e.type);
coords[e.type] = {
screen: {
x: e.screenX,
y: e.screenY,
},
client: {
x: e.clientX,
y: e.clientY,
},
};
resolve();
});
}));
}
synthesizePlainDragAndDrop({
srcElement: target,
srcX: 2,
srcY: 2,
stepX: 10,
stepY: 10,
});
await Promise.all(promises);
info(JSON.stringify(coords));
for (let coordType of ["screen", "client"]) {
is(coords.dragend[coordType].x, coords.dragstart[coordType].x + 12, `x ${coordType} is correct`);
is(coords.dragend[coordType].y, coords.dragstart[coordType].y + 12, `y ${coordType} is correct`);
}
});
</script>
6 changes: 1 addition & 5 deletions widget/PuppetWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1023,11 +1023,7 @@ LayoutDeviceIntPoint PuppetWidget::GetChromeOffset() {
}

LayoutDeviceIntPoint PuppetWidget::WidgetToScreenOffset() {
auto positionRalativeToWindow =
WidgetToTopLevelWidgetTransform().TransformPoint(LayoutDevicePoint());

return GetWindowPosition() +
LayoutDeviceIntPoint::Round(positionRalativeToWindow);
return GetWindowPosition() + WidgetToTopLevelWidgetOffset();
}

LayoutDeviceIntPoint PuppetWidget::GetWindowPosition() {
Expand Down
19 changes: 14 additions & 5 deletions widget/nsBaseDragService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,16 +259,22 @@ NS_IMETHODIMP nsBaseDragService::SetDragEndPointForTests(int32_t aScreenX,
MOZ_ASSERT(mDoingDrag);
MOZ_ASSERT(mSourceDocument);
MOZ_ASSERT(mSessionIsSynthesizedForTests);

if (!mDoingDrag || !mSourceDocument || !mSessionIsSynthesizedForTests) {
return NS_ERROR_FAILURE;
}
nsPresContext* presContext = mSourceDocument->GetPresContext();
if (NS_WARN_IF(!presContext)) {
nsPresContext* pc = mSourceDocument->GetPresContext();
if (NS_WARN_IF(!pc)) {
return NS_ERROR_FAILURE;
}
SetDragEndPoint(
LayoutDeviceIntPoint(presContext->CSSPixelsToDevPixels(aScreenX),
presContext->CSSPixelsToDevPixels(aScreenY)));
auto p = LayoutDeviceIntPoint::Round(CSSIntPoint(aScreenX, aScreenY) *
pc->CSSToDevPixelScale());
// p is screen-relative, and we want them to be top-level-widget-relative.
if (nsCOMPtr<nsIWidget> widget = pc->GetRootWidget()) {
p -= widget->WidgetToScreenOffset();
p += widget->WidgetToTopLevelWidgetOffset();
}
SetDragEndPoint(p);
return NS_OK;
}

Expand Down Expand Up @@ -656,6 +662,9 @@ nsBaseDragService::FireDragEventAtSource(EventMessage aEventMessage,
event.mInputSource = mInputSource;
if (aEventMessage == eDragEnd) {
event.mRefPoint = mEndDragPoint;
if (widget) {
event.mRefPoint -= widget->WidgetToTopLevelWidgetOffset();
}
event.mUserCancelled = mUserCancelled;
}
event.mModifiers = aKeyModifiers;
Expand Down
2 changes: 1 addition & 1 deletion widget/nsBaseDragService.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ class nsBaseDragService : public nsIDragService, public nsIDragSession {
// drag image.
mozilla::CSSIntPoint mScreenPosition;

// the screen position where the drag ended
// The position relative to the top level widget where the drag ended.
mozilla::LayoutDeviceIntPoint mEndDragPoint;

uint32_t mSuppressLevel;
Expand Down
6 changes: 6 additions & 0 deletions widget/nsIWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -1313,6 +1313,12 @@ class nsIWidget : public nsISupports {
return mozilla::LayoutDeviceToLayoutDeviceMatrix4x4();
}

mozilla::LayoutDeviceIntPoint WidgetToTopLevelWidgetOffset() {
return mozilla::LayoutDeviceIntPoint::Round(
WidgetToTopLevelWidgetTransform().TransformPoint(
mozilla::LayoutDevicePoint()));
}

/**
* Given the specified client size, return the corresponding window size,
* which includes the area for the borders and titlebar. This method
Expand Down

0 comments on commit d28e76a

Please sign in to comment.