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
|
// the type here - GetFrame() only returns object frames, and that means we're
|
||||||
// a plugin)
|
// a plugin)
|
||||||
// Also make sure that we still refer to the same data.
|
// 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->mURI == mURI &&
|
||||||
mContent->mContentType.Equals(mContentType)) {
|
mContent->mContentType.Equals(mContentType)) {
|
||||||
if (LOG_ENABLED()) {
|
if (LOG_ENABLED()) {
|
||||||
@ -140,7 +141,7 @@ nsAsyncInstantiateEvent::Run()
|
|||||||
mContent, mContentType.get(), mURI.get(), spec.get()));
|
mContent, mContentType.get(), mURI.get(), spec.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult rv = mContent->Instantiate(mContentType, mURI);
|
nsresult rv = mContent->Instantiate(frame, mContentType, mURI);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
mContent->Fallback(PR_TRUE);
|
mContent->Fallback(PR_TRUE);
|
||||||
}
|
}
|
||||||
@ -643,7 +644,7 @@ nsObjectLoadingContent::EnsureInstantiation(nsIPluginInstance** aInstance)
|
|||||||
// We may have a plugin instance already; if so, do nothing
|
// We may have a plugin instance already; if so, do nothing
|
||||||
nsresult rv = frame->GetPluginInstance(*aInstance);
|
nsresult rv = frame->GetPluginInstance(*aInstance);
|
||||||
if (!*aInstance) {
|
if (!*aInstance) {
|
||||||
rv = Instantiate(mContentType, mURI);
|
rv = Instantiate(frame, mContentType, mURI);
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
rv = frame->GetPluginInstance(*aInstance);
|
rv = frame->GetPluginInstance(*aInstance);
|
||||||
} else {
|
} else {
|
||||||
@ -931,6 +932,7 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
|
|||||||
if (overrideType.IsEmpty()) {
|
if (overrideType.IsEmpty()) {
|
||||||
newType = GetTypeOfContent(aTypeHint);
|
newType = GetTypeOfContent(aTypeHint);
|
||||||
} else {
|
} else {
|
||||||
|
mContentType = overrideType;
|
||||||
newType = eType_Plugin;
|
newType = eType_Plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -957,6 +959,7 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
|
|||||||
// Must notify here for plugins
|
// Must notify here for plugins
|
||||||
// If aNotify is false, we'll just wait until we get a frame and use the
|
// If aNotify is false, we'll just wait until we get a frame and use the
|
||||||
// async instantiate path.
|
// async instantiate path.
|
||||||
|
// XXX is this still needed? (for documents?)
|
||||||
mType = newType;
|
mType = newType;
|
||||||
if (aNotify)
|
if (aNotify)
|
||||||
notifier.Notify();
|
notifier.Notify();
|
||||||
@ -967,7 +970,7 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
|
|||||||
rv = LoadImage(aURI, aForceLoad, PR_FALSE);
|
rv = LoadImage(aURI, aForceLoad, PR_FALSE);
|
||||||
break;
|
break;
|
||||||
case eType_Plugin:
|
case eType_Plugin:
|
||||||
rv = Instantiate(aTypeHint, aURI);
|
rv = TryInstantiate(mContentType, mURI);
|
||||||
break;
|
break;
|
||||||
case eType_Document:
|
case eType_Document:
|
||||||
rv = mFrameLoader->LoadURI(aURI);
|
rv = mFrameLoader->LoadURI(aURI);
|
||||||
@ -1019,8 +1022,6 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
|
|||||||
// Or: supported class id, plugin will handle the load.
|
// Or: supported class id, plugin will handle the load.
|
||||||
LOG(("OBJLC [%p]: (classid) Changing type from %u to eType_Plugin\n", this, mType));
|
LOG(("OBJLC [%p]: (classid) Changing type from %u to eType_Plugin\n", this, mType));
|
||||||
mType = eType_Plugin;
|
mType = eType_Plugin;
|
||||||
if (aNotify)
|
|
||||||
notifier.Notify();
|
|
||||||
|
|
||||||
// At this point, the stored content type
|
// At this point, the stored content type
|
||||||
// must be equal to our type hint. Similar,
|
// 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;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1062,10 +1063,8 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
|
|||||||
}
|
}
|
||||||
// E.g. mms://
|
// E.g. mms://
|
||||||
mType = eType_Plugin;
|
mType = eType_Plugin;
|
||||||
if (aNotify)
|
|
||||||
notifier.Notify();
|
|
||||||
|
|
||||||
rv = Instantiate(aTypeHint, aURI);
|
rv = TryInstantiate(aTypeHint, aURI);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1436,13 +1435,29 @@ nsObjectLoadingContent::GetFrame(PRBool aFlushLayout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsObjectLoadingContent::Instantiate(const nsACString& aMIMEType, nsIURI* aURI)
|
nsObjectLoadingContent::TryInstantiate(const nsACString& aMIMEType,
|
||||||
|
nsIURI* aURI)
|
||||||
{
|
{
|
||||||
nsIObjectFrame* frame = GetFrame(PR_FALSE);
|
nsIObjectFrame* frame = GetFrame(PR_FALSE);
|
||||||
if (!frame) {
|
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
|
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);
|
nsCString typeToUse(aMIMEType);
|
||||||
if (typeToUse.IsEmpty() && aURI) {
|
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
|
// 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");
|
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));
|
typeToUse.get(), aURI));
|
||||||
return frame->Instantiate(typeToUse.get(), aURI);
|
return aFrame->Instantiate(typeToUse.get(), aURI);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ PRBool
|
/* static */ PRBool
|
||||||
|
@ -284,12 +284,18 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
|||||||
*/
|
*/
|
||||||
nsIObjectFrame* GetFrame(PRBool aFlushLayout);
|
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
|
* Instantiates the plugin. This differs from GetFrame()->Instantiate() in
|
||||||
* that it ensures that the URI will be non-null, and that a MIME type
|
* that it ensures that the URI will be non-null, and that a MIME type
|
||||||
* will be passed.
|
* 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
|
* 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;
|
mInstantiating = PR_FALSE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsresult rv = nsObjectFrameSuper::Init(aContent, aParent, aPrevInFlow);
|
return 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -724,7 +720,6 @@ nsObjectFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FixupWindow(nsSize(aMetrics.width, aMetrics.height));
|
FixupWindow(nsSize(aMetrics.width, aMetrics.height));
|
||||||
|
|
||||||
aStatus = NS_FRAME_COMPLETE;
|
aStatus = NS_FRAME_COMPLETE;
|
||||||
@ -776,10 +771,6 @@ nsObjectFrame::InstantiatePlugin(nsIPluginHost* aPluginHost,
|
|||||||
appShell->ResumeNative();
|
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;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -796,11 +787,17 @@ nsObjectFrame::FixupWindow(const nsSize& aSize)
|
|||||||
|
|
||||||
NS_ENSURE_TRUE(window, /**/);
|
NS_ENSURE_TRUE(window, /**/);
|
||||||
|
|
||||||
nsPoint origin;
|
#ifdef XP_MACOSX
|
||||||
nsIView *parentWithView;
|
mInstanceOwner->FixUpPluginWindow(ePluginPaintDisable);
|
||||||
GetOffsetFromView(origin, &parentWithView);
|
#endif
|
||||||
window->x = presContext->AppUnitsToDevPixels(origin.x);
|
|
||||||
window->y = presContext->AppUnitsToDevPixels(origin.y);
|
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->width = presContext->AppUnitsToDevPixels(aSize.width);
|
||||||
window->height = presContext->AppUnitsToDevPixels(aSize.height);
|
window->height = presContext->AppUnitsToDevPixels(aSize.height);
|
||||||
|
|
||||||
@ -896,6 +893,15 @@ nsObjectFrame::DidReflow(nsPresContext* aPresContext,
|
|||||||
const nsHTMLReflowState* aReflowState,
|
const nsHTMLReflowState* aReflowState,
|
||||||
nsDidReflowStatus aStatus)
|
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);
|
nsresult rv = nsObjectFrameSuper::DidReflow(aPresContext, aReflowState, aStatus);
|
||||||
|
|
||||||
// The view is created hidden; once we have reflowed it and it has been
|
// 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);
|
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;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user