Bug 1331402 - Update plugins' clipRects when hiding a tab. r?jimm, r?mattwoodrow
In non-e10s, all tabs of a window would share one nsRootPresContext. When
switching tabs, the tab switch paint would trigger a call to
nsRootPresContext::ComputePluginGeometryUpdates, which would call
SetEmptyWidgetConfiguration on all registered nsPluginFrames, notably also
those inside the tab that was hidden.
With e10s, every tab has its own nsRootPresContext, and paints in one tab do
not trigger calls to nsRootPresContext::ComputePluginGeometryUpdates on the
root pres contexts of other tabs. So when painting the new tab, the registered
plugin frames in the old tab were not notified that they were now hidden.
This patch now does that in TabChild::MakeHidden.
MozReview-Commit-ID: LlW9dKKFqZE
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -2660,16 +2660,26 @@ TabChild::MakeHidden()
}
CompositorBridgeChild* compositor = CompositorBridgeChild::Get();
// Clear cached resources directly. This avoids one extra IPC
// round-trip from CompositorBridgeChild to CompositorBridgeParent.
compositor->RecvClearCachedResources(mLayersId);
+ // Hide all plugins in this tab.
+ if (nsCOMPtr<nsIPresShell> shell = GetPresShell()) {
+ if (nsPresContext* presContext = shell->GetPresContext()) {
+ nsRootPresContext* rootPresContext = presContext->GetRootPresContext();
+ nsIFrame* rootFrame = shell->FrameConstructor()->GetRootFrame();
+ rootPresContext->ComputePluginGeometryUpdates(rootFrame, nullptr, nullptr);
+ rootPresContext->ApplyPluginGeometryUpdates();
+ }
+ }
+
if (mPuppetWidget) {
mPuppetWidget->Show(false);
}
}
NS_IMETHODIMP
TabChild::GetMessageManager(nsIContentFrameMessageManager** aResult)
{
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -2958,29 +2958,32 @@ nsRootPresContext::ComputePluginGeometry
}
if (!nsLayoutUtils::IsAncestorFrameCrossDoc(aFrame, f)) {
// f is not managed by this frame so we should ignore it.
continue;
}
f->SetEmptyWidgetConfiguration();
}
- nsIFrame* rootFrame = FrameManager()->GetRootFrame();
-
- if (rootFrame && aBuilder->ContainsPluginItem()) {
- aBuilder->SetForPluginGeometry();
- aBuilder->SetAccurateVisibleRegions();
- // Merging and flattening has already been done and we should not do it
- // again. nsDisplayScroll(Info)Layer doesn't support trying to flatten
- // again.
- aBuilder->SetAllowMergingAndFlattening(false);
- nsRegion region = rootFrame->GetVisualOverflowRectRelativeToSelf();
- // nsDisplayPlugin::ComputeVisibility will automatically set a non-hidden
- // widget configuration for the plugin, if it's visible.
- aList->ComputeVisibilityForRoot(aBuilder, ®ion);
+ if (aBuilder) {
+ MOZ_ASSERT(aList);
+ nsIFrame* rootFrame = FrameManager()->GetRootFrame();
+
+ if (rootFrame && aBuilder->ContainsPluginItem()) {
+ aBuilder->SetForPluginGeometry();
+ aBuilder->SetAccurateVisibleRegions();
+ // Merging and flattening has already been done and we should not do it
+ // again. nsDisplayScroll(Info)Layer doesn't support trying to flatten
+ // again.
+ aBuilder->SetAllowMergingAndFlattening(false);
+ nsRegion region = rootFrame->GetVisualOverflowRectRelativeToSelf();
+ // nsDisplayPlugin::ComputeVisibility will automatically set a non-hidden
+ // widget configuration for the plugin, if it's visible.
+ aList->ComputeVisibilityForRoot(aBuilder, ®ion);
+ }
}
#ifdef XP_MACOSX
// We control painting of Mac plugins, so just apply geometry updates now.
// This is not happening during a paint event.
ApplyPluginGeometryUpdates();
#else
if (XRE_IsParentProcess()) {
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -1519,16 +1519,18 @@ public:
/**
* Compute geometry updates for each plugin given that aList is the display
* list for aFrame. The updates are not yet applied;
* ApplyPluginGeometryUpdates is responsible for that. In the meantime they
* are stored on each nsPluginFrame.
* This needs to be called even when aFrame is a popup, since although
* windowed plugins aren't allowed in popups, windowless plugins are
* and ComputePluginGeometryUpdates needs to be called for them.
+ * aBuilder and aList can be null. This indicates that all plugins are
+ * hidden because we're in a background tab.
*/
void ComputePluginGeometryUpdates(nsIFrame* aFrame,
nsDisplayListBuilder* aBuilder,
nsDisplayList* aList);
/**
* Apply the stored plugin geometry updates. This should normally be called
* in DidPaint so the plugins are moved/clipped immediately after we've