Bug 1532901 - Fix event.screenX and event.screenY inside out-of-process iframes. r=nika

Differential Revision: https://phabricator.services.mozilla.com/D25582

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Henri Sivonen 2019-04-09 10:26:31 +00:00
Родитель e6f56104fb
Коммит 95281be87c
8 изменённых файлов: 80 добавлений и 3 удалений

Просмотреть файл

@ -529,8 +529,19 @@ CSSIntPoint Event::GetScreenCoords(nsPresContext* aPresContext,
return CSSIntPoint(aPoint.x, aPoint.y);
}
// (Potentially) transform the point from the coordinate space of an
// out-of-process iframe to the coordinate space of the native
// window. The transform can only be applied to a point whose components
// are floating-point values, so convert the integer point first, then
// transform, and then round the result back to an integer point.
LayoutDevicePoint floatPoint(aPoint);
LayoutDevicePoint topLevelPoint =
guiEvent->mWidget->WidgetToTopLevelWidgetTransform().TransformPoint(
floatPoint);
LayoutDeviceIntPoint rounded = RoundedToInt(topLevelPoint);
nsPoint pt = LayoutDevicePixel::ToAppUnits(
aPoint,
rounded,
aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom());
if (PresShell* presShell = aPresContext->GetPresShell()) {
@ -539,7 +550,7 @@ CSSIntPoint Event::GetScreenCoords(nsPresContext* aPresContext,
}
pt += LayoutDevicePixel::ToAppUnits(
guiEvent->mWidget->WidgetToScreenOffset(),
guiEvent->mWidget->TopLevelWidgetToScreenOffset(),
aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom());
return CSSPixel::FromAppUnitsRounded(pt);

Просмотреть файл

@ -32,7 +32,7 @@ include "mozilla/layers/LayersMessageUtils.h";
using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
using moveonly mozilla::gfx::PaintFragment from "mozilla/gfx/CrossProcessPaint.h";
using mozilla::gfx::Matrix from "mozilla/gfx/Matrix.h";
using mozilla::gfx::Matrix4x4 from "mozilla/gfx/Matrix.h";
using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h";
using mozilla::LayoutDeviceIntPoint from "Units.h";
using mozilla::LayoutDevicePoint from "Units.h";
@ -643,6 +643,8 @@ child:
async SizeModeChanged(nsSizeMode sizeMode);
async ChildToParentMatrix(Matrix4x4 aMatrix);
async ParentActivated(bool aActivated);
async SetKeyboardIndicators(UIStateChangeType showAccelerators,

Просмотреть файл

@ -1216,6 +1216,13 @@ mozilla::ipc::IPCResult TabChild::RecvSizeModeChanged(
return IPC_OK();
}
mozilla::ipc::IPCResult TabChild::RecvChildToParentMatrix(
const mozilla::gfx::Matrix4x4& aMatrix) {
mChildToParentConversionMatrix =
Some(LayoutDeviceToLayoutDeviceMatrix4x4::FromUnknownMatrix(aMatrix));
return IPC_OK();
}
bool TabChild::UpdateFrame(const RepaintRequest& aRequest) {
return TabChildBase::UpdateFrameHandler(aRequest);
}
@ -1456,6 +1463,14 @@ void TabChild::ProcessPendingCoalescedMouseDataAndDispatchEvents() {
}
}
LayoutDeviceToLayoutDeviceMatrix4x4 TabChild::GetChildToParentConversionMatrix() const {
if (mChildToParentConversionMatrix) {
return *mChildToParentConversionMatrix;
}
LayoutDevicePoint offset(GetChromeOffset());
return LayoutDeviceToLayoutDeviceMatrix4x4::Translation(offset);
}
void TabChild::FlushAllCoalescedMouseData() {
MOZ_ASSERT(mCoalesceMouseMoveEvents);

Просмотреть файл

@ -312,6 +312,9 @@ class TabChild final : public TabChildBase,
virtual mozilla::ipc::IPCResult RecvSizeModeChanged(
const nsSizeMode& aSizeMode) override;
virtual mozilla::ipc::IPCResult RecvChildToParentMatrix(
const mozilla::gfx::Matrix4x4& aMatrix) override;
mozilla::ipc::IPCResult RecvActivate();
mozilla::ipc::IPCResult RecvDeactivate();
@ -637,6 +640,10 @@ class TabChild final : public TabChildBase,
// The HANDLE object for the widget this TabChild in.
WindowsHandle WidgetNativeData() { return mWidgetNativeData; }
// The transform from the coordinate space of this TabChild to the coordinate
// space of the native window its TabParent is in.
mozilla::LayoutDeviceToLayoutDeviceMatrix4x4 GetChildToParentConversionMatrix() const;
// Prepare to dispatch all coalesced mousemove events. We'll move all data
// in mCoalescedMouseData to a nsDeque; then we start processing them. We
// can't fetch the coalesced event one by one and dispatch it because we may
@ -905,6 +912,8 @@ class TabChild final : public TabChildBase,
WindowsHandle mWidgetNativeData;
Maybe<LayoutDeviceToLayoutDeviceMatrix4x4> mChildToParentConversionMatrix;
// This state is used to keep track of the current visible tabs (the ones
// rendering layers). There may be more than one if there are multiple browser
// windows open, or tabs are being warmed up. There may be none if this

Просмотреть файл

@ -2062,6 +2062,10 @@ TabParent::GetChildToParentConversionMatrix() {
void TabParent::SetChildToParentConversionMatrix(
const LayoutDeviceToLayoutDeviceMatrix4x4& aMatrix) {
mChildToParentConversionMatrix = Some(aMatrix);
if (mIsDestroyed) {
return;
}
mozilla::Unused << SendChildToParentMatrix(aMatrix.ToUnknownMatrix());
}
LayoutDeviceIntPoint TabParent::GetChildProcessOffset() {

Просмотреть файл

@ -286,6 +286,15 @@ void PuppetWidget::Invalidate(const LayoutDeviceIntRect& aRect) {
}
}
mozilla::LayoutDeviceToLayoutDeviceMatrix4x4
PuppetWidget::WidgetToTopLevelWidgetTransform() {
if (!GetOwningTabChild()) {
NS_WARNING("PuppetWidget without Tab does not have transform information.");
return mozilla::LayoutDeviceToLayoutDeviceMatrix4x4();
}
return GetOwningTabChild()->GetChildToParentConversionMatrix();
}
void PuppetWidget::InitEvent(WidgetGUIEvent& aEvent,
LayoutDeviceIntPoint* aPoint) {
if (nullptr == aPoint) {

Просмотреть файл

@ -129,10 +129,17 @@ class PuppetWidget : public nsBaseWidget,
return NS_ERROR_UNEXPECTED;
}
virtual mozilla::LayoutDeviceToLayoutDeviceMatrix4x4
WidgetToTopLevelWidgetTransform() override;
virtual LayoutDeviceIntPoint WidgetToScreenOffset() override {
return GetWindowPosition() + GetChromeOffset();
}
virtual LayoutDeviceIntPoint TopLevelWidgetToScreenOffset() override {
return GetWindowPosition();
}
int32_t RoundsWidgetCoordinatesTo() override;
void InitEvent(WidgetGUIEvent& aEvent,

Просмотреть файл

@ -1345,6 +1345,26 @@ class nsIWidget : public nsISupports {
*/
virtual LayoutDeviceIntPoint WidgetToScreenOffset() = 0;
/**
* The same as WidgetToScreenOffset(), except in the case of
* PuppetWidget where this method omits the chrome offset.
*/
virtual LayoutDeviceIntPoint TopLevelWidgetToScreenOffset() {
return WidgetToScreenOffset();
}
/**
* For a PuppetWidget, returns the transform from the coordinate
* space of the PuppetWidget to the coordinate space of the
* top-level native widget.
*
* Identity transform in other cases.
*/
virtual mozilla::LayoutDeviceToLayoutDeviceMatrix4x4
WidgetToTopLevelWidgetTransform() {
return mozilla::LayoutDeviceToLayoutDeviceMatrix4x4();
}
/**
* Given the specified client size, return the corresponding window size,
* which includes the area for the borders and titlebar. This method