Bug 381746: odd and changing border in frameset (and a couple other regressions relating to black boxes). r+sr=roc.
authorsharparrow1@yahoo.com
Fri, 25 May 2007 20:45:00 -0700
changeset 1884 e4a5f62760659489e0b26ef2a3a30584c0b75145
parent 1883 84172b9759317ff738ff66ca057e59d2e38544d4
child 1885 e6d0678c5d1faf25a904fc829857d019da822fe9
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
bugs381746
milestone1.9a5pre
Bug 381746: odd and changing border in frameset (and a couple other regressions relating to black boxes). r+sr=roc.
view/src/nsView.cpp
view/src/nsView.h
--- a/view/src/nsView.cpp
+++ b/view/src/nsView.cpp
@@ -33,22 +33,19 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsView.h"
 #include "nsIWidget.h"
 #include "nsViewManager.h"
-#include "nsIWidget.h"
 #include "nsGUIEvent.h"
 #include "nsIDeviceContext.h"
 #include "nsIComponentManager.h"
-#include "nsIRenderingContext.h"
-#include "nsTransform2D.h"
 #include "nsIScrollableView.h"
 #include "nsGfxCIID.h"
 #include "nsIRegion.h"
 #include "nsIInterfaceRequestor.h"
 
 
 //mmptemp
 
@@ -339,16 +336,49 @@ void nsView::ResetWidgetBounds(PRBool aR
   } else if (aRecurse) {
     // reposition any widgets under this view
     for (nsView* v = GetFirstChild(); v; v = v->GetNextSibling()) {
       v->ResetWidgetBounds(PR_TRUE, aMoveOnly, aInvalidateChangedSize);
     }
   }
 }
 
+nsRect nsView::CalcWidgetBounds(nsWindowType aType)
+{
+  nsCOMPtr<nsIDeviceContext> dx;
+  mViewManager->GetDeviceContext(*getter_AddRefs(dx));
+  NS_ASSERTION(dx, "View manager can't be created without a device context");
+  PRInt32 p2a = dx->AppUnitsPerDevPixel();
+
+  nsRect viewBounds(mDimBounds);
+
+  if (GetParent()) {
+    // put offset into screen coordinates
+    nsPoint offset;
+    nsIWidget* parentWidget = GetParent()->GetNearestWidget(&offset);
+    viewBounds += offset;
+
+    if (aType == eWindowType_popup && mVis == nsViewVisibility_kShow) {
+      nsRect screenRect(0,0,1,1);
+      parentWidget->WidgetToScreen(screenRect, screenRect);
+      viewBounds += nsPoint(NSIntPixelsToAppUnits(screenRect.x, p2a),
+                            NSIntPixelsToAppUnits(screenRect.y, p2a));
+    }
+  }
+
+  nsRect newBounds(viewBounds);
+  newBounds.ScaleRoundPreservingCenters(1.0f / p2a);
+
+  nsPoint roundedOffset(NSIntPixelsToAppUnits(newBounds.x, p2a),
+                        NSIntPixelsToAppUnits(newBounds.y, p2a));
+  mViewToWidgetOffset = viewBounds.TopLeft() - roundedOffset;
+
+  return newBounds;
+}
+
 void nsView::DoResetWidgetBounds(PRBool aMoveOnly,
                                  PRBool aInvalidateChangedSize) {
   // The geometry of a root view's widget is controlled externally,
   // NOT by sizing or positioning the view
   if (mViewManager->GetRootView() == this) {
     return;
   }
   
@@ -362,65 +392,34 @@ void nsView::DoResetWidgetBounds(PRBool 
     // moving hidden comboboxes around, or doing X server roundtrips
     // to compute their true screen position. This could mean that WidgetToScreen
     // operations on these widgets don't return up-to-date values, but popup
     // positions aren't reliable anyway because of correction to be on or off-screen.
     return;
   }
 
   NS_PRECONDITION(mWindow, "Why was this called??");
-  nsIDeviceContext  *dx;
-  
-  mViewManager->GetDeviceContext(dx);
-  PRInt32 p2a = dx->AppUnitsPerDevPixel();
-  NS_RELEASE(dx);
+
+  nsRect newBounds = CalcWidgetBounds(type);
 
-  nsPoint offset(0, 0);
-  if (GetParent()) {
-    nsIWidget* parentWidget = GetParent()->GetNearestWidget(&offset);
-    
-    if (type == eWindowType_popup) {
-      // put offset into screen coordinates
-      nsRect screenRect(0,0,1,1);
-      parentWidget->WidgetToScreen(screenRect, screenRect);
-      offset += nsPoint(NSIntPixelsToAppUnits(screenRect.x, p2a),
-                        NSIntPixelsToAppUnits(screenRect.y, p2a));
-    }
-  }
-
-  nsRect viewBounds(mDimBounds + offset);
-
-  nsRect newBounds(viewBounds);
-  newBounds.ScaleRoundPreservingCenters(1.0f / p2a);
-
-  PRBool changedPos = PR_TRUE;
-  PRBool changedSize = PR_TRUE;
-  if (!(mVFlags & NS_VIEW_FLAG_HAS_POSITIONED_WIDGET)) {
-    mVFlags |= NS_VIEW_FLAG_HAS_POSITIONED_WIDGET;
-  } else {
-    changedPos = curBounds.TopLeft() != newBounds.TopLeft();
-    changedSize = curBounds.Size() != newBounds.Size();
-  }
+  PRBool changedPos = curBounds.TopLeft() != newBounds.TopLeft();
+  PRBool changedSize = curBounds.Size() != newBounds.Size();
 
   if (changedPos) {
     if (changedSize && !aMoveOnly) {
       mWindow->Resize(newBounds.x, newBounds.y, newBounds.width, newBounds.height,
                       aInvalidateChangedSize);
     } else {
       mWindow->Move(newBounds.x, newBounds.y);
     }
   } else {
     if (changedSize && !aMoveOnly) {
       mWindow->Resize(newBounds.width, newBounds.height, aInvalidateChangedSize);
     } // else do nothing!
   }
-
-  nsPoint roundedOffset(NSIntPixelsToAppUnits(newBounds.x, p2a),
-                        NSIntPixelsToAppUnits(newBounds.y, p2a));
-  mViewToWidgetOffset = viewBounds.TopLeft() - roundedOffset;
 }
 
 void nsView::SetDimensions(const nsRect& aRect, PRBool aPaint, PRBool aResizeWidget)
 {
   nsRect dims = aRect;
   dims.MoveBy(mPosX, mPosY);
 
   // Don't use nsRect's operator== here, since it returns true when
@@ -605,37 +604,35 @@ static PRInt32 FindNonAutoZIndex(nsView*
 
 nsresult nsIView::CreateWidget(const nsIID &aWindowIID,
                                nsWidgetInitData *aWidgetInitData,
                                nsNativeWidget aNative,
                                PRBool aEnableDragDrop,
                                PRBool aResetVisibility,
                                nsContentType aContentType)
 {
-  nsIDeviceContext  *dx;
-  nsRect            trect = mDimBounds;
-
   if (NS_UNLIKELY(mWindow)) {
     NS_ERROR("We already have a window for this view? BAD");
     ViewWrapper* wrapper = GetWrapperFor(mWindow);
     NS_IF_RELEASE(wrapper);
     mWindow->SetClientData(nsnull);
     NS_RELEASE(mWindow);
   }
 
-  mViewManager->GetDeviceContext(dx);
-  float scale = 1.0f / dx->AppUnitsPerDevPixel();
+  nsView* v = NS_STATIC_CAST(nsView*, this);
 
-  trect *= scale;
+  nsRect trect = v->CalcWidgetBounds(aWidgetInitData
+                                     ? aWidgetInitData->mWindowType
+                                     : eWindowType_child);
 
-  nsView* v = NS_STATIC_CAST(nsView*, this);
   if (NS_OK == v->LoadWidget(aWindowIID))
   {
     PRBool usewidgets;
-
+    nsCOMPtr<nsIDeviceContext> dx;
+    mViewManager->GetDeviceContext(*getter_AddRefs(dx));
     dx->SupportsNativeWidgets(usewidgets);
 
     if (PR_TRUE == usewidgets)
     {
       PRBool initDataPassedIn = PR_TRUE;
       nsWidgetInitData initData;
       if (!aWidgetInitData) {
         // No initData, we're a child window
@@ -649,21 +646,18 @@ nsresult nsIView::CreateWidget(const nsI
 
       if (aNative)
         mWindow->Create(aNative, trect, ::HandleEvent, dx, nsnull, nsnull, aWidgetInitData);
       else
       {
         if (!initDataPassedIn && GetParent() && 
           GetParent()->GetViewManager() != mViewManager)
           initData.mListenForResizes = PR_TRUE;
-
-        nsPoint offset(0, 0);
-        nsIWidget* parentWidget = GetParent() ? GetParent()->GetNearestWidget(&offset)
-          : nsnull;
-        trect += offset;
+        nsIWidget* parentWidget = GetParent() ? GetParent()->GetNearestWidget(nsnull)
+                                              : nsnull;
         if (aWidgetInitData->mWindowType == eWindowType_popup) {
           // Without a parent, we can't make a popup.  This can happen
           // when printing
           if (!parentWidget)
             return NS_ERROR_FAILURE;
           mWindow->Create(parentWidget->GetNativeData(NS_NATIVE_WIDGET), trect,
                           ::HandleEvent, dx, nsnull, nsnull, aWidgetInitData);
         } else {
@@ -672,27 +666,31 @@ nsresult nsIView::CreateWidget(const nsI
         }
       }
       if (aEnableDragDrop) {
         mWindow->EnableDragDrop(PR_TRUE);
       }
       
       // propagate the z-index to the widget.
       UpdateNativeWidgetZIndexes(v, FindNonAutoZIndex(v));
+    } else {
+      // We should tell the widget its size even if we don't create a
+      // native widget.  (At the moment, this doesn't really matter,
+      // but we might want it to work at some point.)
+      mWindow->Resize(trect.x, trect.y, trect.width, trect.height,
+                      PR_FALSE);
     }
   }
 
   //make sure visibility state is accurate
-  
+
   if (aResetVisibility) {
     v->SetVisibility(GetVisibility());
   }
 
-  NS_RELEASE(dx);
-
   return NS_OK;
 }
 
 void nsView::SetZIndex(PRBool aAuto, PRInt32 aZIndex, PRBool aTopMost)
 {
   PRBool oldIsAuto = GetZIndexIsAuto();
   mVFlags = (mVFlags & ~NS_VIEW_FLAG_AUTO_ZINDEX) | (aAuto ? NS_VIEW_FLAG_AUTO_ZINDEX : 0);
   mZIndex = aZIndex;
@@ -718,18 +716,16 @@ NS_IMETHODIMP nsView::SetWidget(nsIWidge
   mWindow = aWidget;
 
   if (nsnull != mWindow)
   {
     NS_ADDREF(mWindow);
     mWindow->SetClientData(wrapper);
   }
 
-  mVFlags &= ~NS_VIEW_FLAG_HAS_POSITIONED_WIDGET;
-
   UpdateNativeWidgetZIndexes(this, FindNonAutoZIndex(this));
 
   return NS_OK;
 }
 
 //
 // internal window creation functions
 //
@@ -744,33 +740,32 @@ nsresult nsView::LoadWidget(const nsCID 
 
   if (NS_SUCCEEDED(rv)) {
     // Set the widget's client data
     mWindow->SetClientData(wrapper);
   } else {
     delete wrapper;
   }
 
-  mVFlags &= ~NS_VIEW_FLAG_HAS_POSITIONED_WIDGET;
   return rv;
 }
 
 #ifdef DEBUG
 void nsIView::List(FILE* out, PRInt32 aIndent) const
 {
   PRInt32 i;
   for (i = aIndent; --i >= 0; ) fputs("  ", out);
   fprintf(out, "%p ", (void*)this);
   if (nsnull != mWindow) {
     nsRect windowBounds;
     nsRect nonclientBounds;
     float p2t;
     nsIDeviceContext *dx;
     mViewManager->GetDeviceContext(dx);
-    p2t = dx->AppUnitsPerDevPixel();
+    p2t = (float) dx->AppUnitsPerDevPixel();
     NS_RELEASE(dx);
     mWindow->GetClientBounds(windowBounds);
     windowBounds *= p2t;
     mWindow->GetBounds(nonclientBounds);
     nonclientBounds *= p2t;
     nsrefcnt widgetRefCnt = mWindow->AddRef() - 1;
     mWindow->Release();
     PRInt32 Z;
--- a/view/src/nsView.h
+++ b/view/src/nsView.h
@@ -53,35 +53,20 @@
 class nsIRegion;
 class nsIRenderingContext;
 class nsIViewManager;
 class nsViewManager;
 class nsZPlaceholderView;
 
 // View flags private to the view module
 
-// indicates that the view is or contains a placeholder view
-#define NS_VIEW_FLAG_CONTAINS_PLACEHOLDER 0x0100
-
 // Flag to determine whether the view will check if events can be handled
 // by its children or just handle the events itself
 #define NS_VIEW_FLAG_DONT_CHECK_CHILDREN  0x0200
 
-// set if this view is clipping its normal descendants
-// to its bounds. When this flag is set, child views
-// bounds need not be inside this view's bounds.
-#define NS_VIEW_FLAG_CLIP_CHILDREN_TO_BOUNDS      0x0800
-
-// set if this view is clipping its descendants (including
-// placeholders) to its bounds
-#define NS_VIEW_FLAG_CLIP_PLACEHOLDERS_TO_BOUNDS  0x1000
-
-// set if this view has positioned its widget at least once
-#define NS_VIEW_FLAG_HAS_POSITIONED_WIDGET 0x2000
-
 class nsView : public nsIView
 {
 public:
   nsView(nsViewManager* aViewManager = nsnull,
          nsViewVisibility aVisibility = nsViewVisibility_kShow);
 
   NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
 
@@ -217,21 +202,23 @@ public:
   void InvalidateHierarchy(nsViewManager *aViewManagerParent);
 
   virtual ~nsView();
 
   nsPoint ViewToWidgetOffset() const {
     return mViewToWidgetOffset;
   }
 
+  nsRect CalcWidgetBounds(nsWindowType aType);
+
 protected:
   // Do the actual work of ResetWidgetBounds, unconditionally.  Don't
   // call this method if we have no widget.
   void DoResetWidgetBounds(PRBool aMoveOnly, PRBool aInvalidateChangedSize);
-  
+
   nsZPlaceholderView* mZParent;
 
   // mClipRect is relative to the view's origin.
   nsRect*      mClipRect;
   nsRegion*    mDirtyRegion;
   nsPoint      mViewToWidgetOffset;
   PRPackedBool mChildRemoved;
 };