Bug 1104036 - Make -moz-window-dragging work in rectilinear 2d transforms. r=roc

This commit is contained in:
Markus Stange 2015-01-23 13:07:51 -05:00
Родитель 7a21cff941
Коммит baedc2af15
3 изменённых файлов: 39 добавлений и 11 удалений

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

@ -1236,10 +1236,31 @@ nsDisplayListBuilder::RecomputeCurrentAnimatedGeometryRoot()
void
nsDisplayListBuilder::AdjustWindowDraggingRegion(nsIFrame* aFrame)
{
if (!IsForPainting() || IsInSubdocument() || IsInTransform()) {
if (!IsForPainting() || IsInSubdocument()) {
return;
}
Matrix4x4 referenceFrameToRootReferenceFrame;
// The const_cast is for nsLayoutUtils::GetTransformToAncestor.
nsIFrame* referenceFrame = const_cast<nsIFrame*>(FindReferenceFrameFor(aFrame));
if (IsInTransform()) {
// Only support 2d rectilinear transforms. Transform support is needed for
// the horizontal flip transform that's applied to the urlbar textbox in
// RTL mode - it should be able to exclude itself from the draggable region.
referenceFrameToRootReferenceFrame =
nsLayoutUtils::GetTransformToAncestor(referenceFrame, mReferenceFrame);
Matrix referenceFrameToRootReferenceFrame2d;
if (!referenceFrameToRootReferenceFrame.Is2D(&referenceFrameToRootReferenceFrame2d) ||
!referenceFrameToRootReferenceFrame2d.IsRectilinear()) {
return;
}
} else {
MOZ_ASSERT(referenceFrame == mReferenceFrame,
"referenceFrameToRootReferenceFrame needs to be adjusted");
}
// We do some basic visibility checking on the frame's border box here.
// We intersect it both with the current dirty rect and with the current
// clip. Either one is just a conservative approximation on its own, but
@ -1260,11 +1281,19 @@ nsDisplayListBuilder::AdjustWindowDraggingRegion(nsIFrame* aFrame)
borderBox = clip->ApplyNonRoundedIntersection(borderBox);
}
if (!borderBox.IsEmpty()) {
const nsStyleUserInterface* styleUI = aFrame->StyleUserInterface();
if (styleUI->mWindowDragging == NS_STYLE_WINDOW_DRAGGING_DRAG) {
mWindowDraggingRegion.OrWith(borderBox);
} else {
mWindowDraggingRegion.SubOut(borderBox);
LayoutDeviceRect devPixelBorderBox =
LayoutDevicePixel::FromAppUnits(borderBox, aFrame->PresContext()->AppUnitsPerDevPixel());
LayoutDeviceRect transformedDevPixelBorderBox =
TransformTo<LayoutDevicePixel>(referenceFrameToRootReferenceFrame, devPixelBorderBox);
transformedDevPixelBorderBox.Round();
LayoutDeviceIntRect transformedDevPixelBorderBoxInt;
if (transformedDevPixelBorderBox.ToIntRect(&transformedDevPixelBorderBoxInt)) {
const nsStyleUserInterface* styleUI = aFrame->StyleUserInterface();
if (styleUI->mWindowDragging == NS_STYLE_WINDOW_DRAGGING_DRAG) {
mWindowDraggingRegion.OrWith(LayoutDevicePixel::ToUntyped(transformedDevPixelBorderBoxInt));
} else {
mWindowDraggingRegion.SubOut(LayoutDevicePixel::ToUntyped(transformedDevPixelBorderBoxInt));
}
}
}
}

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

@ -513,7 +513,7 @@ public:
*/
void AdjustWindowDraggingRegion(nsIFrame* aFrame);
const nsRegion& GetWindowDraggingRegion() { return mWindowDraggingRegion; }
const nsIntRegion& GetWindowDraggingRegion() { return mWindowDraggingRegion; }
/**
* Allocate memory in our arena. It will only be freed when this display list
@ -875,7 +875,7 @@ private:
nsRect mDirtyRect;
nsRegion mWindowExcludeGlassRegion;
nsRegion mWindowOpaqueRegion;
nsRegion mWindowDraggingRegion;
nsIntRegion mWindowDraggingRegion;
// The display item for the Windows window glass background, if any
nsDisplayItem* mGlassDisplayItem;
nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy;

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

@ -3239,9 +3239,8 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
widget->UpdateOpaqueRegion(
opaqueRegion.ToNearestPixels(presContext->AppUnitsPerDevPixel()));
const nsRegion& draggingRegion = builder.GetWindowDraggingRegion();
widget->UpdateWindowDraggingRegion(
draggingRegion.ToNearestPixels(presContext->AppUnitsPerDevPixel()));
const nsIntRegion& draggingRegion = builder.GetWindowDraggingRegion();
widget->UpdateWindowDraggingRegion(draggingRegion);
}
}