mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-16 22:04:36 +00:00
Bug 339548. Part 9: Create nsRootPresContext::UpdatePluginGeometry, and use it. Make nsObjectFrame manage its widget directly.
This commit is contained in:
parent
3da1f8631b
commit
dce2b0d98a
@ -95,7 +95,6 @@
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsIPrefBranch2.h"
|
||||
#include "nsIObjectFrame.h"
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsXULPopupManager.h"
|
||||
#endif
|
||||
|
@ -1534,9 +1534,7 @@ nsFocusManager::Focus(nsPIDOMWindow* aWindow,
|
||||
nsIFrame* contentFrame = presShell->GetPrimaryFrameFor(aContent);
|
||||
nsIObjectFrame* objectFrame = do_QueryFrame(contentFrame);
|
||||
if (objectFrame) {
|
||||
nsIView* view = contentFrame->GetViewExternal();
|
||||
NS_ASSERTION(view, "Object frames must have views");
|
||||
nsCOMPtr<nsIWidget> widget = view->GetWidget();
|
||||
nsIWidget* widget = objectFrame->GetWidget();
|
||||
if (widget)
|
||||
widget->SetFocus(PR_TRUE);
|
||||
}
|
||||
|
@ -7712,7 +7712,8 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
|
||||
// processing restyles
|
||||
BeginUpdate();
|
||||
|
||||
nsPropertyTable *propTable = mPresShell->GetPresContext()->PropertyTable();
|
||||
nsPresContext* presContext = mPresShell->GetPresContext();
|
||||
nsPropertyTable *propTable = presContext->PropertyTable();
|
||||
|
||||
// Mark frames so that we skip frames that die along the way, bug 123049.
|
||||
// A frame can be in the list multiple times with different hints. Further
|
||||
@ -7730,6 +7731,9 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
|
||||
}
|
||||
|
||||
index = count;
|
||||
PRBool didInvalidate = PR_FALSE;
|
||||
PRBool didReflow = PR_FALSE;
|
||||
|
||||
while (0 <= --index) {
|
||||
nsIFrame* frame;
|
||||
nsIContent* content;
|
||||
@ -7765,9 +7769,11 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
|
||||
#endif
|
||||
if (hint & nsChangeHint_ReflowFrame) {
|
||||
StyleChangeReflow(frame);
|
||||
didReflow = PR_TRUE;
|
||||
}
|
||||
if (hint & (nsChangeHint_RepaintFrame | nsChangeHint_SyncFrameView)) {
|
||||
ApplyRenderingChangeToTree(mPresShell->GetPresContext(), frame, hint);
|
||||
ApplyRenderingChangeToTree(presContext, frame, hint);
|
||||
didInvalidate = PR_TRUE;
|
||||
}
|
||||
if (hint & nsChangeHint_UpdateCursor) {
|
||||
nsIViewManager* viewMgr = mPresShell->GetViewManager();
|
||||
@ -7778,7 +7784,15 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
|
||||
}
|
||||
|
||||
EndUpdate();
|
||||
|
||||
|
||||
if (didInvalidate && !didReflow) {
|
||||
// RepaintFrame changes can indicate changes in opacity etc which
|
||||
// can require plugin clipping to change. If we requested a reflow,
|
||||
// we don't need to do this since the reflow will do it for us.
|
||||
nsIFrame* rootFrame = mPresShell->FrameManager()->GetRootFrame();
|
||||
presContext->RootPresContext()->UpdatePluginGeometry(rootFrame);
|
||||
}
|
||||
|
||||
// cleanup references and verify the style tree. Note that the latter needs
|
||||
// to happen once we've processed the whole list, since until then the tree
|
||||
// is not in fact in a consistent state.
|
||||
|
@ -389,15 +389,17 @@ public:
|
||||
*/
|
||||
enum Type {
|
||||
TYPE_GENERIC,
|
||||
TYPE_OUTLINE,
|
||||
|
||||
TYPE_BORDER,
|
||||
TYPE_CLIP,
|
||||
TYPE_OPACITY,
|
||||
TYPE_OUTLINE,
|
||||
TYPE_PLUGIN,
|
||||
#ifdef MOZ_SVG
|
||||
TYPE_SVG_EFFECTS,
|
||||
#endif
|
||||
TYPE_WRAPLIST,
|
||||
TYPE_TRANSFORM,
|
||||
TYPE_BORDER
|
||||
TYPE_WRAPLIST
|
||||
};
|
||||
|
||||
struct HitTestState {
|
||||
|
@ -93,6 +93,7 @@
|
||||
#include "prenv.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsObjectFrame.h"
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
#include "nsSMILAnimationController.h"
|
||||
@ -2156,4 +2157,176 @@ nsRootPresContext::nsRootPresContext(nsIDocument* aDocument,
|
||||
nsPresContextType aType)
|
||||
: nsPresContext(aDocument, aType)
|
||||
{
|
||||
mRegisteredPlugins.Init();
|
||||
}
|
||||
|
||||
nsRootPresContext::~nsRootPresContext()
|
||||
{
|
||||
NS_ASSERTION(mRegisteredPlugins.Count() == 0,
|
||||
"All plugins should have been unregistered");
|
||||
}
|
||||
|
||||
void
|
||||
nsRootPresContext::RegisterPluginForGeometryUpdates(nsObjectFrame* aPlugin)
|
||||
{
|
||||
mRegisteredPlugins.PutEntry(aPlugin);
|
||||
}
|
||||
|
||||
void
|
||||
nsRootPresContext::UnregisterPluginForGeometryUpdates(nsObjectFrame* aPlugin)
|
||||
{
|
||||
mRegisteredPlugins.RemoveEntry(aPlugin);
|
||||
}
|
||||
|
||||
struct PluginGeometryClosure {
|
||||
nsIFrame* mRootFrame;
|
||||
nsIFrame* mChangedSubtree;
|
||||
nsRect mChangedRect;
|
||||
nsTHashtable<nsPtrHashKey<nsObjectFrame> > mAffectedPlugins;
|
||||
nsRect mAffectedPluginBounds;
|
||||
nsTArray<nsIWidget::Configuration>* mOutputConfigurations;
|
||||
};
|
||||
static PLDHashOperator
|
||||
PluginBoundsEnumerator(nsPtrHashKey<nsObjectFrame>* aEntry, void* userArg)
|
||||
{
|
||||
PluginGeometryClosure* closure = static_cast<PluginGeometryClosure*>(userArg);
|
||||
nsObjectFrame* f = aEntry->GetKey();
|
||||
nsRect fBounds = f->GetContentRect() +
|
||||
f->GetParent()->GetOffsetTo(closure->mRootFrame);
|
||||
// We're identifying the plugins that may have been affected by changes
|
||||
// to the frame subtree rooted at aChangedRoot. Any plugin that overlaps
|
||||
// the overflow area of aChangedRoot could have its clip region affected
|
||||
// because it might be covered (or uncovered) by changes to the subtree.
|
||||
// Plugins in the subtree might have changed position and/or size, and
|
||||
// they might not be in aChangedRoot's overflow area (because they're
|
||||
// being clipped by an ancestor in the subtree).
|
||||
if (fBounds.Intersects(closure->mChangedRect) ||
|
||||
nsLayoutUtils::IsAncestorFrameCrossDoc(closure->mChangedSubtree, f)) {
|
||||
closure->mAffectedPluginBounds.UnionRect(
|
||||
closure->mAffectedPluginBounds, fBounds);
|
||||
closure->mAffectedPlugins.PutEntry(f);
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
PluginHideEnumerator(nsPtrHashKey<nsObjectFrame>* aEntry, void* userArg)
|
||||
{
|
||||
PluginGeometryClosure* closure = static_cast<PluginGeometryClosure*>(userArg);
|
||||
nsObjectFrame* f = aEntry->GetKey();
|
||||
f->GetEmptyClipConfiguration(closure->mOutputConfigurations);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static void
|
||||
RecoverPluginGeometry(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayList* aList, PluginGeometryClosure* aClosure)
|
||||
{
|
||||
for (nsDisplayItem* i = aList->GetBottom(); i; i = i->GetAbove()) {
|
||||
switch (i->GetType()) {
|
||||
case nsDisplayItem::TYPE_PLUGIN: {
|
||||
nsDisplayPlugin* displayPlugin = static_cast<nsDisplayPlugin*>(i);
|
||||
nsObjectFrame* f = static_cast<nsObjectFrame*>(
|
||||
displayPlugin->GetUnderlyingFrame());
|
||||
// Ignore plugins which aren't supposed to be affected by this
|
||||
// operation --- their bounds will not have been included in the
|
||||
// display list computations so the visible region computed for them
|
||||
// would be incorrect
|
||||
nsPtrHashKey<nsObjectFrame>* entry =
|
||||
aClosure->mAffectedPlugins.GetEntry(f);
|
||||
if (entry) {
|
||||
displayPlugin->GetWidgetConfiguration(aBuilder,
|
||||
aClosure->mOutputConfigurations);
|
||||
// we've dealt with this plugin now
|
||||
aClosure->mAffectedPlugins.RawRemoveEntry(entry);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
nsDisplayList* sublist = i->GetList();
|
||||
if (sublist) {
|
||||
RecoverPluginGeometry(aBuilder, sublist, aClosure);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <stdio.h>
|
||||
|
||||
static PRBool gDumpPluginList = PR_FALSE;
|
||||
#endif
|
||||
|
||||
void
|
||||
nsRootPresContext::GetPluginGeometryUpdates(nsIFrame* aChangedSubtree,
|
||||
nsTArray<nsIWidget::Configuration>* aConfigurations)
|
||||
{
|
||||
if (mRegisteredPlugins.Count() == 0)
|
||||
return;
|
||||
|
||||
PluginGeometryClosure closure;
|
||||
closure.mRootFrame = mShell->FrameManager()->GetRootFrame();
|
||||
closure.mChangedSubtree = aChangedSubtree;
|
||||
closure.mChangedRect = aChangedSubtree->GetOverflowRect() +
|
||||
aChangedSubtree->GetOffsetTo(closure.mRootFrame);
|
||||
closure.mAffectedPlugins.Init();
|
||||
closure.mOutputConfigurations = aConfigurations;
|
||||
// Fill in closure.mAffectedPlugins and closure.mAffectedPluginBounds
|
||||
mRegisteredPlugins.EnumerateEntries(PluginBoundsEnumerator, &closure);
|
||||
|
||||
nsRect bounds;
|
||||
if (bounds.IntersectRect(closure.mAffectedPluginBounds,
|
||||
closure.mRootFrame->GetRect())) {
|
||||
// It's OK to disable GetUsedX assertions because after a reflow,
|
||||
// any changed geometry will cause UpdatePluginGeometry to happen
|
||||
// again.
|
||||
nsAutoDisableGetUsedXAssertions disableAssertions;
|
||||
|
||||
nsDisplayListBuilder builder(closure.mRootFrame, PR_FALSE, PR_FALSE);
|
||||
builder.SetAccurateVisibleRegions();
|
||||
nsDisplayList list;
|
||||
|
||||
builder.EnterPresShell(closure.mRootFrame, bounds);
|
||||
closure.mRootFrame->BuildDisplayListForStackingContext(
|
||||
&builder, bounds, &list);
|
||||
builder.LeavePresShell(closure.mRootFrame, bounds);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (gDumpPluginList) {
|
||||
fprintf(stderr, "Plugins --- before optimization (bounds %d,%d,%d,%d):\n",
|
||||
bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
nsIFrameDebug::PrintDisplayList(&builder, list);
|
||||
}
|
||||
#endif
|
||||
|
||||
nsRegion visibleRegion(bounds);
|
||||
list.OptimizeVisibility(&builder, &visibleRegion);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (gDumpPluginList) {
|
||||
fprintf(stderr, "Plugins --- after optimization:\n");
|
||||
nsIFrameDebug::PrintDisplayList(&builder, list);
|
||||
}
|
||||
#endif
|
||||
|
||||
RecoverPluginGeometry(&builder, &list, &closure);
|
||||
list.DeleteAll();
|
||||
}
|
||||
|
||||
// Plugins that we didn't find in the display list are not visible
|
||||
closure.mAffectedPlugins.EnumerateEntries(PluginHideEnumerator, &closure);
|
||||
}
|
||||
|
||||
void
|
||||
nsRootPresContext::UpdatePluginGeometry(nsIFrame* aChangedSubtree)
|
||||
{
|
||||
nsTArray<nsIWidget::Configuration> configurations;
|
||||
GetPluginGeometryUpdates(aChangedSubtree, &configurations);
|
||||
if (configurations.IsEmpty())
|
||||
return;
|
||||
nsIWidget* widget = configurations[0].mChild->GetParent();
|
||||
NS_ASSERTION(widget, "Plugin must have a parent");
|
||||
widget->ConfigureChildren(configurations);
|
||||
}
|
||||
|
@ -70,6 +70,7 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
class nsImageLoader;
|
||||
#ifdef IBMBIDI
|
||||
@ -98,6 +99,7 @@ class nsIRunnable;
|
||||
class gfxUserFontSet;
|
||||
class nsUserFontSet;
|
||||
struct nsFontFaceRuleContainer;
|
||||
class nsObjectFrame;
|
||||
|
||||
#ifdef MOZ_REFLOW_PERF
|
||||
class nsIRenderingContext;
|
||||
@ -1066,6 +1068,42 @@ public:
|
||||
class nsRootPresContext : public nsPresContext {
|
||||
public:
|
||||
nsRootPresContext(nsIDocument* aDocument, nsPresContextType aType) NS_HIDDEN;
|
||||
virtual ~nsRootPresContext();
|
||||
|
||||
/**
|
||||
* Registers a plugin to receive geometry updates (position and clip
|
||||
* region) so it can update its widget.
|
||||
* Callers must call UnregisterPluginForGeometryUpdates before
|
||||
* the aPlugin frame is destroyed.
|
||||
*/
|
||||
void RegisterPluginForGeometryUpdates(nsObjectFrame* aPlugin);
|
||||
/**
|
||||
* Stops a plugin receiving geometry updates (position and clip
|
||||
* region). If the plugin was not already registered, this does
|
||||
* nothing.
|
||||
*/
|
||||
void UnregisterPluginForGeometryUpdates(nsObjectFrame* aPlugin);
|
||||
|
||||
/**
|
||||
* Iterate through all plugins that are registered for geometry updates
|
||||
* and update their position and clip region to match the current frame
|
||||
* tree. Only frames at or under aChangedRoot can have changed their
|
||||
* geometry.
|
||||
*/
|
||||
void UpdatePluginGeometry(nsIFrame* aChangedRoot);
|
||||
|
||||
/**
|
||||
* Iterate through all plugins that are registered for geometry updates
|
||||
* and compute their position and clip region according to the
|
||||
* current frame tree. Only frames at or under aChangedRoot can have
|
||||
* changed their geometry. The computed positions and clip regions are
|
||||
* appended to aConfigurations.
|
||||
*/
|
||||
void GetPluginGeometryUpdates(nsIFrame* aChangedRoot,
|
||||
nsTArray<nsIWidget::Configuration>* aConfigurations);
|
||||
|
||||
private:
|
||||
nsTHashtable<nsPtrHashKey<nsObjectFrame> > mRegisteredPlugins;
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -4629,6 +4629,8 @@ PresShell::UnsuppressAndInvalidate()
|
||||
rootFrame->Invalidate(rect);
|
||||
}
|
||||
|
||||
mPresContext->RootPresContext()->UpdatePluginGeometry(rootFrame);
|
||||
|
||||
// now that painting is unsuppressed, focus may be set on the document
|
||||
nsPIDOMWindow *win = mDocument->GetWindow();
|
||||
if (win)
|
||||
@ -7229,6 +7231,8 @@ PresShell::DoReflow(nsIFrame* target, PRBool aInterruptible)
|
||||
PostReflowEvent();
|
||||
}
|
||||
|
||||
mPresContext->RootPresContext()->UpdatePluginGeometry(target);
|
||||
|
||||
return !interrupted;
|
||||
}
|
||||
|
||||
|
@ -1816,6 +1816,9 @@ nsGfxScrollFrameInner::ScrollPositionDidChange(nsIScrollableView* aScrollable, n
|
||||
// Notify that the display has changed
|
||||
mOuter->InvalidateWithFlags(nsRect(nsPoint(0, 0), mOuter->GetSize()),
|
||||
nsIFrame::INVALIDATE_NOTIFY_ONLY);
|
||||
|
||||
mOuter->PresContext()->RootPresContext()->UpdatePluginGeometry(mOuter);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1579,6 +1579,8 @@ public:
|
||||
*
|
||||
* This function is fastest when aOther is an ancestor of |this|.
|
||||
*
|
||||
* This function works across document boundaries.
|
||||
*
|
||||
* NOTE: this actually returns the offset from aOther to |this|, but
|
||||
* that offset is added to transform _coordinates_ from |this| to
|
||||
* aOther.
|
||||
|
@ -89,6 +89,11 @@ public:
|
||||
* is currently active in this frame.
|
||||
*/
|
||||
virtual void StopPlugin() = 0;
|
||||
|
||||
/**
|
||||
* Get the native widget for the plugin, if any.
|
||||
*/
|
||||
virtual nsIWidget* GetWidget() = 0;
|
||||
};
|
||||
|
||||
#endif /* nsIObjectFrame_h___ */
|
||||
|
@ -116,6 +116,8 @@
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsFrameManager.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
// headers for plugin scriptability
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
@ -597,10 +599,19 @@ nsObjectFrame::Destroy()
|
||||
(mContent && mContent->GetCurrentDoc()->GetDisplayDocument()),
|
||||
"about to crash due to bug 136927");
|
||||
|
||||
PresContext()->RootPresContext()->UnregisterPluginForGeometryUpdates(this);
|
||||
|
||||
// we need to finish with the plugin before native window is destroyed
|
||||
// doing this in the destructor is too late.
|
||||
StopPluginInternal(PR_TRUE);
|
||||
|
||||
|
||||
// StopPluginInternal might have disowned the widget; if it has,
|
||||
// mWidget will be null.
|
||||
if (mWidget) {
|
||||
GetView()->DetachWidgetEventHandler(mWidget);
|
||||
mWidget->Destroy();
|
||||
}
|
||||
|
||||
nsObjectFrameSuper::Destroy();
|
||||
}
|
||||
|
||||
@ -640,6 +651,8 @@ nsObjectFrame::CreateWidgetForView(nsIView* aView)
|
||||
// Bug 179822: Create widget and allow non-unicode SubClass
|
||||
nsWidgetInitData initData;
|
||||
initData.mUnicode = PR_FALSE;
|
||||
initData.clipChildren = PR_TRUE;
|
||||
initData.clipSiblings = PR_TRUE;
|
||||
return aView->CreateWidget(kWidgetCID, &initData);
|
||||
}
|
||||
|
||||
@ -659,6 +672,11 @@ nsObjectFrame::CreateWidget(nscoord aWidth,
|
||||
// XXX is the above comment correct?
|
||||
viewMan->SetViewVisibility(view, nsViewVisibility_kHide);
|
||||
|
||||
PRBool usewidgets;
|
||||
nsCOMPtr<nsIDeviceContext> dx;
|
||||
viewMan->GetDeviceContext(*getter_AddRefs(dx));
|
||||
dx->SupportsNativeWidgets(usewidgets);
|
||||
|
||||
//this is ugly. it was ripped off from didreflow(). MMP
|
||||
// Position and size view relative to its parent, not relative to our
|
||||
// parent frame (our parent frame may not have a view).
|
||||
@ -671,14 +689,38 @@ nsObjectFrame::CreateWidget(nscoord aWidth,
|
||||
viewMan->ResizeView(view, r);
|
||||
viewMan->MoveViewTo(view, origin.x, origin.y);
|
||||
|
||||
if (!aViewOnly && !view->HasWidget()) {
|
||||
nsresult rv = CreateWidgetForView(view);
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_OK; //XXX why OK? MMP
|
||||
}
|
||||
if (!aViewOnly && !mWidget && usewidgets) {
|
||||
nsresult rv;
|
||||
mWidget = do_CreateInstance(kWidgetCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsRootPresContext* rpc = PresContext()->RootPresContext();
|
||||
// XXX this breaks plugins in popups ... do we care?
|
||||
nsIWidget* parentWidget =
|
||||
rpc->PresShell()->FrameManager()->GetRootFrame()->GetWindow();
|
||||
|
||||
nsWidgetInitData initData;
|
||||
initData.mUnicode = PR_FALSE;
|
||||
initData.clipChildren = PR_TRUE;
|
||||
initData.clipSiblings = PR_TRUE;
|
||||
// We want mWidget to be able to deliver events to us, especially on
|
||||
// Mac where events to the plugin are routed through Gecko. So we
|
||||
// allow the view to attach its event handler to mWidget even though
|
||||
// mWidget isn't the view's designated widget.
|
||||
EVENT_CALLBACK eventHandler = view->AttachWidgetEventHandler(mWidget);
|
||||
mWidget->Create(parentWidget, nsIntRect(0,0,0,0),
|
||||
eventHandler, dx, nsnull, nsnull, &initData);
|
||||
|
||||
mWidget->EnableDragDrop(PR_TRUE);
|
||||
|
||||
rpc->RegisterPluginForGeometryUpdates(this);
|
||||
rpc->UpdatePluginGeometry(this);
|
||||
|
||||
mWidget->Show(PR_TRUE);
|
||||
}
|
||||
|
||||
{
|
||||
if (mWidget) {
|
||||
// Here we set the background color for this widget because some plugins will use
|
||||
// the child window background color when painting. If it's not set, it may default to gray
|
||||
// Sometimes, a frame doesn't have a background color or is transparent. In this
|
||||
@ -686,13 +728,10 @@ nsObjectFrame::CreateWidget(nscoord aWidth,
|
||||
for (nsIFrame* frame = this; frame; frame = frame->GetParent()) {
|
||||
const nsStyleBackground* background = frame->GetStyleBackground();
|
||||
if (!background->IsTransparent()) { // make sure we got an actual color
|
||||
nsIWidget* win = view->GetWidget();
|
||||
if (win)
|
||||
win->SetBackgroundColor(background->mBackgroundColor);
|
||||
mWidget->SetBackgroundColor(background->mBackgroundColor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!IsHidden()) {
|
||||
@ -1071,11 +1110,97 @@ nsObjectFrame::PaintPrintPlugin(nsIFrame* aFrame, nsIRenderingContext* aCtx,
|
||||
static_cast<nsObjectFrame*>(aFrame)->PrintPlugin(*aCtx, aDirtyRect);
|
||||
}
|
||||
|
||||
/*static */ void
|
||||
nsObjectFrame::PaintPlugin(nsIFrame* aFrame, nsIRenderingContext* aCtx,
|
||||
const nsRect& aDirtyRect, nsPoint aPt)
|
||||
nsRect
|
||||
nsDisplayPlugin::GetBounds(nsDisplayListBuilder* aBuilder)
|
||||
{
|
||||
static_cast<nsObjectFrame*>(aFrame)->PaintPlugin(*aCtx, aDirtyRect, aPt);
|
||||
return mFrame->GetContentRect() +
|
||||
aBuilder->ToReferenceFrame(mFrame->GetParent());
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayPlugin::Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsIRenderingContext* aCtx,
|
||||
const nsRect& aDirtyRect)
|
||||
{
|
||||
nsObjectFrame* f = static_cast<nsObjectFrame*>(mFrame);
|
||||
f->PaintPlugin(*aCtx, aDirtyRect, GetBounds(aBuilder).TopLeft());
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsDisplayPlugin::OptimizeVisibility(nsDisplayListBuilder* aBuilder,
|
||||
nsRegion* aVisibleRegion)
|
||||
{
|
||||
mVisibleRegion.And(*aVisibleRegion, GetBounds(aBuilder));
|
||||
return nsDisplayItem::OptimizeVisibility(aBuilder, aVisibleRegion);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsDisplayPlugin::IsOpaque(nsDisplayListBuilder* aBuilder)
|
||||
{
|
||||
nsObjectFrame* f = static_cast<nsObjectFrame*>(mFrame);
|
||||
return f->IsOpaque();
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayPlugin::GetWidgetConfiguration(nsDisplayListBuilder* aBuilder,
|
||||
nsTArray<nsIWidget::Configuration>* aConfigurations)
|
||||
{
|
||||
nsObjectFrame* f = static_cast<nsObjectFrame*>(mFrame);
|
||||
f->ComputeWidgetGeometry(mVisibleRegion, aBuilder->ToReferenceFrame(mFrame),
|
||||
aConfigurations);
|
||||
}
|
||||
|
||||
void
|
||||
nsObjectFrame::ComputeWidgetGeometry(const nsRegion& aRegion,
|
||||
const nsPoint& aPluginOrigin,
|
||||
nsTArray<nsIWidget::Configuration>* aConfigurations)
|
||||
{
|
||||
if (!mWidget)
|
||||
return;
|
||||
|
||||
nsIWidget::Configuration* configuration =
|
||||
aConfigurations->AppendElement();
|
||||
if (!configuration)
|
||||
return;
|
||||
configuration->mChild = mWidget;
|
||||
|
||||
nsPresContext* presContext = PresContext();
|
||||
PRInt32 appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
|
||||
nsIFrame* rootFrame =
|
||||
presContext->RootPresContext()->PresShell()->FrameManager()->GetRootFrame();
|
||||
nsRect bounds = GetContentRect() + GetParent()->GetOffsetTo(rootFrame);
|
||||
configuration->mBounds = bounds.ToNearestPixels(appUnitsPerDevPixel);
|
||||
|
||||
nsRegionRectIterator iter(aRegion);
|
||||
nsIntPoint pluginOrigin = aPluginOrigin.ToNearestPixels(appUnitsPerDevPixel);
|
||||
for (const nsRect* r = iter.Next(); r; r = iter.Next()) {
|
||||
// Snap *r to pixels while it's relative to the painted widget, to
|
||||
// improve consistency with rectangle and image drawing
|
||||
nsIntRect pixRect =
|
||||
r->ToNearestPixels(appUnitsPerDevPixel) - pluginOrigin;
|
||||
if (!pixRect.IsEmpty()) {
|
||||
configuration->mClipRegion.AppendElement(pixRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsObjectFrame::IsOpaque() const
|
||||
{
|
||||
#if defined(XP_MACOSX)
|
||||
return PR_FALSE;
|
||||
#else
|
||||
if (mInstanceOwner) {
|
||||
nsPluginWindow * window;
|
||||
mInstanceOwner->GetWindow(window);
|
||||
if (window->type == nsPluginWindowType_Drawable) {
|
||||
// XXX we possibly should call nsPluginInstanceVariable_TransparentBool
|
||||
// here to optimize for windowless but opaque plugins
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
return PR_TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1104,7 +1229,7 @@ nsObjectFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayGeneric(this, PaintPrintPlugin, "PrintPlugin"));
|
||||
|
||||
return aLists.Content()->AppendNewToTop(new (aBuilder)
|
||||
nsDisplayGeneric(this, PaintPlugin, "Plugin"));
|
||||
nsDisplayPlugin(this));
|
||||
}
|
||||
|
||||
void
|
||||
@ -2122,17 +2247,12 @@ nsObjectFrame::StopPluginInternal(PRBool aDelayedStop)
|
||||
nsWeakFrame weakFrame(this);
|
||||
|
||||
#if defined(XP_WIN) || defined(MOZ_X11)
|
||||
if (aDelayedStop) {
|
||||
if (aDelayedStop && mWidget) {
|
||||
// If we're asked to do a delayed stop it means we're stopping the
|
||||
// plugin because we're destroying the frame. In that case, tell
|
||||
// the view to disown the widget (i.e. leave it up to us to
|
||||
// destroy it).
|
||||
|
||||
// Disown the view while we still know it's safe to do so.
|
||||
nsIView *view = GetView();
|
||||
if (view) {
|
||||
view->DisownWidget();
|
||||
}
|
||||
// plugin because we're destroying the frame. In that case, disown
|
||||
// the widget.
|
||||
GetView()->DetachWidgetEventHandler(mWidget);
|
||||
mWidget = nsnull;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -4855,11 +4975,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
|
||||
context->DevPixelsToAppUnits(mPluginWindow->height),
|
||||
windowless);
|
||||
if (NS_OK == rv) {
|
||||
view = mOwner->GetView();
|
||||
|
||||
if (view) {
|
||||
mWidget = view->GetWidget();
|
||||
}
|
||||
mWidget = mOwner->GetWidget();
|
||||
|
||||
if (PR_TRUE == windowless) {
|
||||
mPluginWindow->type = nsPluginWindowType_Drawable;
|
||||
@ -4938,23 +5054,16 @@ WindowRef nsPluginInstanceOwner::FixUpPluginWindow(PRInt32 inPaintState)
|
||||
if (!pluginPort)
|
||||
return nsnull;
|
||||
|
||||
// first, check our view for CSS visibility style
|
||||
PRBool isVisible =
|
||||
mOwner->GetView()->GetVisibility() == nsViewVisibility_kShow;
|
||||
|
||||
nsCOMPtr<nsIPluginWidget> pluginWidget = do_QueryInterface(mWidget);
|
||||
|
||||
nsIntPoint pluginOrigin;
|
||||
nsIntRect widgetClip;
|
||||
PRBool widgetVisible;
|
||||
pluginWidget->GetPluginClipRect(widgetClip, pluginOrigin, widgetVisible);
|
||||
mWidgetVisible = widgetVisible;
|
||||
|
||||
// printf("GetPluginClipRect returning visible %d\n", widgetVisible);
|
||||
|
||||
isVisible &= widgetVisible;
|
||||
if (!isVisible)
|
||||
widgetClip.Empty();
|
||||
|
||||
#ifndef NP_NO_QUICKDRAW
|
||||
// set the port coordinates
|
||||
if (drawingModel == NPDrawingModelQuickDraw) {
|
||||
@ -4985,8 +5094,6 @@ WindowRef nsPluginInstanceOwner::FixUpPluginWindow(PRInt32 inPaintState)
|
||||
mPluginWindow->clipRect.top = widgetClip.y;
|
||||
mPluginWindow->clipRect.left = widgetClip.x;
|
||||
|
||||
mWidgetVisible = isVisible;
|
||||
|
||||
if (!mWidgetVisible || inPaintState == ePluginPaintDisable) {
|
||||
mPluginWindow->clipRect.bottom = mPluginWindow->clipRect.top;
|
||||
mPluginWindow->clipRect.right = mPluginWindow->clipRect.left;
|
||||
|
@ -46,6 +46,8 @@
|
||||
|
||||
#include "nsIObjectFrame.h"
|
||||
#include "nsFrame.h"
|
||||
#include "nsRegion.h"
|
||||
#include "nsDisplayList.h"
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
class nsIAccessible;
|
||||
@ -55,6 +57,7 @@ class nsPluginInstanceOwner;
|
||||
class nsIPluginHost;
|
||||
class nsIPluginInstance;
|
||||
class nsPresContext;
|
||||
class nsDisplayPlugin;
|
||||
|
||||
#define nsObjectFrameSuper nsFrame
|
||||
|
||||
@ -123,6 +126,18 @@ public:
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// Compute the desired position of the plugin's widget, on the assumption
|
||||
// that it is not visible (clipped out or covered by opaque content).
|
||||
// This will only be called for plugins which have been registered
|
||||
// with the root pres context for geometry updates.
|
||||
// The widget, its new position, size and (empty) clip region are appended
|
||||
// as a Configuration record to aConfigurations.
|
||||
// If there is no widget associated with the plugin, this
|
||||
// simply does nothing.
|
||||
void GetEmptyClipConfiguration(nsTArray<nsIWidget::Configuration>* aConfigurations) {
|
||||
ComputeWidgetGeometry(nsRegion(), nsPoint(0,0), aConfigurations);
|
||||
}
|
||||
|
||||
// accessibility support
|
||||
#ifdef ACCESSIBILITY
|
||||
NS_IMETHOD GetAccessible(nsIAccessible** aAccessible);
|
||||
@ -168,6 +183,8 @@ protected:
|
||||
// check attributes and optionally CSS to see if we should display anything
|
||||
PRBool IsHidden(PRBool aCheckVisibilityStyle = PR_TRUE) const;
|
||||
|
||||
PRBool IsOpaque() const;
|
||||
|
||||
void NotifyContentObjectWrapper();
|
||||
|
||||
nsIntPoint GetWindowOriginInPixels(PRBool aWindowless);
|
||||
@ -189,9 +206,27 @@ protected:
|
||||
*/
|
||||
NS_HIDDEN_(nsresult) PrepareInstanceOwner();
|
||||
|
||||
/**
|
||||
* Get the widget geometry for the plugin. aRegion is in some appunits
|
||||
* coordinate system whose origin is device-pixel-aligned (if possible),
|
||||
* and aPluginOrigin gives the top-left of the plugin in that coordinate
|
||||
* system. It doesn't matter what that coordinate system actually is,
|
||||
* as long as aRegion and aPluginOrigin are consistent.
|
||||
* This will append a Configuration object to aConfigurations
|
||||
* containing the widget, its desired position, size and clip region.
|
||||
*/
|
||||
void ComputeWidgetGeometry(const nsRegion& aRegion,
|
||||
const nsPoint& aPluginOrigin,
|
||||
nsTArray<nsIWidget::Configuration>* aConfigurations);
|
||||
|
||||
nsIWidget* GetWidget() { return mWidget; }
|
||||
|
||||
friend class nsPluginInstanceOwner;
|
||||
friend class nsDisplayPlugin;
|
||||
|
||||
private:
|
||||
nsRefPtr<nsPluginInstanceOwner> mInstanceOwner;
|
||||
nsCOMPtr<nsIWidget> mWidget;
|
||||
nsIntRect mWindowlessRect;
|
||||
|
||||
// For assertions that make it easier to determine if a crash is due
|
||||
@ -200,5 +235,41 @@ private:
|
||||
PRBool mPreventInstantiation;
|
||||
};
|
||||
|
||||
class nsDisplayPlugin : public nsDisplayItem {
|
||||
public:
|
||||
nsDisplayPlugin(nsIFrame* aFrame)
|
||||
: nsDisplayItem(aFrame)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsDisplayPlugin);
|
||||
}
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
virtual ~nsDisplayPlugin() {
|
||||
MOZ_COUNT_DTOR(nsDisplayPlugin);
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual Type GetType() { return TYPE_PLUGIN; }
|
||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
|
||||
virtual PRBool IsOpaque(nsDisplayListBuilder* aBuilder);
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx,
|
||||
const nsRect& aDirtyRect);
|
||||
virtual PRBool OptimizeVisibility(nsDisplayListBuilder* aBuilder,
|
||||
nsRegion* aVisibleRegion);
|
||||
|
||||
NS_DISPLAY_DECL_NAME("Plugin")
|
||||
|
||||
// Compute the desired position and clip region of the plugin's widget.
|
||||
// This will only be called for plugins which have been registered
|
||||
// with the root pres context for geometry updates.
|
||||
// The widget, its new position, size and clip region are appended as
|
||||
// a Configuration record to aConfigurations.
|
||||
// If there is no widget associated with the plugin, this
|
||||
// simply does nothing.
|
||||
void GetWidgetConfiguration(nsDisplayListBuilder* aBuilder,
|
||||
nsTArray<nsIWidget::Configuration>* aConfigurations);
|
||||
|
||||
private:
|
||||
nsRegion mVisibleRegion;
|
||||
};
|
||||
|
||||
#endif /* nsObjectFrame_h___ */
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "nsRect.h"
|
||||
#include "nsPoint.h"
|
||||
#include "nsNativeWidget.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsWidgetInitData.h"
|
||||
|
||||
class nsIViewManager;
|
||||
@ -323,6 +324,17 @@ public:
|
||||
mVFlags |= NS_VIEW_DISOWNS_WIDGET;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make aWidget direct its events to this view.
|
||||
* The caller must call DetachWidgetEventHandler before this view
|
||||
* is destroyed.
|
||||
*/
|
||||
EVENT_CALLBACK AttachWidgetEventHandler(nsIWidget* aWidget);
|
||||
/**
|
||||
* Stop aWidget directing its events to this view.
|
||||
*/
|
||||
void DetachWidgetEventHandler(nsIWidget* aWidget);
|
||||
|
||||
/**
|
||||
* If called, will make the view invalidate its frame instead of BitBlitting
|
||||
* it when there's a scroll.
|
||||
|
@ -730,6 +730,31 @@ nsresult nsView::LoadWidget(const nsCID &aClassIID)
|
||||
return rv;
|
||||
}
|
||||
|
||||
EVENT_CALLBACK nsIView::AttachWidgetEventHandler(nsIWidget* aWidget)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
void* data = nsnull;
|
||||
aWidget->GetClientData(data);
|
||||
NS_ASSERTION(!data, "Already got client data");
|
||||
#endif
|
||||
|
||||
nsView* v = static_cast<nsView*>(this);
|
||||
ViewWrapper* wrapper = new ViewWrapper(v);
|
||||
if (!wrapper)
|
||||
return nsnull;
|
||||
NS_ADDREF(wrapper); // Will be released in DetachWidgetEventHandler
|
||||
aWidget->SetClientData(wrapper);
|
||||
return ::HandleEvent;
|
||||
}
|
||||
|
||||
void nsIView::DetachWidgetEventHandler(nsIWidget* aWidget)
|
||||
{
|
||||
ViewWrapper* wrapper = GetWrapperFor(aWidget);
|
||||
NS_ASSERTION(!wrapper || wrapper->GetView() == this, "Wrong view");
|
||||
NS_IF_RELEASE(wrapper);
|
||||
aWidget->SetClientData(nsnull);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void nsIView::List(FILE* out, PRInt32 aIndent) const
|
||||
{
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "gfxContext.h"
|
||||
#include "nsIPluginWidget.h"
|
||||
|
||||
static NS_DEFINE_IID(kBlenderCID, NS_BLENDER_CID);
|
||||
static NS_DEFINE_IID(kRegionCID, NS_REGION_CID);
|
||||
@ -469,8 +470,6 @@ void nsViewManager::Refresh(nsView *aView, nsIRenderingContext *aContext,
|
||||
SetPainting(PR_TRUE);
|
||||
|
||||
nsCOMPtr<nsIRenderingContext> localcx;
|
||||
NS_ASSERTION(aView->GetWidget(),
|
||||
"Must have a widget to calculate coordinates correctly");
|
||||
if (nsnull == aContext)
|
||||
{
|
||||
localcx = CreateRenderingContext(*aView);
|
||||
@ -568,7 +567,16 @@ void nsViewManager::ProcessPendingUpdates(nsView* aView, PRBool aDoInvalidate)
|
||||
NS_ASSERTION(mRefreshEnabled, "Cannot process pending updates with refresh disabled");
|
||||
nsRegion* dirtyRegion = aView->GetDirtyRegion();
|
||||
if (dirtyRegion) {
|
||||
UpdateWidgetArea(aView, *dirtyRegion, nsnull);
|
||||
nsView* nearestViewWithWidget = aView;
|
||||
while (!nearestViewWithWidget->HasWidget() &&
|
||||
nearestViewWithWidget->GetParent()) {
|
||||
nearestViewWithWidget =
|
||||
static_cast<nsView*>(nearestViewWithWidget->GetParent());
|
||||
}
|
||||
nsRegion r = *dirtyRegion;
|
||||
r.MoveBy(aView->GetOffsetTo(nearestViewWithWidget));
|
||||
UpdateWidgetArea(nearestViewWithWidget,
|
||||
nearestViewWithWidget->GetNearestWidget(nsnull), r, nsnull);
|
||||
dirtyRegion->SetEmpty();
|
||||
}
|
||||
}
|
||||
@ -675,13 +683,15 @@ nsViewManager::UpdateViewAfterScroll(nsView *aView, const nsRegion& aUpdateRegio
|
||||
nsPoint offset = aView->GetOffsetTo(displayRoot);
|
||||
damageRect.MoveBy(offset);
|
||||
|
||||
UpdateWidgetArea(displayRoot, nsRegion(damageRect), aView);
|
||||
UpdateWidgetArea(displayRoot, displayRoot->GetNearestWidget(nsnull),
|
||||
nsRegion(damageRect), aView);
|
||||
if (!aUpdateRegion.IsEmpty()) {
|
||||
// XXX We should update the region, not the bounds rect, but that requires
|
||||
// a little more work. Fix this when we reshuffle this code.
|
||||
nsRegion update(aUpdateRegion);
|
||||
update.MoveBy(offset);
|
||||
UpdateWidgetArea(displayRoot, update, nsnull);
|
||||
UpdateWidgetArea(displayRoot, displayRoot->GetNearestWidget(nsnull),
|
||||
update, nsnull);
|
||||
// FlushPendingInvalidates();
|
||||
}
|
||||
|
||||
@ -689,14 +699,32 @@ nsViewManager::UpdateViewAfterScroll(nsView *aView, const nsRegion& aUpdateRegio
|
||||
--RootViewManager()->mScrollCnt;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
IsWidgetDrawnByPlugin(nsIWidget* aWidget, nsIView* aView)
|
||||
{
|
||||
if (aView->GetWidget() == aWidget)
|
||||
return PR_FALSE;
|
||||
nsCOMPtr<nsIPluginWidget> pw = do_QueryInterface(aWidget);
|
||||
if (pw) {
|
||||
// It's a plugin widget, but one that we are responsible for painting
|
||||
// (i.e., a Mac widget)
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aWidget the widget for aWidgetView; in some cases the widget
|
||||
* is being managed directly by the frame system, so aWidgetView->GetWidget()
|
||||
* will return null but nsView::GetViewFor(aWidget) returns aWidgetview
|
||||
* @param aDamagedRegion this region, relative to aWidgetView, is invalidated in
|
||||
* every widget child of aWidgetView, plus aWidgetView's own widget
|
||||
* @param aIgnoreWidgetView if non-null, the aIgnoreWidgetView's widget and its
|
||||
* children are not updated.
|
||||
*/
|
||||
void
|
||||
nsViewManager::UpdateWidgetArea(nsView *aWidgetView, const nsRegion &aDamagedRegion,
|
||||
nsViewManager::UpdateWidgetArea(nsView *aWidgetView, nsIWidget* aWidget,
|
||||
const nsRegion &aDamagedRegion,
|
||||
nsView* aIgnoreWidgetView)
|
||||
{
|
||||
if (!IsRefreshEnabled()) {
|
||||
@ -727,11 +755,9 @@ nsViewManager::UpdateWidgetArea(nsView *aWidgetView, const nsRegion &aDamagedReg
|
||||
// If the widget is hidden, it don't cover nothing
|
||||
if (nsViewVisibility_kHide == aWidgetView->GetVisibility()) {
|
||||
#ifdef DEBUG
|
||||
// Assert if view is hidden but widget is visible
|
||||
nsIWidget* widget = aWidgetView->GetNearestWidget(nsnull);
|
||||
if (widget) {
|
||||
if (aWidget) {
|
||||
PRBool visible;
|
||||
widget->IsVisible(visible);
|
||||
aWidget->IsVisible(visible);
|
||||
NS_ASSERTION(!visible, "View is hidden but widget is visible!");
|
||||
}
|
||||
#endif
|
||||
@ -743,8 +769,7 @@ nsViewManager::UpdateWidgetArea(nsView *aWidgetView, const nsRegion &aDamagedReg
|
||||
return;
|
||||
}
|
||||
|
||||
nsIWidget* widget = aWidgetView->GetNearestWidget(nsnull);
|
||||
if (!widget) {
|
||||
if (!aWidget) {
|
||||
// The root view or a scrolling view might not have a widget
|
||||
// (for example, during printing). We get here when we scroll
|
||||
// during printing to show selected options in a listbox, for example.
|
||||
@ -755,13 +780,15 @@ nsViewManager::UpdateWidgetArea(nsView *aWidgetView, const nsRegion &aDamagedReg
|
||||
// accumulate the union of all the child widget areas, or at least
|
||||
// some subset of that.
|
||||
nsRegion children;
|
||||
if (widget->GetTransparencyMode() != eTransparencyTransparent) {
|
||||
for (nsIWidget* childWidget = widget->GetFirstChild();
|
||||
if (aWidget->GetTransparencyMode() != eTransparencyTransparent) {
|
||||
for (nsIWidget* childWidget = aWidget->GetFirstChild();
|
||||
childWidget;
|
||||
childWidget = childWidget->GetNextSibling()) {
|
||||
nsView* view = nsView::GetViewFor(childWidget);
|
||||
NS_ASSERTION(view != aWidgetView, "will recur infinitely");
|
||||
if (view && view->GetVisibility() == nsViewVisibility_kShow) {
|
||||
PRBool visible;
|
||||
childWidget->IsVisible(visible);
|
||||
if (view && visible && !IsWidgetDrawnByPlugin(childWidget, view)) {
|
||||
// Don't mess with views that are in completely different view
|
||||
// manager trees
|
||||
if (view->GetViewManager()->RootViewManager() == RootViewManager()) {
|
||||
@ -769,7 +796,7 @@ nsViewManager::UpdateWidgetArea(nsView *aWidgetView, const nsRegion &aDamagedReg
|
||||
nsRegion damage = intersection;
|
||||
nsPoint offset = view->GetOffsetTo(aWidgetView);
|
||||
damage.MoveBy(-offset);
|
||||
UpdateWidgetArea(view, damage, aIgnoreWidgetView);
|
||||
UpdateWidgetArea(view, childWidget, damage, aIgnoreWidgetView);
|
||||
|
||||
nsIntRect bounds;
|
||||
childWidget->GetBounds(bounds);
|
||||
@ -795,7 +822,7 @@ nsViewManager::UpdateWidgetArea(nsView *aWidgetView, const nsRegion &aDamagedReg
|
||||
const nsRect* r;
|
||||
for (nsRegionRectIterator iter(leftOver); (r = iter.Next());) {
|
||||
nsIntRect bounds = ViewToWidget(aWidgetView, aWidgetView, *r);
|
||||
widget->Invalidate(bounds, PR_FALSE);
|
||||
aWidget->Invalidate(bounds, PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -824,7 +851,8 @@ NS_IMETHODIMP nsViewManager::UpdateView(nsIView *aView, const nsRect &aRect, PRU
|
||||
// can overlap each other and be translucent. So we have to possibly
|
||||
// invalidate our rect in each of the widgets we have lying about.
|
||||
damagedRect.MoveBy(view->GetOffsetTo(displayRoot));
|
||||
UpdateWidgetArea(displayRoot, nsRegion(damagedRect), nsnull);
|
||||
UpdateWidgetArea(displayRoot, displayRoot->GetNearestWidget(nsnull),
|
||||
nsRegion(damagedRect), nsnull);
|
||||
|
||||
RootViewManager()->IncrementUpdateCount();
|
||||
|
||||
|
@ -210,7 +210,8 @@ private:
|
||||
void ReparentChildWidgets(nsIView* aView, nsIWidget *aNewWidget);
|
||||
void ReparentWidgets(nsIView* aView, nsIView *aParent);
|
||||
already_AddRefed<nsIRenderingContext> CreateRenderingContext(nsView &aView);
|
||||
void UpdateWidgetArea(nsView *aWidgetView, const nsRegion &aDamagedRegion,
|
||||
void UpdateWidgetArea(nsView *aWidgetView, nsIWidget* aWidget,
|
||||
const nsRegion &aDamagedRegion,
|
||||
nsView* aIgnoreWidgetView);
|
||||
|
||||
void UpdateViews(nsView *aView, PRUint32 aUpdateFlags);
|
||||
|
@ -44,8 +44,8 @@
|
||||
{0xd530ce43, 0x8f6e, 0x45c5, \
|
||||
{ 0xa9, 0x84, 0x35, 0xc4, 0x3d, 0xa1, 0x90, 0x73 }}
|
||||
|
||||
struct nsRect;
|
||||
struct nsPoint;
|
||||
struct nsIntPoint;
|
||||
class nsIPluginInstanceOwner;
|
||||
|
||||
class NS_NO_VTABLE nsIPluginWidget : public nsISupports
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user