mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-24 11:27:49 +00:00
Bug 390385 make sure that plugins don't get instantiated before the first Reflow of the objectframe, so that the first NPP_SetWindow call contains the right dimensions r+sr=bz
This commit is contained in:
parent
640a4e236d
commit
952d1075d3
@ -128,7 +128,8 @@ nsAsyncInstantiateEvent::Run()
|
||||
// the type here - GetFrame() only returns object frames, and that means we're
|
||||
// a plugin)
|
||||
// Also make sure that we still refer to the same data.
|
||||
if (mContent->GetFrame(PR_FALSE) == mFrame &&
|
||||
nsIObjectFrame* frame = mContent->GetFrame(PR_FALSE);
|
||||
if (frame == mFrame &&
|
||||
mContent->mURI == mURI &&
|
||||
mContent->mContentType.Equals(mContentType)) {
|
||||
if (LOG_ENABLED()) {
|
||||
@ -140,7 +141,7 @@ nsAsyncInstantiateEvent::Run()
|
||||
mContent, mContentType.get(), mURI.get(), spec.get()));
|
||||
}
|
||||
|
||||
nsresult rv = mContent->Instantiate(mContentType, mURI);
|
||||
nsresult rv = mContent->Instantiate(frame, mContentType, mURI);
|
||||
if (NS_FAILED(rv)) {
|
||||
mContent->Fallback(PR_TRUE);
|
||||
}
|
||||
@ -643,7 +644,7 @@ nsObjectLoadingContent::EnsureInstantiation(nsIPluginInstance** aInstance)
|
||||
// We may have a plugin instance already; if so, do nothing
|
||||
nsresult rv = frame->GetPluginInstance(*aInstance);
|
||||
if (!*aInstance) {
|
||||
rv = Instantiate(mContentType, mURI);
|
||||
rv = Instantiate(frame, mContentType, mURI);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = frame->GetPluginInstance(*aInstance);
|
||||
} else {
|
||||
@ -931,6 +932,7 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
|
||||
if (overrideType.IsEmpty()) {
|
||||
newType = GetTypeOfContent(aTypeHint);
|
||||
} else {
|
||||
mContentType = overrideType;
|
||||
newType = eType_Plugin;
|
||||
}
|
||||
|
||||
@ -957,6 +959,7 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
|
||||
// Must notify here for plugins
|
||||
// If aNotify is false, we'll just wait until we get a frame and use the
|
||||
// async instantiate path.
|
||||
// XXX is this still needed? (for documents?)
|
||||
mType = newType;
|
||||
if (aNotify)
|
||||
notifier.Notify();
|
||||
@ -967,7 +970,7 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
|
||||
rv = LoadImage(aURI, aForceLoad, PR_FALSE);
|
||||
break;
|
||||
case eType_Plugin:
|
||||
rv = Instantiate(aTypeHint, aURI);
|
||||
rv = TryInstantiate(mContentType, mURI);
|
||||
break;
|
||||
case eType_Document:
|
||||
rv = mFrameLoader->LoadURI(aURI);
|
||||
@ -1019,8 +1022,6 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
|
||||
// Or: supported class id, plugin will handle the load.
|
||||
LOG(("OBJLC [%p]: (classid) Changing type from %u to eType_Plugin\n", this, mType));
|
||||
mType = eType_Plugin;
|
||||
if (aNotify)
|
||||
notifier.Notify();
|
||||
|
||||
// At this point, the stored content type
|
||||
// must be equal to our type hint. Similar,
|
||||
@ -1043,7 +1044,7 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
|
||||
}
|
||||
}
|
||||
|
||||
rv = Instantiate(mContentType, mURI);
|
||||
rv = TryInstantiate(mContentType, mURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1062,10 +1063,8 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
|
||||
}
|
||||
// E.g. mms://
|
||||
mType = eType_Plugin;
|
||||
if (aNotify)
|
||||
notifier.Notify();
|
||||
|
||||
rv = Instantiate(aTypeHint, aURI);
|
||||
rv = TryInstantiate(aTypeHint, aURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1436,13 +1435,29 @@ nsObjectLoadingContent::GetFrame(PRBool aFlushLayout)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsObjectLoadingContent::Instantiate(const nsACString& aMIMEType, nsIURI* aURI)
|
||||
nsObjectLoadingContent::TryInstantiate(const nsACString& aMIMEType,
|
||||
nsIURI* aURI)
|
||||
{
|
||||
nsIObjectFrame* frame = GetFrame(PR_FALSE);
|
||||
if (!frame) {
|
||||
LOG(("OBJLC [%p]: Attempted to instantiate, but have no frame\n", this));
|
||||
LOG(("OBJLC [%p]: No frame yet\n", this));
|
||||
return NS_OK; // Not a failure to have no frame
|
||||
}
|
||||
nsIFrame* iframe;
|
||||
CallQueryInterface(frame, &iframe);
|
||||
if (iframe->GetStateBits() & NS_FRAME_FIRST_REFLOW) {
|
||||
LOG(("OBJLC [%p]: Frame hasn't been reflown yet\n", this));
|
||||
return NS_OK; // Not a failure to have no frame
|
||||
}
|
||||
return Instantiate(frame, aMIMEType, aURI);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsObjectLoadingContent::Instantiate(nsIObjectFrame* aFrame,
|
||||
const nsACString& aMIMEType,
|
||||
nsIURI* aURI)
|
||||
{
|
||||
NS_ASSERTION(aFrame, "Must have a frame here");
|
||||
|
||||
nsCString typeToUse(aMIMEType);
|
||||
if (typeToUse.IsEmpty() && aURI) {
|
||||
@ -1463,9 +1478,9 @@ nsObjectLoadingContent::Instantiate(const nsACString& aMIMEType, nsIURI* aURI)
|
||||
|
||||
// We'll always have a type or a URI by the time we get here
|
||||
NS_ASSERTION(aURI || !typeToUse.IsEmpty(), "Need a URI or a type");
|
||||
LOG(("OBJLC [%p]: Calling [%p]->Instantiate(<%s>, %p)\n", this, frame,
|
||||
LOG(("OBJLC [%p]: Calling [%p]->Instantiate(<%s>, %p)\n", this, aFrame,
|
||||
typeToUse.get(), aURI));
|
||||
return frame->Instantiate(typeToUse.get(), aURI);
|
||||
return aFrame->Instantiate(typeToUse.get(), aURI);
|
||||
}
|
||||
|
||||
/* static */ PRBool
|
||||
|
@ -284,12 +284,18 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
||||
*/
|
||||
nsIObjectFrame* GetFrame(PRBool aFlushLayout);
|
||||
|
||||
/**
|
||||
* Checks if we have a frame that's ready for instantiation, and if so,
|
||||
* calls Instantiate().
|
||||
*/
|
||||
nsresult TryInstantiate(const nsACString& aMIMEType, nsIURI* aURI);
|
||||
|
||||
/**
|
||||
* Instantiates the plugin. This differs from GetFrame()->Instantiate() in
|
||||
* that it ensures that the URI will be non-null, and that a MIME type
|
||||
* will be passed.
|
||||
*/
|
||||
nsresult Instantiate(const nsACString& aMIMEType, nsIURI* aURI);
|
||||
nsresult Instantiate(nsIObjectFrame* aFrame, const nsACString& aMIMEType, nsIURI* aURI);
|
||||
|
||||
/**
|
||||
* Whether to treat this content as a plugin, even though we can't handle
|
||||
|
@ -506,11 +506,7 @@ nsObjectFrame::Init(nsIContent* aContent,
|
||||
mInstantiating = PR_FALSE;
|
||||
#endif
|
||||
|
||||
nsresult rv = nsObjectFrameSuper::Init(aContent, aParent, aPrevInFlow);
|
||||
nsCOMPtr<nsIObjectLoadingContent> objContent(do_QueryInterface(mContent));
|
||||
NS_ASSERTION(objContent, "Why not an object loading content?");
|
||||
objContent->HasNewFrame(this);
|
||||
return rv;
|
||||
return nsObjectFrameSuper::Init(aContent, aParent, aPrevInFlow);
|
||||
}
|
||||
|
||||
void
|
||||
@ -724,7 +720,6 @@ nsObjectFrame::Reflow(nsPresContext* aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
FixupWindow(nsSize(aMetrics.width, aMetrics.height));
|
||||
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
@ -776,10 +771,6 @@ nsObjectFrame::InstantiatePlugin(nsIPluginHost* aPluginHost,
|
||||
appShell->ResumeNative();
|
||||
}
|
||||
|
||||
// XXX having to do this sucks. it'd be better to move the code from DidReflow
|
||||
// to FixupWindow or something.
|
||||
PresContext()->GetPresShell()->
|
||||
FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -796,11 +787,17 @@ nsObjectFrame::FixupWindow(const nsSize& aSize)
|
||||
|
||||
NS_ENSURE_TRUE(window, /**/);
|
||||
|
||||
nsPoint origin;
|
||||
nsIView *parentWithView;
|
||||
GetOffsetFromView(origin, &parentWithView);
|
||||
window->x = presContext->AppUnitsToDevPixels(origin.x);
|
||||
window->y = presContext->AppUnitsToDevPixels(origin.y);
|
||||
#ifdef XP_MACOSX
|
||||
mInstanceOwner->FixUpPluginWindow(ePluginPaintDisable);
|
||||
#endif
|
||||
|
||||
PRBool windowless = (window->type == nsPluginWindowType_Drawable);
|
||||
|
||||
nsPoint origin = GetWindowOriginInPixels(windowless);
|
||||
|
||||
window->x = origin.x;
|
||||
window->y = origin.y;
|
||||
|
||||
window->width = presContext->AppUnitsToDevPixels(aSize.width);
|
||||
window->height = presContext->AppUnitsToDevPixels(aSize.height);
|
||||
|
||||
@ -896,6 +893,15 @@ nsObjectFrame::DidReflow(nsPresContext* aPresContext,
|
||||
const nsHTMLReflowState* aReflowState,
|
||||
nsDidReflowStatus aStatus)
|
||||
{
|
||||
// Do this check before calling the superclass, as that clears
|
||||
// NS_FRAME_FIRST_REFLOW
|
||||
if (aStatus == NS_FRAME_REFLOW_FINISHED &&
|
||||
(GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
|
||||
nsCOMPtr<nsIObjectLoadingContent> objContent(do_QueryInterface(mContent));
|
||||
NS_ASSERTION(objContent, "Why not an object loading content?");
|
||||
objContent->HasNewFrame(this);
|
||||
}
|
||||
|
||||
nsresult rv = nsObjectFrameSuper::DidReflow(aPresContext, aReflowState, aStatus);
|
||||
|
||||
// The view is created hidden; once we have reflowed it and it has been
|
||||
@ -1391,11 +1397,6 @@ nsObjectFrame::Instantiate(nsIChannel* aChannel, nsIStreamListener** aStreamList
|
||||
|
||||
rv = pluginHost->InstantiatePluginForChannel(aChannel, mInstanceOwner, aStreamListener);
|
||||
|
||||
// XXX having to do this sucks. it'd be better to move the code from DidReflow
|
||||
// to FixupWindow.
|
||||
PresContext()->GetPresShell()->
|
||||
FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user