Bug 715867 - Don't fire duplicate sizemodechange events on Mac. r=smichaud
authorMarkus Stange <mstange@themasta.com>
Tue, 31 Jan 2012 11:40:03 +0100
changeset 85800 d2bf6d11d889618553625580ae5a2718221e642b
parent 85799 c0256a2b39861b37fbb40918eabf2313d0d90915
child 85824 1faaebaf134fbd36b01d620449714531a03322ee
push id5517
push usermstange@themasta.com
push dateTue, 31 Jan 2012 10:52:07 +0000
treeherdermozilla-inbound@d2bf6d11d889 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmichaud
bugs715867
milestone12.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 715867 - Don't fire duplicate sizemodechange events on Mac. r=smichaud
widget/cocoa/nsCocoaWindow.mm
widget/tests/Makefile.in
widget/tests/empty_window.xul
widget/tests/test_bug596600.xul
widget/tests/test_sizemode_events.xul
widget/tests/window_bug596600.xul
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -1057,27 +1057,24 @@ NS_IMETHODIMP nsCocoaWindow::Move(PRInt3
 
 // Position the window behind the given window
 NS_METHOD nsCocoaWindow::PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
                                      nsIWidget *aWidget, bool aActivate)
 {
   return NS_OK;
 }
 
-// Note bug 278777, we need to update state when the window is unminimized
-// from the dock by users.
 NS_METHOD nsCocoaWindow::SetSizeMode(PRInt32 aMode)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
-  PRInt32 previousMode;
-  nsBaseWidget::GetSizeMode(&previousMode);
-
-  nsresult rv = nsBaseWidget::SetSizeMode(aMode);
-  NS_ENSURE_SUCCESS(rv, rv);
+  // mSizeMode will be updated in DispatchSizeModeEvent, which will be called
+  // from a delegate method that handles the state change during one of the
+  // calls below.
+  nsSizeMode previousMode = mSizeMode;
 
   if (aMode == nsSizeMode_Normal) {
     if ([mWindow isMiniaturized])
       [mWindow deminiaturize:nil];
     else if (previousMode == nsSizeMode_Maximized && [mWindow isZoomed])
       [mWindow zoom:nil];
   }
   else if (aMode == nsSizeMode_Minimized) {
@@ -1414,18 +1411,23 @@ nsCocoaWindow::ReportMoveEvent()
   mInReportMoveEvent = false;
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 void
 nsCocoaWindow::DispatchSizeModeEvent()
 {
+  nsSizeMode newMode = GetWindowSizeMode(mWindow);
+  if (mSizeMode == newMode)
+    return;
+
+  mSizeMode = newMode;
   nsSizeModeEvent event(true, NS_SIZEMODE, this);
-  event.mSizeMode = GetWindowSizeMode(mWindow);
+  event.mSizeMode = mSizeMode;
   event.time = PR_IntervalNow();
 
   nsEventStatus status = nsEventStatus_eIgnore;
   DispatchEvent(&event, status);
 }
 
 void
 nsCocoaWindow::ReportSizeEvent()
--- a/widget/tests/Makefile.in
+++ b/widget/tests/Makefile.in
@@ -82,16 +82,18 @@ include $(topsrcdir)/config/rules.mk
 		window_wheeltransaction.xul \
 		test_imestate.html \
 		window_imestate_iframes.html \
 		test_plugin_scroll_consistency.html \
 		test_composition_text_querycontent.xul \
 		window_composition_text_querycontent.xul \
 		test_input_events_on_deactive_window.xul \
 		test_position_on_resize.xul \
+		empty_window.xul \
+		test_sizemode_events.xul \
 		$(NULL)
 		
 # test_bug413277.html mac-only based on 604789, 605178
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
 _CHROME_FILES += native_menus_window.xul \
                test_native_menus.xul \
                native_mouse_mac_window.xul \
@@ -104,17 +106,16 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
                window_bug522217.xul \
                test_platform_colors.xul \
                test_standalone_native_menu.xul \
                standalone_native_menu_window.xul \
                test_bug586713.xul \
                bug586713_window.xul \
                test_key_event_counts.xul \
                test_bug596600.xul \
-               window_bug596600.xul \
                test_bug673301.xul \
                $(NULL)
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
 _CHROME_FILES  += taskbar_previews.xul \
 		window_state_windows.xul \
 		taskbar_progress.xul \
rename from widget/tests/window_bug596600.xul
rename to widget/tests/empty_window.xul
--- a/widget/tests/window_bug596600.xul
+++ b/widget/tests/empty_window.xul
@@ -1,4 +1,4 @@
 <?xml version="1.0"?>
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<window title="Window for Test for Mozilla Bug 596600"
+<window title="Empty window"
   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>
--- a/widget/tests/test_bug596600.xul
+++ b/widget/tests/test_bug596600.xul
@@ -31,19 +31,19 @@ var gExpectedEvents = [];
 function moveMouseTo(x, y, andThen) {
   var utils = gLeftWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
                                  getInterface(Components.interfaces.nsIDOMWindowUtils);
   utils.sendNativeMouseEvent(x, y, NSMouseMoved, 0, gLeftWindow.documentElement);
   SimpleTest.executeSoon(andThen);
 }
 
 function openWindows() {
-  gLeftWindow = open('window_bug596600.xul', '_blank', 'chrome,screenX=50,screenY=50,width=200,height=200');
+  gLeftWindow = open('empty_window.xul', '_blank', 'chrome,screenX=50,screenY=50,width=200,height=200');
   SimpleTest.waitForFocus(function () {
-    gRightWindow = open('window_bug596600.xul', '', 'chrome,screenX=300,screenY=50,width=200,height=200');
+    gRightWindow = open('empty_window.xul', '', 'chrome,screenX=300,screenY=50,width=200,height=200');
     SimpleTest.waitForFocus(attachIFrameToRightWindow, gRightWindow);
   }, gLeftWindow);
 }
 
 function attachIFrameToRightWindow() {
   gIFrame = gLeftWindow.document.createElementNS(XUL_NS, "iframe");
   gIFrame.setAttribute("type", "content");
   gIFrame.setAttribute("clickthrough", "never");
new file mode 100644
--- /dev/null
+++ b/widget/tests/test_sizemode_events.xul
@@ -0,0 +1,107 @@
+<?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="Test for bug 715867"
+  xmlns:html="http://www.w3.org/1999/xhtml"
+  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+  <title>Test for bug 715867</title>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+
+<body  xmlns="http://www.w3.org/1999/xhtml">
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+
+<script class="testbody" type="application/javascript">
+<![CDATA[
+
+const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+
+gWindow = null;
+
+gSizeModeDidChange = false;
+gSizeModeDidChangeTo = 0;
+
+function sizemodeChanged(e) {
+  gSizeModeDidChange = true;
+  gSizeModeDidChangeTo = gWindow.windowState;
+}
+
+function expectSizeModeChange(newMode, duringActionCallback) {
+  gSizeModeDidChange = false;
+
+  duringActionCallback();
+
+  if (newMode == 0) {
+    // No change should have taken place, no event should have fired.
+    ok(!gSizeModeDidChange, "No sizemodechange event should have fired.");
+  } else {
+    // Size mode change event was expected to fire.
+    ok(gSizeModeDidChange, "A sizemodechanged event should have fired.");
+    is(gSizeModeDidChangeTo, newMode, "The new sizemode should have the expected value.");
+  }
+}
+
+function startTest() {
+  if (navigator.platform.indexOf("Lin") != -1) {
+    ok(true, "This test is disabled on Linux because it expects window sizemode changes to be synchronous (which is not the case on Linux).");
+    SimpleTest.finish();
+    return;
+  };
+  openWindow();
+}
+
+function openWindow() {
+  gWindow = open('empty_window.xul', '_blank', 'chrome,screenX=50,screenY=50,width=200,height=200,resizable');
+  SimpleTest.waitForFocus(runTest, gWindow);
+}
+
+function runTest() {
+  // Install event handler.
+  gWindow.addEventListener("sizemodechange", sizemodeChanged, false);
+
+  // Run tests.
+  expectSizeModeChange(gWindow.STATE_MINIMIZED, function () {
+    gWindow.minimize();
+  });
+
+  expectSizeModeChange(gWindow.STATE_NORMAL, function () {
+    gWindow.restore();
+  });
+
+  expectSizeModeChange(gWindow.STATE_MAXIMIZED, function () {
+    gWindow.maximize();
+  });
+
+  expectSizeModeChange(gWindow.STATE_NORMAL, function () {
+    gWindow.restore();
+  });
+
+  // Normal window resizing shouldn't fire a sizemodechanged event, bug 715867.
+  expectSizeModeChange(0, function () {
+    gWindow.resizeTo(gWindow.outerWidth + 10, gWindow.outerHeight);
+  });
+
+  expectSizeModeChange(0, function () {
+    gWindow.resizeTo(gWindow.outerWidth, gWindow.outerHeight + 10);
+  });
+
+  gWindow.removeEventListener("sizemodechange", sizemodeChanged, false);
+  gWindow.close();
+  SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(startTest);
+
+]]>
+</script>
+
+</window>