Bug 429954 - Windows that open already maximized will un-maximize to a teeny-tiny window in upper left.
authorMarkus Stange <mstange@themasta.com>
Fri, 14 Aug 2009 10:02:54 +1200
changeset 31533 71f1dacf8bdd75524c376ec67b067f74edaf80b9
parent 31532 8880b3778f5344b432f61cb6e68234c5705718eb
child 31534 6b30334ec1202208aa7c7b8c1535a560901eeab2
push id8560
push usermstange@themasta.com
push dateThu, 13 Aug 2009 23:10:22 +0000
treeherdermozilla-central@cc6bebbd93bb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs429954
milestone1.9.3a1pre
Bug 429954 - Windows that open already maximized will un-maximize to a teeny-tiny window in upper left. Disallow zooming of windows that already have the zoomed size but have never been zoomed, because otherwise bad things happen to the window size. Moreover, reflect the window's zoom state in its size mode as nsSizeMode_Maximized. r=josh
widget/src/cocoa/nsCocoaWindow.h
widget/src/cocoa/nsCocoaWindow.mm
--- a/widget/src/cocoa/nsCocoaWindow.h
+++ b/widget/src/cocoa/nsCocoaWindow.h
@@ -98,16 +98,17 @@ typedef struct _nsCocoaWindowList {
 
 @interface WindowDelegate : NSObject
 {
   nsCocoaWindow* mGeckoWindow; // [WEAK] (we are owned by the window)
   // Used to avoid duplication when we send NS_ACTIVATE and
   // NS_DEACTIVATE to Gecko for toplevel widgets.  Starts out
   // PR_FALSE.
   PRBool mToplevelActiveState;
+  BOOL mHasEverBeenZoomed;
 }
 + (void)paintMenubarForWindow:(NSWindow*)aWindow;
 - (id)initWithGeckoWindow:(nsCocoaWindow*)geckoWind;
 - (void)windowDidResize:(NSNotification*)aNotification;
 - (void)sendFocusEvent:(PRUint32)eventType;
 - (nsCocoaWindow*)geckoWidget;
 - (PRBool)toplevelActiveState;
 - (void)sendToplevelActivateEvents;
@@ -233,18 +234,17 @@ public:
     NS_IMETHOD GetAttention(PRInt32 aCycleCount);
     virtual PRBool HasPendingInputEvent();
     virtual nsTransparencyMode GetTransparencyMode();
     virtual void SetTransparencyMode(nsTransparencyMode aMode);
     NS_IMETHOD SetWindowShadowStyle(PRInt32 aStyle);
     virtual void SetShowsToolbarButton(PRBool aShow);
     NS_IMETHOD SetWindowTitlebarColor(nscolor aColor, PRBool aActive);
 
-    // dispatch an NS_SIZEMODE event on miniaturize or deminiaturize
-    void DispatchSizeModeEvent(nsSizeMode aSizeMode);
+    void DispatchSizeModeEvent();
 
     virtual gfxASurface* GetThebesSurface();
 
     // be notified that a some form of drag event needs to go into Gecko
     virtual PRBool DragEvent(unsigned int aMessage, Point aMouseGlobal, UInt16 aKeyModifiers);
 
     // Helpers to prevent recursive resizing during live-resize
     PRBool IsResizing () const { return mIsResizing; }
--- a/widget/src/cocoa/nsCocoaWindow.mm
+++ b/widget/src/cocoa/nsCocoaWindow.mm
@@ -1266,21 +1266,30 @@ nsCocoaWindow::DispatchEvent(nsGUIEvent*
   if (mEventListener && aStatus != nsEventStatus_eConsumeNoDefault)
     aStatus = mEventListener->ProcessEvent(*event);
 
   NS_IF_RELEASE(aWidget);
 
   return NS_OK;
 }
 
+static nsSizeMode
+GetWindowSizeMode(NSWindow* aWindow) {
+  if ([aWindow isMiniaturized])
+    return nsSizeMode_Minimized;
+  if (([aWindow styleMask] & NSResizableWindowMask) && [aWindow isZoomed])
+    return nsSizeMode_Maximized;
+  return nsSizeMode_Normal;
+}
+
 void
-nsCocoaWindow::DispatchSizeModeEvent(nsSizeMode aSizeMode)
+nsCocoaWindow::DispatchSizeModeEvent()
 {
   nsSizeModeEvent event(PR_TRUE, NS_SIZEMODE, this);
-  event.mSizeMode = aSizeMode;
+  event.mSizeMode = GetWindowSizeMode(mWindow);
   event.time = PR_IntervalNow();
 
   nsEventStatus status = nsEventStatus_eIgnore;
   DispatchEvent(&event, status);
 }
 
 void
 nsCocoaWindow::ReportSizeEvent(NSRect *r)
@@ -1578,16 +1587,17 @@ nsCocoaWindow::UnifiedShading(void* aInf
 
 - (id)initWithGeckoWindow:(nsCocoaWindow*)geckoWind
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
   [super init];
   mGeckoWindow = geckoWind;
   mToplevelActiveState = PR_FALSE;
+  mHasEverBeenZoomed = PR_FALSE;
   return self;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 - (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)proposedFrameSize
 {
   RollUpPopups();
@@ -1595,16 +1605,18 @@ nsCocoaWindow::UnifiedShading(void* aInf
   return proposedFrameSize;
 }
 
 - (void)windowDidResize:(NSNotification *)aNotification
 {
   if (!mGeckoWindow || mGeckoWindow->IsResizing())
     return;
 
+  // Resizing might have changed our zoom state.
+  mGeckoWindow->DispatchSizeModeEvent();
   mGeckoWindow->ReportSizeEvent();
 }
 
 - (void)windowDidBecomeMain:(NSNotification *)aNotification
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   RollUpPopups();
@@ -1695,23 +1707,32 @@ nsCocoaWindow::UnifiedShading(void* aInf
 - (void)windowWillMiniaturize:(NSNotification *)aNotification
 {
   RollUpPopups();
 }
 
 - (void)windowDidMiniaturize:(NSNotification *)aNotification
 {
   if (mGeckoWindow)
-    mGeckoWindow->DispatchSizeModeEvent(nsSizeMode_Minimized);
+    mGeckoWindow->DispatchSizeModeEvent();
 }
 
 - (void)windowDidDeminiaturize:(NSNotification *)aNotification
 {
   if (mGeckoWindow)
-    mGeckoWindow->DispatchSizeModeEvent(nsSizeMode_Normal);
+    mGeckoWindow->DispatchSizeModeEvent();
+}
+
+- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)proposedFrame
+{
+  if (!mHasEverBeenZoomed && [window isZoomed])
+    return NO; // See bug 429954.
+
+  mHasEverBeenZoomed = YES;
+  return YES;
 }
 
 - (void)sendFocusEvent:(PRUint32)eventType
 {
   if (!mGeckoWindow)
     return;
 
   nsEventStatus status = nsEventStatus_eIgnore;