Bug 1447056 part 2 - Invoke Resize in SetSizeConstraints with the current size to apply the new constraints. r?bz draft
authorXidorn Quan <me@upsuper.org>
Fri, 23 Mar 2018 12:51:15 +1100
changeset 771964 1c6a0b0aae636f658555d4e2261eb3731df71f65
parent 771963 1d1f62a81d9fc059af9038eebc64256aeba397d3
child 771986 9abb9b406db8babe6f787bf8ae277f0f392f9f90
push id103809
push userxquan@mozilla.com
push dateSat, 24 Mar 2018 01:18:18 +0000
reviewersbz
bugs1447056
milestone61.0a1
Bug 1447056 part 2 - Invoke Resize in SetSizeConstraints with the current size to apply the new constraints. r?bz MozReview-Commit-ID: 9kRcDHTPCqt
toolkit/content/tests/chrome/chrome.ini
toolkit/content/tests/chrome/test_window_intrinsic_size.xul
toolkit/content/tests/chrome/window_intrinsic_size.xul
widget/nsBaseWidget.cpp
--- a/toolkit/content/tests/chrome/chrome.ini
+++ b/toolkit/content/tests/chrome/chrome.ini
@@ -178,16 +178,18 @@ skip-if = os == "linux"
 [test_tooltip.xul]
 skip-if = (os == 'mac' && os_version == '10.10') || (os == 'win') # Bug 1141245, frequent timeouts on OSX 10.10, Windows
 [test_tooltip_noautohide.xul]
 [test_tree.xul]
 [test_tree_hier.xul]
 [test_tree_hier_cell.xul]
 [test_tree_single.xul]
 [test_tree_view.xul]
+[test_window_intrinsic_size.xul]
+support-files = window_intrinsic_size.xul
 # test_panel_focus.xul won't work if the Full Keyboard Access preference is set to
 # textboxes and lists only, so skip this test on Mac
 [test_panel_focus.xul]
 support-files = window_panel_focus.xul
 skip-if = toolkit == "cocoa"
 [test_chromemargin.xul]
 support-files = window_chromemargin.xul
 skip-if = toolkit == "cocoa"
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/chrome/test_window_intrinsic_size.xul
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+<window title="Window Open Test"
+        onload="runTest()"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+<script type="application/javascript"
+        src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+<script type="application/javascript"
+        src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
+<script class="testbody" type="application/javascript"><![CDATA[
+  SimpleTest.waitForExplicitFinish();
+
+  function openWindow(features = "") {
+    return window.openDialog("window_intrinsic_size.xul",
+                             null, "chrome,dialog=no,all," + features);
+  }
+
+  function checkWindowSize(win, width, height, msg) {
+    is(win.innerWidth, width, "width should match " + msg);
+    is(win.innerHeight, height, "height should match " + msg);
+  }
+
+  async function runTest() {
+    let win = openWindow();
+    await SimpleTest.promiseFocus(win);
+    checkWindowSize(win, 300, 500, "with width attribute specified");
+
+    win = openWindow("width=400");
+    await SimpleTest.promiseFocus(win);
+    checkWindowSize(win, 400, 500, "with width feature specified");
+
+    SimpleTest.finish();
+  }
+]]></script>
+<body xmlns="http://www.w3.org/1999/xhtml">
+<p id="display">
+</p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+</pre>
+</body>
+</window>
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/chrome/window_intrinsic_size.xul
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<window title="Window Open Test"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        width="300">
+<div xmlns="http://www.w3.org/1999/xhtml" style="height: 500px"></div>
+</window>
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -1756,18 +1756,45 @@ nsBaseWidget::ResolveIconName(const nsAS
               getter_AddRefs(file));
   if (file && ResolveIconNameHelper(file, aIconName, aIconSuffix))
     NS_ADDREF(*aResult = file);
 }
 
 void nsBaseWidget::SetSizeConstraints(const SizeConstraints& aConstraints)
 {
   mSizeConstraints = aConstraints;
-  // We can't ensure that the size is honored at this point because we're
-  // probably in the middle of a reflow.
+
+  // Popups are constrained during layout, and we don't want to synchronously
+  // paint from reflow, so bail out... This is not great, but it's no worse than
+  // what we used to do.
+  //
+  // The right fix here is probably making constraint changes go through the
+  // view manager and such.
+  if (mWindowType == eWindowType_popup) {
+    return;
+  }
+
+  // If the current size doesn't meet the new constraints, trigger a
+  // resize to apply it. Note that, we don't want to invoke Resize if
+  // the new constraints don't affect the current size, because Resize
+  // implementation on some platforms may touch other geometry even if
+  // the size don't need to change.
+  LayoutDeviceIntSize curSize = mBounds.Size();
+  LayoutDeviceIntSize clampedSize =
+    Max(aConstraints.mMinSize, Min(aConstraints.mMaxSize, curSize));
+  if (clampedSize != curSize) {
+    gfx::Size size;
+    if (BoundsUseDesktopPixels()) {
+      DesktopSize desktopSize = clampedSize / GetDesktopToDeviceScale();
+      size = desktopSize.ToUnknownSize();
+    } else {
+      size = gfx::Size(clampedSize.ToUnknownSize());
+    }
+    Resize(size.width, size.height, true);
+  }
 }
 
 const widget::SizeConstraints nsBaseWidget::GetSizeConstraints()
 {
   return mSizeConstraints;
 }
 
 // static