Bug 469203. Don't try to make toplevel HTML documents transparent, it just doesn't work and the window can disappear in a mysterious way. r+sr=dbaron
authorRobert O'Callahan <robert@ocallahan.org>
Mon, 29 Dec 2008 21:17:08 +1300
changeset 23154 295ef42f86d4ba4d483c035d48274d1cc773528a
parent 23153 6f760def9fcd8949e82476dacf79add2844f7e68
child 23155 abef302b61be021d31d810c279ba3351e7cd62c3
push idunknown
push userunknown
push dateunknown
bugs469203
milestone1.9.2a1pre
Bug 469203. Don't try to make toplevel HTML documents transparent, it just doesn't work and the window can disappear in a mysterious way. r+sr=dbaron
layout/generic/nsContainerFrame.cpp
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -483,42 +483,69 @@ IsTopLevelWidget(nsPresContext* aPresCon
 
 static void
 SyncFrameViewGeometryDependentProperties(nsPresContext*  aPresContext,
                                          nsIFrame*        aFrame,
                                          nsStyleContext*  aStyleContext,
                                          nsIView*         aView,
                                          PRUint32         aFlags)
 {
+#ifdef MOZ_XUL
   nsIViewManager* vm = aView->GetViewManager();
 
   PRBool isCanvas;
   const nsStyleBackground* bg;
   nsCSSRendering::FindBackground(aPresContext, aFrame, &bg, &isCanvas);
 
-  if (isCanvas) {
-    nsIView* rootView;
-    vm->GetRootView(rootView);
+  if (!isCanvas)
+    return;
+
+  nsIView* rootView;
+  vm->GetRootView(rootView);
+
+  if (!aView->HasWidget() || aView != rootView ||
+      !IsTopLevelWidget(aPresContext))
+    return;
 
-    if (aView->HasWidget() && aView == rootView &&
-        IsTopLevelWidget(aPresContext)) {
-      // The issue here is that the CSS 'background' propagates from the root
-      // element's frame (rootFrame) to the real root frame (nsViewportFrame),
-      // so we need to call GetFrameTransparency on that. But -moz-appearance
-      // does not propagate so we need to check that directly on rootFrame.
-      nsTransparencyMode mode = nsLayoutUtils::GetFrameTransparency(aFrame);
-      nsIFrame *rootFrame = aPresContext->PresShell()->FrameConstructor()->GetRootElementStyleFrame();
-      if(rootFrame && NS_THEME_WIN_GLASS == rootFrame->GetStyleDisplay()->mAppearance)
-        mode = eTransparencyGlass;
-      nsIWidget* widget = aView->GetWidget();
-      widget->SetTransparencyMode(mode);
-      if (rootFrame)
-        widget->SetWindowShadowStyle(rootFrame->GetStyleUIReset()->mWindowShadow);
-    }
+  nsIContent* rootContent = aPresContext->Document()->GetRootContent();
+  if (!rootContent || !rootContent->IsNodeOfType(nsINode::eXUL)) {
+    // Scrollframes use native widgets which don't work well with
+    // translucent windows, at least in Windows XP. So if the document
+    // has a root scrollrame it's useless to try to make it transparent,
+    // we'll just get something broken.
+    // nsCSSFrameConstructor::ConstructRootFrame constructs root
+    // scrollframes whenever the root element is not a XUL element, so
+    // we test for that here. We can't just call
+    // presShell->GetRootScrollFrame() since that might not have
+    // been constructed yet.
+    // We can change this to allow translucent toplevel HTML documents
+    // (e.g. to do something like Dashboard widgets), once we
+    // have broad support for translucent scrolled documents, but be
+    // careful because apparently some Firefox extensions expect
+    // openDialog("something.html") to produce an opaque window
+    // even if the HTML doesn't have a background-color set.
+    return;
   }
+
+  // The issue here is that the CSS 'background' propagates from the root
+  // element's frame (rootFrame) to the real root frame (nsViewportFrame),
+  // so we need to call GetFrameTransparency on that. But -moz-appearance
+  // does not propagate so we need to check that directly on rootFrame.
+  nsTransparencyMode mode = nsLayoutUtils::GetFrameTransparency(aFrame);
+  nsIFrame *rootFrame = aPresContext->PresShell()->FrameConstructor()->GetRootElementStyleFrame();
+  if (rootFrame &&
+      NS_THEME_WIN_GLASS == rootFrame->GetStyleDisplay()->mAppearance) {
+    mode = eTransparencyGlass;
+  }
+  nsIWidget* widget = aView->GetWidget();
+  widget->SetTransparencyMode(mode);
+  if (rootFrame) {
+    widget->SetWindowShadowStyle(rootFrame->GetStyleUIReset()->mWindowShadow);
+  }
+#endif
 }
 
 void
 nsContainerFrame::SyncFrameViewAfterReflow(nsPresContext* aPresContext,
                                            nsIFrame*       aFrame,
                                            nsIView*        aView,
                                            const nsRect*   aCombinedArea,
                                            PRUint32        aFlags)