Bug 469774 - Never descend into nsMenuPopupFrames when building display lists. Fixes drawing bugs that occurred when a caret was visible in a popup. r=roc
authorMarkus Stange <mstange@themasta.com>
Tue, 08 Sep 2009 09:43:20 +1200
changeset 32291 f8ee121bd0e1f51fdd15da603610b0a4f6af43d4
parent 32290 13ee3ebd9396955408995a9020872f6215d6c9ec
child 32292 7076c06685e1760e80af27b97e3640b952a4c96e
push idunknown
push userunknown
push dateunknown
reviewersroc
bugs469774
milestone1.9.3a1pre
Bug 469774 - Never descend into nsMenuPopupFrames when building display lists. Fixes drawing bugs that occurred when a caret was visible in a popup. r=roc
layout/generic/nsFrame.cpp
layout/generic/test/Makefile.in
layout/generic/test/test_bug469774.xul
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -1412,17 +1412,17 @@ nsIFrame::BuildDisplayListForChild(nsDis
   // dirty rect in child-relative coordinates
   nsRect dirty = aDirtyRect - aChild->GetOffsetTo(this);
 
   nsIAtom* childType = aChild->GetType();
   if (childType == nsGkAtoms::placeholderFrame) {
     nsPlaceholderFrame* placeholder = static_cast<nsPlaceholderFrame*>(aChild);
     aChild = placeholder->GetOutOfFlowFrame();
     NS_ASSERTION(aChild, "No out of flow frame?");
-    if (!aChild)
+    if (!aChild || aChild->GetType() == nsGkAtoms::menuPopupFrame)
       return NS_OK;
     // update for the new child
     disp = aChild->GetStyleDisplay();
     // Make sure that any attempt to use childType below is disappointed. We
     // could call GetType again but since we don't currently need it, let's
     // avoid the virtual call.
     childType = nsnull;
     // Recheck NS_FRAME_TOO_DEEP_IN_FRAME_TREE
--- a/layout/generic/test/Makefile.in
+++ b/layout/generic/test/Makefile.in
@@ -79,16 +79,17 @@ include $(topsrcdir)/config/rules.mk
 		$(warning test_bug421839-1.html disabled because it calls finish twice which can cause timeouts) \
 		test_bug421839-2.html \
 		bug421839-2-page.html \
 		test_bug438840.html \
 		test_bug448860.html \
 		test_bug460532.html \
 		test_bug468167.html \
 		test_bug469613.xul \
+		test_bug469774.xul \
 		test_bug470212.html \
 		test_bug503813.html \
 		test_bug507902.html \
 		test_movement_by_characters.html \
 		test_movement_by_words.html \
 		test_plugin_clipping.xhtml \
 		test_plugin_clipping2.xhtml \
 		test_plugin_clipping_transformed.xhtml \
new file mode 100644
--- /dev/null
+++ b/layout/generic/test/test_bug469774.xul
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=469774
+-->
+<window title="Mozilla Bug 469774"
+  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+  <title>Test for Bug 469774</title>
+  <script type="application/javascript" src="/MochiKit/packed.js" />
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"/>
+  <script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
+
+<vbox height="50"/>
+
+<menupopup id="popup">
+  <textbox id="textbox"/>
+</menupopup>
+
+<body  xmlns="http://www.w3.org/1999/xhtml">
+  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=469774">Mozilla Bug 469774</a>
+
+  <p id="display"></p>
+<div id="content" style="display: none">
+</div>
+</body>
+
+<script class="testbody" type="application/javascript;version=1.7"><![CDATA[
+
+/** Test for Bug 469774 **/
+
+// Test whether menu popups are blocked from being painted in their parent window.
+
+// Like snapshotWindow, but with DRAWWINDOW_DRAW_CARET
+function snapShot() {
+  netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
+  var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
+  canvas.setAttribute("width", 200);
+  canvas.setAttribute("height", 50);
+  var ctx = canvas.getContext("2d");
+  ctx.drawWindow(window, 0, 0, 200, 50, "transparent", ctx.DRAWWINDOW_DRAW_CARET);
+  return canvas;
+}
+
+function doTest() {
+  window.removeEventListener("focus", doTest, false);
+
+  var before = snapShot();
+
+  var popup = document.getElementById("popup");
+  popup.openPopup(null, "after_start", 0, 0, false, false);
+
+  popup.addEventListener("popupshown", function() {
+    var textbox = document.getElementById("textbox");
+    textbox.focus(); // show caret
+
+    var after = snapShot();
+
+    var equal, str1, str2;
+    [equal, str1, str2] = compareSnapshots(after, before, true);
+    ok(equal, "Showing a popup shouldn't affect drawing in its parent window",
+       "got " + str1 + " but expected " + str2);
+
+    popup.hidePopup();
+    SimpleTest.finish();
+  }, false);
+}
+
+SimpleTest.waitForExplicitFinish();
+window.addEventListener("focus", doTest, false);
+
+]]></script>
+
+</window>