diff options
Diffstat (limited to 'layout/generic/nsPluginFrame.cpp')
-rw-r--r-- | layout/generic/nsPluginFrame.cpp | 127 |
1 files changed, 123 insertions, 4 deletions
diff --git a/layout/generic/nsPluginFrame.cpp b/layout/generic/nsPluginFrame.cpp index ea42d9bd37..eee3f46b8b 100644 --- a/layout/generic/nsPluginFrame.cpp +++ b/layout/generic/nsPluginFrame.cpp @@ -69,6 +69,11 @@ #endif /* MOZ_LOGGING */ #include "mozilla/Logging.h" +#ifdef XP_MACOSX +#include "gfxQuartzNativeDrawing.h" +#include "mozilla/gfx/QuartzSupport.h" +#endif + #ifdef MOZ_X11 #include "mozilla/X11Util.h" using mozilla::DefaultXDisplay; @@ -313,6 +318,15 @@ nsPluginFrame::PrepForDrawing(nsIWidget *aWidget) mInnerView->AttachWidgetEventHandler(mWidget); +#ifdef XP_MACOSX + // On Mac, we need to invalidate ourselves since even windowed + // plugins are painted through Thebes and we need to ensure + // the PaintedLayer containing the plugin is updated. + if (parentWidget == GetNearestWidget()) { + InvalidateFrame(); + } +#endif + RegisterPluginForGeometryUpdates(); // Here we set the background color for this widget because some plugins will use @@ -551,12 +565,27 @@ nsPluginFrame::FixupWindow(const nsSize& aSize) nsIntPoint origin = GetWindowOriginInPixels(windowless); // window must be in "display pixels" +#if defined(XP_MACOSX) + // window must be in "display pixels" + double scaleFactor = 1.0; + if (NS_FAILED(mInstanceOwner->GetContentsScaleFactor(&scaleFactor))) { + scaleFactor = 1.0; + } + int intScaleFactor = ceil(scaleFactor); + window->x = origin.x / intScaleFactor; + window->y = origin.y / intScaleFactor; + window->width = presContext->AppUnitsToDevPixels(aSize.width) / intScaleFactor; + window->height = presContext->AppUnitsToDevPixels(aSize.height) / intScaleFactor; +#else window->x = origin.x; window->y = origin.y; window->width = presContext->AppUnitsToDevPixels(aSize.width); window->height = presContext->AppUnitsToDevPixels(aSize.height); +#endif +#ifndef XP_MACOSX mInstanceOwner->UpdateWindowPositionAndClipRect(false); +#endif NotifyPluginReflowObservers(); } @@ -587,6 +616,13 @@ nsPluginFrame::CallSetWindow(bool aCheckIsHidden) RefPtr<nsPluginInstanceOwner> instanceOwnerRef(mInstanceOwner); // refresh the plugin port as well +#ifdef XP_MACOSX + mInstanceOwner->FixUpPluginWindow(nsPluginInstanceOwner::ePluginPaintEnable); + // Bail now if our frame has been destroyed. + if (!instanceOwnerRef->GetFrame()) { + return NS_ERROR_FAILURE; + } +#endif window->window = mInstanceOwner->GetPluginPort(); // Adjust plugin dimensions according to pixel snap results @@ -606,11 +642,24 @@ nsPluginFrame::CallSetWindow(bool aCheckIsHidden) intBounds.x += intOffset.x; intBounds.y += intOffset.y; +#if defined(XP_MACOSX) + // window must be in "display pixels" + double scaleFactor = 1.0; + if (NS_FAILED(instanceOwnerRef->GetContentsScaleFactor(&scaleFactor))) { + scaleFactor = 1.0; + } + + size_t intScaleFactor = ceil(scaleFactor); + window->x = intBounds.x / intScaleFactor; + window->y = intBounds.y / intScaleFactor; + window->width = intBounds.width / intScaleFactor; + window->height = intBounds.height / intScaleFactor; +#else window->x = intBounds.x; window->y = intBounds.y; window->width = intBounds.width; window->height = intBounds.height; - +#endif // BE CAREFUL: By the time we get here the PluginFrame is sometimes destroyed // and poisoned. If we reference local fields (implicit this deref), // we will crash. @@ -1012,6 +1061,11 @@ nsPluginFrame::NotifyPluginReflowObservers() void nsPluginFrame::DidSetWidgetGeometry() { +#if defined(XP_MACOSX) + if (mInstanceOwner && !IsHidden()) { + mInstanceOwner->FixUpPluginWindow(nsPluginInstanceOwner::ePluginPaintEnable); + } +#else if (!mWidget && mInstanceOwner) { // UpdateWindowVisibility will notify the plugin of position changes // by updating the NPWindow and calling NPP_SetWindow/AsyncSetWindow. @@ -1022,20 +1076,29 @@ nsPluginFrame::DidSetWidgetGeometry() nsLayoutUtils::IsPopup(nsLayoutUtils::GetDisplayRootFrame(this)) || !mNextConfigurationBounds.IsEmpty()); } +#endif } bool nsPluginFrame::IsOpaque() const { +#if defined(XP_MACOSX) + return false; +#else + if (mInstanceOwner && mInstanceOwner->UseAsyncRendering()) { return false; } return !IsTransparentMode(); +#endif } bool nsPluginFrame::IsTransparentMode() const { +#if defined(XP_MACOSX) + return false; +#else if (!mInstanceOwner) return false; @@ -1057,6 +1120,7 @@ nsPluginFrame::IsTransparentMode() const bool transparent = false; pi->IsTransparent(&transparent); return transparent; +#endif } void @@ -1077,20 +1141,27 @@ nsPluginFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, DO_GLOBAL_REFLOW_COUNT_DSP("nsPluginFrame"); +#ifndef XP_MACOSX if (mWidget && aBuilder->IsInTransform()) { // Windowed plugins should not be rendered inside a transform. return; } +#endif if (aBuilder->IsForPainting() && mInstanceOwner) { // Update plugin frame for both content scaling and full zoom changes. mInstanceOwner->ResolutionMayHaveChanged(); +#ifdef XP_MACOSX + mInstanceOwner->WindowFocusMayHaveChanged(); +#endif if (mInstanceOwner->UseAsyncRendering()) { NPWindow* window = nullptr; mInstanceOwner->GetWindow(window); bool isVisible = window && window->width > 0 && window->height > 0; if (isVisible && aBuilder->ShouldSyncDecodeImages()) { +#ifndef XP_MACOSX mInstanceOwner->UpdateWindowVisibility(true); +#endif } mInstanceOwner->NotifyPaintWaiter(aBuilder); @@ -1167,8 +1238,8 @@ nsPluginFrame::PrintPlugin(nsRenderingContext& aRenderingContext, window.clipRect.left = 0; window.clipRect.right = 0; // platform specific printing code -#if defined(XP_UNIX) - // Doesn't work in a thebes world. +#if defined(XP_UNIX) || defined(XP_MACOSX) + // Doesn't work in a thebes world, or on OS X. (void)window; (void)npprint; #elif defined(XP_WIN) @@ -1306,7 +1377,20 @@ nsPluginFrame::BuildLayer(nsDisplayListBuilder* aBuilder, if (window->width <= 0 || window->height <= 0) return nullptr; - IntSize size(window->width, window->height); +#if defined(XP_MACOSX) + // window is in "display pixels", but size needs to be in device pixels + // window must be in "display pixels" + double scaleFactor = 1.0; + if (NS_FAILED(mInstanceOwner->GetContentsScaleFactor(&scaleFactor))) { + scaleFactor = 1.0; + } + + size_t intScaleFactor = ceil(scaleFactor); +#else + size_t intScaleFactor = 1; +#endif + + IntSize size(window->width * intScaleFactor, window->height * intScaleFactor); nsRect area = GetContentRectRelativeToSelf() + aItem->ToReferenceFrame(); gfxRect r = nsLayoutUtils::RectToGfxRect(area, PresContext()->AppUnitsPerDevPixel()); @@ -1336,6 +1420,11 @@ nsPluginFrame::BuildLayer(nsDisplayListBuilder* aBuilder, NS_ASSERTION(layer->GetType() == Layer::TYPE_IMAGE, "Bad layer type"); ImageLayer* imglayer = static_cast<ImageLayer*>(layer.get()); +#ifdef XP_MACOSX + if (!mInstanceOwner->UseAsyncRendering()) { + mInstanceOwner->DoCocoaEventDrawRect(r, nullptr); + } +#endif imglayer->SetScaleToSize(size, ScaleMode::STRETCH); imglayer->SetContainer(container); @@ -1456,11 +1545,37 @@ nsPluginFrame::HandleEvent(nsPresContext* aPresContext, return rv; #endif +#ifdef XP_MACOSX + // we want to process some native mouse events in the cocoa event model + if ((anEvent->mMessage == eMouseEnterIntoWidget || + anEvent->mMessage == eWheel) && + mInstanceOwner->GetEventModel() == NPEventModelCocoa) { + *anEventStatus = mInstanceOwner->ProcessEvent(*anEvent); + // Due to plugin code reentering Gecko, this frame may be dead at this + // point. + return rv; + } + + // These two calls to nsIPresShell::SetCapturingContext() (on mouse-down + // and mouse-up) are needed to make the routing of mouse events while + // dragging conform to standard OS X practice, and to the Cocoa NPAPI spec. + // See bug 525078 and bug 909678. + if (anEvent->mMessage == eMouseDown) { + nsIPresShell::SetCapturingContent(GetContent(), CAPTURE_IGNOREALLOWED); + } +#endif + rv = nsFrame::HandleEvent(aPresContext, anEvent, anEventStatus); // We need to be careful from this point because the call to // nsFrame::HandleEvent() might have killed us. +#ifdef XP_MACOSX + if (anEvent->mMessage == eMouseUp) { + nsIPresShell::SetCapturingContent(nullptr, 0); + } +#endif + return rv; } @@ -1636,7 +1751,11 @@ NS_NewObjectFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) bool nsPluginFrame::IsPaintedByGecko() const { +#ifdef XP_MACOSX + return true; +#else return !mWidget; +#endif } NS_IMPL_FRAMEARENA_HELPERS(nsPluginFrame) |